1 /*
2 * Copyright (C) 2022 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 "chre_api/chre/sensor.h"
18
19 #include <cstdint>
20
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/core/settings.h"
23 #include "chre/platform/linux/pal_sensor.h"
24 #include "chre/platform/log.h"
25 #include "chre/util/system/napp_permissions.h"
26 #include "chre_api/chre/common.h"
27 #include "chre_api/chre/event.h"
28
29 #include "gtest/gtest.h"
30 #include "inc/test_util.h"
31 #include "test_base.h"
32 #include "test_event.h"
33 #include "test_event_queue.h"
34 #include "test_util.h"
35
36 namespace chre {
37 namespace {
38
39 class SensorTest : public TestBase {};
40
TEST_F(SensorTest,SensorCanSubscribeAndUnsubscribeToDataEvents)41 TEST_F(SensorTest, SensorCanSubscribeAndUnsubscribeToDataEvents) {
42 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
43
44 struct Configuration {
45 uint32_t sensorHandle;
46 uint64_t interval;
47 enum chreSensorConfigureMode mode;
48 };
49
50 class App : public TestNanoapp {
51 public:
52 void handleEvent(uint32_t, uint16_t eventType,
53 const void *eventData) override {
54 switch (eventType) {
55 case CHRE_EVENT_SENSOR_SAMPLING_CHANGE: {
56 auto *event =
57 static_cast<const struct chreSensorSamplingStatusEvent *>(
58 eventData);
59 TestEventQueueSingleton::get()->pushEvent(
60 CHRE_EVENT_SENSOR_SAMPLING_CHANGE, *event);
61 break;
62 }
63
64 case CHRE_EVENT_TEST_EVENT: {
65 auto event = static_cast<const TestEvent *>(eventData);
66 switch (event->type) {
67 case CONFIGURE: {
68 auto config = static_cast<const Configuration *>(event->data);
69 const bool success = chreSensorConfigure(
70 config->sensorHandle, config->mode, config->interval, 0);
71 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
72 break;
73 }
74 }
75 }
76 }
77 }
78 };
79
80 uint64_t appId = loadNanoapp(MakeUnique<App>());
81
82 bool success;
83
84 EXPECT_FALSE(chrePalSensorIsSensor0Enabled());
85
86 Configuration config{.sensorHandle = 0,
87 .interval = CHRE_NSEC_PER_SEC,
88 .mode = CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS};
89 sendEventToNanoapp(appId, CONFIGURE, config);
90 waitForEvent(CONFIGURE, &success);
91 EXPECT_TRUE(success);
92 struct chreSensorSamplingStatusEvent event;
93 waitForEvent(CHRE_EVENT_SENSOR_SAMPLING_CHANGE, &event);
94 EXPECT_EQ(event.sensorHandle, config.sensorHandle);
95 EXPECT_EQ(event.status.interval, config.interval);
96 EXPECT_TRUE(event.status.enabled);
97 EXPECT_TRUE(chrePalSensorIsSensor0Enabled());
98
99 config = {.sensorHandle = 0,
100 .interval = 50,
101 .mode = CHRE_SENSOR_CONFIGURE_MODE_DONE};
102 sendEventToNanoapp(appId, CONFIGURE, config);
103 waitForEvent(CONFIGURE, &success);
104 EXPECT_TRUE(success);
105 EXPECT_FALSE(chrePalSensorIsSensor0Enabled());
106 }
107
TEST_F(SensorTest,SensorUnsubscribeToDataEventsOnUnload)108 TEST_F(SensorTest, SensorUnsubscribeToDataEventsOnUnload) {
109 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
110
111 struct Configuration {
112 uint32_t sensorHandle;
113 uint64_t interval;
114 enum chreSensorConfigureMode mode;
115 };
116
117 class App : public TestNanoapp {
118 public:
119 void handleEvent(uint32_t, uint16_t eventType,
120 const void *eventData) override {
121 switch (eventType) {
122 case CHRE_EVENT_SENSOR_SAMPLING_CHANGE: {
123 auto *event =
124 static_cast<const struct chreSensorSamplingStatusEvent *>(
125 eventData);
126 TestEventQueueSingleton::get()->pushEvent(
127 CHRE_EVENT_SENSOR_SAMPLING_CHANGE, *event);
128 break;
129 }
130
131 case CHRE_EVENT_TEST_EVENT: {
132 auto event = static_cast<const TestEvent *>(eventData);
133 switch (event->type) {
134 case CONFIGURE: {
135 auto config = static_cast<const Configuration *>(event->data);
136 const bool success = chreSensorConfigure(
137 config->sensorHandle, config->mode, config->interval, 0);
138 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
139 break;
140 }
141 }
142 }
143 }
144 }
145 };
146
147 uint64_t appId = loadNanoapp(MakeUnique<App>());
148
149 EXPECT_FALSE(chrePalSensorIsSensor0Enabled());
150
151 Configuration config{.sensorHandle = 0,
152 .interval = 10 * 1000 * 1000, // 10 ms aka 100 Hz
153 .mode = CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS};
154 sendEventToNanoapp(appId, CONFIGURE, config);
155 bool success;
156 waitForEvent(CONFIGURE, &success);
157 EXPECT_TRUE(success);
158 struct chreSensorSamplingStatusEvent event;
159 waitForEvent(CHRE_EVENT_SENSOR_SAMPLING_CHANGE, &event);
160 EXPECT_EQ(event.sensorHandle, config.sensorHandle);
161 EXPECT_EQ(event.status.interval, config.interval);
162 EXPECT_TRUE(event.status.enabled);
163 EXPECT_TRUE(chrePalSensorIsSensor0Enabled());
164
165 unloadNanoapp(appId);
166 EXPECT_FALSE(chrePalSensorIsSensor0Enabled());
167 }
168
169 } // namespace
170 } // namespace chre
171