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