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