14d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/*
24d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Copyright (C) 2016 The Android Open Source Project
34d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
44d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Licensed under the Apache License, Version 2.0 (the "License");
54d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * you may not use this file except in compliance with the License.
64d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * You may obtain a copy of the License at
74d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
84d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *      http://www.apache.org/licenses/LICENSE-2.0
94d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Unless required by applicable law or agreed to in writing, software
114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * distributed under the License is distributed on an "AS IS" BASIS,
124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * See the License for the specific language governing permissions and
144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * limitations under the License.
154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */
164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <general_test/send_message_to_host_test.h>
184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cinttypes>
204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cstddef>
214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/nano_endian.h>
234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/nano_string.h>
244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/send_message.h>
254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <chre.h>
274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::MessageType;
294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendFatalFailureToHost;
304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendInternalFailureToHost;
314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendSuccessToHost;
324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/*
354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Our test essentially has nine stages.  The first eight stages all involve
364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * sending data to the Host.  Here is a table describing them:
374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage | Data length | Callback
394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * ------|-------------|--------------
404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 0     | small       | smallMessage0
414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 1     | small       | smallMessage1
424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 2     | small       | nullptr
434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 3     | small       | smallMessage0
444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 4     | nullptr     | nullptr
454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 5     | 4 bytes     | nullptr
464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 6     | MAX + 1     | largeMessage
474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 7     | MAX         | largeMessage
484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage 8 involves waiting for an incoming zero-sized message from the Host.
504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * The focus of the first four stages is making sure the correct callback
524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * gets invoked and a nullptr callback works.
534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage 4 tests sending a null message to the Host (that should send).
554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage 5 is not testing anything, but it's necessary to get data
574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * to the host to confirm the message in stage 7 is correct.
584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage 6 tests that we properly reject oversized messages.  This
604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * data should _not_ make it to the host.
614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Stage 7 tests that we can send the maximum claimed size to the host.
634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Every single stage which has a non-null callback is not considered a
654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * "success" until that callback has been invoked.  There is no CHRE
664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * requirement in terms of the order in which these callbacks are
674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * invoked, which is why the markSuccess() method uses a bitmask and
684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * checks for overall success every time we gets success from a single
694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * stage.
704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * We consider the test successful only when all stages have reported success.
724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Note that the Host will not perform Stage 8 until after it has received
734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * all the expected messages from the nanoapp.  That's how we can confirm
744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * all messages actually made it through to the Host.
754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */
764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// TODO(b/32114261): Remove this and actually test a variety of message types.
784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr uint32_t kUntestedMessageType = UINT32_C(0x51501984);
794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguronamespace general_test {
814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// TODO(b/32114261): Remove this variable.
834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroextern bool gUseNycMessageHack;
844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurouint8_t SendMessageToHostTest::sSmallMessageData[kSmallMessageTestCount][kSmallMessageSize];
864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid *SendMessageToHostTest::sLargeMessageData[2];
874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr size_t SendMessageToHostTest::kLargeSizes[2];
884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurobool SendMessageToHostTest::sInMethod = false;
904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurouint32_t SendMessageToHostTest::sFinishedBitmask = 0;
914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurotemplate<uint8_t kCallbackIndex>
934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::smallMessageCallback(void *message,
944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                                 size_t messageSize) {
954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sInMethod) {
964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("smallMessageCallback called while another "
974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "nanoapp method is running");
984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = true;
1004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (message == nullptr) {
1014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("smallMessageCallback given null message");
1024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (messageSize != kSmallMessageSize) {
1044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    uint32_t size = static_cast<uint32_t>(messageSize);
1054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("smallMessageCallback given bad messageSize:",
1064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &size);
1074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  const uint8_t *msg = static_cast<const uint8_t*>(message);
1094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (size_t i = 0; i < messageSize; i++) {
1104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (msg[i] != kDataByte) {
1114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Corrupt data in smallMessageCallback");
1124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
1134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t stage = getSmallDataIndex(msg);
1164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint8_t expectedCallbackIndex = 2;
1174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  switch (stage) {
1184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    case 0:  // fall-through
1194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    case 3:
1204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      expectedCallbackIndex = 0;
1214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      break;
1224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    case 1:
1234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      expectedCallbackIndex = 1;
1244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      break;
1254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    case 2:
1264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("callback invoked when null callback "
1274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                             "given");
1284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      break;
1294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    default:
1304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendInternalFailureToHost("Invalid index", &stage);
1314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (expectedCallbackIndex != kCallbackIndex) {
1334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Incorrect callback function called.");
1344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(stage);
1374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = false;
1384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::smallMessageCallback0(void *message,
1414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                                  size_t messageSize) {
1424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  smallMessageCallback<0>(message, messageSize);
1434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::smallMessageCallback1(void *message,
1464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                                  size_t messageSize) {
1474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  smallMessageCallback<1>(message, messageSize);
1484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurouint32_t SendMessageToHostTest::getSmallDataIndex(const uint8_t *data) {
1514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // O(N) is fine.  N is small and this is test code.
1524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (uint32_t i = 0; i < kSmallMessageTestCount; i++) {
1534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (data == sSmallMessageData[i]) {
1544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      return i;
1554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
1564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sendFatalFailureToHost("Bad memory sent to smallMessageCallback");
1584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // We should never get here.
1594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  return kSmallMessageTestCount;
1604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::largeMessageCallback(void *message,
1634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                                 size_t messageSize) {
1644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sInMethod) {
1654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("largeMessageCallback called while another "
1664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "nanoapp method is running");
1674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = true;
1694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (message == nullptr) {
1704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("largeMessageCallback given null message");
1714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t index = 2;
1734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (message == sLargeMessageData[0]) {
1744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    index = 0;
1754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else if (message == sLargeMessageData[1]) {
1764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    index = 1;
1774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
1784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("largeMessageCallback given bad message");
1794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (messageSize != kLargeSizes[index]) {
1814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("largeMessageCallback given incorrect "
1824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "messageSize");
1834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  const uint8_t *msg = static_cast<const uint8_t*>(message);
1854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (size_t i = 0; i < messageSize; i++) {
1864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (msg[i] != kDataByte) {
1874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Corrupt data in largeMessageCallback");
1884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
1894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreHeapFree(sLargeMessageData[index]);
1914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // index 0 == stage 6, index 1 == stage 7
1924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(index + 6);
1934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = false;
1954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::markSuccess(uint32_t stage) {
1984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreLog(CHRE_LOG_DEBUG, "Stage %" PRIu32 " succeeded", stage);
1994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t finishedBit = (1 << stage);
2004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sFinishedBitmask & finishedBit) {
2014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("callback called multiple times for stage:",
2024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &stage);
2034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if ((kAllFinished & finishedBit) == 0) {
2054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("markSuccess bad stage", &stage);
2064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sFinishedBitmask |= finishedBit;
2084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sFinishedBitmask == kAllFinished) {
2094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendSuccessToHost();
2104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::prepTestMemory() {
2144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  nanoapp_testing::memset(sSmallMessageData, kDataByte,
2154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                          sizeof(sSmallMessageData));
2164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (size_t i = 0; i < 2; i++) {
2184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sLargeMessageData[i] = chreHeapAlloc(kLargeSizes[i]);
2194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (sLargeMessageData[i] == nullptr) {
2204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Insufficient heap memory for test");
2214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
2224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    nanoapp_testing::memset(sLargeMessageData[i], kDataByte,
2234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                            kLargeSizes[i]);
2244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::sendMessageMaxSize() {
2284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Our focus here is just sending this data; we're not trying to
2294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // test anything.  So we use the helper function.
2304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t maxSize = CHRE_MESSAGE_TO_HOST_MAX_SIZE;
2314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  nanoapp_testing::hostToLittleEndian(&maxSize);
2324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): We intentionally don't have a namespace using
2334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     declaration for sendMessageToHost because it's generally
2344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     incorrect to use while we're working around this bug.  When the
2354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     bug is fixed, we'll add this declaration, and use the method
2364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     widely.
2374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  nanoapp_testing::sendMessageToHost(MessageType::kContinue,
2384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                     &maxSize, sizeof(maxSize));
2394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// Wrapper for chreSendMessageToHost() that sets sInMethod to false during its
2424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// execution, to allow for inline callbacks (this CHRE API is allowed to call
2434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// the free callback either within the function, or at an unspecified later time
2444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// when this nanoapp is not otherwise executing).
2454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurobool SendMessageToHostTest::sendMessageToHost(
2464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    void *message, uint32_t messageSize, uint32_t reservedMessageType,
2474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    chreMessageFreeFunction *freeCallback) {
2484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = false;
2494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  bool success = chreSendMessageToHost(message, messageSize,
2504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                       reservedMessageType, freeCallback);
2514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = true;
2524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  return success;
2544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur IshiguroSendMessageToHostTest::SendMessageToHostTest()
2574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  : Test(CHRE_API_VERSION_1_0) {
2584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::setUp(uint32_t messageSize,
2614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                  const void * /* message */) {
2624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): We need this hackery so we can get the raw bytes
2634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     from the host, without the test infrastructure trying to
2644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     interpret them.  This won't be necessary when messageType is
2654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     properly sent.
2664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  gUseNycMessageHack = false;
2674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = true;
2694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (messageSize != 0) {
2704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost(
2714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "SendMessageToHost message expects 0 additional bytes, got ",
2724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        &messageSize);
2734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  prepTestMemory();
2764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 0
2784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(sSmallMessageData[0], kSmallMessageSize,
2794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                         kUntestedMessageType, smallMessageCallback0)) {
2804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 0");
2814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 1
2844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(sSmallMessageData[1], kSmallMessageSize,
2854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                         kUntestedMessageType, smallMessageCallback1)) {
2864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 1");
2874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 2
2904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(sSmallMessageData[2], kSmallMessageSize,
2914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                         kUntestedMessageType, nullptr)) {
2924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 2");
2934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // There's no callback, so we mark this as a success.
2954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(2);
2964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 3
2984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(sSmallMessageData[3], kSmallMessageSize,
2994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                         kUntestedMessageType, smallMessageCallback0)) {
3004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 3");
3014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 4
3044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(nullptr, 0, kUntestedMessageType, nullptr)) {
3054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 4");
3064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // There's no callback, so we mark this as a success.
3084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(4);
3094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 5
3114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sendMessageMaxSize();
3124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // There's no callback, so we mark this as a success.
3134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(5);
3144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 6
3164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sendMessageToHost(sLargeMessageData[0], kLargeSizes[0],
3174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                        kUntestedMessageType, largeMessageCallback)) {
3184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Oversized data to chreSendMessageToHost "
3194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "claimed success");
3204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // stage: 7
3234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!sendMessageToHost(sLargeMessageData[1], kLargeSizes[1],
3244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                         kUntestedMessageType, largeMessageCallback)) {
3254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Failed chreSendMessageToHost stage 7");
3264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = false;
3294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
3304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SendMessageToHostTest::handleEvent(uint32_t senderInstanceId,
3324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                        uint16_t eventType,
3334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                        const void* eventData) {
3344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (sInMethod) {
3354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent invoked while another nanoapp "
3364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "method is running");
3374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = true;
3394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): Use getMessageDataFromHostEvent().  We can't do
3414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     that now because our messageType is probably wrong.
3424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (senderInstanceId != CHRE_INSTANCE_ID) {
3434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent got event from unexpected sender:",
3444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &senderInstanceId);
3454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (eventType != CHRE_EVENT_MESSAGE_FROM_HOST) {
3474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    unexpectedEvent(eventType);
3484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  auto dataStruct = static_cast<const chreMessageFromHostData *>(eventData);
3514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): Test the message type.
3524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (dataStruct->messageSize != 0) {
3534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent got non-zero message size",
3544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &dataStruct->messageSize);
3554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
3564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // We don't test dataStruct->message.  We don't require this to be
3574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // nullptr.  If a CHRE choses to deal in 0-sized memory blocks, that's
3584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // acceptable.
3594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Stage 8 was successful.  Note that other stages might still be waiting
3614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // for freeCallbacks.  So we don't send success to the host, but just
3624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // mark our stage as a success.
3634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(8);
3644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  sInMethod = false;
3664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
3674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
3684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}  // namespace general_test
369