1 /*
2  * Copyright (C) 2022-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 
16 #include "setting_utils.h"
17 
18 #include "common_event_manager.h"
19 #include "rdb_errno.h"
20 #include "telephony_errors.h"
21 #include "telephony_log_wrapper.h"
22 #include "want.h"
23 #include "datashare_errno.h"
24 
25 namespace OHOS {
26 namespace Telephony {
27 using namespace AppExecFwk;
28 
29 const std::string SettingUtils::NETWORK_SEARCH_SETTING_URI =
30     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
31 static const std::string NETWORK_SEARCH_SETTING_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
32 const std::string SettingUtils::NETWORK_SEARCH_SETTING_AUTO_TIME_URI =
33     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=auto_time";
34 const std::string SettingUtils::NETWORK_SEARCH_SETTING_AUTO_TIMEZONE_URI =
35     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=auto_timezone";
36 const std::string SettingUtils::NETWORK_SEARCH_SETTING_AIRPLANE_MODE_URI =
37     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=airplane_mode";
38 const std::string SettingUtils::NETWORK_SEARCH_SETTING_PREFERRED_NETWORK_MODE_URI =
39     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=preferred_network_mode";
40 
41 const std::string SettingUtils::SETTINGS_NETWORK_SEARCH_AUTO_TIME = "auto_time";
42 const std::string SettingUtils::SETTINGS_NETWORK_SEARCH_AUTO_TIMEZONE = "auto_timezone";
43 const std::string SettingUtils::SETTINGS_NETWORK_SEARCH_AIRPLANE_MODE = "settings.telephony.airplanemode";
44 const std::string SettingUtils::SETTINGS_NETWORK_SEARCH_PREFERRED_NETWORK_MODE =
45     "settings.telephony.preferrednetworkmode";
46 const std::string SettingUtils::COMMON_EVENT_DATA_SHARE_READY = "usual.event.DATA_SHARE_READY";
47 
48 SettingUtils::SettingUtils() = default;
49 
50 SettingUtils::~SettingUtils() = default;
51 
CreateDataShareHelper()52 std::shared_ptr<DataShare::DataShareHelper> SettingUtils::CreateDataShareHelper()
53 {
54     sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
55     if (saManager == nullptr) {
56         TELEPHONY_LOGE("SettingUtils: GetSystemAbilityManager failed.");
57         return nullptr;
58     }
59     sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(TELEPHONY_CORE_SERVICE_SYS_ABILITY_ID);
60     if (remoteObj == nullptr) {
61         TELEPHONY_LOGE("SettingUtils: GetSystemAbility Service Failed.");
62         return nullptr;
63     }
64     return DataShare::DataShareHelper::Creator(remoteObj, NETWORK_SEARCH_SETTING_URI, NETWORK_SEARCH_SETTING_EXT_URI);
65 }
66 
CreateNonBlockDataShareHelper()67 std::shared_ptr<DataShare::DataShareHelper> SettingUtils::CreateNonBlockDataShareHelper()
68 {
69     sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70     if (saManager == nullptr) {
71         TELEPHONY_LOGE("SettingUtils: GetSystemAbilityManager failed.");
72         return nullptr;
73     }
74     sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(TELEPHONY_CORE_SERVICE_SYS_ABILITY_ID);
75     if (remoteObj == nullptr) {
76         TELEPHONY_LOGE("SettingUtils: GetSystemAbility Service Failed.");
77         return nullptr;
78     }
79     if (!isDdsReady_.load()) {
80         TELEPHONY_LOGE("SettingUtils: distributedData is not started.");
81         return nullptr;
82     }
83     auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj, NETWORK_SEARCH_SETTING_URI,
84         NETWORK_SEARCH_SETTING_EXT_URI);
85     if (ret == DataShare::E_OK) {
86         return helper;
87     } else if (ret == DataShare::E_DATA_SHARE_NOT_READY) {
88         TELEPHONY_LOGE("SettingUtils: datashare not ready.");
89         return nullptr;
90     } else {
91         TELEPHONY_LOGE("SettingUtils: create datashare fail, ret = %{public}d.", ret);
92         return nullptr;
93     }
94 }
95 
UnRegisterSettingsObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)96 bool SettingUtils::UnRegisterSettingsObserver(
97     const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
98 {
99     std::lock_guard<std::mutex> lock(mtx_);
100     auto it = registerInfos_.begin();
101     for (; it != registerInfos_.end();) {
102         if (it->first == uri && it->second == dataObserver) {
103             it = registerInfos_.erase(it);
104         } else {
105             it++;
106         }
107     }
108     std::shared_ptr<DataShare::DataShareHelper> settingHelper = CreateNonBlockDataShareHelper();
109     if (settingHelper == nullptr) {
110         TELEPHONY_LOGE("settingHelper is null");
111         return false;
112     }
113     settingHelper->UnregisterObserver(uri, dataObserver);
114     settingHelper->Release();
115     TELEPHONY_LOGI("SettingUtils: UnRegisterObserver Success");
116     return true;
117 }
118 
RegisterSettingsObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)119 bool SettingUtils::RegisterSettingsObserver(
120     const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
121 {
122     std::lock_guard<std::mutex> lock(mtx_);
123     auto it = registerInfos_.begin();
124     for (; it != registerInfos_.end(); it++) {
125         if (it->first == uri && it->second == dataObserver) {
126             break;
127         }
128     }
129     if (it == registerInfos_.end()) {
130         registerInfos_.emplace_back(std::make_pair(uri, dataObserver));
131     }
132     return RegisterToDataShare(uri, dataObserver);
133 }
134 
RegisterSettingsObserver()135 void SettingUtils::RegisterSettingsObserver()
136 {
137     std::lock_guard<std::mutex> lock(mtx_);
138     for (auto it = registerInfos_.begin(); it != registerInfos_.end(); it++) {
139         if (it->second == nullptr) {
140             continue;
141         }
142         RegisterToDataShare(it->first, it->second);
143         if (it->first.ToString() == NETWORK_SEARCH_SETTING_AIRPLANE_MODE_URI) {
144             it->second->OnChange();
145         }
146     }
147 }
148 
RegisterToDataShare(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)149 bool SettingUtils::RegisterToDataShare(
150     const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
151 {
152     std::shared_ptr<DataShare::DataShareHelper> settingHelper = CreateNonBlockDataShareHelper();
153     if (settingHelper == nullptr) {
154         TELEPHONY_LOGE("settingHelper is null");
155         return false;
156     }
157     settingHelper->RegisterObserver(uri, dataObserver);
158     settingHelper->Release();
159     TELEPHONY_LOGI("SettingUtils: RegisterObserver Success");
160     return true;
161 }
162 
Query(Uri uri,const std::string & key,std::string & value)163 int32_t SettingUtils::Query(Uri uri, const std::string &key, std::string &value)
164 {
165     TELEPHONY_LOGI("SettingUtils:Query");
166     std::shared_ptr<DataShare::DataShareHelper> settingHelper = CreateNonBlockDataShareHelper();
167     if (settingHelper == nullptr) {
168         TELEPHONY_LOGE("settingHelper is null");
169         return TELEPHONY_ERR_LOCAL_PTR_NULL;
170     }
171 
172     std::vector<std::string> columns;
173     DataShare::DataSharePredicates predicates;
174     predicates.EqualTo(SETTING_KEY, key);
175     auto result = settingHelper->Query(uri, predicates, columns);
176     if (result == nullptr) {
177         TELEPHONY_LOGE("SettingUtils: query error, result is null");
178         settingHelper->Release();
179         return TELEPHONY_ERR_LOCAL_PTR_NULL;
180     }
181 
182     if (result->GoToFirstRow() != DataShare::E_OK) {
183         TELEPHONY_LOGE("SettingUtils: query error, go to first row error");
184         result->Close();
185         settingHelper->Release();
186         return TELEPHONY_ERR_DATABASE_READ_FAIL;
187     }
188 
189     int columnIndex = 0;
190     result->GetColumnIndex(SETTING_VALUE, columnIndex);
191     result->GetString(columnIndex, value);
192     result->Close();
193     settingHelper->Release();
194     TELEPHONY_LOGI("SettingUtils: query success");
195     return TELEPHONY_SUCCESS;
196 }
197 
Insert(Uri uri,const std::string & key,const std::string & value)198 int32_t SettingUtils::Insert(Uri uri, const std::string &key, const std::string &value)
199 {
200     TELEPHONY_LOGI("SettingUtils: insert start");
201     std::shared_ptr<DataShare::DataShareHelper> settingHelper = CreateNonBlockDataShareHelper();
202     if (settingHelper == nullptr) {
203         TELEPHONY_LOGE("settingHelper is null");
204         return TELEPHONY_ERR_LOCAL_PTR_NULL;
205     }
206     DataShare::DataShareValuesBucket valuesBucket;
207     DataShare::DataShareValueObject keyObj(key);
208     DataShare::DataShareValueObject valueObj(value);
209     valuesBucket.Put(SETTING_KEY, keyObj);
210     valuesBucket.Put(SETTING_VALUE, valueObj);
211     int32_t result = settingHelper->Insert(uri, valuesBucket);
212     if (result == RDB_INVALID_VALUE) {
213         settingHelper->Release();
214         return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
215     }
216     TELEPHONY_LOGI("SettingUtils: insert success");
217     settingHelper->NotifyChange(uri);
218     settingHelper->Release();
219     return TELEPHONY_SUCCESS;
220 }
221 
Update(Uri uri,const std::string & key,const std::string & value)222 int32_t SettingUtils::Update(Uri uri, const std::string &key, const std::string &value)
223 {
224     TELEPHONY_LOGI("SettingUtils:update");
225     std::string queryValue = "";
226     if (Query(uri, key, queryValue) != TELEPHONY_SUCCESS) {
227         return Insert(uri, key, value);
228     }
229     std::shared_ptr<DataShare::DataShareHelper> settingHelper = CreateNonBlockDataShareHelper();
230     if (settingHelper == nullptr) {
231         TELEPHONY_LOGE("settingHelper is null");
232         return TELEPHONY_ERR_LOCAL_PTR_NULL;
233     }
234     DataShare::DataShareValuesBucket valuesBucket;
235     DataShare::DataShareValueObject valueObj(value);
236     valuesBucket.Put(SETTING_VALUE, valueObj);
237     DataShare::DataSharePredicates predicates;
238     predicates.EqualTo(SETTING_KEY, key);
239     int32_t result = settingHelper->Update(uri, predicates, valuesBucket);
240     if (result == RDB_INVALID_VALUE) {
241         settingHelper->Release();
242         return TELEPHONY_ERR_DATABASE_WRITE_FAIL;
243     }
244     TELEPHONY_LOGI("SettingUtils: update success");
245     settingHelper->NotifyChange(uri);
246     settingHelper->Release();
247     return TELEPHONY_SUCCESS;
248 }
249 
SetCommonEventSubscribeInfo(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)250 void SettingUtils::SetCommonEventSubscribeInfo(const EventFwk::CommonEventSubscribeInfo &subscribeInfo)
251 {
252     commonEventSubscriber_ = std::make_shared<BroadcastSubscriber>(subscribeInfo);
253 }
254 
GetCommonEventSubscriber()255 std::shared_ptr<EventFwk::CommonEventSubscriber> SettingUtils::GetCommonEventSubscriber()
256 {
257     return commonEventSubscriber_;
258 }
259 
UpdateDdsState(bool isReady)260 void SettingUtils::UpdateDdsState(bool isReady)
261 {
262     if (isReady == isDdsReady_.load()) {
263         return;
264     }
265     isDdsReady_.store(isReady);
266     if (isReady) {
267         TELEPHONY_LOGI("Distributed data service start.");
268         RegisterSettingsObserver();
269     }
270 }
271 
BroadcastSubscriber(const EventFwk::CommonEventSubscribeInfo & sp)272 SettingUtils::BroadcastSubscriber::BroadcastSubscriber(const EventFwk::CommonEventSubscribeInfo &sp)
273     : EventFwk::CommonEventSubscriber(sp)
274 {}
275 
OnReceiveEvent(const EventFwk::CommonEventData & data)276 void SettingUtils::BroadcastSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
277 {
278     const AAFwk::Want &want = data.GetWant();
279     std::string action = want.GetAction();
280     if (action != COMMON_EVENT_DATA_SHARE_READY) {
281         TELEPHONY_LOGE("SettingUtils::CommonEventSubscriber event is not COMMON_EVENT_DATA_SHARE_READY");
282         return;
283     }
284     SettingUtils::GetInstance()->RegisterSettingsObserver();
285     TELEPHONY_LOGI("SettingUtils::OnReceiveEvent datashare is ready!");
286 }
287 
AutoTimeObserver(std::shared_ptr<NetworkSearchHandler> & networkSearchHandler)288 AutoTimeObserver::AutoTimeObserver(std::shared_ptr<NetworkSearchHandler> &networkSearchHandler)
289     : networkSearchHandler_(networkSearchHandler)
290 {}
291 
OnChange()292 void AutoTimeObserver::OnChange()
293 {
294     TELEPHONY_LOGI("AutoTimeObserver::OnChange");
295     if (networkSearchHandler_ != nullptr) {
296         InnerEvent::Pointer event = InnerEvent::Get(SettingEventCode::MSG_AUTO_TIME);
297         networkSearchHandler_->SendEvent(event);
298     }
299 }
300 
AutoTimezoneObserver(std::shared_ptr<NetworkSearchHandler> & networkSearchHandler)301 AutoTimezoneObserver::AutoTimezoneObserver(std::shared_ptr<NetworkSearchHandler> &networkSearchHandler)
302     : networkSearchHandler_(networkSearchHandler)
303 {}
304 
OnChange()305 void AutoTimezoneObserver::OnChange()
306 {
307     TELEPHONY_LOGI("AutoTimezoneObserver::OnChange");
308     if (networkSearchHandler_ != nullptr) {
309         InnerEvent::Pointer event = InnerEvent::Get(SettingEventCode::MSG_AUTO_TIMEZONE);
310         networkSearchHandler_->SendEvent(event);
311     }
312 }
313 
AirplaneModeObserver(std::shared_ptr<NetworkSearchHandler> & networkSearchHandler)314 AirplaneModeObserver::AirplaneModeObserver(std::shared_ptr<NetworkSearchHandler> &networkSearchHandler)
315     : networkSearchHandler_(networkSearchHandler)
316 {}
317 
OnChange()318 void AirplaneModeObserver::OnChange()
319 {
320     TELEPHONY_LOGI("AirplaneModeObserver::OnChange");
321     if (networkSearchHandler_ != nullptr) {
322         InnerEvent::Pointer event = InnerEvent::Get(SettingEventCode::MSG_AUTO_AIRPLANE_MODE);
323         networkSearchHandler_->SendEvent(event);
324     }
325 }
326 } // namespace Telephony
327 } // namespace OHOS
328