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