• 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 
16 #ifdef FEATURE_GNSS_SUPPORT
17 #include "gnss_ability.h"
18 
19 #include <file_ex.h>
20 #include <thread>
21 
22 #include "event_runner.h"
23 #include "idevmgr_hdi.h"
24 #include "ipc_skeleton.h"
25 #include "iproxy_broker.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28 
29 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
30 #include "agnss_event_callback.h"
31 #endif
32 #include "common_hisysevent.h"
33 #include "common_utils.h"
34 #include "gnss_event_callback.h"
35 #include "i_cached_locations_callback.h"
36 #include "location_dumper.h"
37 #include "location_log.h"
38 #include "location_sa_load_manager.h"
39 #include "locationhub_ipc_interface_code.h"
40 
41 namespace OHOS {
42 namespace Location {
43 namespace {
44 constexpr int32_t GET_HDI_SERVICE_COUNT = 30;
45 constexpr uint32_t WAIT_MS = 200;
46 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
47 constexpr int AGNSS_SERVER_PORT = 7275;
48 const std::string AGNSS_SERVER_ADDR = "supl.platform.hicloud.com";
49 #endif
50 const uint32_t EVENT_REPORT_LOCATION = 0x0100;
51 const uint32_t EVENT_INTERVAL_UNITE = 1000;
52 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
53 constexpr const char *AGNSS_SERVICE_NAME = "agnss_interface_service";
54 #endif
55 constexpr const char *GNSS_SERVICE_NAME = "gnss_interface_service";
56 }
57 
58 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(
59     DelayedSingleton<GnssAbility>::GetInstance().get());
60 
GnssAbility()61 GnssAbility::GnssAbility() : SystemAbility(LOCATION_GNSS_SA_ID, true)
62 {
63     gnssStatusCallback_ = std::make_unique<std::map<pid_t, sptr<IGnssStatusCallback>>>();
64     nmeaCallback_ = std::make_unique<std::map<pid_t, sptr<INmeaMessageCallback>>>();
65     gnssInterface_ = nullptr;
66     gnssCallback_ = nullptr;
67 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
68     agnssCallback_ = nullptr;
69     agnssInterface_ = nullptr;
70 #endif
71     gnssWorkingStatus_ = GNSS_STATUS_NONE;
72     SetAbility(GNSS_ABILITY);
73     gnssHandler_ = std::make_shared<GnssHandler>(AppExecFwk::EventRunner::Create(true));
74     isHdiConnected_ = false;
75     LBSLOGI(GNSS, "ability constructed.");
76 }
77 
~GnssAbility()78 GnssAbility::~GnssAbility()
79 {
80     gnssCallback_ = nullptr;
81 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
82     agnssCallback_ = nullptr;
83 #endif
84     if (isHdiConnected_) {
85         DisableGnss();
86         RemoveHdi();
87         isHdiConnected_ = false;
88     }
89 }
90 
OnStart()91 void GnssAbility::OnStart()
92 {
93     if (state_ == ServiceRunningState::STATE_RUNNING) {
94         LBSLOGI(GNSS, "ability has already started.");
95         return;
96     }
97     if (!Init()) {
98         LBSLOGE(GNSS, "failed to init ability");
99         OnStop();
100         return;
101     }
102     state_ = ServiceRunningState::STATE_RUNNING;
103     LBSLOGI(GNSS, "OnStart start ability success.");
104 }
105 
OnStop()106 void GnssAbility::OnStop()
107 {
108     state_ = ServiceRunningState::STATE_NOT_START;
109     registerToAbility_ = false;
110     LBSLOGI(GNSS, "OnStop ability stopped.");
111 }
112 
Init()113 bool GnssAbility::Init()
114 {
115     if (!registerToAbility_) {
116         bool ret = Publish(AsObject());
117         if (!ret) {
118             LBSLOGE(GNSS, "Init Publish failed!");
119             return false;
120         }
121         registerToAbility_ = true;
122     }
123     return true;
124 }
125 
SendLocationRequest(WorkRecord & workrecord)126 LocationErrCode GnssAbility::SendLocationRequest(WorkRecord &workrecord)
127 {
128     LocationRequest(workrecord);
129     return ERRCODE_SUCCESS;
130 }
131 
SetEnable(bool state)132 LocationErrCode GnssAbility::SetEnable(bool state)
133 {
134     if (state) {
135         Enable(true, AsObject());
136         return ERRCODE_SUCCESS;
137     }
138     if (!CheckIfGnssConnecting()) {
139         Enable(false, AsObject());
140     }
141     return ERRCODE_SUCCESS;
142 }
143 
UnloadGnssSystemAbility()144 void GnssAbility::UnloadGnssSystemAbility()
145 {
146     auto locationSaLoadManager = DelayedSingleton<LocationSaLoadManager>::GetInstance();
147     if (!CheckIfGnssConnecting() && locationSaLoadManager != nullptr) {
148         locationSaLoadManager->UnloadLocationSa(LOCATION_GNSS_SA_ID);
149     }
150 }
151 
CheckIfGnssConnecting()152 bool GnssAbility::CheckIfGnssConnecting()
153 {
154     std::unique_lock<std::mutex> gnssLock(gnssMutex_);
155     std::unique_lock<std::mutex> nmeaLock(nmeaMutex_);
156     return IsMockEnabled() || !gnssStatusCallback_->empty()
157         || !nmeaCallback_->empty() || isHdiConnected_ || IsMockProcessing();
158 }
159 
RefrashRequirements()160 LocationErrCode GnssAbility::RefrashRequirements()
161 {
162     HandleRefrashRequirements();
163     return ERRCODE_SUCCESS;
164 }
165 
RegisterGnssStatusCallback(const sptr<IRemoteObject> & callback,pid_t uid)166 LocationErrCode GnssAbility::RegisterGnssStatusCallback(const sptr<IRemoteObject>& callback, pid_t uid)
167 {
168     if (callback == nullptr) {
169         LBSLOGE(GNSS, "register an invalid gnssStatus callback");
170         return ERRCODE_INVALID_PARAM;
171     }
172     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) GnssStatusCallbackDeathRecipient());
173     callback->AddDeathRecipient(death);
174     sptr<IGnssStatusCallback> gnssStatusCallback = iface_cast<IGnssStatusCallback>(callback);
175     if (gnssStatusCallback == nullptr) {
176         LBSLOGE(GNSS, "cast switch callback fail!");
177         return ERRCODE_INVALID_PARAM;
178     }
179     std::unique_lock<std::mutex> lock(gnssMutex_);
180     gnssStatusCallback_->erase(uid);
181     gnssStatusCallback_->insert(std::make_pair(uid, gnssStatusCallback));
182     LBSLOGD(GNSS, "after uid:%{public}d register, gnssStatusCallback size:%{public}s",
183         uid, std::to_string(gnssStatusCallback_->size()).c_str());
184     return ERRCODE_SUCCESS;
185 }
186 
UnregisterGnssStatusCallback(const sptr<IRemoteObject> & callback)187 LocationErrCode GnssAbility::UnregisterGnssStatusCallback(const sptr<IRemoteObject>& callback)
188 {
189     if (callback == nullptr) {
190         LBSLOGE(GNSS, "unregister an invalid gnssStatus callback");
191         return ERRCODE_INVALID_PARAM;
192     }
193     sptr<IGnssStatusCallback> gnssStatusCallback = iface_cast<IGnssStatusCallback>(callback);
194     if (gnssStatusCallback == nullptr) {
195         LBSLOGE(GNSS, "cast gnssStatus callback fail!");
196         return ERRCODE_INVALID_PARAM;
197     }
198 
199     std::unique_lock<std::mutex> lock(gnssMutex_);
200     pid_t uid = -1;
201     for (auto iter = gnssStatusCallback_->begin(); iter != gnssStatusCallback_->end(); iter++) {
202         sptr<IRemoteObject> remoteObject = (iter->second)->AsObject();
203         if (remoteObject == callback) {
204             uid = iter->first;
205             break;
206         }
207     }
208     gnssStatusCallback_->erase(uid);
209     LBSLOGD(GNSS, "after uid:%{public}d unregister, gnssStatus callback size:%{public}s",
210         uid, std::to_string(gnssStatusCallback_->size()).c_str());
211     return ERRCODE_SUCCESS;
212 }
213 
RegisterNmeaMessageCallback(const sptr<IRemoteObject> & callback,pid_t uid)214 LocationErrCode GnssAbility::RegisterNmeaMessageCallback(const sptr<IRemoteObject>& callback, pid_t uid)
215 {
216     if (callback == nullptr) {
217         LBSLOGE(GNSS, "register an invalid nmea callback");
218         return ERRCODE_INVALID_PARAM;
219     }
220     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) NmeaCallbackDeathRecipient());
221     callback->AddDeathRecipient(death);
222     sptr<INmeaMessageCallback> nmeaCallback = iface_cast<INmeaMessageCallback>(callback);
223     if (nmeaCallback == nullptr) {
224         LBSLOGE(GNSS, "cast nmea callback fail!");
225         return ERRCODE_INVALID_PARAM;
226     }
227     std::unique_lock<std::mutex> lock(nmeaMutex_);
228     nmeaCallback_->erase(uid);
229     nmeaCallback_->insert(std::make_pair(uid, nmeaCallback));
230     LBSLOGD(GNSS, "after uid:%{public}d register, nmeaCallback size:%{public}s",
231         uid, std::to_string(nmeaCallback_->size()).c_str());
232     return ERRCODE_SUCCESS;
233 }
234 
UnregisterNmeaMessageCallback(const sptr<IRemoteObject> & callback)235 LocationErrCode GnssAbility::UnregisterNmeaMessageCallback(const sptr<IRemoteObject>& callback)
236 {
237     if (callback == nullptr) {
238         LBSLOGE(GNSS, "unregister an invalid nmea callback");
239         return ERRCODE_INVALID_PARAM;
240     }
241     sptr<INmeaMessageCallback> nmeaCallback = iface_cast<INmeaMessageCallback>(callback);
242     if (nmeaCallback == nullptr) {
243         LBSLOGE(GNSS, "cast nmea callback fail!");
244         return ERRCODE_INVALID_PARAM;
245     }
246 
247     std::unique_lock<std::mutex> lock(nmeaMutex_);
248     pid_t uid = -1;
249     for (auto iter = nmeaCallback_->begin(); iter != nmeaCallback_->end(); iter++) {
250         sptr<IRemoteObject> remoteObject = (iter->second)->AsObject();
251         if (remoteObject == callback) {
252             uid = iter->first;
253             break;
254         }
255     }
256     nmeaCallback_->erase(uid);
257     LBSLOGD(GNSS, "after uid:%{public}d unregister, nmea callback size:%{public}s",
258         uid, std::to_string(nmeaCallback_->size()).c_str());
259     return ERRCODE_SUCCESS;
260 }
261 
RegisterCachedCallback(const std::unique_ptr<CachedGnssLocationsRequest> & request,const sptr<IRemoteObject> & callback)262 LocationErrCode GnssAbility::RegisterCachedCallback(const std::unique_ptr<CachedGnssLocationsRequest>& request,
263     const sptr<IRemoteObject>& callback)
264 {
265     if (callback == nullptr) {
266         LBSLOGE(GNSS, "register an invalid cached location callback");
267         return ERRCODE_INVALID_PARAM;
268     }
269     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) CachedLocationCallbackDeathRecipient());
270     callback->AddDeathRecipient(death);
271     sptr<ICachedLocationsCallback> cachedCallback = iface_cast<ICachedLocationsCallback>(callback);
272     if (cachedCallback == nullptr) {
273         LBSLOGE(GNSS, "cast cached location callback fail!");
274         return ERRCODE_INVALID_PARAM;
275     }
276     LBSLOGD(GNSS, "request:%{public}d %{public}d",
277         request->reportingPeriodSec, request->wakeUpCacheQueueFull ? 1 : 0);
278     return ERRCODE_NOT_SUPPORTED;
279 }
280 
UnregisterCachedCallback(const sptr<IRemoteObject> & callback)281 LocationErrCode GnssAbility::UnregisterCachedCallback(const sptr<IRemoteObject>& callback)
282 {
283     if (callback == nullptr) {
284         LBSLOGE(GNSS, "register an invalid cached location callback");
285         return ERRCODE_INVALID_PARAM;
286     }
287 
288     sptr<ICachedLocationsCallback> cachedCallback = iface_cast<ICachedLocationsCallback>(callback);
289     if (cachedCallback == nullptr) {
290         LBSLOGE(GNSS, "cast cached location callback fail!");
291         return ERRCODE_INVALID_PARAM;
292     }
293     return ERRCODE_NOT_SUPPORTED;
294 }
295 
RequestRecord(WorkRecord & workRecord,bool isAdded)296 void GnssAbility::RequestRecord(WorkRecord &workRecord, bool isAdded)
297 {
298     LBSLOGI(GNSS, "enter RequestRecord");
299     if (isAdded) {
300         if (!isHdiConnected_) {
301             ConnectHdi();
302             EnableGnss();
303 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
304             SetAgnssCallback();
305             SetAgnssServer();
306 #endif
307             isHdiConnected_ = true;
308         }
309         StartGnss();
310     } else {
311         if (isHdiConnected_) {
312             StopGnss();
313             if (GetRequestNum() == 0) {
314                 RemoveHdi();
315                 isHdiConnected_ = false;
316             }
317         }
318     }
319     std::string state = isAdded ? "start" : "stop";
320     WriteGnssStateEvent(state, workRecord.GetPid(0), workRecord.GetUid(0));
321 }
322 
ReConnectHdi()323 void GnssAbility::ReConnectHdi()
324 {
325     LBSLOGI(GNSS, "%{public}s called", __func__);
326     if (!isHdiConnected_) {
327         LBSLOGI(GNSS, "%{public}s: HDI should be disconnected", __func__);
328         return;
329     }
330     ConnectHdi();
331     EnableGnss();
332 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
333     SetAgnssCallback();
334     SetAgnssServer();
335 #endif
336     StartGnss();
337 }
338 
GetCachedGnssLocationsSize(int & size)339 LocationErrCode GnssAbility::GetCachedGnssLocationsSize(int& size)
340 {
341     size = -1;
342     return ERRCODE_NOT_SUPPORTED;
343 }
344 
FlushCachedGnssLocations()345 LocationErrCode GnssAbility::FlushCachedGnssLocations()
346 {
347     LBSLOGE(GNSS, "%{public}s not support", __func__);
348     return ERRCODE_NOT_SUPPORTED;
349 }
350 
SendCommand(std::unique_ptr<LocationCommand> & commands)351 LocationErrCode GnssAbility::SendCommand(std::unique_ptr<LocationCommand>& commands)
352 {
353     return ERRCODE_SUCCESS;
354 }
355 
AddFence(std::unique_ptr<GeofenceRequest> & request)356 LocationErrCode GnssAbility::AddFence(std::unique_ptr<GeofenceRequest>& request)
357 {
358     return ERRCODE_NOT_SUPPORTED;
359 }
360 
RemoveFence(std::unique_ptr<GeofenceRequest> & request)361 LocationErrCode GnssAbility::RemoveFence(std::unique_ptr<GeofenceRequest>& request)
362 {
363     return ERRCODE_NOT_SUPPORTED;
364 }
365 
ReportGnssSessionStatus(int status)366 void GnssAbility::ReportGnssSessionStatus(int status)
367 {
368 }
369 
ReportNmea(int64_t timestamp,const std::string & nmea)370 void GnssAbility::ReportNmea(int64_t timestamp, const std::string &nmea)
371 {
372     std::unique_lock<std::mutex> lock(nmeaMutex_);
373     for (auto iter = nmeaCallback_->begin(); iter != nmeaCallback_->end(); iter++) {
374         sptr<INmeaMessageCallback> nmeaCallback = (iter->second);
375         nmeaCallback->OnMessageChange(timestamp, nmea);
376     }
377 }
378 
ReportSv(const std::unique_ptr<SatelliteStatus> & sv)379 void GnssAbility::ReportSv(const std::unique_ptr<SatelliteStatus> &sv)
380 {
381     std::unique_lock<std::mutex> lock(gnssMutex_);
382     for (auto iter = gnssStatusCallback_->begin(); iter != gnssStatusCallback_->end(); iter++) {
383         sptr<IGnssStatusCallback> callback = (iter->second);
384         callback->OnStatusChange(sv);
385     }
386 }
387 
EnableGnss()388 bool GnssAbility::EnableGnss()
389 {
390     if (gnssInterface_ == nullptr || gnssCallback_ == nullptr) {
391         LBSLOGE(GNSS, "gnssInterface_ or gnssCallback_ is nullptr");
392         return false;
393     }
394     int32_t ret = gnssInterface_->EnableGnss(gnssCallback_);
395     LBSLOGI(GNSS, "Successfully enable_gnss!, %{public}d", ret);
396     gnssWorkingStatus_ = (ret == 0) ? GNSS_STATUS_ENGINE_ON : GNSS_STATUS_NONE;
397     return true;
398 }
399 
DisableGnss()400 void GnssAbility::DisableGnss()
401 {
402     if (gnssInterface_ == nullptr) {
403         LBSLOGE(GNSS, "gnssInterface_ is nullptr");
404         return;
405     }
406     if (!IsGnssEnabled()) {
407         LBSLOGE(GNSS, "gnss has been disabled");
408         return;
409     }
410     int ret = gnssInterface_->DisableGnss();
411     if (ret == 0) {
412         gnssWorkingStatus_ = GNSS_STATUS_ENGINE_OFF;
413     }
414 }
415 
IsGnssEnabled()416 bool GnssAbility::IsGnssEnabled()
417 {
418     return (gnssWorkingStatus_ != GNSS_STATUS_ENGINE_OFF &&
419         gnssWorkingStatus_ != GNSS_STATUS_NONE);
420 }
421 
StartGnss()422 void GnssAbility::StartGnss()
423 {
424     if (gnssInterface_ == nullptr) {
425         LBSLOGE(GNSS, "gnssInterface_ is nullptr");
426         return;
427     }
428     if (!IsGnssEnabled()) {
429         LBSLOGE(GNSS, "gnss has been disabled");
430         return;
431     }
432     if (gnssWorkingStatus_ == GNSS_STATUS_SESSION_BEGIN) {
433         LBSLOGD(GNSS, "GNSS navigation started");
434         return;
435     }
436     if (GetRequestNum() == 0) {
437         return;
438     }
439     int ret = gnssInterface_->StartGnss(GNSS_START_TYPE_NORMAL);
440     if (ret == 0) {
441         gnssWorkingStatus_ = GNSS_STATUS_SESSION_BEGIN;
442     }
443 }
444 
StopGnss()445 void GnssAbility::StopGnss()
446 {
447     if (gnssInterface_ == nullptr) {
448         LBSLOGE(GNSS, "gnssInterface_ is nullptr");
449         return;
450     }
451     if (!IsGnssEnabled()) {
452         LBSLOGE(GNSS, "gnss has been disabled");
453         return;
454     }
455     if (GetRequestNum() != 0) {
456         return;
457     }
458     int ret = gnssInterface_->StopGnss(GNSS_START_TYPE_NORMAL);
459     if (ret == 0) {
460         gnssWorkingStatus_ = GNSS_STATUS_SESSION_END;
461     }
462 }
463 
ConnectHdi()464 bool GnssAbility::ConnectHdi()
465 {
466     auto devmgr = HDI::DeviceManager::V1_0::IDeviceManager::Get();
467     if (devmgr == nullptr) {
468         LBSLOGE(GNSS, "fail to get devmgr.");
469         return false;
470     }
471     if (devmgr->LoadDevice(GNSS_SERVICE_NAME) != 0) {
472         LBSLOGE(GNSS, "Load gnss service failed!");
473         return false;
474     }
475 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
476     if (devmgr->LoadDevice(AGNSS_SERVICE_NAME) != 0) {
477         LBSLOGE(GNSS, "Load agnss service failed!");
478         return false;
479     }
480 #endif
481     int32_t retry = 0;
482     while (retry < GET_HDI_SERVICE_COUNT) {
483         std::unique_lock<std::mutex> lock(hdiMutex_, std::defer_lock);
484         lock.lock();
485         gnssInterface_ = IGnssInterface::Get();
486 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
487         agnssInterface_ = IAGnssInterface::Get();
488 #endif
489         if (gnssInterface_ != nullptr && agnssInterface_ != nullptr) {
490             LBSLOGI(GNSS, "connect v1_0 hdi success.");
491             gnssCallback_ = new (std::nothrow) GnssEventCallback();
492 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
493             agnssCallback_ = new (std::nothrow) AGnssEventCallback();
494 #endif
495             RegisterLocationHdiDeathRecipient();
496             lock.unlock();
497             return true;
498         }
499         lock.unlock();
500         retry++;
501         LBSLOGE(GNSS, "connect hdi service failed, retry : %{public}d", retry);
502         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
503     }
504     LBSLOGE(GNSS, "connect v1_0 hdi failed.");
505     return false;
506 }
507 
RemoveHdi()508 bool GnssAbility::RemoveHdi()
509 {
510     auto devmgr = HDI::DeviceManager::V1_0::IDeviceManager::Get();
511     if (devmgr == nullptr) {
512         LBSLOGE(GNSS, "fail to get devmgr.");
513         return false;
514     }
515     if (devmgr->UnloadDevice(GNSS_SERVICE_NAME) != 0) {
516         LBSLOGE(GNSS, "Load gnss service failed!");
517         return false;
518     }
519 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
520     if (devmgr->UnloadDevice(AGNSS_SERVICE_NAME) != 0) {
521         LBSLOGE(GNSS, "Load agnss service failed!");
522         return false;
523     }
524 #endif
525     return true;
526 }
527 
528 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
SetAgnssServer()529 void GnssAbility::SetAgnssServer()
530 {
531     if (agnssInterface_ == nullptr) {
532         LBSLOGE(GNSS, "agnssInterface_ is nullptr");
533         return;
534     }
535     if (!IsGnssEnabled()) {
536         LBSLOGE(GNSS, "gnss has been disabled");
537         return;
538     }
539     AGnssServerInfo info;
540     info.type = AGNSS_TYPE_SUPL;
541     info.server = AGNSS_SERVER_ADDR;
542     info.port = AGNSS_SERVER_PORT;
543     agnssInterface_->SetAgnssServer(info);
544 }
545 
SetAgnssCallback()546 void GnssAbility::SetAgnssCallback()
547 {
548     LBSLOGI(GNSS, "enter SetAgnssCallback");
549     if (agnssInterface_ == nullptr || agnssCallback_ == nullptr) {
550         LBSLOGE(GNSS, "agnssInterface_ or agnssCallback_ is nullptr");
551         return;
552     }
553     if (!IsGnssEnabled()) {
554         LBSLOGE(GNSS, "gnss has been disabled");
555         return;
556     }
557     agnssInterface_->SetAgnssCallback(agnssCallback_);
558 }
559 
SetSetId(const SubscriberSetId & id)560 void GnssAbility::SetSetId(const SubscriberSetId& id)
561 {
562     if (agnssInterface_ == nullptr) {
563         LBSLOGE(GNSS, "agnssInterface_ is nullptr");
564         return;
565     }
566     if (!IsGnssEnabled()) {
567         LBSLOGE(GNSS, "gnss has been disabled");
568         return;
569     }
570     agnssInterface_->SetSubscriberSetId(id);
571 }
572 
SetRefInfo(const AGnssRefInfo & refInfo)573 void GnssAbility::SetRefInfo(const AGnssRefInfo& refInfo)
574 {
575     if (agnssInterface_ == nullptr) {
576         LBSLOGE(GNSS, "agnssInterface_ is nullptr");
577         return;
578     }
579     if (!IsGnssEnabled()) {
580         LBSLOGE(GNSS, "gnss has been disabled");
581         return;
582     }
583     agnssInterface_->SetAgnssRefInfo(refInfo);
584 }
585 #endif
586 
SaDumpInfo(std::string & result)587 void GnssAbility::SaDumpInfo(std::string& result)
588 {
589     result += "Gnss Location enable status: true";
590     result += "\n";
591 }
592 
Dump(int32_t fd,const std::vector<std::u16string> & args)593 int32_t GnssAbility::Dump(int32_t fd, const std::vector<std::u16string>& args)
594 {
595     std::vector<std::string> vecArgs;
596     std::transform(args.begin(), args.end(), std::back_inserter(vecArgs), [](const std::u16string &arg) {
597         return Str16ToStr8(arg);
598     });
599 
600     LocationDumper dumper;
601     std::string result;
602     dumper.GnssDump(SaDumpInfo, vecArgs, result);
603     if (!SaveStringToFd(fd, result)) {
604         LBSLOGE(GNSS, "Gnss save string to fd failed!");
605         return ERR_OK;
606     }
607     return ERR_OK;
608 }
609 
EnableMock()610 LocationErrCode GnssAbility::EnableMock()
611 {
612     if (!EnableLocationMock()) {
613         return ERRCODE_NOT_SUPPORTED;
614     }
615     return ERRCODE_SUCCESS;
616 }
617 
DisableMock()618 LocationErrCode GnssAbility::DisableMock()
619 {
620     if (!DisableLocationMock()) {
621         return ERRCODE_NOT_SUPPORTED;
622     }
623     return ERRCODE_SUCCESS;
624 }
625 
SetMocked(const int timeInterval,const std::vector<std::shared_ptr<Location>> & location)626 LocationErrCode GnssAbility::SetMocked(const int timeInterval,
627     const std::vector<std::shared_ptr<Location>> &location)
628 {
629     if (!SetMockedLocations(timeInterval, location)) {
630         return ERRCODE_NOT_SUPPORTED;
631     }
632     return ERRCODE_SUCCESS;
633 }
634 
IsMockEnabled()635 bool GnssAbility::IsMockEnabled()
636 {
637     return IsLocationMocked();
638 }
639 
IsMockProcessing()640 bool GnssAbility::IsMockProcessing()
641 {
642     auto loc = GetLocationMock();
643     return !loc.empty();
644 }
645 
ProcessReportLocationMock()646 void GnssAbility::ProcessReportLocationMock()
647 {
648     std::vector<std::shared_ptr<Location>> mockLocationArray = GetLocationMock();
649     if (mockLocationIndex_ < mockLocationArray.size()) {
650         ReportMockedLocation(mockLocationArray[mockLocationIndex_++]);
651         if (gnssHandler_ != nullptr) {
652             gnssHandler_->SendHighPriorityEvent(EVENT_REPORT_LOCATION,
653                 0, GetTimeIntervalMock() * EVENT_INTERVAL_UNITE);
654         }
655     } else {
656         ClearLocationMock();
657         mockLocationIndex_ = 0;
658     }
659 }
660 
SendReportMockLocationEvent()661 void GnssAbility::SendReportMockLocationEvent()
662 {
663     if (gnssHandler_ != nullptr) {
664         gnssHandler_->SendHighPriorityEvent(EVENT_REPORT_LOCATION, 0, 0);
665     }
666 }
667 
ReportMockedLocation(const std::shared_ptr<Location> location)668 int32_t GnssAbility::ReportMockedLocation(const std::shared_ptr<Location> location)
669 {
670     if ((IsLocationMocked() && !location->GetIsFromMock()) ||
671         (!IsLocationMocked() && location->GetIsFromMock())) {
672         LBSLOGE(GNSS, "location mock is enabled, do not report gnss location!");
673         return ERR_OK;
674     }
675     ReportLocationInfo(GNSS_ABILITY, location);
676 #ifdef FEATURE_PASSIVE_SUPPORT
677     ReportLocationInfo(PASSIVE_ABILITY, location);
678 #endif
679     return ERR_OK;
680 }
681 
SendMessage(uint32_t code,MessageParcel & data,MessageParcel & reply)682 void GnssAbility::SendMessage(uint32_t code, MessageParcel &data, MessageParcel &reply)
683 {
684     if (gnssHandler_ == nullptr) {
685         reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
686         return;
687     }
688     switch (code) {
689         case static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST): {
690             std::unique_ptr<WorkRecord> workrecord = WorkRecord::Unmarshalling(data);
691             AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::
692                 Get(code, workrecord);
693             if (gnssHandler_->SendEvent(event)) {
694                 reply.WriteInt32(ERRCODE_SUCCESS);
695             } else {
696                 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
697             }
698             break;
699         }
700         case static_cast<uint32_t>(GnssInterfaceCode::SET_MOCKED_LOCATIONS): {
701             if (!IsMockEnabled()) {
702                 reply.WriteInt32(ERRCODE_NOT_SUPPORTED);
703                 break;
704             }
705             int timeInterval = data.ReadInt32();
706             int locationSize = data.ReadInt32();
707             timeInterval = timeInterval < 0 ? 1 : timeInterval;
708             locationSize = locationSize > INPUT_ARRAY_LEN_MAX ? INPUT_ARRAY_LEN_MAX :
709                 locationSize;
710             std::shared_ptr<std::vector<std::shared_ptr<Location>>> vcLoc =
711                 std::make_shared<std::vector<std::shared_ptr<Location>>>();
712             for (int i = 0; i < locationSize; i++) {
713                 vcLoc->push_back(Location::UnmarshallingShared(data));
714             }
715             AppExecFwk::InnerEvent::Pointer event =
716                 AppExecFwk::InnerEvent::Get(code, vcLoc, timeInterval);
717             if (gnssHandler_->SendEvent(event)) {
718                 reply.WriteInt32(ERRCODE_SUCCESS);
719             } else {
720                 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
721             }
722             break;
723         }
724         default:
725             break;
726     }
727 }
728 
RegisterLocationHdiDeathRecipient()729 void GnssAbility::RegisterLocationHdiDeathRecipient()
730 {
731     if (gnssInterface_ == nullptr) {
732         LBSLOGE(GNSS, "%{public}s: gnssInterface_ is nullptr", __func__);
733         return;
734     }
735     sptr<IRemoteObject> obj = OHOS::HDI::hdi_objcast<IGnssInterface>(gnssInterface_);
736     if (obj == nullptr) {
737         LBSLOGE(GNSS, "%{public}s: hdi obj is nullptr", __func__);
738         return;
739     }
740     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) LocationHdiDeathRecipient());
741     obj->AddDeathRecipient(death);
742 }
743 
GnssHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)744 GnssHandler::GnssHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner) : EventHandler(runner) {}
745 
~GnssHandler()746 GnssHandler::~GnssHandler() {}
747 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)748 void GnssHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event)
749 {
750     auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
751     if (gnssAbility == nullptr) {
752         LBSLOGE(GNSS, "ProcessEvent: gnss ability is nullptr");
753         return;
754     }
755     uint32_t eventId = event->GetInnerEventId();
756     LBSLOGI(GNSS, "ProcessEvent event:%{public}d", eventId);
757     switch (eventId) {
758         case EVENT_REPORT_LOCATION: {
759             gnssAbility->ProcessReportLocationMock();
760             break;
761         }
762         case static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST): {
763             std::unique_ptr<WorkRecord> workrecord = event->GetUniqueObject<WorkRecord>();
764             if (workrecord != nullptr) {
765                 gnssAbility->LocationRequest(*workrecord);
766             }
767             break;
768         }
769         case static_cast<uint32_t>(GnssInterfaceCode::SET_MOCKED_LOCATIONS): {
770             int timeInterval = event->GetParam();
771             auto vcLoc = event->GetSharedObject<std::vector<std::shared_ptr<Location>>>();
772             if (vcLoc != nullptr) {
773                 std::vector<std::shared_ptr<Location>> mockLocations;
774                 for (auto it = vcLoc->begin(); it != vcLoc->end(); ++it) {
775                     mockLocations.push_back(*it);
776                 }
777                 gnssAbility->SetMocked(timeInterval, mockLocations);
778             }
779             break;
780         }
781         default:
782             break;
783     }
784     gnssAbility->UnloadGnssSystemAbility();
785 }
786 
LocationHdiDeathRecipient()787 LocationHdiDeathRecipient::LocationHdiDeathRecipient()
788 {
789 }
790 
~LocationHdiDeathRecipient()791 LocationHdiDeathRecipient::~LocationHdiDeathRecipient()
792 {
793 }
794 
OnRemoteDied(const wptr<IRemoteObject> & remote)795 void LocationHdiDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
796 {
797     auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
798     if (gnssAbility != nullptr) {
799         LBSLOGI(LOCATOR, "hdi reconnecting");
800         // wait for device unloaded
801         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
802         gnssAbility->ReConnectHdi();
803         LBSLOGI(LOCATOR, "hdi connected finish");
804     }
805 }
806 } // namespace Location
807 } // namespace OHOS
808 #endif
809