1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2021 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 #ifndef CHRE_SIMULATION_TEST_UTIL_H_
18*84e33947SAndroid Build Coastguard Worker #define CHRE_SIMULATION_TEST_UTIL_H_
19*84e33947SAndroid Build Coastguard Worker
20*84e33947SAndroid Build Coastguard Worker #include <chre/nanoapp.h>
21*84e33947SAndroid Build Coastguard Worker #include <cstdint>
22*84e33947SAndroid Build Coastguard Worker
23*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre/core/nanoapp.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/util/unique_ptr.h"
26*84e33947SAndroid Build Coastguard Worker #include "test_event.h"
27*84e33947SAndroid Build Coastguard Worker #include "test_event_queue.h"
28*84e33947SAndroid Build Coastguard Worker
29*84e33947SAndroid Build Coastguard Worker namespace chre {
30*84e33947SAndroid Build Coastguard Worker
31*84e33947SAndroid Build Coastguard Worker constexpr uint64_t kDefaultTestNanoappId = 0x0123456789abcdef;
32*84e33947SAndroid Build Coastguard Worker
33*84e33947SAndroid Build Coastguard Worker /**
34*84e33947SAndroid Build Coastguard Worker * Unregister all nanoapps.
35*84e33947SAndroid Build Coastguard Worker *
36*84e33947SAndroid Build Coastguard Worker * This is called by the test framework to unregister all nanoapps after each
37*84e33947SAndroid Build Coastguard Worker * test. The destructor is called when the nanoapp is unregistered.
38*84e33947SAndroid Build Coastguard Worker */
39*84e33947SAndroid Build Coastguard Worker void unregisterAllTestNanoapps();
40*84e33947SAndroid Build Coastguard Worker
41*84e33947SAndroid Build Coastguard Worker /**
42*84e33947SAndroid Build Coastguard Worker * Information about a test nanoapp.
43*84e33947SAndroid Build Coastguard Worker */
44*84e33947SAndroid Build Coastguard Worker struct TestNanoappInfo {
45*84e33947SAndroid Build Coastguard Worker const char *name = "Test";
46*84e33947SAndroid Build Coastguard Worker uint64_t id = kDefaultTestNanoappId;
47*84e33947SAndroid Build Coastguard Worker uint32_t version = 0;
48*84e33947SAndroid Build Coastguard Worker uint32_t perms = NanoappPermissions::CHRE_PERMS_NONE;
49*84e33947SAndroid Build Coastguard Worker };
50*84e33947SAndroid Build Coastguard Worker
51*84e33947SAndroid Build Coastguard Worker /**
52*84e33947SAndroid Build Coastguard Worker * Test nanoapp.
53*84e33947SAndroid Build Coastguard Worker *
54*84e33947SAndroid Build Coastguard Worker * Tests typically inherit this class and override the entry points to test the
55*84e33947SAndroid Build Coastguard Worker * nanoapp behavior.
56*84e33947SAndroid Build Coastguard Worker *
57*84e33947SAndroid Build Coastguard Worker * The bulk of the code should be in the handleEvent method to respond to
58*84e33947SAndroid Build Coastguard Worker * events sent to the nanoapp by the platform and by the sendEventToNanoapp
59*84e33947SAndroid Build Coastguard Worker * function. start and end can be use to setup and cleanup the test environment
60*84e33947SAndroid Build Coastguard Worker * around each test.
61*84e33947SAndroid Build Coastguard Worker *
62*84e33947SAndroid Build Coastguard Worker * Note: end is only executed when the nanoapp is explicitly unloaded.
63*84e33947SAndroid Build Coastguard Worker */
64*84e33947SAndroid Build Coastguard Worker class TestNanoapp {
65*84e33947SAndroid Build Coastguard Worker public:
66*84e33947SAndroid Build Coastguard Worker TestNanoapp() = default;
TestNanoapp(TestNanoappInfo info)67*84e33947SAndroid Build Coastguard Worker explicit TestNanoapp(TestNanoappInfo info) : mTestNanoappInfo(info) {}
~TestNanoapp()68*84e33947SAndroid Build Coastguard Worker virtual ~TestNanoapp() {}
69*84e33947SAndroid Build Coastguard Worker
70*84e33947SAndroid Build Coastguard Worker // NanoappStart Entrypoint.
start()71*84e33947SAndroid Build Coastguard Worker virtual bool start() {
72*84e33947SAndroid Build Coastguard Worker return true;
73*84e33947SAndroid Build Coastguard Worker }
74*84e33947SAndroid Build Coastguard Worker
75*84e33947SAndroid Build Coastguard Worker // nanoappHandleEvent Entrypoint.
handleEvent(uint32_t,uint16_t,const void *)76*84e33947SAndroid Build Coastguard Worker virtual void handleEvent(uint32_t /*senderInstanceId*/,
77*84e33947SAndroid Build Coastguard Worker uint16_t /*eventType*/, const void * /*eventData*/) {
78*84e33947SAndroid Build Coastguard Worker }
79*84e33947SAndroid Build Coastguard Worker
80*84e33947SAndroid Build Coastguard Worker // nanoappEnd Entrypoint.
end()81*84e33947SAndroid Build Coastguard Worker virtual void end() {}
82*84e33947SAndroid Build Coastguard Worker
name()83*84e33947SAndroid Build Coastguard Worker const char *name() {
84*84e33947SAndroid Build Coastguard Worker return mTestNanoappInfo.name;
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker
id()87*84e33947SAndroid Build Coastguard Worker uint64_t id() {
88*84e33947SAndroid Build Coastguard Worker return mTestNanoappInfo.id;
89*84e33947SAndroid Build Coastguard Worker }
90*84e33947SAndroid Build Coastguard Worker
version()91*84e33947SAndroid Build Coastguard Worker uint32_t version() {
92*84e33947SAndroid Build Coastguard Worker return mTestNanoappInfo.version;
93*84e33947SAndroid Build Coastguard Worker }
94*84e33947SAndroid Build Coastguard Worker
perms()95*84e33947SAndroid Build Coastguard Worker uint32_t perms() {
96*84e33947SAndroid Build Coastguard Worker return mTestNanoappInfo.perms;
97*84e33947SAndroid Build Coastguard Worker }
98*84e33947SAndroid Build Coastguard Worker
99*84e33947SAndroid Build Coastguard Worker private:
100*84e33947SAndroid Build Coastguard Worker const TestNanoappInfo mTestNanoappInfo;
101*84e33947SAndroid Build Coastguard Worker };
102*84e33947SAndroid Build Coastguard Worker
103*84e33947SAndroid Build Coastguard Worker /**
104*84e33947SAndroid Build Coastguard Worker * @return the statically loaded nanoapp based on the arguments.
105*84e33947SAndroid Build Coastguard Worker *
106*84e33947SAndroid Build Coastguard Worker * @see chreNslNanoappInfo for param descriptions.
107*84e33947SAndroid Build Coastguard Worker */
108*84e33947SAndroid Build Coastguard Worker UniquePtr<Nanoapp> createStaticNanoapp(
109*84e33947SAndroid Build Coastguard Worker const char *name, uint64_t appId, uint32_t appVersion, uint32_t appPerms,
110*84e33947SAndroid Build Coastguard Worker decltype(nanoappStart) *startFunc,
111*84e33947SAndroid Build Coastguard Worker decltype(nanoappHandleEvent) *handleEventFunc,
112*84e33947SAndroid Build Coastguard Worker decltype(nanoappEnd) *endFunc);
113*84e33947SAndroid Build Coastguard Worker
114*84e33947SAndroid Build Coastguard Worker /**
115*84e33947SAndroid Build Coastguard Worker * @return the statically loaded nanoapp based on the arguments, additionally
116*84e33947SAndroid Build Coastguard Worker * sets info struct version
117*84e33947SAndroid Build Coastguard Worker *
118*84e33947SAndroid Build Coastguard Worker * @see chreNslNanoappInfo for param descriptions.
119*84e33947SAndroid Build Coastguard Worker */
120*84e33947SAndroid Build Coastguard Worker UniquePtr<Nanoapp> createStaticNanoapp(
121*84e33947SAndroid Build Coastguard Worker uint8_t infoStructVersion, const char *name, uint64_t appId,
122*84e33947SAndroid Build Coastguard Worker uint32_t appVersion, uint32_t appPerms, decltype(nanoappStart) *startFunc,
123*84e33947SAndroid Build Coastguard Worker decltype(nanoappHandleEvent) *handleEventFunc,
124*84e33947SAndroid Build Coastguard Worker decltype(nanoappEnd) *endFunc);
125*84e33947SAndroid Build Coastguard Worker
126*84e33947SAndroid Build Coastguard Worker /**
127*84e33947SAndroid Build Coastguard Worker * Deletes memory allocated by createStaticNanoapp.
128*84e33947SAndroid Build Coastguard Worker *
129*84e33947SAndroid Build Coastguard Worker * This function must be called when the nanoapp is no more used.
130*84e33947SAndroid Build Coastguard Worker */
131*84e33947SAndroid Build Coastguard Worker void deleteNanoappInfos();
132*84e33947SAndroid Build Coastguard Worker
133*84e33947SAndroid Build Coastguard Worker /**
134*84e33947SAndroid Build Coastguard Worker * Default CHRE nanoapp entry points that don't do anything.
135*84e33947SAndroid Build Coastguard Worker */
136*84e33947SAndroid Build Coastguard Worker bool defaultNanoappStart();
137*84e33947SAndroid Build Coastguard Worker void defaultNanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType,
138*84e33947SAndroid Build Coastguard Worker const void *eventData);
139*84e33947SAndroid Build Coastguard Worker void defaultNanoappEnd();
140*84e33947SAndroid Build Coastguard Worker
141*84e33947SAndroid Build Coastguard Worker /**
142*84e33947SAndroid Build Coastguard Worker * Create static nanoapp and load it in CHRE.
143*84e33947SAndroid Build Coastguard Worker *
144*84e33947SAndroid Build Coastguard Worker * This function returns after the nanoapp start has been executed.
145*84e33947SAndroid Build Coastguard Worker *
146*84e33947SAndroid Build Coastguard Worker * @see createStatic Nanoapp.
147*84e33947SAndroid Build Coastguard Worker */
148*84e33947SAndroid Build Coastguard Worker void loadNanoapp(const char *name, uint64_t appId, uint32_t appVersion,
149*84e33947SAndroid Build Coastguard Worker uint32_t appPerms, decltype(nanoappStart) *startFunc,
150*84e33947SAndroid Build Coastguard Worker decltype(nanoappHandleEvent) *handleEventFunc,
151*84e33947SAndroid Build Coastguard Worker decltype(nanoappEnd) *endFunc);
152*84e33947SAndroid Build Coastguard Worker
153*84e33947SAndroid Build Coastguard Worker /**
154*84e33947SAndroid Build Coastguard Worker * Create a static nanoapp and load it in CHRE.
155*84e33947SAndroid Build Coastguard Worker *
156*84e33947SAndroid Build Coastguard Worker * This function returns after the nanoapp start has been executed.
157*84e33947SAndroid Build Coastguard Worker *
158*84e33947SAndroid Build Coastguard Worker * @return The id of the nanoapp.
159*84e33947SAndroid Build Coastguard Worker */
160*84e33947SAndroid Build Coastguard Worker uint64_t loadNanoapp(UniquePtr<TestNanoapp> app);
161*84e33947SAndroid Build Coastguard Worker
162*84e33947SAndroid Build Coastguard Worker /**
163*84e33947SAndroid Build Coastguard Worker * Unload nanoapp corresponding to appId.
164*84e33947SAndroid Build Coastguard Worker *
165*84e33947SAndroid Build Coastguard Worker * This function returns after the nanoapp end has been executed.
166*84e33947SAndroid Build Coastguard Worker *
167*84e33947SAndroid Build Coastguard Worker * @param appId App Id of nanoapp to be unloaded.
168*84e33947SAndroid Build Coastguard Worker */
169*84e33947SAndroid Build Coastguard Worker void unloadNanoapp(uint64_t appId);
170*84e33947SAndroid Build Coastguard Worker
171*84e33947SAndroid Build Coastguard Worker /**
172*84e33947SAndroid Build Coastguard Worker * A convenience deferred callback function that can be used to start an already
173*84e33947SAndroid Build Coastguard Worker * loaded nanoapp.
174*84e33947SAndroid Build Coastguard Worker *
175*84e33947SAndroid Build Coastguard Worker * @param type The callback type.
176*84e33947SAndroid Build Coastguard Worker * @param nanoapp A pointer to the nanoapp that is already loaded.
177*84e33947SAndroid Build Coastguard Worker */
178*84e33947SAndroid Build Coastguard Worker void testFinishLoadingNanoappCallback(SystemCallbackType type,
179*84e33947SAndroid Build Coastguard Worker UniquePtr<Nanoapp> &&nanoapp);
180*84e33947SAndroid Build Coastguard Worker
181*84e33947SAndroid Build Coastguard Worker /**
182*84e33947SAndroid Build Coastguard Worker * A convenience deferred callback function to unload a nanoapp.
183*84e33947SAndroid Build Coastguard Worker *
184*84e33947SAndroid Build Coastguard Worker * @param type The callback type.
185*84e33947SAndroid Build Coastguard Worker * @param data The data containing the appId.
186*84e33947SAndroid Build Coastguard Worker * @param extraData Extra data.
187*84e33947SAndroid Build Coastguard Worker */
188*84e33947SAndroid Build Coastguard Worker void testFinishUnloadingNanoappCallback(uint16_t type, void *data,
189*84e33947SAndroid Build Coastguard Worker void *extraData);
190*84e33947SAndroid Build Coastguard Worker
191*84e33947SAndroid Build Coastguard Worker /**
192*84e33947SAndroid Build Coastguard Worker * Deallocate the memory allocated for a TestEvent.
193*84e33947SAndroid Build Coastguard Worker */
194*84e33947SAndroid Build Coastguard Worker void freeTestEventDataCallback(uint16_t /*eventType*/, void *eventData);
195*84e33947SAndroid Build Coastguard Worker
196*84e33947SAndroid Build Coastguard Worker /**
197*84e33947SAndroid Build Coastguard Worker * Sends a message to a nanoapp.
198*84e33947SAndroid Build Coastguard Worker *
199*84e33947SAndroid Build Coastguard Worker * This function is typically used to execute code in the context of the
200*84e33947SAndroid Build Coastguard Worker * nanoapp in its handleEvent method.
201*84e33947SAndroid Build Coastguard Worker *
202*84e33947SAndroid Build Coastguard Worker * @param appId ID of the nanoapp.
203*84e33947SAndroid Build Coastguard Worker * @param eventType The event to send.
204*84e33947SAndroid Build Coastguard Worker */
205*84e33947SAndroid Build Coastguard Worker void sendEventToNanoapp(uint64_t appId, uint16_t eventType);
206*84e33947SAndroid Build Coastguard Worker
207*84e33947SAndroid Build Coastguard Worker /**
208*84e33947SAndroid Build Coastguard Worker * Sends a message to a nanoapp with data.
209*84e33947SAndroid Build Coastguard Worker *
210*84e33947SAndroid Build Coastguard Worker * This function is typically used to execute code in the context of the
211*84e33947SAndroid Build Coastguard Worker * nanoapp in its handleEvent method.
212*84e33947SAndroid Build Coastguard Worker *
213*84e33947SAndroid Build Coastguard Worker * The nanoapp handleEvent function will receive a a TestEvent instance
214*84e33947SAndroid Build Coastguard Worker * populated with the eventType and a pointer to as copy of the evenData as
215*84e33947SAndroid Build Coastguard Worker * a CHRE_EVENT_TEST_EVENT event.
216*84e33947SAndroid Build Coastguard Worker *
217*84e33947SAndroid Build Coastguard Worker * @param appId ID of the nanoapp.
218*84e33947SAndroid Build Coastguard Worker * @param eventType The event to send.
219*84e33947SAndroid Build Coastguard Worker * @param eventData The data to send.
220*84e33947SAndroid Build Coastguard Worker */
221*84e33947SAndroid Build Coastguard Worker template <class T>
sendEventToNanoapp(uint64_t appId,uint16_t eventType,const T & eventData)222*84e33947SAndroid Build Coastguard Worker void sendEventToNanoapp(uint64_t appId, uint16_t eventType,
223*84e33947SAndroid Build Coastguard Worker const T &eventData) {
224*84e33947SAndroid Build Coastguard Worker static_assert(std::is_trivial<T>::value);
225*84e33947SAndroid Build Coastguard Worker uint16_t instanceId;
226*84e33947SAndroid Build Coastguard Worker if (EventLoopManagerSingleton::get()
227*84e33947SAndroid Build Coastguard Worker ->getEventLoop()
228*84e33947SAndroid Build Coastguard Worker .findNanoappInstanceIdByAppId(appId, &instanceId)) {
229*84e33947SAndroid Build Coastguard Worker auto event = memoryAlloc<TestEvent>();
230*84e33947SAndroid Build Coastguard Worker ASSERT_NE(event, nullptr);
231*84e33947SAndroid Build Coastguard Worker event->type = eventType;
232*84e33947SAndroid Build Coastguard Worker auto ptr = memoryAlloc<T>();
233*84e33947SAndroid Build Coastguard Worker ASSERT_NE(ptr, nullptr);
234*84e33947SAndroid Build Coastguard Worker *ptr = eventData;
235*84e33947SAndroid Build Coastguard Worker event->data = ptr;
236*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
237*84e33947SAndroid Build Coastguard Worker CHRE_EVENT_TEST_EVENT, static_cast<void *>(event),
238*84e33947SAndroid Build Coastguard Worker freeTestEventDataCallback, instanceId);
239*84e33947SAndroid Build Coastguard Worker } else {
240*84e33947SAndroid Build Coastguard Worker LOGE("No instance found for nanoapp id = 0x%016" PRIx64, appId);
241*84e33947SAndroid Build Coastguard Worker }
242*84e33947SAndroid Build Coastguard Worker }
243*84e33947SAndroid Build Coastguard Worker
244*84e33947SAndroid Build Coastguard Worker } // namespace chre
245*84e33947SAndroid Build Coastguard Worker
246*84e33947SAndroid Build Coastguard Worker #endif // CHRE_SIMULATION_TEST_UTIL_H_
247