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