xref: /aosp_15_r20/system/chre/test/simulation/gnss_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 "chre_api/chre/gnss.h"
18*84e33947SAndroid Build Coastguard Worker 
19*84e33947SAndroid Build Coastguard Worker #include <cstdint>
20*84e33947SAndroid Build Coastguard Worker #include <functional>
21*84e33947SAndroid Build Coastguard Worker 
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/platform/linux/pal_gnss.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/platform/log.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/napp_permissions.h"
27*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/event.h"
28*84e33947SAndroid Build Coastguard Worker #include "gtest/gtest.h"
29*84e33947SAndroid Build Coastguard Worker #include "inc/test_util.h"
30*84e33947SAndroid Build Coastguard Worker #include "test_base.h"
31*84e33947SAndroid Build Coastguard Worker #include "test_event.h"
32*84e33947SAndroid Build Coastguard Worker #include "test_event_queue.h"
33*84e33947SAndroid Build Coastguard Worker #include "test_util.h"
34*84e33947SAndroid Build Coastguard Worker 
35*84e33947SAndroid Build Coastguard Worker namespace chre {
36*84e33947SAndroid Build Coastguard Worker namespace {
37*84e33947SAndroid Build Coastguard Worker 
38*84e33947SAndroid Build Coastguard Worker /**
39*84e33947SAndroid Build Coastguard Worker  * Wait for the predicate to become true with a timeout.
40*84e33947SAndroid Build Coastguard Worker  *
41*84e33947SAndroid Build Coastguard Worker  * @return the last value of the predicate.
42*84e33947SAndroid Build Coastguard Worker  */
waitForCondition(const std::function<bool ()> & predicate,std::chrono::milliseconds timeout)43*84e33947SAndroid Build Coastguard Worker bool waitForCondition(const std::function<bool()> &predicate,
44*84e33947SAndroid Build Coastguard Worker                       std::chrono::milliseconds timeout) {
45*84e33947SAndroid Build Coastguard Worker   constexpr std::chrono::milliseconds kSleepDuration(100);
46*84e33947SAndroid Build Coastguard Worker   bool result;
47*84e33947SAndroid Build Coastguard Worker   std::chrono::milliseconds time;
48*84e33947SAndroid Build Coastguard Worker   while (!(result = predicate()) && time < timeout) {
49*84e33947SAndroid Build Coastguard Worker     std::this_thread::sleep_for(kSleepDuration);
50*84e33947SAndroid Build Coastguard Worker     time += kSleepDuration;
51*84e33947SAndroid Build Coastguard Worker   }
52*84e33947SAndroid Build Coastguard Worker   return result;
53*84e33947SAndroid Build Coastguard Worker }
54*84e33947SAndroid Build Coastguard Worker 
55*84e33947SAndroid Build Coastguard Worker // ref b/228669574
TEST_F(TestBase,GnssSubscriptionWithSettingChange)56*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssSubscriptionWithSettingChange) {
57*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(LOCATION_REQUEST, 0);
58*84e33947SAndroid Build Coastguard Worker 
59*84e33947SAndroid Build Coastguard Worker   struct LocationRequest {
60*84e33947SAndroid Build Coastguard Worker     bool enable;
61*84e33947SAndroid Build Coastguard Worker     uint32_t cookie;
62*84e33947SAndroid Build Coastguard Worker   };
63*84e33947SAndroid Build Coastguard Worker 
64*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
65*84e33947SAndroid Build Coastguard Worker    public:
66*84e33947SAndroid Build Coastguard Worker     App()
67*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
68*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
69*84e33947SAndroid Build Coastguard Worker 
70*84e33947SAndroid Build Coastguard Worker     bool start() override {
71*84e33947SAndroid Build Coastguard Worker       chreUserSettingConfigureEvents(CHRE_USER_SETTING_LOCATION,
72*84e33947SAndroid Build Coastguard Worker                                      true /*enabled*/);
73*84e33947SAndroid Build Coastguard Worker       return true;
74*84e33947SAndroid Build Coastguard Worker     }
75*84e33947SAndroid Build Coastguard Worker 
76*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
77*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
78*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
79*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_GNSS_ASYNC_RESULT: {
80*84e33947SAndroid Build Coastguard Worker           auto *event = static_cast<const chreAsyncResult *>(eventData);
81*84e33947SAndroid Build Coastguard Worker           if (event->success) {
82*84e33947SAndroid Build Coastguard Worker             TestEventQueueSingleton::get()->pushEvent(
83*84e33947SAndroid Build Coastguard Worker                 CHRE_EVENT_GNSS_ASYNC_RESULT,
84*84e33947SAndroid Build Coastguard Worker                 *(static_cast<const uint32_t *>(event->cookie)));
85*84e33947SAndroid Build Coastguard Worker           }
86*84e33947SAndroid Build Coastguard Worker           break;
87*84e33947SAndroid Build Coastguard Worker         }
88*84e33947SAndroid Build Coastguard Worker 
89*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_SETTING_CHANGED_LOCATION: {
90*84e33947SAndroid Build Coastguard Worker           TestEventQueueSingleton::get()->pushEvent(
91*84e33947SAndroid Build Coastguard Worker               CHRE_EVENT_SETTING_CHANGED_LOCATION);
92*84e33947SAndroid Build Coastguard Worker           break;
93*84e33947SAndroid Build Coastguard Worker         }
94*84e33947SAndroid Build Coastguard Worker 
95*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
96*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
97*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
98*84e33947SAndroid Build Coastguard Worker             case LOCATION_REQUEST: {
99*84e33947SAndroid Build Coastguard Worker               auto request = static_cast<const LocationRequest *>(event->data);
100*84e33947SAndroid Build Coastguard Worker               bool success;
101*84e33947SAndroid Build Coastguard Worker               mCookie = request->cookie;
102*84e33947SAndroid Build Coastguard Worker               if (request->enable) {
103*84e33947SAndroid Build Coastguard Worker                 success = chreGnssLocationSessionStartAsync(
104*84e33947SAndroid Build Coastguard Worker                     1000 /*minIntervalMs*/, 1000 /*minTimeToNextFixMs*/,
105*84e33947SAndroid Build Coastguard Worker                     &mCookie);
106*84e33947SAndroid Build Coastguard Worker               } else {
107*84e33947SAndroid Build Coastguard Worker                 success = chreGnssLocationSessionStopAsync(&mCookie);
108*84e33947SAndroid Build Coastguard Worker               }
109*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(LOCATION_REQUEST,
110*84e33947SAndroid Build Coastguard Worker                                                         success);
111*84e33947SAndroid Build Coastguard Worker               break;
112*84e33947SAndroid Build Coastguard Worker             }
113*84e33947SAndroid Build Coastguard Worker           }
114*84e33947SAndroid Build Coastguard Worker         }
115*84e33947SAndroid Build Coastguard Worker       }
116*84e33947SAndroid Build Coastguard Worker     }
117*84e33947SAndroid Build Coastguard Worker 
118*84e33947SAndroid Build Coastguard Worker     void end() override {
119*84e33947SAndroid Build Coastguard Worker       chreUserSettingConfigureEvents(CHRE_USER_SETTING_LOCATION,
120*84e33947SAndroid Build Coastguard Worker                                      false /*enabled*/);
121*84e33947SAndroid Build Coastguard Worker     }
122*84e33947SAndroid Build Coastguard Worker 
123*84e33947SAndroid Build Coastguard Worker    protected:
124*84e33947SAndroid Build Coastguard Worker     uint32_t mCookie;
125*84e33947SAndroid Build Coastguard Worker   };
126*84e33947SAndroid Build Coastguard Worker 
127*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
128*84e33947SAndroid Build Coastguard Worker 
129*84e33947SAndroid Build Coastguard Worker   bool success;
130*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
131*84e33947SAndroid Build Coastguard Worker   chrePalGnssDelaySendingLocationEvents(true);
132*84e33947SAndroid Build Coastguard Worker 
133*84e33947SAndroid Build Coastguard Worker   LocationRequest request{.enable = true, .cookie = 0x123};
134*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LOCATION_REQUEST, request);
135*84e33947SAndroid Build Coastguard Worker   waitForEvent(LOCATION_REQUEST, &success);
136*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
137*84e33947SAndroid Build Coastguard Worker   chrePalGnssStartSendingLocationEvents();
138*84e33947SAndroid Build Coastguard Worker   uint32_t cookie;
139*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
140*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
141*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsLocationEnabled());
142*84e33947SAndroid Build Coastguard Worker 
143*84e33947SAndroid Build Coastguard Worker   EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
144*84e33947SAndroid Build Coastguard Worker       Setting::LOCATION, false /* enabled */);
145*84e33947SAndroid Build Coastguard Worker 
146*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
147*84e33947SAndroid Build Coastguard Worker 
148*84e33947SAndroid Build Coastguard Worker   // Wait for the setting change to propagate to GNSS.
149*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(waitForCondition([]() { return !chrePalGnssIsLocationEnabled(); },
150*84e33947SAndroid Build Coastguard Worker                                std::chrono::milliseconds(1000)));
151*84e33947SAndroid Build Coastguard Worker 
152*84e33947SAndroid Build Coastguard Worker   EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
153*84e33947SAndroid Build Coastguard Worker       Setting::LOCATION, true /* enabled */);
154*84e33947SAndroid Build Coastguard Worker 
155*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
156*84e33947SAndroid Build Coastguard Worker 
157*84e33947SAndroid Build Coastguard Worker   // Wait for the setting change to propagate to GNSS.
158*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(waitForCondition([]() { return chrePalGnssIsLocationEnabled(); },
159*84e33947SAndroid Build Coastguard Worker                                std::chrono::milliseconds(1000)));
160*84e33947SAndroid Build Coastguard Worker 
161*84e33947SAndroid Build Coastguard Worker   request.enable = false;
162*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LOCATION_REQUEST, request);
163*84e33947SAndroid Build Coastguard Worker   waitForEvent(LOCATION_REQUEST, &success);
164*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
165*84e33947SAndroid Build Coastguard Worker   chrePalGnssStartSendingLocationEvents();
166*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
167*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
168*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
169*84e33947SAndroid Build Coastguard Worker   chrePalGnssDelaySendingLocationEvents(false);
170*84e33947SAndroid Build Coastguard Worker }
171*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssCanSubscribeAndUnsubscribeToLocation)172*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssCanSubscribeAndUnsubscribeToLocation) {
173*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(LOCATION_REQUEST, 0);
174*84e33947SAndroid Build Coastguard Worker 
175*84e33947SAndroid Build Coastguard Worker   struct LocationRequest {
176*84e33947SAndroid Build Coastguard Worker     bool enable;
177*84e33947SAndroid Build Coastguard Worker     uint32_t cookie;
178*84e33947SAndroid Build Coastguard Worker   };
179*84e33947SAndroid Build Coastguard Worker 
180*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
181*84e33947SAndroid Build Coastguard Worker    public:
182*84e33947SAndroid Build Coastguard Worker     App()
183*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
184*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
185*84e33947SAndroid Build Coastguard Worker 
186*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
187*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
188*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
189*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_GNSS_ASYNC_RESULT: {
190*84e33947SAndroid Build Coastguard Worker           auto *event = static_cast<const chreAsyncResult *>(eventData);
191*84e33947SAndroid Build Coastguard Worker           if (event->success) {
192*84e33947SAndroid Build Coastguard Worker             TestEventQueueSingleton::get()->pushEvent(
193*84e33947SAndroid Build Coastguard Worker                 CHRE_EVENT_GNSS_ASYNC_RESULT,
194*84e33947SAndroid Build Coastguard Worker                 *(static_cast<const uint32_t *>(event->cookie)));
195*84e33947SAndroid Build Coastguard Worker           }
196*84e33947SAndroid Build Coastguard Worker           break;
197*84e33947SAndroid Build Coastguard Worker         }
198*84e33947SAndroid Build Coastguard Worker 
199*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
200*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
201*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
202*84e33947SAndroid Build Coastguard Worker             case LOCATION_REQUEST: {
203*84e33947SAndroid Build Coastguard Worker               auto request = static_cast<const LocationRequest *>(event->data);
204*84e33947SAndroid Build Coastguard Worker               bool success;
205*84e33947SAndroid Build Coastguard Worker               mCookie = request->cookie;
206*84e33947SAndroid Build Coastguard Worker               if (request->enable) {
207*84e33947SAndroid Build Coastguard Worker                 success = chreGnssLocationSessionStartAsync(
208*84e33947SAndroid Build Coastguard Worker                     1000 /*minIntervalMs*/, 1000 /*minTimeToNextFixMs*/,
209*84e33947SAndroid Build Coastguard Worker                     &mCookie);
210*84e33947SAndroid Build Coastguard Worker               } else {
211*84e33947SAndroid Build Coastguard Worker                 success = chreGnssLocationSessionStopAsync(&mCookie);
212*84e33947SAndroid Build Coastguard Worker               }
213*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(LOCATION_REQUEST,
214*84e33947SAndroid Build Coastguard Worker                                                         success);
215*84e33947SAndroid Build Coastguard Worker               break;
216*84e33947SAndroid Build Coastguard Worker             }
217*84e33947SAndroid Build Coastguard Worker           }
218*84e33947SAndroid Build Coastguard Worker         }
219*84e33947SAndroid Build Coastguard Worker       }
220*84e33947SAndroid Build Coastguard Worker     }
221*84e33947SAndroid Build Coastguard Worker 
222*84e33947SAndroid Build Coastguard Worker    protected:
223*84e33947SAndroid Build Coastguard Worker     uint32_t mCookie;
224*84e33947SAndroid Build Coastguard Worker   };
225*84e33947SAndroid Build Coastguard Worker 
226*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
227*84e33947SAndroid Build Coastguard Worker 
228*84e33947SAndroid Build Coastguard Worker   bool success;
229*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
230*84e33947SAndroid Build Coastguard Worker 
231*84e33947SAndroid Build Coastguard Worker   LocationRequest request{.enable = true, .cookie = 0x123};
232*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LOCATION_REQUEST, request);
233*84e33947SAndroid Build Coastguard Worker   waitForEvent(LOCATION_REQUEST, &success);
234*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
235*84e33947SAndroid Build Coastguard Worker   uint32_t cookie;
236*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
237*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
238*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsLocationEnabled());
239*84e33947SAndroid Build Coastguard Worker 
240*84e33947SAndroid Build Coastguard Worker   request.enable = false;
241*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LOCATION_REQUEST, request);
242*84e33947SAndroid Build Coastguard Worker   waitForEvent(LOCATION_REQUEST, &success);
243*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
244*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
245*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
246*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
247*84e33947SAndroid Build Coastguard Worker }
248*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssUnsubscribeToLocationOnUnload)249*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssUnsubscribeToLocationOnUnload) {
250*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(LOCATION_REQUEST, 0);
251*84e33947SAndroid Build Coastguard Worker 
252*84e33947SAndroid Build Coastguard Worker   struct LocationRequest {
253*84e33947SAndroid Build Coastguard Worker     bool enable;
254*84e33947SAndroid Build Coastguard Worker     uint32_t cookie;
255*84e33947SAndroid Build Coastguard Worker   };
256*84e33947SAndroid Build Coastguard Worker 
257*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
258*84e33947SAndroid Build Coastguard Worker    public:
259*84e33947SAndroid Build Coastguard Worker     App()
260*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
261*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
262*84e33947SAndroid Build Coastguard Worker 
263*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
264*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
265*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
266*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_GNSS_ASYNC_RESULT: {
267*84e33947SAndroid Build Coastguard Worker           auto *event = static_cast<const chreAsyncResult *>(eventData);
268*84e33947SAndroid Build Coastguard Worker           if (event->success) {
269*84e33947SAndroid Build Coastguard Worker             TestEventQueueSingleton::get()->pushEvent(
270*84e33947SAndroid Build Coastguard Worker                 CHRE_EVENT_GNSS_ASYNC_RESULT,
271*84e33947SAndroid Build Coastguard Worker                 *(static_cast<const uint32_t *>(event->cookie)));
272*84e33947SAndroid Build Coastguard Worker           }
273*84e33947SAndroid Build Coastguard Worker           break;
274*84e33947SAndroid Build Coastguard Worker         }
275*84e33947SAndroid Build Coastguard Worker 
276*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
277*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
278*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
279*84e33947SAndroid Build Coastguard Worker             case LOCATION_REQUEST: {
280*84e33947SAndroid Build Coastguard Worker               auto request = static_cast<const LocationRequest *>(event->data);
281*84e33947SAndroid Build Coastguard Worker               if (request->enable) {
282*84e33947SAndroid Build Coastguard Worker                 mCookie = request->cookie;
283*84e33947SAndroid Build Coastguard Worker                 const bool success = chreGnssLocationSessionStartAsync(
284*84e33947SAndroid Build Coastguard Worker                     1000 /*minIntervalMs*/, 1000 /*minTimeToNextFixMs*/,
285*84e33947SAndroid Build Coastguard Worker                     &mCookie);
286*84e33947SAndroid Build Coastguard Worker                 TestEventQueueSingleton::get()->pushEvent(LOCATION_REQUEST,
287*84e33947SAndroid Build Coastguard Worker                                                           success);
288*84e33947SAndroid Build Coastguard Worker               }
289*84e33947SAndroid Build Coastguard Worker               break;
290*84e33947SAndroid Build Coastguard Worker             }
291*84e33947SAndroid Build Coastguard Worker           }
292*84e33947SAndroid Build Coastguard Worker         }
293*84e33947SAndroid Build Coastguard Worker       }
294*84e33947SAndroid Build Coastguard Worker     }
295*84e33947SAndroid Build Coastguard Worker 
296*84e33947SAndroid Build Coastguard Worker    protected:
297*84e33947SAndroid Build Coastguard Worker     uint32_t mCookie;
298*84e33947SAndroid Build Coastguard Worker   };
299*84e33947SAndroid Build Coastguard Worker 
300*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
301*84e33947SAndroid Build Coastguard Worker 
302*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
303*84e33947SAndroid Build Coastguard Worker 
304*84e33947SAndroid Build Coastguard Worker   LocationRequest request{.enable = true, .cookie = 0x123};
305*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LOCATION_REQUEST, request);
306*84e33947SAndroid Build Coastguard Worker   bool success;
307*84e33947SAndroid Build Coastguard Worker   waitForEvent(LOCATION_REQUEST, &success);
308*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
309*84e33947SAndroid Build Coastguard Worker   uint32_t cookie;
310*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
311*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
312*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsLocationEnabled());
313*84e33947SAndroid Build Coastguard Worker 
314*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(appId);
315*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
316*84e33947SAndroid Build Coastguard Worker }
317*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssCanSubscribeAndUnsubscribeToMeasurement)318*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssCanSubscribeAndUnsubscribeToMeasurement) {
319*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(MEASUREMENT_REQUEST, 0);
320*84e33947SAndroid Build Coastguard Worker 
321*84e33947SAndroid Build Coastguard Worker   struct MeasurementRequest {
322*84e33947SAndroid Build Coastguard Worker     bool enable;
323*84e33947SAndroid Build Coastguard Worker     uint32_t cookie;
324*84e33947SAndroid Build Coastguard Worker   };
325*84e33947SAndroid Build Coastguard Worker 
326*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
327*84e33947SAndroid Build Coastguard Worker    public:
328*84e33947SAndroid Build Coastguard Worker     App()
329*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
330*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
331*84e33947SAndroid Build Coastguard Worker 
332*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
333*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
334*84e33947SAndroid Build Coastguard Worker       static uint32_t cookie;
335*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
336*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_GNSS_ASYNC_RESULT: {
337*84e33947SAndroid Build Coastguard Worker           auto *event = static_cast<const chreAsyncResult *>(eventData);
338*84e33947SAndroid Build Coastguard Worker           if (event->success) {
339*84e33947SAndroid Build Coastguard Worker             TestEventQueueSingleton::get()->pushEvent(
340*84e33947SAndroid Build Coastguard Worker                 CHRE_EVENT_GNSS_ASYNC_RESULT,
341*84e33947SAndroid Build Coastguard Worker                 *(static_cast<const uint32_t *>(event->cookie)));
342*84e33947SAndroid Build Coastguard Worker           }
343*84e33947SAndroid Build Coastguard Worker           break;
344*84e33947SAndroid Build Coastguard Worker         }
345*84e33947SAndroid Build Coastguard Worker 
346*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
347*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
348*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
349*84e33947SAndroid Build Coastguard Worker             case MEASUREMENT_REQUEST: {
350*84e33947SAndroid Build Coastguard Worker               auto request =
351*84e33947SAndroid Build Coastguard Worker                   static_cast<const MeasurementRequest *>(event->data);
352*84e33947SAndroid Build Coastguard Worker               bool success;
353*84e33947SAndroid Build Coastguard Worker               mCookie = request->cookie;
354*84e33947SAndroid Build Coastguard Worker               if (request->enable) {
355*84e33947SAndroid Build Coastguard Worker                 success = chreGnssMeasurementSessionStartAsync(
356*84e33947SAndroid Build Coastguard Worker                     1000 /*minIntervalMs*/, &mCookie);
357*84e33947SAndroid Build Coastguard Worker               } else {
358*84e33947SAndroid Build Coastguard Worker                 cookie = request->cookie;
359*84e33947SAndroid Build Coastguard Worker                 success = chreGnssMeasurementSessionStopAsync(&mCookie);
360*84e33947SAndroid Build Coastguard Worker               }
361*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(MEASUREMENT_REQUEST,
362*84e33947SAndroid Build Coastguard Worker                                                         success);
363*84e33947SAndroid Build Coastguard Worker               break;
364*84e33947SAndroid Build Coastguard Worker             }
365*84e33947SAndroid Build Coastguard Worker           }
366*84e33947SAndroid Build Coastguard Worker         }
367*84e33947SAndroid Build Coastguard Worker       }
368*84e33947SAndroid Build Coastguard Worker     }
369*84e33947SAndroid Build Coastguard Worker 
370*84e33947SAndroid Build Coastguard Worker    protected:
371*84e33947SAndroid Build Coastguard Worker     uint32_t mCookie;
372*84e33947SAndroid Build Coastguard Worker   };
373*84e33947SAndroid Build Coastguard Worker 
374*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
375*84e33947SAndroid Build Coastguard Worker 
376*84e33947SAndroid Build Coastguard Worker   bool success;
377*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
378*84e33947SAndroid Build Coastguard Worker 
379*84e33947SAndroid Build Coastguard Worker   MeasurementRequest request{.enable = true, .cookie = 0x123};
380*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, MEASUREMENT_REQUEST, request);
381*84e33947SAndroid Build Coastguard Worker   waitForEvent(MEASUREMENT_REQUEST, &success);
382*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
383*84e33947SAndroid Build Coastguard Worker   uint32_t cookie;
384*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
385*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
386*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsMeasurementEnabled());
387*84e33947SAndroid Build Coastguard Worker 
388*84e33947SAndroid Build Coastguard Worker   request.enable = false;
389*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, MEASUREMENT_REQUEST, request);
390*84e33947SAndroid Build Coastguard Worker   waitForEvent(MEASUREMENT_REQUEST, &success);
391*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
392*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
393*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
394*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsMeasurementEnabled());
395*84e33947SAndroid Build Coastguard Worker }
396*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssUnsubscribeToMeasurementOnUnload)397*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssUnsubscribeToMeasurementOnUnload) {
398*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(MEASUREMENT_REQUEST, 0);
399*84e33947SAndroid Build Coastguard Worker 
400*84e33947SAndroid Build Coastguard Worker   struct MeasurementRequest {
401*84e33947SAndroid Build Coastguard Worker     bool enable;
402*84e33947SAndroid Build Coastguard Worker     uint32_t cookie;
403*84e33947SAndroid Build Coastguard Worker   };
404*84e33947SAndroid Build Coastguard Worker 
405*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
406*84e33947SAndroid Build Coastguard Worker    public:
407*84e33947SAndroid Build Coastguard Worker     App()
408*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
409*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
410*84e33947SAndroid Build Coastguard Worker 
411*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
412*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
413*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
414*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_GNSS_ASYNC_RESULT: {
415*84e33947SAndroid Build Coastguard Worker           auto *event = static_cast<const chreAsyncResult *>(eventData);
416*84e33947SAndroid Build Coastguard Worker           if (event->success) {
417*84e33947SAndroid Build Coastguard Worker             TestEventQueueSingleton::get()->pushEvent(
418*84e33947SAndroid Build Coastguard Worker                 CHRE_EVENT_GNSS_ASYNC_RESULT,
419*84e33947SAndroid Build Coastguard Worker                 *(static_cast<const uint32_t *>(event->cookie)));
420*84e33947SAndroid Build Coastguard Worker           }
421*84e33947SAndroid Build Coastguard Worker           break;
422*84e33947SAndroid Build Coastguard Worker         }
423*84e33947SAndroid Build Coastguard Worker 
424*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
425*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
426*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
427*84e33947SAndroid Build Coastguard Worker             case MEASUREMENT_REQUEST: {
428*84e33947SAndroid Build Coastguard Worker               auto request =
429*84e33947SAndroid Build Coastguard Worker                   static_cast<const MeasurementRequest *>(event->data);
430*84e33947SAndroid Build Coastguard Worker               if (request->enable) {
431*84e33947SAndroid Build Coastguard Worker                 mCookie = request->cookie;
432*84e33947SAndroid Build Coastguard Worker                 const bool success = chreGnssMeasurementSessionStartAsync(
433*84e33947SAndroid Build Coastguard Worker                     1000 /*minIntervalMs*/, &mCookie);
434*84e33947SAndroid Build Coastguard Worker                 TestEventQueueSingleton::get()->pushEvent(MEASUREMENT_REQUEST,
435*84e33947SAndroid Build Coastguard Worker                                                           success);
436*84e33947SAndroid Build Coastguard Worker               }
437*84e33947SAndroid Build Coastguard Worker               break;
438*84e33947SAndroid Build Coastguard Worker             }
439*84e33947SAndroid Build Coastguard Worker           }
440*84e33947SAndroid Build Coastguard Worker         }
441*84e33947SAndroid Build Coastguard Worker       }
442*84e33947SAndroid Build Coastguard Worker     }
443*84e33947SAndroid Build Coastguard Worker 
444*84e33947SAndroid Build Coastguard Worker    protected:
445*84e33947SAndroid Build Coastguard Worker     uint32_t mCookie;
446*84e33947SAndroid Build Coastguard Worker   };
447*84e33947SAndroid Build Coastguard Worker 
448*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
449*84e33947SAndroid Build Coastguard Worker 
450*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsLocationEnabled());
451*84e33947SAndroid Build Coastguard Worker 
452*84e33947SAndroid Build Coastguard Worker   MeasurementRequest request{.enable = true, .cookie = 0x123};
453*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, MEASUREMENT_REQUEST, request);
454*84e33947SAndroid Build Coastguard Worker   bool success;
455*84e33947SAndroid Build Coastguard Worker   waitForEvent(MEASUREMENT_REQUEST, &success);
456*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
457*84e33947SAndroid Build Coastguard Worker   uint32_t cookie;
458*84e33947SAndroid Build Coastguard Worker   waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT, &cookie);
459*84e33947SAndroid Build Coastguard Worker   EXPECT_EQ(cookie, request.cookie);
460*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsMeasurementEnabled());
461*84e33947SAndroid Build Coastguard Worker 
462*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(appId);
463*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsMeasurementEnabled());
464*84e33947SAndroid Build Coastguard Worker }
465*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssCanSubscribeAndUnsubscribeToPassiveListener)466*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssCanSubscribeAndUnsubscribeToPassiveListener) {
467*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(LISTENER_REQUEST, 0);
468*84e33947SAndroid Build Coastguard Worker 
469*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
470*84e33947SAndroid Build Coastguard Worker    public:
471*84e33947SAndroid Build Coastguard Worker     App()
472*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
473*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
474*84e33947SAndroid Build Coastguard Worker 
475*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
476*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
477*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
478*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
479*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
480*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
481*84e33947SAndroid Build Coastguard Worker             case LISTENER_REQUEST: {
482*84e33947SAndroid Build Coastguard Worker               auto enable = *(static_cast<const bool *>(event->data));
483*84e33947SAndroid Build Coastguard Worker               const bool success =
484*84e33947SAndroid Build Coastguard Worker                   chreGnssConfigurePassiveLocationListener(enable);
485*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(LISTENER_REQUEST,
486*84e33947SAndroid Build Coastguard Worker                                                         success);
487*84e33947SAndroid Build Coastguard Worker               break;
488*84e33947SAndroid Build Coastguard Worker             }
489*84e33947SAndroid Build Coastguard Worker           }
490*84e33947SAndroid Build Coastguard Worker         }
491*84e33947SAndroid Build Coastguard Worker       }
492*84e33947SAndroid Build Coastguard Worker     }
493*84e33947SAndroid Build Coastguard Worker   };
494*84e33947SAndroid Build Coastguard Worker 
495*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
496*84e33947SAndroid Build Coastguard Worker 
497*84e33947SAndroid Build Coastguard Worker   bool success;
498*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsPassiveLocationListenerEnabled());
499*84e33947SAndroid Build Coastguard Worker 
500*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LISTENER_REQUEST, true);
501*84e33947SAndroid Build Coastguard Worker   waitForEvent(LISTENER_REQUEST, &success);
502*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
503*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsPassiveLocationListenerEnabled());
504*84e33947SAndroid Build Coastguard Worker 
505*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LISTENER_REQUEST, false);
506*84e33947SAndroid Build Coastguard Worker   waitForEvent(LISTENER_REQUEST, &success);
507*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
508*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsPassiveLocationListenerEnabled());
509*84e33947SAndroid Build Coastguard Worker }
510*84e33947SAndroid Build Coastguard Worker 
TEST_F(TestBase,GnssUnsubscribeToPassiveListenerOnUnload)511*84e33947SAndroid Build Coastguard Worker TEST_F(TestBase, GnssUnsubscribeToPassiveListenerOnUnload) {
512*84e33947SAndroid Build Coastguard Worker   CREATE_CHRE_TEST_EVENT(LISTENER_REQUEST, 0);
513*84e33947SAndroid Build Coastguard Worker 
514*84e33947SAndroid Build Coastguard Worker   class App : public TestNanoapp {
515*84e33947SAndroid Build Coastguard Worker    public:
516*84e33947SAndroid Build Coastguard Worker     App()
517*84e33947SAndroid Build Coastguard Worker         : TestNanoapp(
518*84e33947SAndroid Build Coastguard Worker               TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_GNSS}) {}
519*84e33947SAndroid Build Coastguard Worker 
520*84e33947SAndroid Build Coastguard Worker     void handleEvent(uint32_t, uint16_t eventType,
521*84e33947SAndroid Build Coastguard Worker                      const void *eventData) override {
522*84e33947SAndroid Build Coastguard Worker       switch (eventType) {
523*84e33947SAndroid Build Coastguard Worker         case CHRE_EVENT_TEST_EVENT: {
524*84e33947SAndroid Build Coastguard Worker           auto event = static_cast<const TestEvent *>(eventData);
525*84e33947SAndroid Build Coastguard Worker           switch (event->type) {
526*84e33947SAndroid Build Coastguard Worker             case LISTENER_REQUEST: {
527*84e33947SAndroid Build Coastguard Worker               auto enable = *(static_cast<const bool *>(event->data));
528*84e33947SAndroid Build Coastguard Worker               const bool success =
529*84e33947SAndroid Build Coastguard Worker                   chreGnssConfigurePassiveLocationListener(enable);
530*84e33947SAndroid Build Coastguard Worker               TestEventQueueSingleton::get()->pushEvent(LISTENER_REQUEST,
531*84e33947SAndroid Build Coastguard Worker                                                         success);
532*84e33947SAndroid Build Coastguard Worker             }
533*84e33947SAndroid Build Coastguard Worker           }
534*84e33947SAndroid Build Coastguard Worker         }
535*84e33947SAndroid Build Coastguard Worker       }
536*84e33947SAndroid Build Coastguard Worker     }
537*84e33947SAndroid Build Coastguard Worker   };
538*84e33947SAndroid Build Coastguard Worker 
539*84e33947SAndroid Build Coastguard Worker   uint64_t appId = loadNanoapp(MakeUnique<App>());
540*84e33947SAndroid Build Coastguard Worker 
541*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsPassiveLocationListenerEnabled());
542*84e33947SAndroid Build Coastguard Worker 
543*84e33947SAndroid Build Coastguard Worker   sendEventToNanoapp(appId, LISTENER_REQUEST, true);
544*84e33947SAndroid Build Coastguard Worker   bool success;
545*84e33947SAndroid Build Coastguard Worker   waitForEvent(LISTENER_REQUEST, &success);
546*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(success);
547*84e33947SAndroid Build Coastguard Worker   EXPECT_TRUE(chrePalGnssIsPassiveLocationListenerEnabled());
548*84e33947SAndroid Build Coastguard Worker 
549*84e33947SAndroid Build Coastguard Worker   unloadNanoapp(appId);
550*84e33947SAndroid Build Coastguard Worker   EXPECT_FALSE(chrePalGnssIsPassiveLocationListenerEnabled());
551*84e33947SAndroid Build Coastguard Worker }
552*84e33947SAndroid Build Coastguard Worker 
553*84e33947SAndroid Build Coastguard Worker }  // namespace
554*84e33947SAndroid Build Coastguard Worker }  // namespace chre