• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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/basic_flush_async_test.h>
18 
19 #include <cinttypes>
20 
21 #include <shared/macros.h>
22 #include <shared/send_message.h>
23 #include <shared/time_util.h>
24 
25 #include <chre/util/nanoapp/log.h>
26 #include "chre/util/macros.h"
27 
28 #define LOG_TAG "[BasicFlushAsyncTest]"
29 
30 using nanoapp_testing::kOneMillisecondInNanoseconds;
31 using nanoapp_testing::kOneSecondInNanoseconds;
32 
33 using nanoapp_testing::sendSuccessToHost;
34 
35 namespace general_test {
36 
setUp(uint32_t messageSize,const void * message)37 void BasicSensorFlushAsyncTest::setUp(uint32_t messageSize,
38                                       const void *message) {
39   UNUSED_VAR(message);
40 
41   constexpr uint64_t kFlushTestLatencyNs = 2 * kOneSecondInNanoseconds;
42   constexpr uint64_t kFlushTestStartTimerValueNs =
43       kFlushTestLatencyNs / 2;  // start the test at (now + 1/2*latency)
44 
45   if (messageSize != 0) {
46     EXPECT_FAIL_RETURN("Expected 0 byte message, got more bytes:",
47                        &messageSize);
48   }
49 
50   // TODO: Generalize this test for all sensors by making
51   // BasicSensorFlushAsyncTest a base class for sensor specific tests for the
52   // FlushAsync API
53   if (!chreSensorFindDefault(CHRE_SENSOR_TYPE_ACCELEROMETER, &mSensorHandle)) {
54     EXPECT_FAIL_RETURN("Default Accelerometer not found");
55   }
56 
57   // We set the sampling period of the sensor to 2x the min interval,
58   // and set a variable to track that we get sensor samples within a
59   // reasonable (a small order of magnitude greater than the min interval)
60   // 'wiggle room' from when we start the flush request.
61   struct chreSensorInfo info;
62   if (!chreGetSensorInfo(mSensorHandle, &info)) {
63     EXPECT_FAIL_RETURN("Failed to get sensor info");
64   }
65   mFlushTestTimeWiggleRoomNs = 20 * info.minInterval;
66 
67   if (!chreSensorConfigure(mSensorHandle, CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS,
68                            2 * info.minInterval, kFlushTestLatencyNs)) {
69     EXPECT_FAIL_RETURN("Failed to configure the accelerometer");
70   }
71 
72   // To exercise the test, we need to confirm that we actually get sensor
73   // samples from the flush request. to do this, set a timer to start a flush
74   // request at around latency/2 time from now, and request the flush when it
75   // expires, hoping to receive some of the data accumulated between configure
76   // time and flush request time
77   mFlushStartTimerHandle =
78       chreTimerSet(kFlushTestStartTimerValueNs, &mFlushStartTimerHandle,
79                    true /* one shot */);
80   if (CHRE_TIMER_INVALID == mFlushStartTimerHandle) {
81     EXPECT_FAIL_RETURN("Failed to set flush start timer");
82   }
83 }
84 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)85 void BasicSensorFlushAsyncTest::handleEvent(uint32_t senderInstanceId,
86                                             uint16_t eventType,
87                                             const void *eventData) {
88   UNUSED_VAR(senderInstanceId);
89 
90   switch (eventType) {
91     case CHRE_EVENT_SENSOR_ACCELEROMETER_DATA:
92       handleDataReceived(
93           static_cast<const struct chreSensorThreeAxisData *>(eventData));
94       break;
95 
96     case CHRE_EVENT_SENSOR_FLUSH_COMPLETE:
97       handleFlushComplete(
98           static_cast<const struct chreSensorFlushCompleteEvent *>(eventData));
99       break;
100 
101     case CHRE_EVENT_TIMER:
102       handleTimerExpired(static_cast<const uint32_t *>(eventData));
103       break;
104 
105     default:
106       break;
107   }
108 }
109 
start()110 void BasicSensorFlushAsyncTest::start() {
111   mStarted = true;
112   mFlushRequestTime = chreGetTime();
113 
114   if (!chreSensorFlushAsync(mSensorHandle, &mCookie)) {
115     finish(false /* succeeded */, "Async flush failed");
116   }
117 
118   mFlushTimeoutTimerHandle =
119       chreTimerSet(CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS,
120                    &mFlushTimeoutTimerHandle, true /* oneShot */);
121   if (CHRE_TIMER_INVALID == mFlushTimeoutTimerHandle) {
122     EXPECT_FAIL_RETURN("Failed to set flush start timer");
123   }
124 }
125 
finish(bool succeeded,const char * message)126 void BasicSensorFlushAsyncTest::finish(bool succeeded, const char *message) {
127   mStarted = false;
128 
129   if (mFlushTimeoutTimerHandle != CHRE_TIMER_INVALID) {
130     chreTimerCancel(mFlushTimeoutTimerHandle);
131   }
132 
133   if (!chreSensorConfigureModeOnly(mSensorHandle,
134                                    CHRE_SENSOR_CONFIGURE_MODE_DONE)) {
135     EXPECT_FAIL_RETURN("Failed to release sensor handle");
136   }
137 
138   if (!succeeded) {
139     EXPECT_NE_OR_RETURN(message, nullptr,
140                         "message cannot be null when the test failed");
141     EXPECT_FAIL_RETURN(message);
142   } else {
143     sendSuccessToHost();
144   }
145 }
146 
handleDataReceived(const struct chreSensorThreeAxisData * eventData)147 void BasicSensorFlushAsyncTest::handleDataReceived(
148     const struct chreSensorThreeAxisData *eventData) {
149   // we're only interested in storing the latest timestamp of the sensor data
150   mLatestSensorDataTimestamp = eventData->header.baseTimestamp;
151   for (int i = 0; i < eventData->header.readingCount; ++i) {
152     mLatestSensorDataTimestamp += eventData->readings[i].timestampDelta;
153   }
154 }
155 
handleFlushComplete(const struct chreSensorFlushCompleteEvent * eventData)156 void BasicSensorFlushAsyncTest::handleFlushComplete(
157     const struct chreSensorFlushCompleteEvent *eventData) {
158   if (mStarted) {
159     EXPECT_NE_OR_RETURN(mLatestSensorDataTimestamp, 0,
160                         "No sensor data was received");
161 
162     // we should fail the test if we receive too old a sensor sample.
163     // ideally, we don't receive any samples that was sampled after
164     // our flush request, but for this test, we'll be lenient and assume
165     // that anything between [flushRequestTime - kFlushTestTimeWiggleRoomNs,
166     // now] is OK.
167     uint64_t oldestValidTimestamp =
168         mFlushRequestTime - mFlushTestTimeWiggleRoomNs;
169 
170     EXPECT_GE_OR_RETURN(mLatestSensorDataTimestamp, oldestValidTimestamp,
171                         "Received very old data");
172 
173     LOGI("Flush test: flush request to complete time: %" PRIu64 " ms",
174          (chreGetTime() - mFlushRequestTime) / kOneMillisecondInNanoseconds);
175 
176     // verify event data
177     EXPECT_NE_OR_RETURN(eventData, nullptr, "null event data");
178     EXPECT_EQ_OR_RETURN(eventData->sensorHandle, mSensorHandle,
179                         "Got flush event from a different sensor handle");
180     EXPECT_EQ_OR_RETURN(eventData->errorCode, CHRE_ERROR_NONE,
181                         "Flush Error code was not CHRE_ERROR_NONE");
182     EXPECT_NE_OR_RETURN(eventData->cookie, nullptr,
183                         "Null cookie in flush complete event");
184     EXPECT_EQ_OR_RETURN(*(static_cast<const uint32_t *>(eventData->cookie)),
185                         mCookie, "unexpected cookie in flush complete event");
186 
187     finish(true /* succeeded */, nullptr /* message */);
188   }
189 }
190 
handleTimerExpired(const uint32_t * timerHandle)191 void BasicSensorFlushAsyncTest::handleTimerExpired(
192     const uint32_t *timerHandle) {
193   if (timerHandle != nullptr) {
194     if (mFlushStartTimerHandle == *timerHandle) {
195       start();
196     } else if (mFlushTimeoutTimerHandle == *timerHandle) {
197       finish(false /* succeeded */,
198              "Did not receive flush complete event in time");
199     } else {
200       EXPECT_FAIL_RETURN("Unexpected timer handle received");
201     }
202   } else {
203     EXPECT_FAIL_RETURN("Null timer handle received");
204   }
205 }
206 
207 }  // namespace general_test