xref: /aosp_15_r20/system/chre/test/simulation/rpc_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "rpc_test.h"
18*84e33947SAndroid Build Coastguard Worker 
19*84e33947SAndroid Build Coastguard Worker #include <cstdint>
20*84e33947SAndroid Build Coastguard Worker 
21*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/core/settings.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre/util/nanoapp/log.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/util/time.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/event.h"
27*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/re.h"
28*84e33947SAndroid Build Coastguard Worker 
29*84e33947SAndroid Build Coastguard Worker #include "gtest/gtest.h"
30*84e33947SAndroid Build Coastguard Worker #include "inc/test_util.h"
31*84e33947SAndroid Build Coastguard Worker #include "test_base.h"
32*84e33947SAndroid Build Coastguard Worker #include "test_event.h"
33*84e33947SAndroid Build Coastguard Worker #include "test_event_queue.h"
34*84e33947SAndroid Build Coastguard Worker #include "test_util.h"
35*84e33947SAndroid Build Coastguard Worker 
36*84e33947SAndroid Build Coastguard Worker namespace chre {
37*84e33947SAndroid Build Coastguard Worker 
Increment(const chre_rpc_NumberMessage & request,chre_rpc_NumberMessage & response)38*84e33947SAndroid Build Coastguard Worker pw::Status RpcTestService::Increment(const chre_rpc_NumberMessage &request,
39*84e33947SAndroid Build Coastguard Worker                                      chre_rpc_NumberMessage &response) {
40*84e33947SAndroid Build Coastguard Worker   EnvSingleton::get()->mServer.setPermissionForNextMessage(
41*84e33947SAndroid Build Coastguard Worker       CHRE_MESSAGE_PERMISSION_NONE);
42*84e33947SAndroid Build Coastguard Worker   response.number = request.number + 1;
43*84e33947SAndroid Build Coastguard Worker   return pw::OkStatus();
44*84e33947SAndroid Build Coastguard Worker }
45*84e33947SAndroid Build Coastguard Worker 
46*84e33947SAndroid Build Coastguard Worker namespace {
47*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcCanPublishServicesInNanoappStart)48*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcCanPublishServicesInNanoappStart) {
49*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
50*84e33947SAndroid Build Coastguard Worker    public:
51*84e33947SAndroid Build Coastguard Worker     bool start() override {
52*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService servicesA[] = {
53*84e33947SAndroid Build Coastguard Worker           {.id = 1, .version = 0},
54*84e33947SAndroid Build Coastguard Worker           {.id = 2, .version = 0},
55*84e33947SAndroid Build Coastguard Worker       };
56*84e33947SAndroid Build Coastguard Worker 
57*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService servicesB[] = {
58*84e33947SAndroid Build Coastguard Worker           {.id = 3, .version = 0},
59*84e33947SAndroid Build Coastguard Worker           {.id = 4, .version = 0},
60*84e33947SAndroid Build Coastguard Worker       };
61*84e33947SAndroid Build Coastguard Worker 
62*84e33947SAndroid Build Coastguard Worker       return chrePublishRpcServices(servicesA, 2 /* numServices */) &&
63*84e33947SAndroid Build Coastguard Worker              chrePublishRpcServices(servicesB, 2 /* numServices */);
64*84e33947SAndroid Build Coastguard Worker     }
65*84e33947SAndroid Build Coastguard Worker   };
66*84e33947SAndroid Build Coastguard Worker 
67*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
68*84e33947SAndroid Build Coastguard Worker   Nanoapp *napp = getNanoappByAppId(appId);
69*84e33947SAndroid Build Coastguard Worker   ASSERT_NE(napp, nullptr);
70*84e33947SAndroid Build Coastguard Worker 
71*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices().size(), 4);
72*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[0].id, 1);
73*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[1].id, 2);
74*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[2].id, 3);
75*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[3].id, 4);
76*84e33947SAndroid Build Coastguard Worker }
77*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcCanNotPublishDuplicateServices)78*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcCanNotPublishDuplicateServices) {
79*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
80*84e33947SAndroid Build Coastguard Worker     bool start() override {
81*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService servicesA[] = {
82*84e33947SAndroid Build Coastguard Worker           {.id = 1, .version = 0},
83*84e33947SAndroid Build Coastguard Worker           {.id = 2, .version = 0},
84*84e33947SAndroid Build Coastguard Worker       };
85*84e33947SAndroid Build Coastguard Worker 
86*84e33947SAndroid Build Coastguard Worker       bool success = chrePublishRpcServices(servicesA, 2 /* numServices */);
87*84e33947SAndroid Build Coastguard Worker 
88*84e33947SAndroid Build Coastguard Worker       EXPECT_FALSE(chrePublishRpcServices(servicesA, 2 /* numServices */));
89*84e33947SAndroid Build Coastguard Worker 
90*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService servicesB[] = {
91*84e33947SAndroid Build Coastguard Worker           {.id = 5, .version = 0},
92*84e33947SAndroid Build Coastguard Worker           {.id = 5, .version = 0},
93*84e33947SAndroid Build Coastguard Worker       };
94*84e33947SAndroid Build Coastguard Worker 
95*84e33947SAndroid Build Coastguard Worker       EXPECT_FALSE(chrePublishRpcServices(servicesB, 2 /* numServices */));
96*84e33947SAndroid Build Coastguard Worker 
97*84e33947SAndroid Build Coastguard Worker       return success;
98*84e33947SAndroid Build Coastguard Worker     }
99*84e33947SAndroid Build Coastguard Worker   };
100*84e33947SAndroid Build Coastguard Worker 
101*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
102*84e33947SAndroid Build Coastguard Worker   Nanoapp *napp = getNanoappByAppId(appId);
103*84e33947SAndroid Build Coastguard Worker   ASSERT_NE(napp, nullptr);
104*84e33947SAndroid Build Coastguard Worker 
105*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices().size(), 2);
106*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[0].id, 1);
107*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices()[1].id, 2);
108*84e33947SAndroid Build Coastguard Worker }
109*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcDifferentAppCanPublishSameServices)110*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcDifferentAppCanPublishSameServices) {
111*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
112*84e33947SAndroid Build Coastguard Worker    public:
113*84e33947SAndroid Build Coastguard Worker     explicit App(uint64_t id) : TestNanoapp(TestNanoappInfo{.id = id}) {}
114*84e33947SAndroid Build Coastguard Worker 
115*84e33947SAndroid Build Coastguard Worker     bool start() override {
116*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService services[] = {
117*84e33947SAndroid Build Coastguard Worker           {.id = 1, .version = 0},
118*84e33947SAndroid Build Coastguard Worker           {.id = 2, .version = 0},
119*84e33947SAndroid Build Coastguard Worker       };
120*84e33947SAndroid Build Coastguard Worker 
121*84e33947SAndroid Build Coastguard Worker       return chrePublishRpcServices(services, 2 /* numServices */);
122*84e33947SAndroid Build Coastguard Worker     }
123*84e33947SAndroid Build Coastguard Worker   };
124*84e33947SAndroid Build Coastguard Worker 
125*84e33947SAndroid Build Coastguard Worker   uint64_t app1Id = loadNanoapp(MakeUnique<App>(0x01));
126*84e33947SAndroid Build Coastguard Worker   uint64_t app2Id = loadNanoapp(MakeUnique<App>(0x02));
127*84e33947SAndroid Build Coastguard Worker   Nanoapp *napp1 = getNanoappByAppId(app1Id);
128*84e33947SAndroid Build Coastguard Worker   ASSERT_NE(napp1, nullptr);
129*84e33947SAndroid Build Coastguard Worker 
130*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp1->getRpcServices().size(), 2);
131*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp1->getRpcServices()[0].id, 1);
132*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp1->getRpcServices()[1].id, 2);
133*84e33947SAndroid Build Coastguard Worker 
134*84e33947SAndroid Build Coastguard Worker   Nanoapp *napp2 = getNanoappByAppId(app2Id);
135*84e33947SAndroid Build Coastguard Worker   ASSERT_NE(napp2, nullptr);
136*84e33947SAndroid Build Coastguard Worker 
137*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp2->getRpcServices().size(), 2);
138*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp2->getRpcServices()[0].id, 1);
139*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp2->getRpcServices()[1].id, 2);
140*84e33947SAndroid Build Coastguard Worker }
141*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcCanNotPublishServicesOutsideOfNanoappStart)142*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcCanNotPublishServicesOutsideOfNanoappStart) {
143*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(PUBLISH_SERVICES, 0);
144*84e33947SAndroid Build Coastguard Worker 
145*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
146*84e33947SAndroid Build Coastguard Worker    public:
147*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
148*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
149*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
150*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
151*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
152*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
153*84e33947SAndroid Build Coastguard Worker             case PUBLISH_SERVICES: {
154*84e33947SAndroid Build Coastguard Worker               struct chreNanoappRpcService services[] = {
155*84e33947SAndroid Build Coastguard Worker                   {.id = 1, .version = 0},
156*84e33947SAndroid Build Coastguard Worker                   {.id = 2, .version = 0},
157*84e33947SAndroid Build Coastguard Worker               };
158*84e33947SAndroid Build Coastguard Worker 
159*84e33947SAndroid Build Coastguard Worker               bool success =
160*84e33947SAndroid Build Coastguard Worker                   chrePublishRpcServices(services, 2 /* numServices */);
161*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(PUBLISH_SERVICES,
162*84e33947SAndroid Build Coastguard Worker                                                         success);
163*84e33947SAndroid Build Coastguard Worker               break;
164*84e33947SAndroid Build Coastguard Worker             }
165*84e33947SAndroid Build Coastguard Worker           }
166*84e33947SAndroid Build Coastguard Worker         }
167*84e33947SAndroid Build Coastguard Worker       }
168*84e33947SAndroid Build Coastguard Worker     }
169*84e33947SAndroid Build Coastguard Worker   };
170*84e33947SAndroid Build Coastguard Worker 
171*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
172*84e33947SAndroid Build Coastguard Worker 
173*84e33947SAndroid Build Coastguard Worker   bool success = true;
174*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, PUBLISH_SERVICES);
175*84e33947SAndroid Build Coastguard Worker   waitForEvent(PUBLISH_SERVICES, &success);
176*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(success);
177*84e33947SAndroid Build Coastguard Worker 
178*84e33947SAndroid Build Coastguard Worker   Nanoapp *napp = getNanoappByAppId(appId);
179*84e33947SAndroid Build Coastguard Worker   ASSERT_NE(napp, nullptr);
180*84e33947SAndroid Build Coastguard Worker 
181*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(napp->getRpcServices().size(), 0);
182*84e33947SAndroid Build Coastguard Worker }
183*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcRegisterServicesShouldGracefullyFailOnDuplicatedService)184*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcRegisterServicesShouldGracefullyFailOnDuplicatedService) {
185*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
186*84e33947SAndroid Build Coastguard Worker    public:
187*84e33947SAndroid Build Coastguard Worker     bool start() override {
188*84e33947SAndroid Build Coastguard Worker       static RpcTestService testService;
189*84e33947SAndroid Build Coastguard Worker 
190*84e33947SAndroid Build Coastguard Worker       chre::RpcServer::Service service = {.service = testService,
191*84e33947SAndroid Build Coastguard Worker                                           .id = 0xca8f7150a3f05847,
192*84e33947SAndroid Build Coastguard Worker                                           .version = 0x01020034};
193*84e33947SAndroid Build Coastguard Worker 
194*84e33947SAndroid Build Coastguard Worker       chre::RpcServer &server = EnvSingleton::get()->mServer;
195*84e33947SAndroid Build Coastguard Worker 
196*84e33947SAndroid Build Coastguard Worker       bool status = server.registerServices(1, &service);
197*84e33947SAndroid Build Coastguard Worker 
198*84e33947SAndroid Build Coastguard Worker       EXPECT_TRUE(status);
199*84e33947SAndroid Build Coastguard Worker 
200*84e33947SAndroid Build Coastguard Worker       EXPECT_FALSE(server.registerServices(1, &service));
201*84e33947SAndroid Build Coastguard Worker 
202*84e33947SAndroid Build Coastguard Worker       return status;
203*84e33947SAndroid Build Coastguard Worker     }
204*84e33947SAndroid Build Coastguard Worker 
205*84e33947SAndroid Build Coastguard Worker     void end() override {
206*84e33947SAndroid Build Coastguard Worker       EnvSingleton::get()->closeServer();
207*84e33947SAndroid Build Coastguard Worker     }
208*84e33947SAndroid Build Coastguard Worker   };
209*84e33947SAndroid Build Coastguard Worker 
210*84e33947SAndroid Build Coastguard Worker   EnvSingleton::init();
211*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
212*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(appId);
213*84e33947SAndroid Build Coastguard Worker   EnvSingleton::deinit();
214*84e33947SAndroid Build Coastguard Worker }
215*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcGetNanoappInfoByAppIdReturnsServices)216*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcGetNanoappInfoByAppIdReturnsServices) {
217*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(QUERY_INFO, 0);
218*84e33947SAndroid Build Coastguard Worker 
219*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
220*84e33947SAndroid Build Coastguard Worker    public:
221*84e33947SAndroid Build Coastguard Worker     bool start() override {
222*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService services[] = {
223*84e33947SAndroid Build Coastguard Worker           {.id = 1, .version = 2},
224*84e33947SAndroid Build Coastguard Worker           {.id = 2, .version = 3},
225*84e33947SAndroid Build Coastguard Worker       };
226*84e33947SAndroid Build Coastguard Worker 
227*84e33947SAndroid Build Coastguard Worker       return chrePublishRpcServices(services, 2 /* numServices */);
228*84e33947SAndroid Build Coastguard Worker     }
229*84e33947SAndroid Build Coastguard Worker 
230*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
231*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
232*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
233*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
234*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
235*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
236*84e33947SAndroid Build Coastguard Worker             case QUERY_INFO: {
237*84e33947SAndroid Build Coastguard Worker               auto id = static_cast<uint64_t *>(event->data);
238*84e33947SAndroid Build Coastguard Worker               bool success = chreGetNanoappInfoByAppId(*id, &mInfo);
239*84e33947SAndroid Build Coastguard Worker               const struct chreNanoappInfo *pInfo = success ? &mInfo : nullptr;
240*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(QUERY_INFO, pInfo);
241*84e33947SAndroid Build Coastguard Worker               break;
242*84e33947SAndroid Build Coastguard Worker             }
243*84e33947SAndroid Build Coastguard Worker           }
244*84e33947SAndroid Build Coastguard Worker         }
245*84e33947SAndroid Build Coastguard Worker       }
246*84e33947SAndroid Build Coastguard Worker     }
247*84e33947SAndroid Build Coastguard Worker 
248*84e33947SAndroid Build Coastguard Worker    protected:
249*84e33947SAndroid Build Coastguard Worker     struct chreNanoappInfo mInfo;
250*84e33947SAndroid Build Coastguard Worker   };
251*84e33947SAndroid Build Coastguard Worker 
252*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
253*84e33947SAndroid Build Coastguard Worker 
254*84e33947SAndroid Build Coastguard Worker   struct chreNanoappInfo *pInfo = nullptr;
255*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, QUERY_INFO, appId);
256*84e33947SAndroid Build Coastguard Worker   waitForEvent(QUERY_INFO, &pInfo);
257*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(pInfo != nullptr);
258*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->rpcServiceCount, 2);
259*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->rpcServices[0].id, 1);
260*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->rpcServices[0].version, 2);
261*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->rpcServices[1].id, 2);
262*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->rpcServices[1].version, 3);
263*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->reserved[0], 0);
264*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->reserved[1], 0);
265*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(pInfo->reserved[2], 0);
266*84e33947SAndroid Build Coastguard Worker }
267*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcClientNanoappCanRequestServerNanoapp)268*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcClientNanoappCanRequestServerNanoapp) {
269*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(INCREMENT_REQUEST, 0);
270*84e33947SAndroid Build Coastguard Worker 
271*84e33947SAndroid Build Coastguard Worker   class ClientApp : public TestNanoapp {
272*84e33947SAndroid Build Coastguard Worker    public:
273*84e33947SAndroid Build Coastguard Worker     ClientApp() : TestNanoapp(TestNanoappInfo{.id = kPwRcpClientAppId}) {}
274*84e33947SAndroid Build Coastguard Worker 
275*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t senderInstanceId, uint16_t eventType,
276*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
277*84e33947SAndroid Build Coastguard Worker       Env *env = EnvSingleton::get();
278*84e33947SAndroid Build Coastguard Worker 
279*84e33947SAndroid Build Coastguard Worker       env->mClient.handleEvent(senderInstanceId, eventType, eventData);
280*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
281*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
282*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
283*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
284*84e33947SAndroid Build Coastguard Worker             case INCREMENT_REQUEST: {
285*84e33947SAndroid Build Coastguard Worker               auto client =
286*84e33947SAndroid Build Coastguard Worker                   env->mClient
287*84e33947SAndroid Build Coastguard Worker                       .get<rpc::pw_rpc::nanopb::RpcTestService::Client>();
288*84e33947SAndroid Build Coastguard Worker               if (client.has_value()) {
289*84e33947SAndroid Build Coastguard Worker                 chre_rpc_NumberMessage incrementRequest;
290*84e33947SAndroid Build Coastguard Worker                 incrementRequest.number = *static_cast<uint32_t *>(event->data);
291*84e33947SAndroid Build Coastguard Worker                 env->mIncrementCall = client->Increment(
292*84e33947SAndroid Build Coastguard Worker                     incrementRequest, [](const chre_rpc_NumberMessage &response,
293*84e33947SAndroid Build Coastguard Worker                                          pw::Status status) {
294*84e33947SAndroid Build Coastguard Worker                       if (status.ok()) {
295*84e33947SAndroid Build Coastguard Worker                         EnvSingleton::get()->mNumber = response.number;
296*84e33947SAndroid Build Coastguard Worker                         TestEventQueueSingleton::get()->pushEvent(
297*84e33947SAndroid Build Coastguard Worker                             INCREMENT_REQUEST, true);
298*84e33947SAndroid Build Coastguard Worker                       } else {
299*84e33947SAndroid Build Coastguard Worker                         TestEventQueueSingleton::get()->pushEvent(
300*84e33947SAndroid Build Coastguard Worker                             INCREMENT_REQUEST, false);
301*84e33947SAndroid Build Coastguard Worker                       }
302*84e33947SAndroid Build Coastguard Worker                     });
303*84e33947SAndroid Build Coastguard Worker               } else {
304*84e33947SAndroid Build Coastguard Worker                 TestEventQueueSingleton::get()->pushEvent(INCREMENT_REQUEST,
305*84e33947SAndroid Build Coastguard Worker                                                           false);
306*84e33947SAndroid Build Coastguard Worker               }
307*84e33947SAndroid Build Coastguard Worker             }
308*84e33947SAndroid Build Coastguard Worker           }
309*84e33947SAndroid Build Coastguard Worker         }
310*84e33947SAndroid Build Coastguard Worker       }
311*84e33947SAndroid Build Coastguard Worker     }
312*84e33947SAndroid Build Coastguard Worker 
313*84e33947SAndroid Build Coastguard Worker     void end() {
314*84e33947SAndroid Build Coastguard Worker       EnvSingleton::get()->closeClient();
315*84e33947SAndroid Build Coastguard Worker     }
316*84e33947SAndroid Build Coastguard Worker   };
317*84e33947SAndroid Build Coastguard Worker 
318*84e33947SAndroid Build Coastguard Worker   class ServerApp : public TestNanoapp {
319*84e33947SAndroid Build Coastguard Worker    public:
320*84e33947SAndroid Build Coastguard Worker     ServerApp() : TestNanoapp(TestNanoappInfo{.id = kPwRcpServerAppId}) {}
321*84e33947SAndroid Build Coastguard Worker 
322*84e33947SAndroid Build Coastguard Worker     bool start() override {
323*84e33947SAndroid Build Coastguard Worker       chre::RpcServer::Service service = {
324*84e33947SAndroid Build Coastguard Worker           .service = EnvSingleton::get()->mRpcTestService,
325*84e33947SAndroid Build Coastguard Worker           .id = 0xca8f7150a3f05847,
326*84e33947SAndroid Build Coastguard Worker           .version = 0x01020034};
327*84e33947SAndroid Build Coastguard Worker       return EnvSingleton::get()->mServer.registerServices(1, &service);
328*84e33947SAndroid Build Coastguard Worker     }
329*84e33947SAndroid Build Coastguard Worker 
330*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t senderInstanceId, uint16_t eventType,
331*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
332*84e33947SAndroid Build Coastguard Worker       EnvSingleton::get()->mServer.handleEvent(senderInstanceId, eventType,
333*84e33947SAndroid Build Coastguard Worker                                                eventData);
334*84e33947SAndroid Build Coastguard Worker     }
335*84e33947SAndroid Build Coastguard Worker 
336*84e33947SAndroid Build Coastguard Worker     void end() {
337*84e33947SAndroid Build Coastguard Worker       EnvSingleton::get()->closeServer();
338*84e33947SAndroid Build Coastguard Worker     }
339*84e33947SAndroid Build Coastguard Worker   };
340*84e33947SAndroid Build Coastguard Worker 
341*84e33947SAndroid Build Coastguard Worker   EnvSingleton::init();
342*84e33947SAndroid Build Coastguard Worker   uint64_t serverId = loadNanoapp(MakeUnique<ServerApp>());
343*84e33947SAndroid Build Coastguard Worker   uint64_t clientId = loadNanoapp(MakeUnique<ClientApp>());
344*84e33947SAndroid Build Coastguard Worker   bool status;
345*84e33947SAndroid Build Coastguard Worker   constexpr uint32_t kNumber = 101;
346*84e33947SAndroid Build Coastguard Worker 
347*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(clientId, INCREMENT_REQUEST, kNumber);
348*84e33947SAndroid Build Coastguard Worker   waitForEvent(INCREMENT_REQUEST, &status);
349*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(status);
350*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(EnvSingleton::get()->mNumber, kNumber + 1);
351*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(serverId);
352*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(clientId);
353*84e33947SAndroid Build Coastguard Worker   EnvSingleton::deinit();
354*84e33947SAndroid Build Coastguard Worker }
355*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,PwRpcRpcClientHasServiceCheckForAMatchingService)356*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, PwRpcRpcClientHasServiceCheckForAMatchingService) {
357*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(QUERY_HAS_SERVICE, 0);
358*84e33947SAndroid Build Coastguard Worker 
359*84e33947SAndroid Build Coastguard Worker   struct ServiceInfo {
360*84e33947SAndroid Build Coastguard Worker     uint64_t id;
361*84e33947SAndroid Build Coastguard Worker     uint32_t version;
362*84e33947SAndroid Build Coastguard Worker     uint64_t appId;
363*84e33947SAndroid Build Coastguard Worker   };
364*84e33947SAndroid Build Coastguard Worker 
365*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
366*84e33947SAndroid Build Coastguard Worker    public:
367*84e33947SAndroid Build Coastguard Worker     bool start() override {
368*84e33947SAndroid Build Coastguard Worker       struct chreNanoappRpcService services[] = {{.id = 1, .version = 2}};
369*84e33947SAndroid Build Coastguard Worker 
370*84e33947SAndroid Build Coastguard Worker       return chrePublishRpcServices(services, 1 /* numServices */);
371*84e33947SAndroid Build Coastguard Worker     }
372*84e33947SAndroid Build Coastguard Worker 
373*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType, const void *eventData) {
374*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
375*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
376*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
377*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
378*84e33947SAndroid Build Coastguard Worker             case QUERY_HAS_SERVICE: {
379*84e33947SAndroid Build Coastguard Worker               auto service =
380*84e33947SAndroid Build Coastguard Worker                   static_cast<const struct ServiceInfo *>(event->data);
381*84e33947SAndroid Build Coastguard Worker               RpcClient client{service->appId};
382*84e33947SAndroid Build Coastguard Worker               bool hasService =
383*84e33947SAndroid Build Coastguard Worker                   client.hasService(service->id, service->version);
384*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(QUERY_HAS_SERVICE,
385*84e33947SAndroid Build Coastguard Worker                                                         hasService);
386*84e33947SAndroid Build Coastguard Worker               break;
387*84e33947SAndroid Build Coastguard Worker             }
388*84e33947SAndroid Build Coastguard Worker           }
389*84e33947SAndroid Build Coastguard Worker           break;
390*84e33947SAndroid Build Coastguard Worker         }
391*84e33947SAndroid Build Coastguard Worker       }
392*84e33947SAndroid Build Coastguard Worker     }
393*84e33947SAndroid Build Coastguard Worker   };
394*84e33947SAndroid Build Coastguard Worker 
395*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
396*84e33947SAndroid Build Coastguard Worker 
397*84e33947SAndroid Build Coastguard Worker   ServiceInfo service;
398*84e33947SAndroid Build Coastguard Worker   bool hasService = false;
399*84e33947SAndroid Build Coastguard Worker 
400*84e33947SAndroid Build Coastguard Worker   service = {.id = 1, .version = 2, .appId = appId};
401*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, QUERY_HAS_SERVICE, service);
402*84e33947SAndroid Build Coastguard Worker   waitForEvent(QUERY_HAS_SERVICE, &hasService);
403*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(hasService);
404*84e33947SAndroid Build Coastguard Worker   service = {.id = 10, .version = 2, .appId = appId};
405*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, QUERY_HAS_SERVICE, service);
406*84e33947SAndroid Build Coastguard Worker   waitForEvent(QUERY_HAS_SERVICE, &hasService);
407*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(hasService);
408*84e33947SAndroid Build Coastguard Worker }
409*84e33947SAndroid Build Coastguard Worker 
410*84e33947SAndroid Build Coastguard Worker }  // namespace
411*84e33947SAndroid Build Coastguard Worker 
412*84e33947SAndroid Build Coastguard Worker }  // namespace chre
413