1 /*
2  * Copyright (C) 2021-2023 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 <sstream>
17 #include "network_status_history_manager.h"
18 
19 namespace OHOS {
20 namespace Wifi {
21 
22 constexpr int THRESHOLD_CHECKED_NUM = 2;
23 constexpr int SECOND_FROM_LAST = 1;
24 constexpr int THIRD_FROM_LAST = 2;
25 
Insert(uint32_t & networkStatusHistory,NetworkStatus networkStatus)26 void NetworkStatusHistoryManager::Insert(uint32_t &networkStatusHistory, NetworkStatus networkStatus)
27 {
28     networkStatusHistory =
29         (networkStatusHistory << ITEM_BIT_NUM | static_cast<int>(networkStatus)) & NETWORK_STATUS_HISTORY_MAX_MASK;
30 }
31 
Update(uint32_t & networkStatusHistory,NetworkStatus networkStatus)32 void NetworkStatusHistoryManager::Update(uint32_t &networkStatusHistory, NetworkStatus networkStatus)
33 {
34     networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
35     Insert(networkStatusHistory, networkStatus);
36 }
37 
GetLastNetworkStatus(uint32_t networkHistory)38 NetworkStatus NetworkStatusHistoryManager::GetLastNetworkStatus(uint32_t networkHistory)
39 {
40     return static_cast<NetworkStatus>(networkHistory & NETWORK_STATUS_MASK);
41 }
42 
CountNetworkStatus(uint32_t networkStatusHistory,int counts[NETWORK_STATUS_NUM])43 void NetworkStatusHistoryManager::CountNetworkStatus(uint32_t networkStatusHistory,
44                                                      int counts[NETWORK_STATUS_NUM])
45 {
46     while (networkStatusHistory != 0) {
47         NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
48         counts[static_cast<int>(networkStatus)]++;
49         networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
50     }
51 }
52 
IsInternetAccessByHistory(uint32_t networkStatusHistory)53 bool NetworkStatusHistoryManager::IsInternetAccessByHistory(uint32_t networkStatusHistory)
54 {
55     int counts[NETWORK_STATUS_NUM] = {0};
56     CountNetworkStatus(networkStatusHistory, counts);
57     int checkedNum = counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] +
58         counts[static_cast<int>(NetworkStatus::PORTAL)] +
59         counts[static_cast<int>(NetworkStatus::NO_INTERNET)];
60     if (checkedNum == 0) {
61         return false;
62     }
63     if (GetLastNetworkStatus(networkStatusHistory) == NetworkStatus::HAS_INTERNET) {
64         return true;
65     }
66     if (checkedNum == THRESHOLD_CHECKED_NUM) {
67         return GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST *  ITEM_BIT_NUM) ==
68         NetworkStatus::HAS_INTERNET;
69     }
70     return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] >= checkedNum * RECOVERY_PERCENTAGE;
71 }
72 
IsAllowRecoveryByHistory(uint32_t networkStatusHistory)73 bool NetworkStatusHistoryManager::IsAllowRecoveryByHistory(uint32_t networkStatusHistory)
74 {
75     int counts[NETWORK_STATUS_NUM] = {0};
76     CountNetworkStatus(networkStatusHistory, counts);
77     int checkedNum = counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] +
78         counts[static_cast<int>(NetworkStatus::PORTAL)] +
79         counts[static_cast<int>(NetworkStatus::NO_INTERNET)];
80     if (checkedNum < THRESHOLD_CHECKED_NUM) {
81         return false;
82     }
83     if (checkedNum == THRESHOLD_CHECKED_NUM) {
84         /* get the second from last network status by shifting right */
85         return GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) ==
86         NetworkStatus::HAS_INTERNET;
87     }
88 
89     /* get the last networkStatus and get the second from last network status by shifting right */
90     if (GetLastNetworkStatus(networkStatusHistory) != NetworkStatus::HAS_INTERNET &&
91         GetLastNetworkStatus(networkStatusHistory >>  SECOND_FROM_LAST * ITEM_BIT_NUM) != NetworkStatus::HAS_INTERNET) {
92         return false;
93     }
94 
95     /* get the second from last and third from last network status by shifting right*/
96     if (GetLastNetworkStatus(networkStatusHistory >> SECOND_FROM_LAST * ITEM_BIT_NUM) == NetworkStatus::HAS_INTERNET &&
97         GetLastNetworkStatus(networkStatusHistory >> THIRD_FROM_LAST * ITEM_BIT_NUM) == NetworkStatus::HAS_INTERNET) {
98         return true;
99     }
100     return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] >= checkedNum * RECOVERY_PERCENTAGE;
101 }
102 
IsPortalByHistory(uint32_t networkStatusHistory)103 bool NetworkStatusHistoryManager::IsPortalByHistory(uint32_t networkStatusHistory)
104 {
105     int counts[NETWORK_STATUS_NUM] = {0};
106     CountNetworkStatus(networkStatusHistory, counts);
107     return counts[static_cast<int>(NetworkStatus::PORTAL)] > 0;
108 }
109 
HasInternetEverByHistory(uint32_t networkStatusHistory)110 bool NetworkStatusHistoryManager::HasInternetEverByHistory(uint32_t networkStatusHistory)
111 {
112     int counts[NETWORK_STATUS_NUM] = {0};
113     CountNetworkStatus(networkStatusHistory, counts);
114     return counts[static_cast<int>(NetworkStatus::HAS_INTERNET)] > 0;
115 }
116 
IsEmptyNetworkStatusHistory(uint32_t networkStatusHistory)117 bool NetworkStatusHistoryManager::IsEmptyNetworkStatusHistory(uint32_t networkStatusHistory)
118 {
119     return !networkStatusHistory;
120 }
121 
ToString(uint32_t networkStatusHistory)122 std::string NetworkStatusHistoryManager::ToString(uint32_t networkStatusHistory)
123 {
124     std::stringstream networkStatusString;
125     while (networkStatusHistory != 0) {
126         NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
127         networkStatusString << static_cast<int>(networkStatus) << "/";
128         networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
129     }
130     return networkStatusString.str();
131 }
132 
GetCurrentNetworkStatusHistory2Array(uint32_t networkStatusHistory)133 std::vector<int> NetworkStatusHistoryManager::GetCurrentNetworkStatusHistory2Array(uint32_t networkStatusHistory)
134 {
135     std::vector<int> vNetworkStatusHistory;
136     while (networkStatusHistory != 0) {
137         NetworkStatus networkStatus = GetLastNetworkStatus(networkStatusHistory);
138         if (networkStatus == NetworkStatus::HAS_INTERNET) {
139             vNetworkStatusHistory.emplace_back(1);
140         } else {
141             vNetworkStatusHistory.emplace_back(0);
142         }
143         networkStatusHistory = networkStatusHistory >> ITEM_BIT_NUM;
144     }
145     return vNetworkStatusHistory;
146 }
147 }
148 }