1 /*
2 * Copyright (C) 2021 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 "test_base.h"
18
19 #include <gtest/gtest.h>
20
21 #include <thread>
22
23 #include "chre/core/event_loop_manager.h"
24 #include "chre/core/settings.h"
25 #include "chre/platform/linux/pal_gnss.h"
26 #include "chre/platform/log.h"
27 #include "chre/util/system/napp_permissions.h"
28 #include "chre_api/chre/gnss.h"
29 #include "chre_api/chre/user_settings.h"
30 #include "chre_api/chre/wifi.h"
31 #include "test_event_queue.h"
32 #include "test_util.h"
33
34 namespace chre {
35
36 namespace {
37
38 int8_t gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_DISABLED;
39 int8_t gExpectedWifiSettingState = CHRE_USER_SETTING_STATE_DISABLED;
40
start()41 bool start() {
42 bool success = chreGnssLocationSessionStartAsync(50, 50, nullptr);
43 EXPECT_TRUE(success);
44 chreUserSettingConfigureEvents(CHRE_USER_SETTING_LOCATION, true /* enable */);
45 chreUserSettingConfigureEvents(CHRE_USER_SETTING_WIFI_AVAILABLE,
46 true /* enable */);
47
48 chreWifiNanSubscribeConfig config = {
49 .subscribeType = CHRE_WIFI_NAN_SUBSCRIBE_TYPE_PASSIVE,
50 .service = "SomeService",
51 };
52 success = chreWifiNanSubscribe(&config, nullptr /* cookie */);
53 EXPECT_TRUE(success);
54
55 TestEventQueueSingleton::get()->pushEvent(
56 CHRE_EVENT_SIMULATION_TEST_NANOAPP_LOADED);
57 return true;
58 }
59
handleEvent(uint32_t,uint16_t eventType,const void * eventData)60 void handleEvent(uint32_t /* senderInstanceId */, uint16_t eventType,
61 const void *eventData) {
62 switch (eventType) {
63 case CHRE_EVENT_SETTING_CHANGED_LOCATION: {
64 auto *event = static_cast<const chreUserSettingChangedEvent *>(eventData);
65 EXPECT_EQ(gExpectedLocationSettingState, event->settingState);
66 TestEventQueueSingleton::get()->pushEvent(
67 CHRE_EVENT_SETTING_CHANGED_LOCATION);
68 break;
69 }
70
71 case CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE: {
72 auto *event = static_cast<const chreUserSettingChangedEvent *>(eventData);
73 EXPECT_EQ(gExpectedWifiSettingState, event->settingState);
74 TestEventQueueSingleton::get()->pushEvent(
75 CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE);
76 break;
77 }
78
79 case CHRE_EVENT_GNSS_LOCATION: {
80 TestEventQueueSingleton::get()->pushEvent(CHRE_EVENT_GNSS_LOCATION);
81 break;
82 }
83
84 case CHRE_EVENT_GNSS_ASYNC_RESULT: {
85 TestEventQueueSingleton::get()->pushEvent(CHRE_EVENT_GNSS_ASYNC_RESULT);
86 break;
87 }
88
89 case CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT: {
90 TestEventQueueSingleton::get()->pushEvent(
91 CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT);
92 break;
93 }
94
95 case CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED: {
96 TestEventQueueSingleton::get()->pushEvent(
97 CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED);
98 break;
99 }
100
101 default: {
102 LOGE("Invalid event received type: %u (0x%x)", eventType, eventType);
103 FAIL();
104 }
105 }
106
107 TestEventQueueSingleton::get()->pushEvent(eventType);
108 }
109
end()110 void end() {
111 chreUserSettingConfigureEvents(CHRE_USER_SETTING_LOCATION,
112 false /* enable */);
113 chreUserSettingConfigureEvents(CHRE_USER_SETTING_WIFI_AVAILABLE,
114 false /* enable */);
115 }
116
startTestNanoapp()117 void startTestNanoapp() {
118 constexpr uint64_t kAppId = 0x0123456789abcdef;
119 constexpr uint32_t kAppVersion = 0;
120 constexpr uint32_t kAppPerms =
121 NanoappPermissions::CHRE_PERMS_GNSS | NanoappPermissions::CHRE_PERMS_WIFI;
122
123 UniquePtr<Nanoapp> nanoapp = createStaticNanoapp(
124 "Test nanoapp", kAppId, kAppVersion, kAppPerms, start, handleEvent, end);
125 EventLoopManagerSingleton::get()->deferCallback(
126 SystemCallbackType::FinishLoadingNanoapp, std::move(nanoapp),
127 testFinishLoadingNanoappCallback);
128 }
129
130 } // anonymous namespace
131
132 /**
133 * This test verifies the following GNSS settings behavior:
134 * 1) Nanoapp makes GNSS request
135 * 2) Toggle location setting -> disabled
136 * 3) Toggle location setting -> enabled.
137 * 4) Verify things resume.
138 */
TEST_F(TestBase,LocationSettingsTest)139 TEST_F(TestBase, LocationSettingsTest) {
140 startTestNanoapp();
141
142 waitForEvent(CHRE_EVENT_SIMULATION_TEST_NANOAPP_LOADED);
143
144 waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT);
145 ASSERT_TRUE(chrePalGnssIsLocationEnabled());
146 waitForEvent(CHRE_EVENT_GNSS_LOCATION);
147
148 gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_DISABLED;
149 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
150 Setting::LOCATION, false /* enabled */);
151 waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
152 ASSERT_EQ(
153 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
154 Setting::LOCATION),
155 false);
156 std::this_thread::sleep_for(std::chrono::milliseconds(100));
157 ASSERT_FALSE(chrePalGnssIsLocationEnabled());
158
159 gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_ENABLED;
160 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
161 Setting::LOCATION, true /* enabled */);
162 waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
163 std::this_thread::sleep_for(std::chrono::milliseconds(100));
164 ASSERT_TRUE(
165 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
166 Setting::LOCATION));
167
168 waitForEvent(CHRE_EVENT_GNSS_LOCATION);
169 ASSERT_TRUE(chrePalGnssIsLocationEnabled());
170 }
171
TEST_F(TestBase,DefaultSettingsAreSet)172 TEST_F(TestBase, DefaultSettingsAreSet) {
173 for (uint8_t setting = CHRE_USER_SETTING_LOCATION;
174 setting <= CHRE_USER_SETTING_BLE_AVAILABLE; ++setting) {
175 int8_t expectedSettingState = (setting == CHRE_USER_SETTING_AIRPLANE_MODE)
176 ? CHRE_USER_SETTING_STATE_DISABLED
177 : CHRE_USER_SETTING_STATE_ENABLED;
178 EXPECT_EQ(expectedSettingState, chreUserSettingGetState(setting));
179 }
180 }
181
TEST_F(TestBase,WifiSettingsTest)182 TEST_F(TestBase, WifiSettingsTest) {
183 startTestNanoapp();
184
185 waitForEvent(CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT);
186
187 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
188 Setting::WIFI_AVAILABLE, false /* enabled */);
189 waitForEvent(CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED);
190 waitForEvent(CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE);
191
192 gExpectedWifiSettingState = CHRE_USER_SETTING_STATE_ENABLED;
193 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
194 Setting::WIFI_AVAILABLE, true /* enabled */);
195 waitForEvent(CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE);
196 std::this_thread::sleep_for(std::chrono::milliseconds(100));
197 ASSERT_TRUE(
198 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
199 Setting::WIFI_AVAILABLE));
200 }
201
202 } // namespace chre
203