• 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 <cstddef>  // max_align_t
18 #include <cstdint>
19 #include <new>  // placement new
20 
21 #include <general_test/basic_audio_test.h>
22 #include <general_test/basic_ble_test.h>
23 #include <general_test/basic_flush_async_test.h>
24 #include <general_test/basic_gnss_test.h>
25 #include <general_test/basic_sensor_tests.h>
26 #include <general_test/basic_wifi_test.h>
27 #include <general_test/estimated_host_time_test.h>
28 #include <general_test/event_between_apps_test.h>
29 #include <general_test/get_time_test.h>
30 #include <general_test/gnss_capabilities_test.h>
31 #include <general_test/heap_alloc_stress_test.h>
32 #include <general_test/heap_exhaustion_stability_test.h>
33 #include <general_test/hello_world_test.h>
34 #include <general_test/host_awake_suspend_test.h>
35 #include <general_test/logging_consistency_test.h>
36 #include <general_test/nanoapp_info_by_app_id_test.h>
37 #include <general_test/nanoapp_info_by_instance_id_test.h>
38 #include <general_test/nanoapp_info_events_test_observer.h>
39 #include <general_test/nanoapp_info_events_test_performer.h>
40 #include <general_test/send_event_stress_test.h>
41 #include <general_test/send_event_test.h>
42 #include <general_test/send_message_to_host_test.h>
43 #include <general_test/sensor_info_test.h>
44 #include <general_test/simple_heap_alloc_test.h>
45 #include <general_test/test.h>
46 #include <general_test/test_names.h>
47 #include <general_test/timer_cancel_test.h>
48 #include <general_test/timer_set_test.h>
49 #include <general_test/timer_stress_test.h>
50 #include <general_test/version_consistency_test.h>
51 #include <general_test/wifi_capabilities_test.h>
52 #include <general_test/wwan_capabilities_test.h>
53 #include <general_test/wwan_cell_info_test.h>
54 #include <shared/abort.h>
55 #include <shared/macros.h>
56 #include <shared/nano_endian.h>
57 #include <shared/nano_string.h>
58 #include <shared/send_message.h>
59 
60 #include "chre_api/chre.h"
61 
62 using nanoapp_testing::AbortBlame;
63 using nanoapp_testing::MessageType;
64 
65 using nanoapp_testing::sendInternalFailureToHost;
66 
67 namespace general_test {
68 
69 // The size of this array is checked at compile time by the static_assert
70 // in getNew().
71 alignas(alignof(max_align_t)) static uint8_t gGetNewBackingMemory[128];
72 
73 template <typename N>
getNew()74 static N *getNew() {
75   // We intentionally avoid using chreHeapAlloc() to reduce dependencies
76   // for our tests, especially things like HelloWorld.  This obviously
77   // cannot be called more than once, but our usage doesn't require it.
78   static_assert(sizeof(gGetNewBackingMemory) >= sizeof(N),
79                 "getNew() backing memory is undersized");
80 
81   return new (gGetNewBackingMemory) N();
82 }
83 
84 // TODO(b/32114261): Remove this variable.
85 bool gUseNycMessageHack = true;
86 
87 class App {
88  public:
App()89   App() : mConstructionCookie(kConstructed), mCurrentTest(nullptr) {}
90 
~App()91   ~App() {
92     // Yes, it's very odd to actively set a value in our destructor.
93     // However, since we're making a static instance of this class,
94     // the space for this class will stick around (unlike heap memory
95     // which might get reused), so we can still use this to perform
96     // some testing.
97     mConstructionCookie = kDestructed;
98   }
99 
wasConstructed() const100   bool wasConstructed() const {
101     return mConstructionCookie == kConstructed;
102   }
wasDestructed() const103   bool wasDestructed() const {
104     return mConstructionCookie == kDestructed;
105   }
106 
107   void handleEvent(uint32_t senderInstanceId, uint16_t eventType,
108                    const void *eventData);
109 
110   void createTest(const void *eventData);
111   void freeTest();
112 
113  private:
114   uint32_t mConstructionCookie;
115   Test *mCurrentTest;
116 
117   static constexpr uint32_t kConstructed = UINT32_C(0x51501984);
118   static constexpr uint32_t kDestructed = UINT32_C(0x19845150);
119 
120   // TODO(b/32114261): Remove this method.
121   chreMessageFromHostData adjustHostMessageForNYC(
122       const chreMessageFromHostData *data);
123 };
124 
125 // In the NYC version of the CHRE, the "reservedMessageType" isn't
126 // assured to be sent correctly from the host.  But we want our
127 // tests to be written using this field (it's cleaner).  So in NYC
128 // the host prefixes this value in the first four bytes of 'message',
129 // and here we reconstruct the message to be correct.
130 // TODO(b/32114261): Remove this method.
adjustHostMessageForNYC(const chreMessageFromHostData * data)131 chreMessageFromHostData App::adjustHostMessageForNYC(
132     const chreMessageFromHostData *data) {
133   if (!gUseNycMessageHack) {
134     return *data;
135   }
136   chreMessageFromHostData ret;
137 
138   if (data->messageSize < sizeof(uint32_t)) {
139     sendInternalFailureToHost("Undersized message in adjustHostMessageForNYC");
140   }
141   const uint8_t *messageBytes = static_cast<const uint8_t *>(data->message);
142   nanoapp_testing::memcpy(&(ret.reservedMessageType), messageBytes,
143                           sizeof(ret.reservedMessageType));
144   ret.reservedMessageType =
145       nanoapp_testing::littleEndianToHost(ret.reservedMessageType);
146   ret.messageSize = data->messageSize - sizeof(ret.reservedMessageType);
147   ret.message = messageBytes + sizeof(ret.reservedMessageType);
148   return ret;
149 }
150 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)151 void App::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
152                       const void *eventData) {
153   // TODO: When we get an API that fixes the reservedMessageType,
154   //       then we should only use our adjustedData hack on APIs
155   //       prior to it being fixed.  Eventually, we should remove
156   //       this altogether.
157   chreMessageFromHostData adjustedData;
158   if (eventType == CHRE_EVENT_MESSAGE_FROM_HOST) {
159     auto data = static_cast<const chreMessageFromHostData *>(eventData);
160     adjustedData = adjustHostMessageForNYC(data);
161     eventData = &adjustedData;
162   }
163 
164   if (mCurrentTest != nullptr) {
165     // Our test is in progress, so let it take control.
166     mCurrentTest->testHandleEvent(senderInstanceId, eventType, eventData);
167     return;
168   }
169 
170   // No test in progress, so we expect this message to be the host telling
171   // us which test to run.  We fail if it's anything else.
172   if (eventType != CHRE_EVENT_MESSAGE_FROM_HOST) {
173     uint32_t localEventType = eventType;
174     EXPECT_FAIL_RETURN("Unexpected event type with no established test:",
175                        &localEventType);
176   }
177   if (senderInstanceId != CHRE_INSTANCE_ID) {
178     EXPECT_FAIL_RETURN("Got MESSAGE_FROM_HOST not from CHRE_INSTANCE_ID:",
179                        &senderInstanceId);
180   }
181   createTest(eventData);
182 }
183 
createTest(const void * eventData)184 void App::createTest(const void *eventData) {
185   if (mCurrentTest != nullptr) {
186     sendInternalFailureToHost("Got to createTest() with non-null mCurrentTest");
187   }
188 
189   auto data = static_cast<const chreMessageFromHostData *>(eventData);
190 
191   switch (static_cast<TestNames>(data->reservedMessageType)) {
192     using namespace general_test;
193 
194 #define CASE(testName, className)       \
195   case TestNames::testName:             \
196     mCurrentTest = getNew<className>(); \
197     break;
198 
199     CASE(kHelloWorld, HelloWorldTest);
200     CASE(kSimpleHeapAlloc, SimpleHeapAllocTest);
201     CASE(kHeapAllocStress, HeapAllocStressTest);
202     CASE(kGetTime, GetTimeTest);
203     CASE(kEventBetweenApps0, EventBetweenApps0);
204     CASE(kEventBetweenApps1, EventBetweenApps1);
205     CASE(kSendEvent, SendEventTest);
206     CASE(kBasicAccelerometer, BasicAccelerometerTest);
207     CASE(kBasicInstantMotionDetect, BasicInstantMotionDetectTest);
208     CASE(kBasicStationaryDetect, BasicStationaryDetectTest);
209     CASE(kBasicGyroscope, BasicGyroscopeTest);
210     CASE(kBasicMagnetometer, BasicMagnetometerTest);
211     CASE(kBasicBarometer, BasicBarometerTest);
212     CASE(kBasicLightSensor, BasicLightSensorTest);
213     CASE(kBasicProximity, BasicProximityTest);
214     CASE(kVersionConsistency, VersionConsistencyTest);
215     CASE(kLoggingConsistency, LoggingConsistencyTest);
216     CASE(kSendMessageToHost, SendMessageToHostTest);
217     CASE(kTimerSet, TimerSetTest);
218     CASE(kTimerCancel, TimerCancelTest);
219     CASE(kTimerStress, TimerStressTest);
220     CASE(kSendEventStress, SendEventStressTest);
221     CASE(kHeapExhaustionStability, HeapExhaustionStabilityTest);
222     CASE(kGnssCapabilities, GnssCapabilitiesTest);
223     CASE(kWifiCapabilities, WifiCapabilitiesTest);
224     CASE(kWwanCapabilities, WwanCapabilitiesTest);
225     CASE(kSensorInfo, SensorInfoTest);
226     CASE(kWwanCellInfoTest, WwanCellInfoTest);
227     CASE(kEstimatedHostTime, EstimatedHostTimeTest);
228     CASE(kNanoappInfoByAppId, NanoappInfoByAppIdTest);
229     CASE(kNanoappInfoByInstanceId, NanoappInfoByInstanceIdTest);
230     CASE(kNanoAppInfoEventsPerformer, NanoAppInfoEventsTestPerformer);
231     CASE(kNanoAppInfoEventsObserver, NanoAppInfoEventsTestObserver);
232     CASE(kBasicAudioTest, BasicAudioTest);
233     CASE(kHostAwakeSuspend, HostAwakeSuspendTest);
234     CASE(kBasicGnssTest, BasicGnssTest);
235     CASE(kBasicWifiTest, BasicWifiTest);
236     CASE(kBasicSensorFlushAsyncTest, BasicSensorFlushAsyncTest);
237     CASE(kBasicBleTest, BasicBleTest);
238 
239 #undef CASE
240 
241     default:
242       EXPECT_FAIL_RETURN("Unexpected message type:",
243                          &(data->reservedMessageType));
244   }
245 
246   if (mCurrentTest != nullptr) {
247     mCurrentTest->testSetUp(data->messageSize, data->message);
248   } else {
249     sendInternalFailureToHost("createTest() ended with null mCurrentTest");
250   }
251 }
252 
freeTest()253 void App::freeTest() {
254   if (mCurrentTest == nullptr) {
255     sendInternalFailureToHost("Nanoapp unloading without running any test");
256   }
257   mCurrentTest->~Test();
258 }
259 
260 }  // namespace general_test
261 
262 static general_test::App gApp;
263 
nanoappHandleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)264 extern "C" void nanoappHandleEvent(uint32_t senderInstanceId,
265                                    uint16_t eventType, const void *eventData) {
266   gApp.handleEvent(senderInstanceId, eventType, eventData);
267 }
268 
269 static uint32_t zeroedBytes[13];
270 
nanoappStart(void)271 extern "C" bool nanoappStart(void) {
272   // zeroedBytes is in the BSS and needs to be zero'd out.
273   for (size_t i = 0; i < sizeof(zeroedBytes) / sizeof(zeroedBytes[0]); i++) {
274     if (zeroedBytes[i] != 0) {
275       return false;
276     }
277   }
278 
279   // A CHRE is required to call the constructor of our class prior to
280   // reaching this point.
281   return gApp.wasConstructed();
282 }
283 
nanoappEnd(void)284 extern "C" void nanoappEnd(void) {
285   if (gApp.wasDestructed()) {
286     // It's not legal for us to send a message from here.  The best
287     // we can do is abort, although there's no means for the end user
288     // to see such a failure.
289     // TODO: Figure out how to have this failure noticed.
290     nanoapp_testing::abort(AbortBlame::kChreInNanoappEnd);
291   }
292   gApp.freeTest();
293 
294   // TODO: Unclear how we can test the global destructor being called,
295   //     but that would be good to test.  Since it's supposed to happen
296   //     after this call completes, it's difficult to test.
297 }
298