• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <general_test/send_event_test.h>
18 
19 #include <cstddef>
20 
21 #include <shared/abort.h>
22 #include <shared/array_length.h>
23 #include <shared/macros.h>
24 #include <shared/send_message.h>
25 
26 #include "chre_api/chre.h"
27 
28 using nanoapp_testing::sendSuccessToHost;
29 
30 /*
31  * In a properly running test, we'll invoke chreSendEvent() a total of 12 times.
32  * We initially send eight events upon startup.  And then for each of our four
33  * events which has a non-nullptr completeCallback, we call chreSendEvent()
34  * from that callback.
35  *
36  * For our first eight events, they will either be kEventType0 or kEventType1.
37  * They will either use completeCallback0 or completeCallback1.  They have
38  * various data.  This table describes them all:
39  *
40  * num | eventType | data       | Callback
41  * ----|-----------|------------|---------
42  * 0   | 0         | ptr to num | 0
43  * 1   | 0         | ptr to num | 1
44  * 2   | 1         | ptr to num | 0
45  * 3   | 1         | ptr to num | 1
46  * 4   | 0         | ptr to num | nullptr
47  * 5   | 1         | ptr to num | nullptr
48  * 6   | 0         | nullptr    | nullptr
49  * 7   | 1         | kOddData   | nullptr
50  *
51  * The other four events are all kEventTypeCallback with nullptr data and
52  * nullptr callback.
53  */
54 
55 constexpr uint16_t kEventType0 = CHRE_EVENT_FIRST_USER_VALUE + 0;
56 constexpr uint16_t kEventType1 = CHRE_EVENT_FIRST_USER_VALUE + 1;
57 constexpr uint16_t kEventTypeCallback = CHRE_EVENT_FIRST_USER_VALUE + 2;
58 
59 // NOTE: This is not allowed to be constexpr, even if some version of g++/clang
60 //     allow it.
61 static void *kOddData = reinterpret_cast<void *>(-1);
62 
63 namespace general_test {
64 
65 bool SendEventTest::sInMethod = false;
66 uint8_t SendEventTest::sCallbacksInvoked = 0;
67 
68 template <uint8_t kCallbackIndex>
completeCallback(uint16_t eventType,void * data)69 void SendEventTest::completeCallback(uint16_t eventType, void *data) {
70   if (sInMethod) {
71     EXPECT_FAIL_RETURN(
72         "completeCallback called while another nanoapp method is running.");
73   }
74   sInMethod = true;
75   if ((data == nullptr) || (data == kOddData)) {
76     EXPECT_FAIL_RETURN("completeCallback called with nullptr or odd data.");
77   }
78   uint32_t num = *(reinterpret_cast<uint32_t *>(data));
79   uint16_t expectedEventType = 0xFFFF;
80   uint8_t expectedCallbackIndex = 0xFF;
81   switch (num) {
82     case 0:
83       expectedEventType = kEventType0;
84       expectedCallbackIndex = 0;
85       break;
86     case 1:
87       expectedEventType = kEventType0;
88       expectedCallbackIndex = 1;
89       break;
90     case 2:
91       expectedEventType = kEventType1;
92       expectedCallbackIndex = 0;
93       break;
94     case 3:
95       expectedEventType = kEventType1;
96       expectedCallbackIndex = 1;
97       break;
98     default:
99       EXPECT_FAIL_RETURN("completeCallback given bad data.", &num);
100   }
101   if (expectedEventType != eventType) {
102     EXPECT_FAIL_RETURN("completeCallback bad/eventType mismatch.");
103   }
104   if (expectedCallbackIndex != kCallbackIndex) {
105     EXPECT_FAIL_RETURN("Incorrect callback function called.");
106   }
107   uint8_t mask = static_cast<uint8_t>(1 << num);
108   if ((sCallbacksInvoked & mask) != 0) {
109     EXPECT_FAIL_RETURN("Complete callback invoked multiple times for ", &num);
110   }
111   sCallbacksInvoked |= mask;
112 
113   if (!chreSendEvent(kEventTypeCallback, nullptr, nullptr,
114                      chreGetInstanceId())) {
115     EXPECT_FAIL_RETURN("Failed chreSendEvent in callback.");
116   }
117   sInMethod = false;
118 }
119 
completeCallback0(uint16_t eventType,void * data)120 void SendEventTest::completeCallback0(uint16_t eventType, void *data) {
121   completeCallback<0>(eventType, data);
122 }
123 
completeCallback1(uint16_t eventType,void * data)124 void SendEventTest::completeCallback1(uint16_t eventType, void *data) {
125   completeCallback<1>(eventType, data);
126 }
127 
SendEventTest()128 SendEventTest::SendEventTest() : Test(CHRE_API_VERSION_1_0), mNextNum(0) {}
129 
setUp(uint32_t messageSize,const void *)130 void SendEventTest::setUp(uint32_t messageSize, const void * /* message */) {
131   sInMethod = true;
132   if (messageSize != 0) {
133     EXPECT_FAIL_RETURN("SendEvent message expects 0 additional bytes, got ",
134                        &messageSize);
135   }
136 
137   const uint32_t id = chreGetInstanceId();
138   for (uint32_t i = 0; i < arrayLength(mData); i++) {
139     mData[i] = i;
140   }
141 
142   // num: 0
143   if (!chreSendEvent(kEventType0, &mData[0], completeCallback0, id)) {
144     EXPECT_FAIL_RETURN("Failed chreSendEvent num 0");
145   }
146 
147   // num: 1
148   if (!chreSendEvent(kEventType0, &mData[1], completeCallback1, id)) {
149     EXPECT_FAIL_RETURN("Failed chreSendEvent num 1");
150   }
151 
152   // num: 2
153   if (!chreSendEvent(kEventType1, &mData[2], completeCallback0, id)) {
154     EXPECT_FAIL_RETURN("Failed chreSendEvent num 2");
155   }
156 
157   // num: 3
158   if (!chreSendEvent(kEventType1, &mData[3], completeCallback1, id)) {
159     EXPECT_FAIL_RETURN("Failed chreSendEvent num 3");
160   }
161 
162   // num: 4
163   if (!chreSendEvent(kEventType0, &mData[4], nullptr, id)) {
164     EXPECT_FAIL_RETURN("Failed chreSendEvent num 4");
165   }
166 
167   // num: 5
168   if (!chreSendEvent(kEventType1, &mData[5], nullptr, id)) {
169     EXPECT_FAIL_RETURN("Failed chreSendEvent num 5");
170   }
171 
172   // num: 6
173   if (!chreSendEvent(kEventType0, nullptr, nullptr, id)) {
174     EXPECT_FAIL_RETURN("Failed chreSendEvent num 6");
175   }
176 
177   // num: 7
178   if (!chreSendEvent(kEventType1, kOddData, nullptr, id)) {
179     EXPECT_FAIL_RETURN("Failed chreSendEvent num 7");
180   }
181 
182   sInMethod = false;
183 }
184 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)185 void SendEventTest::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
186                                 const void *eventData) {
187   if (sInMethod) {
188     EXPECT_FAIL_RETURN(
189         "handleEvent invoked while another nanoapp method is running");
190   }
191   sInMethod = true;
192   if (senderInstanceId != chreGetInstanceId()) {
193     EXPECT_FAIL_RETURN("handleEvent got event from unexpected sender:",
194                        &senderInstanceId);
195   }
196 
197   if (mNextNum < 8) {
198     void *expectedData;
199     if (mNextNum < 6) {
200       expectedData = &mData[mNextNum];
201     } else if (mNextNum == 6) {
202       expectedData = nullptr;
203     } else {
204       expectedData = kOddData;
205     }
206 
207     uint16_t expectedEventType = 0xFFFF;
208     switch (mNextNum) {
209       case 0:
210       case 1:
211       case 4:
212       case 6:
213         expectedEventType = kEventType0;
214         break;
215       case 2:
216       case 3:
217       case 5:
218       case 7:
219         expectedEventType = kEventType1;
220         break;
221     }
222 
223     if (expectedEventType != eventType) {
224       EXPECT_FAIL_RETURN("Incorrect event type sent for num ", &mNextNum);
225     }
226     if (expectedData != eventData) {
227       EXPECT_FAIL_RETURN("Incorrect data sent for num ", &mNextNum);
228     }
229 
230   } else {
231     if (eventType != kEventTypeCallback) {
232       EXPECT_FAIL_RETURN("Unexpected event type for num ", &mNextNum);
233     }
234     if (mNextNum == 11) {
235       // This was our last callback.  Everything is good.
236       sendSuccessToHost();
237     }
238   }
239 
240   mNextNum++;
241   sInMethod = false;
242 }
243 
244 }  // namespace general_test
245