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