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