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