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/send_message.h> 24 25 #include <chre.h> 26 27 using nanoapp_testing::sendFatalFailureToHost; 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> 69 void SendEventTest::completeCallback(uint16_t eventType, void *data) { 70 if (sInMethod) { 71 sendFatalFailureToHost("completeCallback called while another nanoapp " 72 "method is running."); 73 } 74 sInMethod = true; 75 if ((data == nullptr) || (data == kOddData)) { 76 sendFatalFailureToHost( 77 "completeCallback called with nullptr or odd data."); 78 } 79 uint32_t num = *(reinterpret_cast<uint32_t*>(data)); 80 uint16_t expectedEventType = 0xFFFF; 81 uint8_t expectedCallbackIndex = 0xFF; 82 switch (num) { 83 case 0: 84 expectedEventType = kEventType0; 85 expectedCallbackIndex = 0; 86 break; 87 case 1: 88 expectedEventType = kEventType0; 89 expectedCallbackIndex = 1; 90 break; 91 case 2: 92 expectedEventType = kEventType1; 93 expectedCallbackIndex = 0; 94 break; 95 case 3: 96 expectedEventType = kEventType1; 97 expectedCallbackIndex = 1; 98 break; 99 default: 100 sendFatalFailureToHost("completeCallback given bad data.", &num); 101 } 102 if (expectedEventType != eventType) { 103 sendFatalFailureToHost("completeCallback bad/eventType mismatch."); 104 } 105 if (expectedCallbackIndex != kCallbackIndex) { 106 sendFatalFailureToHost("Incorrect callback function called."); 107 } 108 uint8_t mask = 1 << num; 109 if ((sCallbacksInvoked & mask) != 0) { 110 sendFatalFailureToHost("Complete callback invoked multiple times for ", 111 &num); 112 } 113 sCallbacksInvoked |= mask; 114 115 if (!chreSendEvent(kEventTypeCallback, nullptr, nullptr, 116 chreGetInstanceId())) { 117 sendFatalFailureToHost("Failed chreSendEvent in callback."); 118 } 119 sInMethod = false; 120 } 121 122 void SendEventTest::completeCallback0(uint16_t eventType, void *data) { 123 completeCallback<0>(eventType, data); 124 } 125 126 void SendEventTest::completeCallback1(uint16_t eventType, void *data) { 127 completeCallback<1>(eventType, data); 128 } 129 130 SendEventTest::SendEventTest() 131 : Test(CHRE_API_VERSION_1_0) , mNextNum(0) { 132 } 133 134 void SendEventTest::setUp(uint32_t messageSize, const void * /* message */) { 135 sInMethod = true; 136 if (messageSize != 0) { 137 sendFatalFailureToHost( 138 "SendEvent message expects 0 additional bytes, got ", 139 &messageSize); 140 } 141 142 const uint32_t id = chreGetInstanceId(); 143 for (uint32_t i = 0; i < arrayLength(mData); i++) { 144 mData[i] = i; 145 } 146 147 // num: 0 148 if (!chreSendEvent(kEventType0, &mData[0], completeCallback0, id)) { 149 sendFatalFailureToHost("Failed chreSendEvent num 0"); 150 } 151 152 // num: 1 153 if (!chreSendEvent(kEventType0, &mData[1], completeCallback1, id)) { 154 sendFatalFailureToHost("Failed chreSendEvent num 1"); 155 } 156 157 // num: 2 158 if (!chreSendEvent(kEventType1, &mData[2], completeCallback0, id)) { 159 sendFatalFailureToHost("Failed chreSendEvent num 2"); 160 } 161 162 // num: 3 163 if (!chreSendEvent(kEventType1, &mData[3], completeCallback1, id)) { 164 sendFatalFailureToHost("Failed chreSendEvent num 3"); 165 } 166 167 // num: 4 168 if (!chreSendEvent(kEventType0, &mData[4], nullptr, id)) { 169 sendFatalFailureToHost("Failed chreSendEvent num 4"); 170 } 171 172 // num: 5 173 if (!chreSendEvent(kEventType1, &mData[5], nullptr, id)) { 174 sendFatalFailureToHost("Failed chreSendEvent num 5"); 175 } 176 177 // num: 6 178 if (!chreSendEvent(kEventType0, nullptr, nullptr, id)) { 179 sendFatalFailureToHost("Failed chreSendEvent num 6"); 180 } 181 182 // num: 7 183 if (!chreSendEvent(kEventType1, kOddData, nullptr, id)) { 184 sendFatalFailureToHost("Failed chreSendEvent num 7"); 185 } 186 187 sInMethod = false; 188 } 189 190 void SendEventTest::handleEvent(uint32_t senderInstanceId, 191 uint16_t eventType, const void* eventData) { 192 if (sInMethod) { 193 sendFatalFailureToHost("handleEvent invoked while another nanoapp " 194 "method is running"); 195 } 196 sInMethod = true; 197 if (senderInstanceId != chreGetInstanceId()) { 198 sendFatalFailureToHost("handleEvent got event from unexpected sender:", 199 &senderInstanceId); 200 } 201 202 if (mNextNum < 8) { 203 void *expectedData; 204 if (mNextNum < 6) { 205 expectedData = &mData[mNextNum]; 206 } else if (mNextNum == 6) { 207 expectedData = nullptr; 208 } else { 209 expectedData = kOddData; 210 } 211 212 uint16_t expectedEventType = 0xFFFF; 213 switch (mNextNum) { 214 case 0: 215 case 1: 216 case 4: 217 case 6: 218 expectedEventType = kEventType0; 219 break; 220 case 2: 221 case 3: 222 case 5: 223 case 7: 224 expectedEventType = kEventType1; 225 break; 226 } 227 228 if (expectedEventType != eventType) { 229 sendFatalFailureToHost("Incorrect event type sent for num ", 230 &mNextNum); 231 } 232 if (expectedData != eventData) { 233 sendFatalFailureToHost("Incorrect data sent for num ", &mNextNum); 234 } 235 236 } else { 237 if (eventType != kEventTypeCallback) { 238 sendFatalFailureToHost("Unexpected event type for num ", &mNextNum); 239 } 240 if (mNextNum == 11) { 241 // This was our last callback. Everything is good. 242 sendSuccessToHost(); 243 } 244 } 245 246 mNextNum++; 247 sInMethod = false; 248 } 249 250 } // namespace general_test 251