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