• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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