blob: a47f64e5be8fdd92d2f5d5f941131e3589589259 [file] [log] [blame]
Arthur Ishiguro4e916c32021-08-12 12:47:03 -07001/*
2 * Copyright (C) 2021 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#include <aidl/Gtest.h>
17#include <aidl/Vintf.h>
18
19#include "VtsHalContexthubUtilsCommon.h"
20
21#include <android/hardware/contexthub/BnContextHub.h>
22#include <android/hardware/contexthub/BnContextHubCallback.h>
23#include <android/hardware/contexthub/IContextHub.h>
24#include <android/hardware/contexthub/IContextHubCallback.h>
25#include <binder/IServiceManager.h>
26#include <binder/ProcessState.h>
27#include <log/log.h>
28
29#include <cinttypes>
30#include <future>
31
32using ::android::ProcessState;
33using ::android::sp;
34using ::android::String16;
35using ::android::binder::Status;
36using ::android::hardware::contexthub::AsyncEventType;
37using ::android::hardware::contexthub::ContextHubInfo;
38using ::android::hardware::contexthub::ContextHubMessage;
Arthur Ishiguro065a9a52021-11-19 00:24:45 +000039using ::android::hardware::contexthub::HostEndpointInfo;
Arthur Ishiguro4e916c32021-08-12 12:47:03 -070040using ::android::hardware::contexthub::IContextHub;
41using ::android::hardware::contexthub::IContextHubCallbackDefault;
42using ::android::hardware::contexthub::NanoappBinary;
43using ::android::hardware::contexthub::NanoappInfo;
Arthur Ishiguro08103072021-12-09 18:30:49 +000044using ::android::hardware::contexthub::NanoappRpcService;
Arthur Ishiguro4e916c32021-08-12 12:47:03 -070045using ::android::hardware::contexthub::Setting;
46using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
47using ::android::hardware::contexthub::vts_utils::waitForCallback;
48
49class ContextHubAidl : public testing::TestWithParam<std::tuple<std::string, int32_t>> {
50 public:
51 virtual void SetUp() override {
52 contextHub = android::waitForDeclaredService<IContextHub>(
53 String16(std::get<0>(GetParam()).c_str()));
54 ASSERT_NE(contextHub, nullptr);
55 }
56
57 uint32_t getHubId() { return std::get<1>(GetParam()); }
58
59 void testSettingChanged(Setting setting);
60
61 sp<IContextHub> contextHub;
62};
63
64TEST_P(ContextHubAidl, TestGetHubs) {
65 std::vector<ContextHubInfo> hubs;
66 ASSERT_TRUE(contextHub->getContextHubs(&hubs).isOk());
67
68 ALOGD("System reports %zu hubs", hubs.size());
69
70 for (const ContextHubInfo& hub : hubs) {
71 ALOGD("Checking hub ID %" PRIu32, hub.id);
72
73 EXPECT_GT(hub.name.size(), 0);
74 EXPECT_GT(hub.vendor.size(), 0);
75 EXPECT_GT(hub.toolchain.size(), 0);
76 EXPECT_GT(hub.peakMips, 0);
77 EXPECT_GT(hub.chrePlatformId, 0);
78 EXPECT_GT(hub.chreApiMajorVersion, 0);
Arthur Ishiguro6471f612021-10-28 21:59:55 +000079 EXPECT_GE(hub.chreApiMinorVersion, 0);
80 EXPECT_GE(hub.chrePatchVersion, 0);
Arthur Ishiguro4e916c32021-08-12 12:47:03 -070081
82 // Minimum 128 byte MTU as required by CHRE API v1.0
83 EXPECT_GE(hub.maxSupportedMessageLengthBytes, UINT32_C(128));
84 }
85}
86
Arthur Ishiguroe6b540d2021-10-29 16:01:35 +000087class EmptyContextHubCallback : public android::hardware::contexthub::BnContextHubCallback {
88 public:
89 Status handleNanoappInfo(const std::vector<NanoappInfo>& /* appInfo */) override {
90 return Status::ok();
91 }
92
93 Status handleContextHubMessage(const ContextHubMessage& /* msg */,
94 const std::vector<String16>& /* msgContentPerms */) override {
95 return Status::ok();
96 }
97
98 Status handleContextHubAsyncEvent(AsyncEventType /* evt */) override { return Status::ok(); }
99
100 Status handleTransactionResult(int32_t /* transactionId */, bool /* success */) override {
101 return Status::ok();
102 }
103};
104
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700105TEST_P(ContextHubAidl, TestRegisterCallback) {
Arthur Ishiguroe6b540d2021-10-29 16:01:35 +0000106 sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make();
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000107 ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700108}
109
110TEST_P(ContextHubAidl, TestRegisterNullCallback) {
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000111 ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700112}
113
114// Helper callback that puts the async appInfo callback data into a promise
115class QueryAppsCallback : public android::hardware::contexthub::BnContextHubCallback {
116 public:
117 Status handleNanoappInfo(const std::vector<NanoappInfo>& appInfo) override {
118 ALOGD("Got app info callback with %zu apps", appInfo.size());
119 promise.set_value(appInfo);
120 return Status::ok();
121 }
122
123 Status handleContextHubMessage(const ContextHubMessage& /* msg */,
124 const std::vector<String16>& /* msgContentPerms */) override {
125 return Status::ok();
126 }
127
128 Status handleContextHubAsyncEvent(AsyncEventType /* evt */) override { return Status::ok(); }
129
130 Status handleTransactionResult(int32_t /* transactionId */, bool /* success */) override {
131 return Status::ok();
132 }
133
134 std::promise<std::vector<NanoappInfo>> promise;
135};
136
137// Calls queryApps() and checks the returned metadata
138TEST_P(ContextHubAidl, TestQueryApps) {
139 sp<QueryAppsCallback> cb = sp<QueryAppsCallback>::make();
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000140 ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
141 ASSERT_TRUE(contextHub->queryNanoapps(getHubId()).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700142
143 std::vector<NanoappInfo> appInfoList;
144 ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appInfoList));
145 for (const NanoappInfo& appInfo : appInfoList) {
146 EXPECT_NE(appInfo.nanoappId, UINT64_C(0));
147 EXPECT_NE(appInfo.nanoappId, kNonExistentAppId);
Arthur Ishiguro08103072021-12-09 18:30:49 +0000148
149 // Verify services are unique.
150 std::set<uint64_t> existingServiceIds;
151 for (const NanoappRpcService& rpcService : appInfo.rpcServices) {
152 EXPECT_NE(rpcService.id, UINT64_C(0));
153 EXPECT_EQ(existingServiceIds.count(rpcService.id), 0);
154 existingServiceIds.insert(rpcService.id);
155 }
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700156 }
157}
158
159// Helper callback that puts the TransactionResult for the expectedTransactionId into a
160// promise
161class TransactionResultCallback : public android::hardware::contexthub::BnContextHubCallback {
162 public:
163 Status handleNanoappInfo(const std::vector<NanoappInfo>& /* appInfo */) override {
164 return Status::ok();
165 }
166
167 Status handleContextHubMessage(const ContextHubMessage& /* msg */,
168 const std::vector<String16>& /* msgContentPerms */) override {
169 return Status::ok();
170 }
171
172 Status handleContextHubAsyncEvent(AsyncEventType /* evt */) override { return Status::ok(); }
173
174 Status handleTransactionResult(int32_t transactionId, bool success) override {
175 ALOGD("Got transaction result callback for transactionId %" PRIu32 " (expecting %" PRIu32
176 ") with success %d",
177 transactionId, expectedTransactionId, success);
178 if (transactionId == expectedTransactionId) {
179 promise.set_value(success);
180 }
181 return Status::ok();
182 }
183
184 uint32_t expectedTransactionId = 0;
185 std::promise<bool> promise;
186};
187
188// Parameterized fixture that sets the callback to TransactionResultCallback
189class ContextHubTransactionTest : public ContextHubAidl {
190 public:
191 virtual void SetUp() override {
192 ContextHubAidl::SetUp();
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000193 ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700194 }
195
196 sp<TransactionResultCallback> cb = sp<TransactionResultCallback>::make();
197};
198
199TEST_P(ContextHubTransactionTest, TestSendMessageToNonExistentNanoapp) {
200 ContextHubMessage message;
201 message.nanoappId = kNonExistentAppId;
202 message.messageType = 1;
203 message.messageBody.resize(4);
204 std::fill(message.messageBody.begin(), message.messageBody.end(), 0);
205
206 ALOGD("Sending message to non-existent nanoapp");
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000207 ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700208}
209
210TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) {
211 cb->expectedTransactionId = 0123;
212 NanoappBinary emptyApp;
213
214 emptyApp.nanoappId = kNonExistentAppId;
215 emptyApp.nanoappVersion = 1;
216 emptyApp.flags = 0;
217 emptyApp.targetChreApiMajorVersion = 1;
218 emptyApp.targetChreApiMinorVersion = 0;
219
220 ALOGD("Loading empty nanoapp");
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000221 bool success = contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId).isOk();
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700222 if (success) {
223 bool transactionSuccess;
224 ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
225 ASSERT_FALSE(transactionSuccess);
226 }
227}
228
229TEST_P(ContextHubTransactionTest, TestUnloadNonexistentNanoapp) {
230 cb->expectedTransactionId = 1234;
231
232 ALOGD("Unloading nonexistent nanoapp");
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000233 bool success =
234 contextHub->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
235 .isOk();
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700236 if (success) {
237 bool transactionSuccess;
238 ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
239 ASSERT_FALSE(transactionSuccess);
240 }
241}
242
243TEST_P(ContextHubTransactionTest, TestEnableNonexistentNanoapp) {
244 cb->expectedTransactionId = 2345;
245
246 ALOGD("Enabling nonexistent nanoapp");
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000247 bool success =
248 contextHub->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
249 .isOk();
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700250 if (success) {
251 bool transactionSuccess;
252 ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
253 ASSERT_FALSE(transactionSuccess);
254 }
255}
256
257TEST_P(ContextHubTransactionTest, TestDisableNonexistentNanoapp) {
258 cb->expectedTransactionId = 3456;
259
260 ALOGD("Disabling nonexistent nanoapp");
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000261 bool success =
262 contextHub->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
263 .isOk();
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700264 if (success) {
265 bool transactionSuccess;
266 ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
267 ASSERT_FALSE(transactionSuccess);
268 }
269}
270
271void ContextHubAidl::testSettingChanged(Setting setting) {
272 // In VTS, we only test that sending the values doesn't cause things to blow up - GTS tests
273 // verify the expected E2E behavior in CHRE
Arthur Ishiguroe6b540d2021-10-29 16:01:35 +0000274 sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make();
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000275 ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700276
277 ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk());
278 ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk());
279
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000280 ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700281}
282
283TEST_P(ContextHubAidl, TestOnLocationSettingChanged) {
284 testSettingChanged(Setting::LOCATION);
285}
286
287TEST_P(ContextHubAidl, TestOnWifiMainSettingChanged) {
288 testSettingChanged(Setting::WIFI_MAIN);
289}
290
291TEST_P(ContextHubAidl, TestOnWifiScanningSettingChanged) {
292 testSettingChanged(Setting::WIFI_SCANNING);
293}
294
295TEST_P(ContextHubAidl, TestOnAirplaneModeSettingChanged) {
296 testSettingChanged(Setting::AIRPLANE_MODE);
297}
298
299TEST_P(ContextHubAidl, TestOnMicrophoneSettingChanged) {
300 testSettingChanged(Setting::MICROPHONE);
301}
302
303std::vector<std::tuple<std::string, int32_t>> generateContextHubMapping() {
304 std::vector<std::tuple<std::string, int32_t>> tuples;
305 auto contextHubAidlNames = android::getAidlHalInstanceNames(IContextHub::descriptor);
306 std::vector<ContextHubInfo> contextHubInfos;
307
308 for (int i = 0; i < contextHubAidlNames.size(); i++) {
309 auto contextHubName = contextHubAidlNames[i].c_str();
310 auto contextHub = android::waitForDeclaredService<IContextHub>(String16(contextHubName));
311 if (contextHub->getContextHubs(&contextHubInfos).isOk()) {
312 for (auto& info : contextHubInfos) {
313 tuples.push_back(std::make_tuple(contextHubName, info.id));
314 }
315 }
316 }
317
318 return tuples;
319}
320
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000321TEST_P(ContextHubAidl, TestHostConnection) {
322 constexpr char16_t kHostEndpointId = 1;
323 HostEndpointInfo hostEndpointInfo;
324 hostEndpointInfo.hostEndpointId = kHostEndpointId;
325
326 ASSERT_TRUE(contextHub->onHostEndpointConnected(hostEndpointInfo).isOk());
327 ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
328}
329
330TEST_P(ContextHubAidl, TestInvalidHostConnection) {
331 constexpr char16_t kHostEndpointId = 1;
332
333 Status status = contextHub->onHostEndpointDisconnected(kHostEndpointId);
334 ASSERT_EQ(status.exceptionCode(), android::binder::Status::EX_ILLEGAL_ARGUMENT);
335}
336
Arthur Ishiguro4e916c32021-08-12 12:47:03 -0700337std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
338 return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
339}
340
341GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextHubAidl);
342INSTANTIATE_TEST_SUITE_P(ContextHub, ContextHubAidl, testing::ValuesIn(generateContextHubMapping()),
343 PrintGeneratedTest);
344
345GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContextHubTransactionTest);
346INSTANTIATE_TEST_SUITE_P(ContextHub, ContextHubTransactionTest,
347 testing::ValuesIn(generateContextHubMapping()), PrintGeneratedTest);
348
349int main(int argc, char** argv) {
350 ::testing::InitGoogleTest(&argc, argv);
351 ProcessState::self()->setThreadPoolMaxThreadCount(1);
352 ProcessState::self()->startThreadPool();
353 return RUN_ALL_TESTS();
354}