1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "contexthub_hidl_hal_test"
18 
19 #include "ContexthubCallbackBase.h"
20 #include "ContexthubHidlTestBase.h"
21 #include "VtsHalContexthubUtilsCommon.h"
22 #include "VtsHalContexthubUtilsHidl.h"
23 
24 #include <android-base/logging.h>
25 #include <android/hardware/contexthub/1.0/IContexthub.h>
26 #include <android/hardware/contexthub/1.1/IContexthub.h>
27 #include <android/hardware/contexthub/1.2/IContexthub.h>
28 #include <android/log.h>
29 #include <gtest/gtest.h>
30 #include <hidl/GtestPrinter.h>
31 #include <hidl/ServiceManagement.h>
32 #include <log/log.h>
33 
34 #include <cinttypes>
35 
36 using ::android::sp;
37 using ::android::hardware::hidl_string;
38 using ::android::hardware::hidl_vec;
39 using ::android::hardware::Return;
40 using ::android::hardware::Void;
41 using ::android::hardware::contexthub::V1_0::ContextHub;
42 using ::android::hardware::contexthub::V1_0::Result;
43 using ::android::hardware::contexthub::V1_0::TransactionResult;
44 using ::android::hardware::contexthub::V1_1::SettingValue;
45 using ::android::hardware::contexthub::V1_2::ContextHubMsg;
46 using ::android::hardware::contexthub::V1_2::HubAppInfo;
47 using ::android::hardware::contexthub::V1_2::IContexthub;
48 using ::android::hardware::contexthub::V1_2::IContexthubCallback;
49 using ::android::hardware::contexthub::V1_2::Setting;
50 using ::android::hardware::contexthub::vts_utils::asBaseType;
51 using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase;
52 using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase;
53 using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList;
54 using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
55 using ::android::hardware::contexthub::vts_utils::waitForCallback;
56 
57 namespace {
58 
59 const std::vector<std::tuple<std::string, std::string>> kTestParameters =
60         getHalAndHubIdList<IContexthub>();
61 
62 class ContexthubCallbackV1_2 : public ContexthubCallbackBase<IContexthubCallback> {
63   public:
handleClientMsg_1_2(const ContextHubMsg &,const hidl_vec<hidl_string> &)64     virtual Return<void> handleClientMsg_1_2(
65             const ContextHubMsg& /*msg*/,
66             const hidl_vec<hidl_string>& /*msgContentPerms*/) override {
67         ALOGD("Got client message callback");
68         return Void();
69     }
70 
handleAppsInfo_1_2(const hidl_vec<HubAppInfo> &)71     virtual Return<void> handleAppsInfo_1_2(const hidl_vec<HubAppInfo>& /*appInfo*/) override {
72         ALOGD("Got app info callback");
73         return Void();
74     }
75 };
76 
77 class ContexthubHidlTest : public ContexthubHidlTestBase<IContexthub> {
78   public:
registerCallback_1_2(sp<IContexthubCallback> cb)79     Result registerCallback_1_2(sp<IContexthubCallback> cb) {
80         return hubApi->registerCallback_1_2(getHubId(), cb);
81     }
82 };
83 
84 // Ensures that the metadata reported in getHubs_1_2() is valid
TEST_P(ContexthubHidlTest,TestGetHubs_1_2)85 TEST_P(ContexthubHidlTest, TestGetHubs_1_2) {
86     hidl_vec<ContextHub> hubList;
87     hubApi->getHubs_1_2(
88             [&hubList](const hidl_vec<ContextHub>& hubs,
89                        const hidl_vec<hidl_string>& /*hubPermissions*/) { hubList = hubs; });
90 
91     ALOGD("System reports %zu hubs", hubList.size());
92 
93     for (const ContextHub& hub : hubList) {
94         ALOGD("Checking hub ID %" PRIu32, hub.hubId);
95 
96         EXPECT_FALSE(hub.name.empty());
97         EXPECT_FALSE(hub.vendor.empty());
98         EXPECT_FALSE(hub.toolchain.empty());
99         EXPECT_GT(hub.peakMips, 0);
100         EXPECT_GE(hub.stoppedPowerDrawMw, 0);
101         EXPECT_GE(hub.sleepPowerDrawMw, 0);
102         EXPECT_GT(hub.peakPowerDrawMw, 0);
103 
104         // Minimum 128 byte MTU as required by CHRE API v1.0
105         EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128));
106     }
107 }
108 
TEST_P(ContexthubHidlTest,TestRegisterCallback)109 TEST_P(ContexthubHidlTest, TestRegisterCallback) {
110     ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId());
111     ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
112 }
113 
TEST_P(ContexthubHidlTest,TestRegisterNullCallback)114 TEST_P(ContexthubHidlTest, TestRegisterNullCallback) {
115     ALOGD("TestRegisterNullCallback called, hubId %" PRIu32, getHubId());
116     ASSERT_OK(registerCallback_1_2(nullptr));
117 }
118 
119 // In VTS, we only test that sending the values doesn't cause things to blow up - other test
120 // suites verify the expected E2E behavior in CHRE
TEST_P(ContexthubHidlTest,TestOnWifiSettingChanged)121 TEST_P(ContexthubHidlTest, TestOnWifiSettingChanged) {
122     ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
123     hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::DISABLED);
124     hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::ENABLED);
125     ASSERT_OK(registerCallback_1_2(nullptr));
126 }
127 
TEST_P(ContexthubHidlTest,TestOnAirplaneModeSettingChanged)128 TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) {
129     ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
130     hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::DISABLED);
131     hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::ENABLED);
132     ASSERT_OK(registerCallback_1_2(nullptr));
133 }
134 
TEST_P(ContexthubHidlTest,TestOnMicrophoneSettingChanged)135 TEST_P(ContexthubHidlTest, TestOnMicrophoneSettingChanged) {
136     ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2()));
137     hubApi->onSettingChanged_1_2(Setting::MICROPHONE, SettingValue::DISABLED);
138     hubApi->onSettingChanged_1_2(Setting::MICROPHONE, SettingValue::ENABLED);
139     ASSERT_OK(registerCallback_1_2(nullptr));
140 }
141 
142 // Helper callback that puts the async appInfo callback data into a promise
143 class QueryAppsCallback : public ContexthubCallbackV1_2 {
144   public:
handleAppsInfo_1_2(const hidl_vec<HubAppInfo> & appInfo)145     virtual Return<void> handleAppsInfo_1_2(const hidl_vec<HubAppInfo>& appInfo) override {
146         ALOGD("Got app info callback with %zu apps", appInfo.size());
147         promise.set_value(appInfo);
148         return Void();
149     }
150 
151     std::promise<hidl_vec<HubAppInfo>> promise;
152 };
153 
154 // Calls queryApps() and checks the returned metadata
TEST_P(ContexthubHidlTest,TestQueryApps)155 TEST_P(ContexthubHidlTest, TestQueryApps) {
156     hidl_vec<hidl_string> hubPerms;
157     hubApi->getHubs_1_2([&hubPerms](const hidl_vec<ContextHub>& /*hubs*/,
158                                     const hidl_vec<hidl_string>& hubPermissions) {
159         hubPerms = hubPermissions;
160     });
161 
162     ALOGD("TestQueryApps called, hubId %u", getHubId());
163     sp<QueryAppsCallback> cb = new QueryAppsCallback();
164     ASSERT_OK(registerCallback_1_2(cb));
165 
166     Result result = hubApi->queryApps(getHubId());
167     ASSERT_OK(result);
168 
169     ALOGD("Waiting for app info callback");
170     hidl_vec<HubAppInfo> appList;
171     ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appList));
172     for (const HubAppInfo& appInfo : appList) {
173         EXPECT_NE(appInfo.info_1_0.appId, UINT64_C(0));
174         EXPECT_NE(appInfo.info_1_0.appId, kNonExistentAppId);
175         for (std::string permission : appInfo.permissions) {
176             ASSERT_TRUE(hubPerms.contains(permission));
177         }
178     }
179 }
180 
181 // Helper callback that puts the TransactionResult for the expectedTxnId into a
182 // promise
183 class TxnResultCallback : public ContexthubCallbackV1_2 {
184   public:
handleTxnResult(uint32_t txnId,TransactionResult result)185     virtual Return<void> handleTxnResult(uint32_t txnId, TransactionResult result) override {
186         ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %" PRIu32
187               ") with result %" PRId32,
188               txnId, expectedTxnId, result);
189         if (txnId == expectedTxnId) {
190             promise.set_value(result);
191         }
192         return Void();
193     }
194 
195     uint32_t expectedTxnId = 0;
196     std::promise<TransactionResult> promise;
197 };
198 
199 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest);
200 INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters),
201                          android::hardware::PrintInstanceTupleNameToString<>);
202 
203 }  // anonymous namespace
204