1 /*
2  * Copyright (c) 2024 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 "network_set_manager.h"
16 
17 #include "accesstoken_kit.h"
18 #include "cloud_file_kit.h"
19 #include "datashare_errno.h"
20 #include "datashare_result_set.h"
21 #include "dfs_error.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "parameters.h"
25 #include "system_ability_definition.h"
26 #include "utils_log.h"
27 
28 namespace OHOS::FileManagement::CloudSync {
29 const std::string QUERY_URI = "datashareproxy://";
30 const std::string PHOTO_NET_CONT = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
31 const std::string SWITCH_STATUS_KEY = "useMobileNetworkData";
32 const std::string CLOUDDRIVE_KEY = "persist.kernel.bundle_name.clouddrive";
33 const std::string PHOTOS_BUNDLE_NAME = "com.ohos.photos";
34 const std::string BUNDLE_NAME_KEY = "key";
35 const std::string BUNDLE_NAME_VALUE = "value";
36 auto clouddriveBundleName = system::GetParameter(CLOUDDRIVE_KEY, "");
37 auto photoQueryUri = PHOTO_NET_CONT + "&key=photo_network_connection_status";
38 auto queryUri = QUERY_URI + clouddriveBundleName + "/cloud_sp?key=" + SWITCH_STATUS_KEY;
39 DataShare::CreateOptions options;
40 
QueryCellularConnect(int32_t userId,const std::string & bundleName)41 int32_t NetworkSetManager::QueryCellularConnect(int32_t userId, const std::string &bundleName)
42 {
43     LOGI("QueryCellularConnect bundleName: %{public}s", bundleName.c_str());
44     DataShare::DataSharePredicates predicates;
45     predicates.EqualTo(BUNDLE_NAME_KEY, SWITCH_STATUS_KEY);
46     std::shared_ptr<DataShare::DataShareResultSet> resultSet;
47     std::vector<std::string> columns;
48     DataShare::CreateOptions options;
49     options.enabled_ = true;
50     auto clouddriveBundleName = system::GetParameter(CLOUDDRIVE_KEY, "");
51     auto queryUri = QUERY_URI + clouddriveBundleName + "/cloud_sp?user=" + std::to_string(userId);
52     Uri uri(queryUri);
53     auto dataShareHelper = DataShare::DataShareHelper::Creator(QUERY_URI, options);
54     if (dataShareHelper == nullptr) {
55         LOGE("dataShareHelper = nullptr");
56         return E_RDB;
57     }
58     resultSet = dataShareHelper->Query(uri, predicates, columns);
59     ReleaseDataShareHelper(dataShareHelper);
60     if (resultSet == nullptr) {
61         return E_RDB;
62     }
63     if (resultSet->GoToFirstRow() != E_OK) {
64         return E_RDB;
65     }
66     int32_t columnIndex = 0;
67     if (resultSet->GetColumnIndex(BUNDLE_NAME_VALUE, columnIndex) != E_OK) {
68         return E_RDB;
69     }
70     int64_t status = -1;
71     if (resultSet->GetLong(columnIndex, status) != E_OK) {
72         return E_RDB;
73     }
74     std::string queryKey = std::to_string(userId) + "/" + bundleName;
75     if (status == 1) {
76         cellularNetMap_.EnsureInsert(queryKey, true);
77         LOGI("QueryCellularConnect on");
78     } else {
79         cellularNetMap_.EnsureInsert(queryKey, false);
80         LOGI("QueryCellularConnect off");
81     }
82     return E_OK;
83 }
84 
QueryNetConnect(int32_t userId,const std::string & bundleName)85 int32_t NetworkSetManager::QueryNetConnect(int32_t userId, const std::string &bundleName)
86 {
87     LOGI("QueryNetConnect bundleName: %{public}s", bundleName.c_str());
88     DataShare::DataSharePredicates predicates;
89     predicates.EqualTo("KEYWORD", "photo_network_connection_status");
90     std::vector<std::string> columns = {"VALUE"};
91     std::shared_ptr<DataShare::DataShareResultSet> resultSet;
92     DataShare::CreateOptions options;
93     options.enabled_ = true;
94     auto queryUri = PHOTO_NET_CONT + "&key=photo_network_connection_status";
95     auto dataShareHelper = DataShare::DataShareHelper::Creator(QUERY_URI, options);
96     Uri uri(queryUri);
97     if (dataShareHelper == nullptr) {
98         LOGE("dataShareHelper = nullptr");
99         return E_RDB;
100     }
101     resultSet = dataShareHelper->Query(uri, predicates, columns);
102     ReleaseDataShareHelper(dataShareHelper);
103     if (resultSet == nullptr) {
104         return E_RDB;
105     }
106     if (resultSet->GoToFirstRow() != E_OK) {
107         return E_RDB;
108     }
109     int32_t columnIndex = 0;
110     if (resultSet->GetColumnIndex(BUNDLE_NAME_VALUE, columnIndex) != E_OK) {
111         return E_RDB;
112     }
113     std::string val;
114     if (resultSet->GetString(columnIndex, val) != E_OK) {
115         return E_RDB;
116     }
117     std::string queryKey = std::to_string(userId) + "/" + bundleName;
118     if (val == "on") {
119         netMap_.EnsureInsert(queryKey, true);
120         LOGI("QueryNetConnect on");
121     } else {
122         netMap_.EnsureInsert(queryKey, false);
123         LOGI("QueryNetConnect off");
124     }
125     return E_OK;
126 }
127 
GetCellularConnect(const std::string & bundleName,const int32_t userId)128 void NetworkSetManager::GetCellularConnect(const std::string &bundleName, const int32_t userId)
129 {
130     bool preCheckSwitch = false;
131     bool getConnect = cellularNetMap_.Find(std::to_string(userId) + "/" + bundleName, preCheckSwitch);
132     if (QueryCellularConnect(userId, bundleName) != E_OK) {
133         cellularNetMap_.EnsureInsert(std::to_string(userId) + "/" +
134                                      bundleName, GetConfigParams(bundleName, userId));
135     }
136 
137     bool endCheckSwitch = false;
138     getConnect = cellularNetMap_.Find(std::to_string(userId) + "/" + bundleName, endCheckSwitch);
139     if (preCheckSwitch && !endCheckSwitch && dataSyncManager_ != nullptr) {
140         dataSyncManager_->StopUploadTask(bundleName, userId);
141     }
142 }
143 
144 
GetNetConnect(const std::string & bundleName,const int32_t userId)145 void NetworkSetManager::GetNetConnect(const std::string &bundleName, const int32_t userId)
146 {
147     if (QueryNetConnect(userId, bundleName) != E_OK) {
148         netMap_.EnsureInsert(std::to_string(userId) + "/" + bundleName, true);
149     }
150 }
151 
GetConfigParams(const std::string & bundleName,int32_t userId)152 bool NetworkSetManager::GetConfigParams(const std::string &bundleName, int32_t userId)
153 {
154     auto driveKit = CloudFile::CloudFileKit::GetInstance();
155     std::map<std::string, std::string> param;
156     auto err = driveKit->GetAppConfigParams(userId, bundleName, param);
157     if (err != E_OK || param.empty()) {
158         LOGE("GetAppConfigParams failed");
159         return false;
160     }
161     int32_t networkData = std::stoi(param["useMobileNetworkData"]);
162     if (networkData == 0) {
163         return false;
164     }
165     return true;
166 }
167 
UnregisterObserver(const std::string & bundleName,const int32_t userId,const int32_t type)168 void NetworkSetManager::UnregisterObserver(const std::string &bundleName, const int32_t userId, const int32_t type)
169 {
170     LOGI("UnregisterObserver start");
171     options.enabled_ = true;
172     auto dataShareHelper = DataShare::DataShareHelper::Creator(QUERY_URI, options);
173     if (dataShareHelper == nullptr) {
174         LOGE("dataShareHelper = nullptr");
175         return;
176     }
177     sptr<MobileNetworkObserver> dataObserver(new (std::nothrow) MobileNetworkObserver(bundleName,
178     userId, type));
179     if (type == CELLULARCONNECT) {
180         Uri observerUri(queryUri);
181         dataShareHelper->UnregisterObserver(observerUri, dataObserver);
182     } else {
183         Uri observerUri(photoQueryUri);
184         dataShareHelper->UnregisterObserver(observerUri, dataObserver);
185     }
186     ReleaseDataShareHelper(dataShareHelper);
187     LOGI("UnregisterObserver type:%{public}d, finish", type);
188 }
189 
RegisterObserver(const std::string & bundleName,const int32_t userId,const int32_t type)190 void NetworkSetManager::RegisterObserver(const std::string &bundleName, const int32_t userId, const int32_t type)
191 {
192     options.enabled_ = true;
193     auto dataShareHelper = DataShare::DataShareHelper::Creator(QUERY_URI, options);
194     if (dataShareHelper == nullptr) {
195         LOGE("dataShareHelper = nullptr");
196         return;
197     }
198     sptr<MobileNetworkObserver> dataObserver(new (std::nothrow) MobileNetworkObserver(bundleName, userId, type));
199     if (type == CELLULARCONNECT) {
200         Uri observerUri(queryUri);
201         dataShareHelper->RegisterObserver(observerUri, dataObserver);
202     } else {
203         Uri observerUri(photoQueryUri);
204         dataShareHelper->RegisterObserver(observerUri, dataObserver);
205     }
206     ReleaseDataShareHelper(dataShareHelper);
207     LOGI("RegisterObserver type:%{public}d, finish", type);
208 }
209 
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)210 void NetworkSetManager::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
211 {
212     if (helper == nullptr) {
213         LOGI("helper is nullptr");
214         return;
215     }
216     if (!helper->Release()) {
217         LOGI("Release data share helper failed");
218         return;
219     }
220     LOGI("Release data share helper finish");
221 }
222 
OnChange()223 void MobileNetworkObserver::OnChange()
224 {
225     LOGI("MobileNetworkObserver OnChange network status");
226     if (observerCallback_ != nullptr) {
227         observerCallback_();
228     }
229     if (type_ == NetworkSetManager::CELLULARCONNECT) {
230         NetworkSetManager::GetCellularConnect(bundleName_, userId_);
231     } else {
232         NetworkSetManager::GetNetConnect(bundleName_, userId_);
233     }
234 }
235 
IsAllowCellularConnect(const std::string & bundleName,const int32_t userId)236 bool NetworkSetManager::IsAllowCellularConnect(const std::string &bundleName, const int32_t userId)
237 {
238     LOGI("IsAllowCellularConnect bundleName: %{public}s", bundleName.c_str());
239     bool checkSwitch = false;
240     bool getCellularConnect = cellularNetMap_.Find(std::to_string(userId) + "/" + bundleName, checkSwitch);
241     if (getCellularConnect == false) {
242         GetCellularConnect(bundleName, userId);
243         return cellularNetMap_.ReadVal(std::to_string(userId) + "/" + bundleName);
244     }
245     return checkSwitch;
246 }
247 
IsAllowNetConnect(const std::string & bundleName,const int32_t userId)248 bool NetworkSetManager::IsAllowNetConnect(const std::string &bundleName, const int32_t userId)
249 {
250     LOGI("IsAllowNetConnect bundleName: %{public}s", bundleName.c_str());
251     bool checkSwitch = true;
252     bool getNetConnect = netMap_.Find(std::to_string(userId) + "/" + bundleName, checkSwitch);
253     if (getNetConnect == false) {
254         GetNetConnect(bundleName, userId);
255         return netMap_.ReadVal(std::to_string(userId) + "/" + bundleName);
256     }
257     return checkSwitch;
258 }
259 
InitNetworkSetManager(const std::string & bundleName,const int32_t userId)260 void NetworkSetManager::InitNetworkSetManager(const std::string &bundleName, const int32_t userId)
261 {
262     LOGI("InitNetworkSetManager bundleName: %{public}s", bundleName.c_str());
263     if (bundleName != PHOTOS_BUNDLE_NAME) {
264         LOGE("InitNetworkSetManager bundleName is illegals");
265         return;
266     }
267     RegisterObserver(bundleName, userId, CELLULARCONNECT);
268     RegisterObserver(bundleName, userId, NETCONNECT);
269     GetCellularConnect(bundleName, userId);
270     GetNetConnect(bundleName, userId);
271 }
272 
InitDataSyncManager(std::shared_ptr<CloudFile::DataSyncManager> dataSyncManager)273 void NetworkSetManager::InitDataSyncManager(std::shared_ptr<CloudFile::DataSyncManager> dataSyncManager)
274 {
275     dataSyncManager_ = dataSyncManager;
276 }
277 
NetWorkChangeStopUploadTask()278 void NetworkSetManager::NetWorkChangeStopUploadTask()
279 {
280     std::map<const std::string, bool> cellularNetMap;
281     auto it = [&](std::string bundleName, bool swichStatus) {
282         cellularNetMap.insert(std::make_pair(bundleName, swichStatus));
283     };
284     cellularNetMap_.Iterate(it);
285 
286     for (auto pair = cellularNetMap.begin(); pair != cellularNetMap.end(); ++pair) {
287         const std::string &key = pair->first;
288         if (key.empty()) {
289             continue;
290         }
291         LOGI("bundleName: %{public}s", key.c_str());
292         size_t pos = key.find("com.ohos.photos");
293         if (pos == std::string::npos) {
294             continue;
295         }
296         auto swichStatus = pair->second;
297         if (swichStatus) {
298             continue;
299         }
300 
301         pos = key.find("/");
302         if (pos == std::string::npos) {
303             continue;
304         }
305         int32_t userId = std::stoi(key.substr(0, pos));
306         std::string bundleName = key.substr(pos + 1);
307         LOGI("bundleName: %{public}s, userId:%{public}d", key.c_str(), userId);
308         if (dataSyncManager_ != nullptr) {
309             dataSyncManager_->StopUploadTask(bundleName, userId);
310         }
311     }
312 }
313 }