Home | History | Annotate | Download | only in general_test
      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