• 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/timer_cancel_test.h>
18 
19 #include <cinttypes>
20 #include <cstddef>
21 
22 #include <shared/macros.h>
23 #include <shared/send_message.h>
24 #include <shared/time_util.h>
25 
26 #include <chre/util/nanoapp/log.h>
27 
28 #include "chre_api/chre.h"
29 
30 #define LOG_TAG "[TimerCancelTest]"
31 
32 using nanoapp_testing::kOneMillisecondInNanoseconds;
33 
34 using nanoapp_testing::sendInternalFailureToHost;
35 using nanoapp_testing::sendSuccessToHost;
36 
37 /*
38  * This test has four stages where we cancel one-shot and recurring timers,
39  * before and after they're triggered.
40  *
41  * See the TimerCancelTest constructor to see which stage tests which setup.
42  *
43  * When all of our stages have succeeded, then we send success to the host.
44  */
45 
46 static uint64_t kDuration = 10 * kOneMillisecondInNanoseconds;
47 
48 namespace general_test {
49 
startStages()50 void TimerCancelTest::startStages() {
51   for (uint32_t i = 0; i < kStageCount; i++) {
52     Stage *stage = &mStages[i];
53     stage->timerId = chreTimerSet(kDuration, stage, stage->oneShot);
54     if (stage->timerId == CHRE_TIMER_INVALID) {
55       EXPECT_FAIL_RETURN("Unable to set timer:", &i);
56     }
57     if (stage->expectCallback) {
58       // Go on to the next stage.  Note this stage will markSuccess()
59       // in handleStageEvent().
60       continue;
61     }
62     if (!chreTimerCancel(stage->timerId)) {
63       EXPECT_FAIL_RETURN("Unable to cancel timer:", &i);
64     }
65     if (chreTimerCancel(stage->timerId)) {
66       EXPECT_FAIL_RETURN("Claimed success in second cancel:", &i);
67     }
68     markSuccess(i);
69   }
70 }
71 
72 // clang-format off
TimerCancelTest()73 TimerCancelTest::TimerCancelTest()
74     : Test(CHRE_API_VERSION_1_0),
75       mInMethod(false),
76       mStages{
77         // expectCallback:false ==> We're canceling before the timer fires.
78         // expectCallback:true  ==> We'll cancel after the timer fires once.
79         //
80         //        stage, oneShot, expectCallback
81           Stage(0,     false,   false),
82           Stage(1,     true,    false),
83           Stage(2,     false,   true  ),
84           Stage(3,     true,    true  )},
85       mFinishedBitmask(0) {}
86 // clang-format on
87 
setUp(uint32_t messageSize,const void *)88 void TimerCancelTest::setUp(uint32_t messageSize, const void * /* message */) {
89   mInMethod = true;
90 
91   if (messageSize != 0) {
92     EXPECT_FAIL_RETURN("TimerCancel message expects 0 additional bytes, got ",
93                        &messageSize);
94   }
95 
96   constexpr uint32_t kUnownedTimer = 0;
97   static_assert((kUnownedTimer != CHRE_TIMER_INVALID), "Bad test");
98   if (chreTimerCancel(kUnownedTimer)) {
99     EXPECT_FAIL_RETURN("Claimed success canceling timer we don't own");
100   }
101 
102   startStages();
103 
104   // Now we wait for some events from the timers to fire.
105 
106   mInMethod = false;
107 }
108 
handleStageEvent(Stage * stage)109 void TimerCancelTest::handleStageEvent(Stage *stage) {
110   if (!stage->expectCallback) {
111     EXPECT_FAIL_RETURN("Timer didn't cancel:", &stage->stage);
112   }
113   // Now we're going to cancel the timer, so we don't expect an
114   // additional call.
115   stage->expectCallback = false;
116 
117   bool cancelSucceeded = chreTimerCancel(stage->timerId);
118   if (stage->oneShot) {
119     if (cancelSucceeded) {
120       EXPECT_FAIL_RETURN("Claimed success canceling one-shot after it fired:",
121                          &stage->stage);
122     }
123   } else {
124     if (!cancelSucceeded) {
125       EXPECT_FAIL_RETURN("Unable to cancel recurring timer:", &stage->stage);
126     }
127   }
128   if (chreTimerCancel(stage->timerId)) {
129     EXPECT_FAIL_RETURN("Claimed success in second cancel:", &stage->stage);
130   }
131   markSuccess(stage->stage);
132 }
133 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)134 void TimerCancelTest::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
135                                   const void *eventData) {
136   if (mInMethod) {
137     EXPECT_FAIL_RETURN(
138         "handleEvent invoked while another nanoapp method is running");
139   }
140   mInMethod = true;
141   if (senderInstanceId != CHRE_INSTANCE_ID) {
142     EXPECT_FAIL_RETURN("handleEvent got event from unexpected sender:",
143                        &senderInstanceId);
144   }
145   if (eventType != CHRE_EVENT_TIMER) {
146     unexpectedEvent(eventType);
147   }
148   const Stage *stage = static_cast<const Stage *>(eventData);
149   if (stage->stage >= kStageCount) {
150     EXPECT_FAIL_RETURN("Invalid handleEvent data:", &stage->stage);
151   }
152   handleStageEvent(const_cast<Stage *>(stage));
153 
154   mInMethod = false;
155 }
156 
markSuccess(uint32_t stage)157 void TimerCancelTest::markSuccess(uint32_t stage) {
158   LOGD("Stage %" PRIu32 " succeeded", stage);
159   uint32_t finishedBit = (1 << stage);
160   if ((kAllFinished & finishedBit) == 0) {
161     EXPECT_FAIL_RETURN("markSuccess bad stage:", &stage);
162   }
163   if ((mFinishedBitmask & finishedBit) != 0) {
164     sendInternalFailureToHost("markSuccess multiple times:", &stage);
165   }
166   mFinishedBitmask |= finishedBit;
167   if (mFinishedBitmask == kAllFinished) {
168     sendSuccessToHost();
169   }
170 }
171 
172 }  // namespace general_test
173