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