• 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 
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