• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "wifi_protect_manager.h"
17 #include "wifi_log.h"
18 #include "wifi_supplicant_hal_interface.h"
19 #ifndef OHOS_ARCH_LITE
20 #include "system_ability_definition.h"
21 #include "connection_observer_client.h"
22 #include "app_mgr_client.h"
23 #include "app_process_data.h"
24 #include "iservice_registry.h"
25 #include "app_mgr_constants.h"
26 #include "define.h"
27 #endif
28 #include "wifi_config_center.h"
29 #include "wifi_app_state_aware.h"
30 
31 #undef LOG_TAG
32 #define LOG_TAG "OHWIFI_MANAGER_LOCK_MANAGER"
33 
34 namespace OHOS {
35 namespace Wifi {
36 constexpr const int WIFI_PROTECT_APP_MAX_COUNT = 100;
37 
WifiProtectManager()38 WifiProtectManager::WifiProtectManager()
39 {
40     mWifiConnected = false;
41     mScreenOn = false;
42     mForceHiPerfMode = false;
43     mForceLowLatencyMode = false;
44     mCurrentOpMode = WifiProtectMode::WIFI_PROTECT_NO_HELD;
45     mFullHighPerfProtectsAcquired = 0;
46     mFullHighPerfProtectsReleased = 0;
47     mFullLowLatencyProtectsAcquired = 0;
48     mFullLowLatencyProtectsReleased = 0;
49     mWifiProtects.clear();
50 }
51 
~WifiProtectManager()52 WifiProtectManager::~WifiProtectManager()
53 {
54 }
55 
GetInstance()56 WifiProtectManager &WifiProtectManager::GetInstance()
57 {
58     static WifiProtectManager instance;
59     return instance;
60 }
61 
IsValidProtectMode(const WifiProtectMode & protectMode)62 bool WifiProtectManager::IsValidProtectMode(const WifiProtectMode &protectMode)
63 {
64     if (protectMode != WifiProtectMode::WIFI_PROTECT_FULL &&
65         protectMode != WifiProtectMode::WIFI_PROTECT_SCAN_ONLY &&
66         protectMode != WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF &&
67         protectMode != WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY) {
68         return false;
69     }
70 
71     return true;
72 }
73 
IsHeldWifiProtect(const std::string & protectName)74 bool WifiProtectManager::IsHeldWifiProtect(const std::string &protectName)
75 {
76     LOGD("%{public}s enter, para bundlename: %{public}s",
77         __func__, protectName.c_str());
78     std::unique_lock<std::mutex> lock(mMutex);
79     std::vector<std::shared_ptr<WifiProtect>>::iterator itor = mWifiProtects.begin();
80     while (itor != mWifiProtects.end()) {
81         if ((*itor)->GetName() == protectName) {
82             LOGI("%{public}s app bundlename: %{public}s has held wifi protect",
83                 __func__, protectName.c_str());
84             return true;
85         }
86         itor++;
87     }
88     return false;
89 }
90 
GetNearlyProtectMode()91 WifiProtectMode WifiProtectManager::GetNearlyProtectMode()
92 {
93 #ifndef OHOS_ARCH_LITE
94     WifiLinkedInfo linkedInfo;
95     WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
96     mWifiConnected = (linkedInfo.connState == ConnState::CONNECTED) ? true : false;
97 
98     int screenState = WifiConfigCenter::GetInstance().GetScreenState();
99     mScreenOn = (screenState == MODE_STATE_OPEN || screenState == MODE_STATE_DEFAULT) ? true : false;
100     int foregroudCount = GetFgLowlatyProtectCount();
101     LOGD("%{public}s mWifiConnected: %{public}d, mScreenOn: %{public}d,"
102         "ForegroundProtectCount: %{public}d, mForceHiPerfMode: %{public}d, mForceLowLatencyMode: %{public}d",
103         __func__, mWifiConnected, mScreenOn, foregroudCount, mForceHiPerfMode, mForceLowLatencyMode);
104 #endif
105     /* If Wifi Client is not connected, then all protects are not effective */
106     if (!mWifiConnected) {
107         return WifiProtectMode::WIFI_PROTECT_NO_HELD;
108     }
109 
110     /* Check if mode is forced to hi-perf */
111     if (mForceHiPerfMode) {
112         return WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF;
113     }
114 
115     /* Check if mode is forced to low-latency */
116     if (mForceLowLatencyMode) {
117         return WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY;
118     }
119 #ifndef OHOS_ARCH_LITE
120     /* If screen is on and has app in foreground and app set wifi protect to low-lantency mode,
121      then set wifi to low-latency
122     */
123     if (mScreenOn && (foregroudCount > 0) &&
124         (mFullLowLatencyProtectsAcquired > mFullLowLatencyProtectsReleased)) {
125         return WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY;
126     }
127     if ((mFullHighPerfProtectsAcquired > mFullHighPerfProtectsReleased) &&
128         mWifiProtects.size() > 0) {
129 #else
130     if (mFullHighPerfProtectsAcquired > mFullHighPerfProtectsReleased) {
131 #endif
132         return WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF;
133     }
134 
135     return WifiProtectMode::WIFI_PROTECT_NO_HELD;
136 }
137 
138 bool WifiProtectManager::InitWifiProtect(
139     const WifiProtectType &protectType,
140     const std::string &protectName)
141 {
142     std::unique_lock<std::mutex> lock(mMutex);
143     std::shared_ptr<WifiProtect> pProtect = std::make_shared<WifiProtect>(protectType,
144         WifiProtectMode::WIFI_PROTECT_FULL, protectName);
145     mWifiProtects.push_back(pProtect);
146     return true;
147 }
148 
149 bool WifiProtectManager::GetWifiProtect(
150     const WifiProtectMode &protectMode,
151     const std::string name)
152 {
153     LOGD("%{public}s mode: %{public}d, bundlename: %{public}s",
154         __func__, static_cast<int>(protectMode), name.c_str());
155 #ifndef OHOS_ARCH_LITE
156     if (!IsValidProtectMode(protectMode) || name.empty()) {
157         LOGE("Input para protectMode[%{public}d] or name[%{public}s] invalid",
158             static_cast<int>(protectMode), name.c_str());
159         return false;
160     }
161     WifiProtectMode curProtectMode = WifiProtectMode::WIFI_PROTECT_DEFAULT;
162 #endif
163     bool isAlreadyExist = false;
164     std::unique_lock<std::mutex> lock(mMutex);
165     std::vector<std::shared_ptr<WifiProtect>>::iterator itor = mWifiProtects.begin();
166     while (itor != mWifiProtects.end()) {
167         if ((*itor)->GetName() == name) {
168             isAlreadyExist = true;
169 #ifndef OHOS_ARCH_LITE
170             curProtectMode = (*itor)->GetProtectMode();
171 #endif
172             break;
173         }
174         itor++;
175     }
176 
177     if (isAlreadyExist) {
178 #ifndef OHOS_ARCH_LITE
179         if (curProtectMode == protectMode) {
180             LOGW("attempted to add a protect when already holding one");
181             return true;
182         } else {
183             LOGE("attempted to add a different protect mode to already holding one,"
184                 "please release holded protect first!");
185             return false;
186         }
187 #else
188         LOGE("attempted to add a protect when already holding one");
189         return false;
190 #endif
191     }
192 #ifndef OHOS_ARCH_LITE
193     if (mWifiProtects.size() >= WIFI_PROTECT_APP_MAX_COUNT) {
194         LOGE("Wifi protect app count out of range[%d].", WIFI_PROTECT_APP_MAX_COUNT);
195         return false;
196     }
197 #endif
198     return AddProtect(protectMode, name);
199 }
200 
201 bool WifiProtectManager::ChangeToPerfMode(bool isEnabled)
202 {
203     std::unique_lock<std::mutex> lock(mMutex);
204     mForceHiPerfMode = isEnabled;
205     mForceLowLatencyMode = false;
206     if (!ChangeWifiPowerMode()) {
207         LOGE("Failed to force hi-perf mode, returning to normal mode");
208         mForceHiPerfMode = false;
209         return false;
210     }
211 
212     return true;
213 }
214 void WifiProtectManager::HandleScreenStateChanged(bool screenOn)
215 {
216 
217     std::unique_lock<std::mutex> lock(mMutex);
218     mScreenOn = screenOn;
219     LOGD("%{public}s screen is on: %{public}d", __func__, mScreenOn);
220 
221 #ifndef OHOS_ARCH_LITE
222     if (ChangeWifiPowerMode()) {
223         LOGD("Failed to update wifi power mode for screen state change");
224     }
225 #endif
226 }
227 
228 void WifiProtectManager::UpdateWifiClientConnected(bool isConnected)
229 {
230     std::unique_lock<std::mutex> lock(mMutex);
231     mWifiConnected = isConnected;
232     LOGD("%{public}s wifi connected: %{public}d", __func__, mWifiConnected);
233 
234 #ifndef OHOS_ARCH_LITE
235     if (ChangeWifiPowerMode()) {
236         LOGD("Failed to update wifi power mode for connect state change");
237     }
238 #endif
239 }
240 
241 bool WifiProtectManager::AddProtect(
242     const WifiProtectMode &protectMode,
243     const std::string &name)
244 {
245     std::shared_ptr<WifiProtect> pProtect = std::make_shared<WifiProtect>(name);
246     if (!pProtect) {
247         LOGE("Wifi protect pointer is null.");
248         return false;
249     }
250 #ifndef OHOS_ARCH_LITE
251     int state = static_cast<int>(AppExecFwk::ApplicationState::APP_STATE_END);
252     if (WifiAppStateAware::GetInstance().IsForegroundApp(name)) {
253         state = static_cast<int>(AppExecFwk::ApplicationState::APP_STATE_FOREGROUND);
254     }
255     LOGD("%{public}s bundle name: %{public}s state: %{public}d",
256         __func__, name.c_str(), state);
257     pProtect->SetAppState(state);
258 #endif
259     pProtect->SetProtectMode(protectMode);
260 
261     mWifiProtects.push_back(pProtect);
262     switch (pProtect->GetProtectMode()) {
263         case WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF:
264             ++mFullHighPerfProtectsAcquired;
265             break;
266         case WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY:
267             ++mFullLowLatencyProtectsAcquired;
268             break;
269         default:
270             break;
271     }
272     return ChangeWifiPowerMode();
273 }
274 
275 bool WifiProtectManager::PutWifiProtect(const std::string &name)
276 {
277     LOGI("%{public}s enter bundlename: %{public}s", __func__, name.c_str());
278     if (name.empty()) {
279         LOGE("invalid bundlename: %{public}s", name.c_str());
280         return false;
281     }
282     std::unique_lock<std::mutex> lock(mMutex);
283     std::shared_ptr<WifiProtect> pWifiProtect = RemoveProtect(name);
284     if (!pWifiProtect) {
285         LOGE("attempting to release a protect that does not exist, protect name: %{public}s.",
286             name.c_str());
287         return false;
288     }
289     switch (pWifiProtect->GetProtectMode()) {
290         case WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF:
291             ++mFullHighPerfProtectsReleased;
292             break;
293         case WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY:
294             ++mFullLowLatencyProtectsReleased;
295             break;
296         default:
297             break;
298     }
299 
300     /* Recalculate the operating mode */
301     bool ret = ChangeWifiPowerMode();
302     return ret;
303 }
304 
305 std::shared_ptr<WifiProtect> WifiProtectManager::RemoveProtect(const std::string &name)
306 {
307     std::shared_ptr<WifiProtect> pProtect = nullptr;
308     std::vector<std::shared_ptr<WifiProtect>>::iterator itor = mWifiProtects.begin();
309     while (itor != mWifiProtects.end()) {
310         if ((*itor)->GetName() == name) {
311             pProtect = *itor;
312             itor = mWifiProtects.erase(itor);
313             break;
314         }
315         itor++;
316     }
317     return pProtect;
318 }
319 
320 bool WifiProtectManager::ChangeWifiPowerMode()
321 {
322     WifiProtectMode newProtectMode = GetNearlyProtectMode();
323     LOGD("%{public}s currMode: %{public}d, newMode: %{public}d",
324         __func__, static_cast<int>(mCurrentOpMode), static_cast<int>(newProtectMode));
325     if (newProtectMode == mCurrentOpMode) {
326         /* No action is needed */
327         LOGD("newProtectMode %{public}d equal to mCurrentOpMode %{public}d, no action is needed",
328             static_cast<int>(newProtectMode), static_cast<int>(mCurrentOpMode));
329         return true;
330     }
331 
332     /* Otherwise, we need to change current mode, first reset it to normal */
333     switch (mCurrentOpMode) {
334         case WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF:
335             if (WifiSupplicantHalInterface::GetInstance().SetPowerSave(true) != WIFI_HAL_OPT_OK) {
336                 LOGE("%{public}s Failed to reset the OpMode from hi-perf to Normal", __func__);
337                 return false;
338             }
339             break;
340         case WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY:
341             if (!SetLowLatencyMode(false)) {
342                 LOGE("%{public}s Failed to reset the OpMode from low-latency to normal", __func__);
343                 return false;
344             }
345             break;
346         case WifiProtectMode::WIFI_PROTECT_NO_HELD:
347         default:
348             /* No action */
349             break;
350     }
351 
352     /* Set the current mode, before we attempt to set the new mode */
353     mCurrentOpMode = WifiProtectMode::WIFI_PROTECT_NO_HELD;
354 
355     /* Now switch to the new opMode */
356     switch (newProtectMode) {
357         case WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF:
358             if (WifiSupplicantHalInterface::GetInstance().SetPowerSave(false) != WIFI_HAL_OPT_OK) {
359                 LOGE("%{public}s Failed to set the OpMode to hi-perf", __func__);
360                 return false;
361             }
362             break;
363         case WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY:
364             if (!SetLowLatencyMode(true)) {
365                 LOGE("%{public}s Failed to set the OpMode to low-latency", __func__);
366                 return false;
367             }
368             LOGE("%{public}s unspport wifi protect mode WIFI_PROTECT_FULL_LOW_LATENCY", __func__);
369             break;
370         case WifiProtectMode::WIFI_PROTECT_NO_HELD:
371             /* No action */
372             break;
373         default:
374             /* Invalid mode, don't change currentOpMode , and exit with error */
375             LOGE("%{public}s Invalid new protect Mode: %{public}d",
376                 __func__, (int)newProtectMode);
377             return false;
378     }
379 
380     /* Now set the mode to the new value */
381     mCurrentOpMode = newProtectMode;
382     LOGD("%{public}s protect mode has been set to %{public}d success.",
383         __func__, static_cast<int>(mCurrentOpMode));
384     return true;
385 }
386 
387 bool WifiProtectManager::SetLowLatencyMode(bool enabled)
388 {
389     /* Only set power save mode */
390     if (WifiSupplicantHalInterface::GetInstance().SetPowerSave(!enabled) != WIFI_HAL_OPT_OK) {
391         LOGE("Failed to set power save mode");
392         return false;
393     }
394 
395     return true;
396 }
397 #ifndef OHOS_ARCH_LITE
398 int WifiProtectManager::GetFgLowlatyProtectCount()
399 {
400     int count = 0;
401     std::vector<std::shared_ptr<WifiProtect>>::iterator iter = mWifiProtects.begin();
402     while (iter != mWifiProtects.end()) {
403         if (static_cast<AppExecFwk::ApplicationState>((*iter)->GetAppState()) ==
404             AppExecFwk::ApplicationState::APP_STATE_FOREGROUND &&
405             (*iter)->GetProtectMode() == WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY) {
406             count += 1;
407             LOGD("%{public}s bundlename %{public}s state %{public}d.",
408                 __func__, (*iter)->GetName().c_str(), (*iter)->GetAppState());
409         }
410         iter++;
411     }
412     return count;
413 }
414 
415 void WifiProtectManager::OnAppDied(const std::string bundlename)
416 {
417     LOGD("Enter %{public}s, remove app bundlename %{public}s.",
418         __func__, bundlename.c_str());
419     std::unique_lock<std::mutex> lock(mMutex);
420     bool needUpdate = false;
421     std::vector<std::shared_ptr<WifiProtect>>::iterator iter = mWifiProtects.begin();
422     while (iter != mWifiProtects.end()) {
423         if ((*iter)->GetName() == bundlename) {
424             WifiProtectMode mode = (*iter)->GetProtectMode();
425             if (mode == WifiProtectMode::WIFI_PROTECT_FULL_HIGH_PERF) {
426                 ++mFullHighPerfProtectsReleased;
427             } else if (mode == WifiProtectMode::WIFI_PROTECT_FULL_LOW_LATENCY) {
428                 ++mFullLowLatencyProtectsReleased;
429             }
430             mWifiProtects.erase(iter);
431             needUpdate = true;
432             LOGI("%{public}s, remove app bundlename %{public}s.",
433                 __func__, bundlename.c_str());
434             break;
435         }
436         iter++;
437     }
438     if (needUpdate) {
439         ChangeWifiPowerMode();
440     }
441 }
442 
443 void WifiProtectManager::OnAppForegroudChanged(const std::string &bundleName, int state)
444 {
445     std::unique_lock<std::mutex> lock(mMutex);
446     bool needUpdate = false;
447     std::vector<std::shared_ptr<WifiProtect>>::iterator iter = mWifiProtects.begin();
448     while (iter != mWifiProtects.end()) {
449         if ((*iter)->GetName() == bundleName) {
450             (*iter)->SetAppState(state);
451             needUpdate = true;
452             LOGD("%{public}s, foreground change bundleName %{public}s state %{public}d.",
453                 __func__, bundleName.c_str(), state);
454             break;
455         }
456         iter++;
457     }
458     if (needUpdate) {
459         ChangeWifiPowerMode();
460     }
461 }
462 
463 #endif
464 }  // namespace Wifi
465 }  // namespace OHOS
466