1 /*
2 * Copyright (C) 2022 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 "country_code_manager.h"
16
17 #include "cellular_data_client.h"
18 #include "core_service_client.h"
19 #include "locale_config.h"
20 #include "parameter.h"
21
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "common_utils.h"
25 #include "constant_definition.h"
26 #include "country_code.h"
27 #include "location_log.h"
28 #include "locator_ability.h"
29 #include "request.h"
30 #include "request_manager.h"
31
32 namespace OHOS {
33 namespace Location {
CountryCodeManager()34 CountryCodeManager::CountryCodeManager()
35 {
36 lastCountryByLocation_ = std::make_shared<CountryCode>();
37 lastCountry_ = std::make_shared<CountryCode>();
38 countryCodeCallback_ = std::make_unique<std::map<pid_t, sptr<ICountryCodeCallback>>>();
39 simSubscriber_ = nullptr;
40 networkSubscriber_ = nullptr;
41 StartPassiveLocationListen();
42 SubscribeLocaleConfigEvent();
43 }
44
~CountryCodeManager()45 CountryCodeManager::~CountryCodeManager()
46 {
47 }
48
NotifyAllListener()49 void CountryCodeManager::NotifyAllListener()
50 {
51 std::lock_guard lock(countryCodeCallbackMutex_);
52 if (lastCountry_ == nullptr || countryCodeCallback_ == nullptr) {
53 LBSLOGE(COUNTRY_CODE, "NotifyAllListener cancel, para is invalid");
54 return;
55 }
56 auto country = std::make_shared<CountryCode>(*lastCountry_);
57 for (auto iter = countryCodeCallback_->begin(); iter != countryCodeCallback_->end(); iter++) {
58 sptr<ICountryCodeCallback> callback = (iter->second);
59 if (callback) {
60 callback->OnCountryCodeChange(country);
61 }
62 }
63 }
64
RegisterCountryCodeCallback(const sptr<IRemoteObject> & callback,pid_t uid)65 void CountryCodeManager::RegisterCountryCodeCallback(const sptr<IRemoteObject>& callback, pid_t uid)
66 {
67 std::unique_lock<std::mutex> lock(countryCodeCallbackMutex_, std::defer_lock);
68 lock.lock();
69 if (callback == nullptr || countryCodeCallback_ == nullptr) {
70 LBSLOGE(COUNTRY_CODE, "callback is invalid");
71 lock.unlock();
72 return;
73 }
74
75 sptr<ICountryCodeCallback> countryCodeCallback = iface_cast<ICountryCodeCallback>(callback);
76 if (countryCodeCallback == nullptr) {
77 LBSLOGE(COUNTRY_CODE, "iface_cast ICountryCodeCallback failed!");
78 lock.unlock();
79 return;
80 }
81 countryCodeCallback_->erase(uid);
82 countryCodeCallback_->insert(std::make_pair(uid, countryCodeCallback));
83 LBSLOGD(COUNTRY_CODE, "after uid:%{public}d register, countryCodeCallback_ size:%{public}s",
84 uid, std::to_string(countryCodeCallback_->size()).c_str());
85 if (countryCodeCallback_->size() != 1) {
86 lock.unlock();
87 return;
88 }
89 lock.unlock();
90 SubscribeSimEvent();
91 SubscribeNetworkStatusEvent();
92 }
93
UnregisterCountryCodeCallback(const sptr<IRemoteObject> & callback)94 void CountryCodeManager::UnregisterCountryCodeCallback(const sptr<IRemoteObject>& callback)
95 {
96 std::unique_lock<std::mutex> lock(countryCodeCallbackMutex_, std::defer_lock);
97 lock.lock();
98 if (callback == nullptr || countryCodeCallback_ == nullptr) {
99 LBSLOGE(COUNTRY_CODE, "unregister an invalid callback");
100 lock.unlock();
101 return;
102 }
103 sptr<ICountryCodeCallback> countryCodeCallback = iface_cast<ICountryCodeCallback>(callback);
104 if (countryCodeCallback == nullptr) {
105 LBSLOGE(COUNTRY_CODE, "iface_cast ICountryCodeCallback failed!");
106 lock.unlock();
107 return;
108 }
109
110 pid_t uid = -1;
111 for (auto iter = countryCodeCallback_->begin(); iter != countryCodeCallback_->end(); iter++) {
112 sptr<IRemoteObject> remoteObject = (iter->second)->AsObject();
113 if (remoteObject == callback) {
114 uid = iter->first;
115 break;
116 }
117 }
118 countryCodeCallback_->erase(uid);
119 LBSLOGD(COUNTRY_CODE, "after uid:%{public}d unregister, countryCodeCallback_ size:%{public}s",
120 uid, std::to_string(countryCodeCallback_->size()).c_str());
121 if (countryCodeCallback_->size() != 0) {
122 lock.unlock();
123 return;
124 }
125 lock.unlock();
126 UnsubscribeSimEvent();
127 UnsubscribeNetworkStatusEvent();
128 }
129
GetCountryCodeByLastLocation()130 std::string CountryCodeManager::GetCountryCodeByLastLocation()
131 {
132 std::string code = "";
133 if (lastCountryByLocation_ == nullptr) {
134 LBSLOGE(COUNTRY_CODE, "lastCountryByLocation_ is nullptr");
135 return code;
136 }
137 if (lastCountryByLocation_->GetCountryCodeStr().empty()) {
138 std::shared_ptr<ReportManager> reportManager = DelayedSingleton<ReportManager>::GetInstance();
139 if (reportManager) {
140 auto lastLocation = reportManager->GetLastLocation();
141 if (lastLocation == nullptr) {
142 return code;
143 }
144 auto location = std::make_unique<Location>(*lastLocation);
145 code = GetCountryCodeByLocation(location);
146 lastCountryByLocation_->SetCountryCodeStr(code);
147 }
148 }
149 return lastCountryByLocation_->GetCountryCodeStr();
150 }
151
UpdateCountryCode(std::string countryCode,int type)152 void CountryCodeManager::UpdateCountryCode(std::string countryCode, int type)
153 {
154 if (lastCountry_ == nullptr) {
155 LBSLOGE(COUNTRY_CODE, "lastCountry_ is nullptr");
156 return;
157 }
158 if (lastCountry_->IsMoreReliable(type)) {
159 LBSLOGI(COUNTRY_CODE, "lastCountry_ is more reliable,there is no need to update the data");
160 return;
161 }
162 lastCountry_->SetCountryCodeStr(countryCode);
163 lastCountry_->SetCountryCodeType(type);
164 }
165
UpdateCountryCodeByLocation(std::string countryCode,int type)166 bool CountryCodeManager::UpdateCountryCodeByLocation(std::string countryCode, int type)
167 {
168 if (lastCountryByLocation_ == nullptr) {
169 LBSLOGE(COUNTRY_CODE, "lastCountryByLocation_ is nullptr");
170 return false;
171 }
172 if (lastCountryByLocation_->GetCountryCodeStr() == countryCode) {
173 LBSLOGE(COUNTRY_CODE, "countryCode is same");
174 return false;
175 }
176
177 lastCountryByLocation_->SetCountryCodeStr(countryCode);
178 lastCountryByLocation_->SetCountryCodeType(type);
179 return true;
180 }
181
GetCountryCodeByLocation(const std::unique_ptr<Location> & location)182 std::string CountryCodeManager::GetCountryCodeByLocation(const std::unique_ptr<Location>& location)
183 {
184 if (location == nullptr) {
185 LBSLOGE(COUNTRY_CODE, "GetCountryCodeByLocation location is nullptr");
186 return "";
187 }
188 return "";
189 }
190
StartPassiveLocationListen()191 void CountryCodeManager::StartPassiveLocationListen()
192 {
193 auto requestManager = DelayedSingleton<RequestManager>::GetInstance();
194 auto locatorAbility = DelayedSingleton<LocatorAbility>::GetInstance();
195 if (requestManager == nullptr || locatorAbility == nullptr) {
196 LBSLOGE(LOCATOR_CALLBACK,
197 "StartPassiveLocationListen: RequestManager is nullptr or LocatorAbility is nullptr.");
198 return;
199 }
200 auto requestConfig = std::make_unique<RequestConfig>();
201 requestConfig->SetScenario(SCENE_NO_POWER);
202 requestConfig->SetTimeInterval(DEFAULT_TIME_INTERVAL);
203
204 sptr<ILocatorCallback> callback =
205 sptr<ILocatorCallback>(new (std::nothrow) CountryCodeManager::LocatorCallback());
206 if (callback == nullptr) {
207 LBSLOGE(COUNTRY_CODE, "callback is nullptr");
208 return;
209 }
210
211 auto request = std::make_shared<Request>();
212 request->SetUid(SYSTEM_UID);
213 request->SetPid(getpid());
214 request->SetPackageName(PROC_NAME);
215 request->SetRequestConfig(*requestConfig);
216 request->SetLocatorCallBack(callback);
217 LBSLOGE(COUNTRY_CODE, "StartPassiveLocationListen");
218 requestManager.get()->HandleStartLocating(request);
219 locatorAbility.get()->ReportLocationStatus(callback, SESSION_START);
220 }
221
GetIsoCountryCode()222 std::shared_ptr<CountryCode> CountryCodeManager::GetIsoCountryCode()
223 {
224 LBSLOGI(COUNTRY_CODE, "CountryCodeManager::GetIsoCountryCode");
225 int type = COUNTRY_CODE_FROM_LOCALE;
226 int slotId = Telephony::CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
227 std::u16string countryCodeForNetwork;
228 DelayedRefSingleton<Telephony::CoreServiceClient>::GetInstance().GetIsoCountryCodeForNetwork(
229 slotId, countryCodeForNetwork);
230 std::string countryCodeStr8 = Str16ToStr8(countryCodeForNetwork);
231 type = COUNTRY_CODE_FROM_NETWORK;
232
233 if (countryCodeStr8.empty()) {
234 countryCodeStr8 = GetCountryCodeByLastLocation();
235 type = COUNTRY_CODE_FROM_LOCATION;
236 }
237
238 if (countryCodeStr8.empty()) {
239 std::u16string countryCodeForSim;
240 DelayedRefSingleton<Telephony::CoreServiceClient>::GetInstance().GetISOCountryCodeForSim(
241 slotId, countryCodeForSim);
242 countryCodeStr8 = Str16ToStr8(countryCodeForSim);
243 type = COUNTRY_CODE_FROM_SIM;
244 }
245
246 if (countryCodeStr8.empty()) {
247 countryCodeStr8 = Global::I18n::LocaleConfig::GetSystemRegion();
248 type = COUNTRY_CODE_FROM_LOCALE;
249 }
250
251 CountryCode country;
252 country.SetCountryCodeStr(countryCodeStr8);
253 country.SetCountryCodeType(type);
254 if (lastCountry_ && !country.IsSame(*lastCountry_) && !lastCountry_->IsMoreReliable(type)) {
255 UpdateCountryCode(countryCodeStr8, type);
256 NotifyAllListener();
257 }
258 return lastCountry_;
259 }
260
SubscribeSimEvent()261 bool CountryCodeManager::SubscribeSimEvent()
262 {
263 LBSLOGD(COUNTRY_CODE, "SubscribeSimEvent");
264 OHOS::EventFwk::MatchingSkills matchingSkills;
265 matchingSkills.AddEvent(SIM_STATE_CHANGE_ACTION);
266 OHOS::EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
267 std::unique_lock<std::mutex> lock(simSubscriberMutex_, std::defer_lock);
268 lock.lock();
269 if (simSubscriber_ == nullptr) {
270 simSubscriber_ = std::make_shared<SimSubscriber>(subscriberInfo);
271 }
272 lock.unlock();
273 bool result = OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(simSubscriber_);
274 if (!result) {
275 LBSLOGE(COUNTRY_CODE, "SubscribeSimEvent failed.");
276 }
277 return result;
278 }
279
SubscribeNetworkStatusEvent()280 bool CountryCodeManager::SubscribeNetworkStatusEvent()
281 {
282 LBSLOGD(COUNTRY_CODE, "SubscribeNetworkStatusEvent");
283 OHOS::EventFwk::MatchingSkills matchingSkills;
284 matchingSkills.AddEvent(SEARCH_NET_WORK_STATE_CHANGE_ACTION);
285 OHOS::EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
286 std::unique_lock<std::mutex> lock(networkSubscriberMutex_, std::defer_lock);
287 lock.lock();
288 if (networkSubscriber_ == nullptr) {
289 networkSubscriber_ = std::make_shared<NetworkSubscriber>(subscriberInfo);
290 }
291 lock.unlock();
292 bool result = OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(networkSubscriber_);
293 if (!result) {
294 LBSLOGE(COUNTRY_CODE, "SubscribeNetworkStatusEvent failed.");
295 }
296 return result;
297 }
298
SubscribeLocaleConfigEvent()299 bool CountryCodeManager::SubscribeLocaleConfigEvent()
300 {
301 auto eventCallback = [](const char *key, const char *value, void *context) {
302 LBSLOGD(COUNTRY_CODE, "LOCALE_KEY changed");
303 auto manager = DelayedSingleton<CountryCodeManager>::GetInstance();
304 if (manager == nullptr) {
305 LBSLOGE(COUNTRY_CODE, "SubscribeLocaleConfigEvent CountryCodeManager is nullptr");
306 return;
307 }
308 manager->GetIsoCountryCode();
309 };
310
311 int ret = WatchParameter(LOCALE_KEY.c_str(), eventCallback, nullptr);
312 if (ret != SUCCESS) {
313 LBSLOGD(COUNTRY_CODE, "WatchParameter fail");
314 return false;
315 }
316 return true;
317 }
318
UnsubscribeSimEvent()319 bool CountryCodeManager::UnsubscribeSimEvent()
320 {
321 LBSLOGD(COUNTRY_CODE, "UnsubscribeSimEvent");
322 if (simSubscriber_) {
323 return OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(simSubscriber_);
324 }
325 return false;
326 }
327
UnsubscribeNetworkStatusEvent()328 bool CountryCodeManager::UnsubscribeNetworkStatusEvent()
329 {
330 LBSLOGD(COUNTRY_CODE, "UnsubscribeNetworkStatusEvent");
331 if (networkSubscriber_) {
332 OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(networkSubscriber_);
333 }
334 return false;
335 }
336
OnLocationReport(const std::unique_ptr<Location> & location)337 void CountryCodeManager::LocatorCallback::OnLocationReport(const std::unique_ptr<Location>& location)
338 {
339 auto manager = DelayedSingleton<CountryCodeManager>::GetInstance();
340 if (manager == nullptr) {
341 LBSLOGE(COUNTRY_CODE, "OnLocationReport CountryCodeManager is nullptr");
342 return;
343 }
344 if (location == nullptr) {
345 LBSLOGE(COUNTRY_CODE, "OnLocationReport location is nullptr");
346 return;
347 }
348 std::string code = manager->GetCountryCodeByLocation(location);
349 CountryCode country;
350 country.SetCountryCodeStr(code);
351 country.SetCountryCodeType(COUNTRY_CODE_FROM_LOCATION);
352 LBSLOGI(COUNTRY_CODE, "OnLocationReport");
353 if (manager->UpdateCountryCodeByLocation(code, COUNTRY_CODE_FROM_LOCATION)) {
354 LBSLOGI(COUNTRY_CODE, "OnLocationReport,countryCode is change");
355 manager->GetIsoCountryCode();
356 }
357 }
358
OnLocatingStatusChange(const int status)359 void CountryCodeManager::LocatorCallback::OnLocatingStatusChange(const int status)
360 {
361 }
362
OnErrorReport(const int errorCode)363 void CountryCodeManager::LocatorCallback::OnErrorReport(const int errorCode)
364 {
365 }
366
NetworkSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo & info)367 CountryCodeManager::NetworkSubscriber::NetworkSubscriber(
368 const OHOS::EventFwk::CommonEventSubscribeInfo &info)
369 : CommonEventSubscriber(info)
370 {
371 LBSLOGD(COUNTRY_CODE, "create NetworkSubscriber");
372 }
373
OnReceiveEvent(const OHOS::EventFwk::CommonEventData & event)374 void CountryCodeManager::NetworkSubscriber::OnReceiveEvent(const OHOS::EventFwk::CommonEventData& event)
375 {
376 auto manager = DelayedSingleton<CountryCodeManager>::GetInstance();
377 if (manager == nullptr) {
378 LBSLOGE(COUNTRY_CODE, "CountryCodeManager is nullptr");
379 return;
380 }
381 LBSLOGI(COUNTRY_CODE, "NetworkSubscriber::OnReceiveEvent");
382 manager->GetIsoCountryCode();
383 }
384
SimSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo & info)385 CountryCodeManager::SimSubscriber::SimSubscriber(
386 const OHOS::EventFwk::CommonEventSubscribeInfo &info)
387 : CommonEventSubscriber(info)
388 {
389 LBSLOGD(COUNTRY_CODE, "create SimSubscriber");
390 }
391
OnReceiveEvent(const OHOS::EventFwk::CommonEventData & event)392 void CountryCodeManager::SimSubscriber::OnReceiveEvent(const OHOS::EventFwk::CommonEventData& event)
393 {
394 auto manager = DelayedSingleton<CountryCodeManager>::GetInstance();
395 if (manager == nullptr) {
396 LBSLOGE(COUNTRY_CODE, "CountryCodeManager is nullptr");
397 return;
398 }
399 LBSLOGI(COUNTRY_CODE, "SimSubscriber::OnReceiveEvent");
400 manager->GetIsoCountryCode();
401 }
402
ReSubscribeEvent()403 void CountryCodeManager::ReSubscribeEvent()
404 {
405 std::unique_lock<std::mutex> lock(countryCodeCallbackMutex_, std::defer_lock);
406 lock.lock();
407 if (countryCodeCallback_->size() <= 0) {
408 LBSLOGE(COUNTRY_CODE, "no valid callback registed, no need to subscribe");
409 lock.unlock();
410 return;
411 }
412 lock.unlock();
413 SubscribeSimEvent();
414 SubscribeNetworkStatusEvent();
415 }
416
ReUnsubscribeEvent()417 void CountryCodeManager::ReUnsubscribeEvent()
418 {
419 std::unique_lock<std::mutex> lock(countryCodeCallbackMutex_, std::defer_lock);
420 lock.lock();
421 if (countryCodeCallback_->size() <= 0) {
422 LBSLOGE(COUNTRY_CODE, "no valid callback registed, no need to unsubscribe");
423 lock.unlock();
424 return;
425 }
426 lock.unlock();
427 UnsubscribeSimEvent();
428 UnsubscribeNetworkStatusEvent();
429 }
430 } // namespace Location
431 } // namespace OHOS
432