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;
39 int8_t gExpectedWifiSettingState;
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 gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_DISABLED;
124 gExpectedWifiSettingState = CHRE_USER_SETTING_STATE_DISABLED;
125
126 UniquePtr<Nanoapp> nanoapp = createStaticNanoapp(
127 "Test nanoapp", kAppId, kAppVersion, kAppPerms, start, handleEvent, end);
128 EventLoopManagerSingleton::get()->deferCallback(
129 SystemCallbackType::FinishLoadingNanoapp, std::move(nanoapp),
130 testFinishLoadingNanoappCallback);
131 }
132
133 } // anonymous namespace
134
135 /**
136 * This test verifies the following GNSS settings behavior:
137 * 1) Nanoapp makes GNSS request
138 * 2) Toggle location setting -> disabled
139 * 3) Toggle location setting -> enabled.
140 * 4) Verify things resume.
141 */
TEST_F(TestBase,LocationSettingsTest)142 TEST_F(TestBase, LocationSettingsTest) {
143 startTestNanoapp();
144
145 waitForEvent(CHRE_EVENT_SIMULATION_TEST_NANOAPP_LOADED);
146
147 waitForEvent(CHRE_EVENT_GNSS_ASYNC_RESULT);
148 ASSERT_TRUE(chrePalGnssIsLocationEnabled());
149 waitForEvent(CHRE_EVENT_GNSS_LOCATION);
150
151 gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_DISABLED;
152 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
153 Setting::LOCATION, false /* enabled */);
154 waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
155 ASSERT_EQ(
156 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
157 Setting::LOCATION),
158 false);
159 std::this_thread::sleep_for(std::chrono::milliseconds(100));
160 ASSERT_FALSE(chrePalGnssIsLocationEnabled());
161
162 gExpectedLocationSettingState = CHRE_USER_SETTING_STATE_ENABLED;
163 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
164 Setting::LOCATION, true /* enabled */);
165 waitForEvent(CHRE_EVENT_SETTING_CHANGED_LOCATION);
166 std::this_thread::sleep_for(std::chrono::milliseconds(100));
167 ASSERT_TRUE(
168 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
169 Setting::LOCATION));
170
171 waitForEvent(CHRE_EVENT_GNSS_LOCATION);
172 ASSERT_TRUE(chrePalGnssIsLocationEnabled());
173 }
174
TEST_F(TestBase,DefaultSettingsAreSet)175 TEST_F(TestBase, DefaultSettingsAreSet) {
176 for (uint8_t setting = CHRE_USER_SETTING_LOCATION;
177 setting <= CHRE_USER_SETTING_BLE_AVAILABLE; ++setting) {
178 int8_t expectedSettingState = (setting == CHRE_USER_SETTING_AIRPLANE_MODE)
179 ? CHRE_USER_SETTING_STATE_DISABLED
180 : CHRE_USER_SETTING_STATE_ENABLED;
181 EXPECT_EQ(expectedSettingState, chreUserSettingGetState(setting));
182 }
183 }
184
TEST_F(TestBase,WifiSettingsTest)185 TEST_F(TestBase, WifiSettingsTest) {
186 startTestNanoapp();
187
188 waitForEvent(CHRE_EVENT_WIFI_NAN_IDENTIFIER_RESULT);
189
190 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
191 Setting::WIFI_AVAILABLE, false /* enabled */);
192 waitForEvent(CHRE_EVENT_WIFI_NAN_SESSION_TERMINATED);
193 waitForEvent(CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE);
194
195 gExpectedWifiSettingState = CHRE_USER_SETTING_STATE_ENABLED;
196 EventLoopManagerSingleton::get()->getSettingManager().postSettingChange(
197 Setting::WIFI_AVAILABLE, true /* enabled */);
198 waitForEvent(CHRE_EVENT_SETTING_CHANGED_WIFI_AVAILABLE);
199 std::this_thread::sleep_for(std::chrono::milliseconds(100));
200 ASSERT_TRUE(
201 EventLoopManagerSingleton::get()->getSettingManager().getSettingEnabled(
202 Setting::WIFI_AVAILABLE));
203 }
204
205 } // namespace chre
206