1 /*
2 * Copyright (c) 2025 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 #include <cinttypes>
16 #include "networkshare_trafficlimit.h"
17 #include "netmgr_ext_log_wrapper.h"
18 #include "net_datashare_utils.h"
19 #include "networkshare_utils.h"
20 #include "net_manager_constants.h"
21 #include "net_stats_constants.h"
22 #include "netsys_controller.h"
23 #include "ffrt_inner.h"
24 #include "net_stats_client.h"
25 #include "networkshare_tracker.h"
26 #include "cellular_data_client.h"
27 #include "networkshare_sub_statemachine.h"
28 #include "core_service_client.h"
29
30 namespace OHOS {
31 namespace NetManagerStandard {
32
33 static constexpr const char *SHARE_SETTING_URI =
34 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_100?Proxy=true&key=";
35 const std::string SHARE_LIMIT = "wifiap_one_usage_limit";
36 const std::string WIFI_AP_STATS = "wifiap_one_usage_stats";
37 const std::string SHARING_LIMIT_TASK_NAME = "networkshare_traffic_limit";
38 constexpr int64_t SECOND_IN_MILLIS = 1000;
39 constexpr int32_t NUMBER_THREE = 3;
40 constexpr int32_t UTIL_MIN_SUB_ID = 0;
41 constexpr int32_t UTIL_SLOT_0 = 0;
42
43
NetworkShareTrafficLimit()44 NetworkShareTrafficLimit::NetworkShareTrafficLimit()
45 {
46 InitEventHandler();
47 }
48
GetInstance()49 NetworkShareTrafficLimit &NetworkShareTrafficLimit::GetInstance()
50 {
51 static NetworkShareTrafficLimit instance;
52 return instance;
53 }
54
InitTetherStatsInfo()55 void NetworkShareTrafficLimit::InitTetherStatsInfo()
56 {
57 tetherTrafficInfos.mMaxSpeed = GetMaxNetworkSpeed();
58 tetherTrafficInfos.mStartSize = 0;
59 tetherTrafficInfos.mLastStatsMills = GetCurrentMilliseconds();
60 tetherTrafficInfos.mLastStatsSize = 0;
61 tetherTrafficInfos.mRemainSize = tetherTrafficInfos.mLimitSize;
62 tetherTrafficInfos.mNetSpeed = 0;
63 tetherTrafficInfos.SharingTrafficValue = 0;
64 lastSharingStatsSize = 0;
65 tmpMills = tetherTrafficInfos.mLastStatsMills;
66 WriteSharingTrafficToDB(WIFI_AP_STATS_DEFAULT_VALUE);
67 }
68
GetMaxNetworkSpeed()69 int64_t NetworkShareTrafficLimit::GetMaxNetworkSpeed()
70 {
71 int32_t slotId = GetDefaultSlotId();
72 int32_t radioTech = static_cast<int32_t>(Telephony::RadioTech::RADIO_TECHNOLOGY_INVALID);
73 Telephony::CoreServiceClient::GetInstance().GetPsRadioTech(slotId, radioTech);
74 NETMGR_EXT_LOG_D("RadioTech=[%{public}d]", static_cast<int32_t>(radioTech));
75 return GetNetSpeedForRadioTech(radioTech);
76 }
77
GetDefaultSlotId()78 int32_t NetworkShareTrafficLimit::GetDefaultSlotId()
79 {
80 int32_t slotId = DelayedRefSingleton<Telephony::CellularDataClient>::GetInstance().GetDefaultCellularDataSlotId();
81 return IsValidSlotId(slotId) ? slotId : UTIL_SLOT_0;
82 }
83
IsValidSlotId(int32_t slotId)84 bool NetworkShareTrafficLimit::IsValidSlotId(int32_t slotId)
85 {
86 return (slotId >= UTIL_MIN_SUB_ID);
87 }
88
GetNetSpeedForRadioTech(int32_t radioTech)89 int64_t NetworkShareTrafficLimit::GetNetSpeedForRadioTech(int32_t radioTech)
90 {
91 switch (static_cast<Telephony::RadioTech>(radioTech)) {
92 case Telephony::RadioTech::RADIO_TECHNOLOGY_WCDMA:
93 case Telephony::RadioTech::RADIO_TECHNOLOGY_HSPAP:
94 case Telephony::RadioTech::RADIO_TECHNOLOGY_HSPA:
95 return static_cast<int64_t>(NetworkSpeed::NETWORK_SPEED_3G);
96 case Telephony::RadioTech::RADIO_TECHNOLOGY_LTE:
97 case Telephony::RadioTech::RADIO_TECHNOLOGY_LTE_CA:
98 return static_cast<int64_t>(NetworkSpeed::NETWORK_SPEED_4G);
99 default:
100 return static_cast<int64_t>(NetworkSpeed::NETWORK_SPEED_2G);
101 }
102 }
103
StartHandleSharingLimitEvent()104 void NetworkShareTrafficLimit::StartHandleSharingLimitEvent()
105 {
106 NETMGR_EXT_LOG_I("StartHandleSharingLimitEvent");
107 std::shared_ptr<SharingTrafficDataObserver> observer = std::make_shared<SharingTrafficDataObserver>();
108 observer->ReadTetherTrafficSetting();
109 observer->RegisterTetherDataSettingObserver();
110 InitTetherStatsInfo();
111 eventHandler_->HandleRemoveTask(SHARING_LIMIT_TASK_NAME);
112 sendMsgDelayed(SHARING_LIMIT_TASK_NAME, STATS_INTERVAL_DEFAULT);
113 }
114
EndHandleSharingLimitEvent()115 void NetworkShareTrafficLimit::EndHandleSharingLimitEvent()
116 {
117 NETMGR_EXT_LOG_I("EndHandleSharingLimitEvent");
118 std::shared_ptr<SharingTrafficDataObserver> observer = std::make_shared<SharingTrafficDataObserver>();
119 observer->UnregisterTetherDataSettingObserver();
120 eventHandler_->HandleRemoveTask(SHARING_LIMIT_TASK_NAME);
121 }
122
SharingTrafficDataObserver()123 SharingTrafficDataObserver::SharingTrafficDataObserver()
124 {
125 mTetherSingleValueObserver_ = std::make_unique<TetherSingleValueObserver>().release();
126 }
127
RegisterTetherDataSettingObserver()128 void SharingTrafficDataObserver::RegisterTetherDataSettingObserver()
129 {
130 NETMGR_EXT_LOG_E("RegisterTetherDataSettingObserver start.");
131 auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
132 Uri uriTether(SHARE_SETTING_URI + SHARE_LIMIT);
133 if (dataShareHelperUtils->RegisterSettingsObserver(uriTether, mTetherSingleValueObserver_) != NETSYS_SUCCESS) {
134 NETMGR_EXT_LOG_E("register mTetherSingleValueObserver_ failed.");
135 }
136 }
137
UnregisterTetherDataSettingObserver()138 void SharingTrafficDataObserver::UnregisterTetherDataSettingObserver()
139 {
140 NETMGR_EXT_LOG_E("UnregisterTetherDataSettingObserver start.");
141 auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
142 Uri uriTether(SHARE_SETTING_URI + SHARE_LIMIT);
143 if (dataShareHelperUtils->UnRegisterSettingsObserver(uriTether, mTetherSingleValueObserver_) != NETSYS_SUCCESS) {
144 NETMGR_EXT_LOG_E("unregister mTetherSingleValueObserver_ failed.");
145 }
146 }
147
ReadTetherTrafficSetting()148 void SharingTrafficDataObserver::ReadTetherTrafficSetting()
149 {
150 NETMGR_EXT_LOG_E("ReadTetherTrafficSetting start.");
151 auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
152 Uri mLimitUri(SHARE_SETTING_URI + SHARE_LIMIT);
153 std::string value = "";
154 int32_t ret = dataShareHelperUtils->Query(mLimitUri, SHARE_LIMIT, value);
155 if (ret != NETMANAGER_SUCCESS) {
156 NETMGR_EXT_LOG_E("Query error.");
157 }
158 int64_t tetherInt = -1;
159 int64_t tetherTmp = -1;
160 if (!value.empty() && NetworkShareUtils::ConvertToInt64(value, tetherTmp)) {
161 tetherInt = tetherTmp;
162 }
163 NETMGR_EXT_LOG_D("tether limit value=%{public}" PRId64, tetherInt);
164 NetworkShareTrafficLimit::GetInstance().UpdataSharingSettingdata(tetherInt);
165 }
166
OnChange()167 void TetherSingleValueObserver::OnChange()
168 {
169 Uri uriTether(SHARE_SETTING_URI + SHARE_LIMIT);
170 std::string value = "";
171 auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
172 int32_t ret = dataShareHelperUtils->Query(uriTether, SHARE_LIMIT, value);
173 if (ret != NETMANAGER_SUCCESS) {
174 NETMGR_EXT_LOG_E("Query error.");
175 }
176 int64_t tetherInt = -1;
177 int64_t tetherTmp = -1;
178 if (!value.empty() && NetworkShareUtils::ConvertToInt64(value, tetherTmp)) {
179 tetherInt = tetherTmp;
180 }
181 NETMGR_EXT_LOG_E("TetherSingleValueObserver OnChanged. dataString: %{public}s, TrafficInt: %{public}" PRId64,
182 value.c_str(), tetherInt);
183 NetworkShareTrafficLimit::GetInstance().UpdataSharingSettingdata(tetherInt);
184 int32_t sharingStatus;
185 NetworkShareTracker::GetInstance().IsSharing(sharingStatus);
186 if (sharingStatus == NETWORKSHARE_IS_SHARING) {
187 NetworkShareTrafficLimit::GetInstance().CheckSharingStatsData();
188 }
189 }
190
UpdataSharingSettingdata(int64_t & tetherInt)191 void NetworkShareTrafficLimit::UpdataSharingSettingdata(int64_t &tetherInt)
192 {
193 SetTetherLimit(tetherInt);
194 }
195
SetTetherLimit(int64_t & tetherInt)196 void NetworkShareTrafficLimit::SetTetherLimit(int64_t &tetherInt)
197 {
198 if (tetherInt < 0) {
199 tetherTrafficInfos.mLimitSize = NO_LIMIT;
200 return;
201 }
202 tetherTrafficInfos.mLimitSize = tetherInt * MB_IN_BYTES;
203 }
204
CheckSharingStatsData()205 void NetworkShareTrafficLimit::CheckSharingStatsData()
206 {
207 UpdataSharingTrafficStats();
208 if (tetherTrafficInfos.mLimitSize < 0 && eventHandler_ != nullptr) {
209 eventHandler_->HandleRemoveTask(SHARING_LIMIT_TASK_NAME);
210 sendMsgDelayed(SHARING_LIMIT_TASK_NAME, STATS_INTERVAL_MAXIMUM);
211 return;
212 }
213
214 if (tetherTrafficInfos.mRemainSize < tetherTrafficInfos.mNetSpeed * DEFAULT_INTERVAL_MINIMUM) {
215 NETMGR_EXT_LOG_I("sharing taffic limit, shut down AP");
216 int32_t ret = NetworkShareTracker::GetInstance().StopNetworkSharing(SharingIfaceType::SHARING_WIFI);
217 if (ret != NETWORKSHARE_ERROR_WIFI_SHARING) {
218 NETMGR_EXT_LOG_I("DisableHotspot wifiSharing successful.");
219 }
220 return;
221 }
222
223 if (eventHandler_ != nullptr) {
224 int64_t updateDelay = STATS_INTERVAL_MAXIMUM;
225 if (IsCellularDataConnection()) {
226 updateDelay = GetNextUpdataDelay();
227 }
228 eventHandler_->HandleRemoveTask(SHARING_LIMIT_TASK_NAME);
229 sendMsgDelayed(SHARING_LIMIT_TASK_NAME, updateDelay);
230 NETMGR_EXT_LOG_I("keep update when mIsDataConnAvailable, UpdateDelay=%{public}" PRId64, updateDelay);
231 }
232 }
233
sendMsgDelayed(const std::string & name,int64_t delayTime)234 void NetworkShareTrafficLimit::sendMsgDelayed(const std::string &name, int64_t delayTime)
235 {
236 std::function<void()> delayed = ([this]() {
237 NetworkShareTrafficLimit::CheckSharingStatsData();
238 NETMGR_EXT_LOG_D("sendMsgDelayed enter");
239 });
240 eventHandler_->HandlePostTask(delayed, name, delayTime);
241 }
242
IsCellularDataConnection()243 bool NetworkShareTrafficLimit::IsCellularDataConnection()
244 {
245 int32_t dataState = Telephony::CellularDataClient::GetInstance().GetCellularDataState();
246 return dataState == static_cast<int32_t>(Telephony::DataConnectionStatus::DATA_STATE_CONNECTED);
247 }
248
GetNextUpdataDelay()249 int64_t NetworkShareTrafficLimit::GetNextUpdataDelay()
250 {
251 int64_t maxDelay = STATS_INTERVAL_MAXIMUM;
252 if (tetherTrafficInfos.mMaxSpeed > 0) {
253 maxDelay = tetherTrafficInfos.mRemainSize * SECOND_IN_MILLIS / tetherTrafficInfos.mMaxSpeed;
254 maxDelay = NetworkShareUtils::Constrain(maxDelay, STATS_INTERVAL_MINIMUM, STATS_INTERVAL_MAXIMUM);
255 }
256 int64_t delay;
257 if (tetherTrafficInfos.mNetSpeed == 0) {
258 delay = maxDelay;
259 } else {
260 delay = tetherTrafficInfos.mRemainSize / tetherTrafficInfos.mNetSpeed / NUMBER_THREE;
261 delay = NetworkShareUtils::Constrain(delay, STATS_INTERVAL_MINIMUM, maxDelay);
262 }
263 return delay;
264 }
265
UpdataSharingTrafficStats()266 void NetworkShareTrafficLimit::UpdataSharingTrafficStats()
267 {
268 nmd::NetworkSharingTraffic traffic;
269 std::string ifaceName;
270 int32_t ret = NetsysController::GetInstance().GetNetworkCellularSharingTraffic(traffic, ifaceName);
271 int64_t tetherStats = static_cast<int64_t>(traffic.receive + traffic.send);
272 if (ret != NETMANAGER_SUCCESS) {
273 NETMGR_EXT_LOG_E("GetTrafficBytes err, ret[%{public}d].", ret);
274 return;
275 }
276
277 int64_t statsMills = GetCurrentMilliseconds();
278 if (tetherStats < tetherTrafficInfos.mStartSize) {
279 NETMGR_EXT_LOG_E("updata tether traffic error");
280 return;
281 }
282
283 int64_t statsSize = tetherStats - tetherTrafficInfos.mStartSize;
284 int64_t elapsedSize = statsSize + tetherTrafficInfos.SharingTrafficValue - tetherTrafficInfos.mLastStatsSize;
285 int64_t elapsedMills = statsMills - tetherTrafficInfos.mLastStatsMills;
286 if (elapsedMills == 0) {
287 return;
288 }
289 tetherTrafficInfos.mNetSpeed = static_cast<int64_t>(elapsedSize / elapsedMills);
290 tetherTrafficInfos.mLastStatsMills = statsMills;
291 tetherTrafficInfos.mLastStatsSize = statsSize + tetherTrafficInfos.SharingTrafficValue;
292 if (tetherTrafficInfos.mLimitSize >= 0 && tetherTrafficInfos.mLimitSize >= tetherTrafficInfos.mLastStatsSize) {
293 tetherTrafficInfos.mRemainSize = tetherTrafficInfos.mLimitSize - tetherTrafficInfos.mLastStatsSize;
294 } else {
295 tetherTrafficInfos.mRemainSize = -1;
296 }
297 int64_t sharingStatsSize = statsSize + tetherTrafficInfos.SharingTrafficValue;
298 if (IsCellularDataConnection() && (lastSharingStatsSize < sharingStatsSize)) {
299 if (elapsedMills >= WRITE_DB_INTERVAL_MINIMUM
300 || (statsMills - tmpMills) >= WRITE_DB_INTERVAL_MINIMUM) {
301 tmpMills = statsMills;
302 WriteSharingTrafficToDB(sharingStatsSize);
303 lastSharingStatsSize = sharingStatsSize;
304 }
305 }
306 }
307
WriteSharingTrafficToDB(const int64_t & traffic)308 void NetworkShareTrafficLimit::WriteSharingTrafficToDB(const int64_t &traffic)
309 {
310 std::lock_guard<ffrt::mutex> lock(lock_);
311 NETMGR_EXT_LOG_I("enter WriteSharingTrafficToDB");
312 auto dataShareHelperUtils = std::make_unique<NetDataShareHelperUtils>();
313 Uri mLimitUri(SHARE_SETTING_URI + WIFI_AP_STATS);
314 std::string value = std::to_string(traffic);
315 int32_t ret = dataShareHelperUtils->Update(mLimitUri, WIFI_AP_STATS, value);
316 if (ret != NETMANAGER_SUCCESS) {
317 NETMGR_EXT_LOG_E("WriteSharingTrafficToDB err, ret[%{public}d].", ret);
318 return;
319 }
320 }
321
SaveSharingTrafficToSettingsDB(nmd::NetworkSharingTraffic & traffic)322 void NetworkShareTrafficLimit::SaveSharingTrafficToSettingsDB(nmd::NetworkSharingTraffic &traffic)
323 {
324 NETMGR_EXT_LOG_I("enter SaveSharingTrafficToSettingsDB .");
325 int64_t tetherStats = static_cast<int64_t>(traffic.receive + traffic.send) + tetherTrafficInfos.SharingTrafficValue;
326 WriteSharingTrafficToDB(tetherStats);
327 }
328
AddSharingTrafficBeforeConnChanged(nmd::NetworkSharingTraffic & traffic)329 void NetworkShareTrafficLimit::AddSharingTrafficBeforeConnChanged(nmd::NetworkSharingTraffic &traffic)
330 {
331 NETMGR_EXT_LOG_E("AddSharingTrafficBeforeConnChanged enter");
332 tetherTrafficInfos.SharingTrafficValue += traffic.receive;
333 tetherTrafficInfos.SharingTrafficValue += traffic.send;
334 }
335
InitEventHandler()336 void NetworkShareTrafficLimit::InitEventHandler()
337 {
338 auto eventRunner = AppExecFwk::EventRunner::Create(true, AppExecFwk::ThreadMode::FFRT);
339 if (eventRunner == nullptr) {
340 NETMGR_EXT_LOG_E("Failed to create a recvRunner");
341 return;
342 }
343 eventHandler_ = std::make_shared<TrafficEventHandler>(eventRunner);
344 }
345
TrafficEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)346 TrafficEventHandler::TrafficEventHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
347 : EventHandler(runner)
348 {}
349
350 TrafficEventHandler::~TrafficEventHandler() = default;
351
HandlePostTask(const Callback & callback,int64_t delayTime)352 bool TrafficEventHandler::HandlePostTask(const Callback &callback, int64_t delayTime)
353 {
354 return AppExecFwk::EventHandler::PostTask(callback, delayTime);
355 }
356
HandlePostTask(const Callback & callback,const std::string & name,int64_t delayTime)357 bool TrafficEventHandler::HandlePostTask(const Callback &callback, const std::string &name, int64_t delayTime)
358 {
359 return AppExecFwk::EventHandler::PostTask(callback, name, delayTime);
360 }
361
HandleRemoveTask(const std::string & name)362 void TrafficEventHandler::HandleRemoveTask(const std::string &name)
363 {
364 AppExecFwk::EventHandler::RemoveTask(name);
365 }
366
SaveSharingTrafficToCachedData(nmd::NetworkSharingTraffic & traffic)367 void NetworkShareTrafficLimit::SaveSharingTrafficToCachedData(nmd::NetworkSharingTraffic &traffic)
368 {
369 NETMGR_EXT_LOG_I("SaveSharingTrafficToCachedData enter");
370 std::string ifaceName;
371 int32_t ret0 = NetsysController::GetInstance().GetNetworkCellularSharingTraffic(traffic, ifaceName);
372 if (ret0 != NETMANAGER_SUCCESS) {
373 NETMGR_EXT_LOG_E("GetTrafficBytes err, ret[%{public}d].", ret0);
374 return;
375 }
376 ffrt::submit([traffic, ifaceName, this]() {SendSharingTrafficToCachedData(traffic, ifaceName);}, {}, {},
377 ffrt::task_attr().name(("SendSharingTrafficToCachedData")));
378 }
379
SendSharingTrafficToCachedData(const nmd::NetworkSharingTraffic & traffic,const std::string & upIface)380 void NetworkShareTrafficLimit::SendSharingTrafficToCachedData(const nmd::NetworkSharingTraffic &traffic,
381 const std::string &upIface)
382 {
383 NETMGR_EXT_LOG_I("NetworkShareSubStateMachine SendSharingTrafficToCachedData enter");
384 NetStatsInfo infos;
385 infos.txBytes_ = static_cast<uint64_t>(traffic.send);
386 infos.rxBytes_ = static_cast<uint64_t>(traffic.receive);
387 infos.iface_ = upIface;
388 auto ret = DelayedSingleton<NetStatsClient>::GetInstance()->SaveSharingTraffic(infos);
389 if (ret != 0) {
390 NETMGR_EXT_LOG_E("SaveSharingTraffic ERROR");
391 }
392 }
393 } // namespace NetManagerStandard
394 } // namespace OHOS
395