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