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/timer_cancel_test.h>
184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cinttypes>
204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cstddef>
214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/send_message.h>
234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <chre.h>
254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendFatalFailureToHost;
274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendInternalFailureToHost;
284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendSuccessToHost;
294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/*
314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * This test has four stages where we cancel one-shot and recurring timers,
324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * before and after they're triggered.
334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * See the TimerCancelTest constructor to see which stage tests which setup.
354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * When all of our stages have succeeded, then we send success to the host.
374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */
384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// 10 milliseconds
404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurostatic uint64_t kDuration = UINT64_C(10000000);
414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguronamespace general_test {
434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid TimerCancelTest::startStages() {
454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (uint32_t i = 0; i < kStageCount; i++) {
464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    Stage *stage = &mStages[i];
474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    stage->timerId = chreTimerSet(kDuration, stage, stage->oneShot);
484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (stage->timerId == CHRE_TIMER_INVALID) {
494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Unable to set timer:", &i);
504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (stage->expectCallback) {
524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      // Go on to the next stage.  Note this stage will markSuccess()
534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      // in handleStageEvent().
544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      continue;
554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (!chreTimerCancel(stage->timerId)) {
574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Unable to cancel timer:", &i);
584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (chreTimerCancel(stage->timerId)) {
604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Claimed success in second cancel:", &i);
614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    markSuccess(i);
634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur IshiguroTimerCancelTest::TimerCancelTest()
674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  : Test(CHRE_API_VERSION_1_0),
684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    mInMethod(false),
694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    mStages{
704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      // expectCallback:false ==> We're canceling before the timer fires.
714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      // expectCallback:true  ==> We'll cancel after the timer fires once.
724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      //
734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      //        stage, oneShot, expectCallback
744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        Stage(0,     false,   false),
754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        Stage(1,     true,    false),
764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        Stage(2,     false,   true  ),
774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        Stage(3,     true,    true  )},
784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    mFinishedBitmask(0) {
794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid TimerCancelTest::setUp(uint32_t messageSize, const void * /* message */) {
824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = true;
834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (messageSize != 0) {
854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost(
864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "TimerCancel message expects 0 additional bytes, got ",
874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        &messageSize);
884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  constexpr uint32_t kUnownedTimer = 0;
914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  static_assert((kUnownedTimer != CHRE_TIMER_INVALID), "Bad test");
924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (chreTimerCancel(kUnownedTimer)) {
934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Claimed success canceling timer we don't own");
944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  startStages();
974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Now we wait for some events from the timers to fire.
994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = false;
1014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid TimerCancelTest::handleStageEvent(Stage *stage) {
1044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!stage->expectCallback) {
1054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Timer didn't cancel:", &stage->stage);
1064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Now we're going to cancel the timer, so we don't expect an
1084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // additional call.
1094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  stage->expectCallback = false;
1104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  bool cancelSucceeded = chreTimerCancel(stage->timerId);
1124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (stage->oneShot) {
1134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (cancelSucceeded) {
1144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Claimed success canceling one-shot after "
1154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                             "it fired:", &stage->stage);
1164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
1174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
1184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (!cancelSucceeded) {
1194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Unable to cancel recurring timer:",
1204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                             &stage->stage);
1214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
1224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (chreTimerCancel(stage->timerId)) {
1244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Claimed success in second cancel:",
1254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &stage->stage);
1264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(stage->stage);
1284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid TimerCancelTest::handleEvent(uint32_t senderInstanceId,
1314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                  uint16_t eventType, const void* eventData) {
1324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (mInMethod) {
1334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent invoked while another nanoapp "
1344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "method is running");
1354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = true;
1374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (senderInstanceId != CHRE_INSTANCE_ID) {
1384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent got event from unexpected sender:",
1394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &senderInstanceId);
1404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (eventType != CHRE_EVENT_TIMER) {
1424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    unexpectedEvent(eventType);
1434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  const Stage *stage = static_cast<const Stage*>(eventData);
1454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (stage->stage >= kStageCount) {
1464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Invalid handleEvent data:", &stage->stage);
1474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  handleStageEvent(const_cast<Stage *>(stage));
1494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = false;
1514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid TimerCancelTest::markSuccess(uint32_t stage) {
1544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreLog(CHRE_LOG_DEBUG, "Stage %" PRIu32 " succeeded", stage);
1554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t finishedBit = (1 << stage);
1564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if ((kAllFinished & finishedBit) == 0) {
1574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("markSuccess bad stage:", &stage);
1584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if ((mFinishedBitmask & finishedBit) != 0) {
1604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendInternalFailureToHost("markSuccess multiple times:", &stage);
1614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mFinishedBitmask |= finishedBit;
1634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (mFinishedBitmask == kAllFinished) {
1644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendSuccessToHost();
1654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}  // namespace general_test
169