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_NETWORK_SUPPORT
17 #include "network_ability.h"
18 #include <file_ex.h>
19 #include <thread>
20 #include "ability_connect_callback_stub.h"
21 #include "ability_manager_client.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "want_agent_helper.h"
26
27 #include "common_utils.h"
28 #include "location_config_manager.h"
29 #include "location_dumper.h"
30 #include "location_log.h"
31 #include "location_sa_load_manager.h"
32 #include "network_callback_host.h"
33 #include "locationhub_ipc_interface_code.h"
34 #include "location_log_event_ids.h"
35 #include "common_hisysevent.h"
36 #include "location_data_rdb_manager.h"
37 #include "hook_utils.h"
38 #include "permission_manager.h"
39
40 #ifdef LOCATION_HICOLLIE_ENABLE
41 #include "xcollie/xcollie.h"
42 #include "xcollie/xcollie_define.h"
43 #endif
44
45 namespace OHOS {
46 namespace Location {
47 const uint32_t EVENT_REPORT_MOCK_LOCATION = 0x0100;
48 const uint32_t EVENT_RESTART_ALL_LOCATION_REQUEST = 0x0200;
49 const uint32_t EVENT_STOP_ALL_LOCATION_REQUEST = 0x0300;
50 const uint32_t EVENT_DISCONNECT_SERVICES = 0x0400;
51 const uint32_t EVENT_INTERVAL_UNITE = 1000;
52 const uint32_t DELAY_RESTART_MS = 500;
53 const uint32_t DELAY_DINCONNECT_MS = 5 * 1000;
54 constexpr uint32_t WAIT_MS = 100;
55 const int MAX_RETRY_COUNT = 5;
56 const std::string UNLOAD_NETWORK_TASK = "network_sa_unload";
57 const std::string DISCONNECT_NETWORK_TASK = "disconnect_network_ability";
58 const uint32_t RETRY_INTERVAL_OF_UNLOAD_SA = 4 * 60 * EVENT_INTERVAL_UNITE;
59 const int TIMEOUT_WATCHDOG = 60; // s
60 const bool REGISTER_RESULT = NetworkAbility::MakeAndRegisterAbility(
61 NetworkAbility::GetInstance());
62
NetworkAbility()63 NetworkAbility::NetworkAbility() : SystemAbility(LOCATION_NETWORK_LOCATING_SA_ID, true)
64 {
65 SetAbility(NETWORK_ABILITY);
66 #ifndef TDD_CASES_ENABLED
67 networkHandler_ =
68 std::make_shared<NetworkHandler>(AppExecFwk::EventRunner::Create(true, AppExecFwk::ThreadMode::FFRT));
69 #endif
70 LBSLOGI(NETWORK, "ability constructed.");
71 }
72
~NetworkAbility()73 NetworkAbility::~NetworkAbility()
74 {
75 std::unique_lock<ffrt::mutex> uniqueLock(connMutex_);
76 conn_ = nullptr;
77 }
78
OnStart()79 void NetworkAbility::OnStart()
80 {
81 if (state_ == ServiceRunningState::STATE_RUNNING) {
82 LBSLOGI(NETWORK, "ability has already started.");
83 return;
84 }
85 if (!Init()) {
86 LBSLOGE(NETWORK, "failed to init ability");
87 OnStop();
88 return;
89 }
90 state_ = ServiceRunningState::STATE_RUNNING;
91 LBSLOGI(NETWORK, "OnStart start ability success.");
92 }
93
OnStop()94 void NetworkAbility::OnStop()
95 {
96 state_ = ServiceRunningState::STATE_NOT_START;
97 registerToAbility_ = false;
98 LBSLOGI(NETWORK, "OnStop ability stopped.");
99 }
100
GetInstance()101 NetworkAbility* NetworkAbility::GetInstance()
102 {
103 static NetworkAbility data;
104 return &data;
105 }
106
Init()107 bool NetworkAbility::Init()
108 {
109 if (!registerToAbility_) {
110 if (!Publish(AsObject())) {
111 LBSLOGE(NETWORK, "Init Publish failed!");
112 return false;
113 }
114 registerToAbility_ = true;
115 }
116 return true;
117 }
118
119 class AbilityConnection : public AAFwk::AbilityConnectionStub {
120 public:
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)121 void OnAbilityConnectDone(
122 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode) override
123 {
124 std::string uri = element.GetURI();
125 LBSLOGD(NETWORK, "Connected uri is %{public}s, result is %{public}d.", uri.c_str(), resultCode);
126 if (resultCode != ERR_OK) {
127 return;
128 }
129 NetworkAbility::GetInstance()->NotifyConnected(remoteObject);
130 }
131
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int)132 void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int) override
133 {
134 std::string uri = element.GetURI();
135 LBSLOGD(NETWORK, "Disconnected uri is %{public}s.", uri.c_str());
136 NetworkAbility::GetInstance()->NotifyDisConnected();
137 }
138 };
139
ConnectNlpService()140 bool NetworkAbility::ConnectNlpService()
141 {
142 LBSLOGD(NETWORK, "start ConnectNlpService");
143 if (!IsConnect()) {
144 AAFwk::Want connectionWant;
145 std::string serviceName;
146 bool result = LocationConfigManager::GetInstance()->GetNlpServiceName(serviceName);
147 if (!result || serviceName.empty()) {
148 LBSLOGE(NETWORK, "get service name failed!");
149 return false;
150 }
151 std::string abilityName;
152 bool res = LocationConfigManager::GetInstance()->GetNlpAbilityName(abilityName);
153 if (!res || abilityName.empty()) {
154 LBSLOGE(NETWORK, "get service name failed!");
155 return false;
156 }
157 connectionWant.SetElementName(serviceName, abilityName);
158 std::unique_lock<ffrt::mutex> lock(connMutex_, std::defer_lock);
159 connMutex_.lock();
160 conn_ = sptr<AAFwk::IAbilityConnection>(new (std::nothrow) AbilityConnection());
161 if (conn_ == nullptr) {
162 LBSLOGE(NETWORK, "get connection failed!");
163 connMutex_.unlock();
164 return false;
165 }
166 int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(connectionWant, conn_, -1);
167 connMutex_.unlock();
168 if (ret != ERR_OK) {
169 LBSLOGE(NETWORK, "Connect cloud service failed, ret = %{public}d", ret);
170 return false;
171 }
172 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
173 auto waitStatus = connectCondition_.wait_for(
174 uniqueLock, std::chrono::seconds(CONNECT_TIME_OUT), [this]() { return nlpServiceProxy_ != nullptr; });
175 if (!waitStatus) {
176 WriteLocationInnerEvent(NLP_SERVICE_TIMEOUT, {});
177 LBSLOGE(NETWORK, "Connect cloudService timeout!");
178 return false;
179 }
180 }
181 RegisterNlpServiceDeathRecipient();
182 return true;
183 }
184
ReConnectNlpService()185 bool NetworkAbility::ReConnectNlpService()
186 {
187 int retryCount = 0;
188 if (IsConnect()) {
189 LBSLOGI(NETWORK, "Connect success!");
190 return true;
191 }
192 while (retryCount < MAX_RETRY_COUNT) {
193 retryCount++;
194 bool ret = ConnectNlpService();
195 if (ret) {
196 LBSLOGI(NETWORK, "Connect success!");
197 return true;
198 }
199 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
200 }
201 return false;
202 }
203
ResetServiceProxy()204 bool NetworkAbility::ResetServiceProxy()
205 {
206 if (networkHandler_ == nullptr) {
207 return false;
208 }
209 networkHandler_->SendHighPriorityEvent(EVENT_DISCONNECT_SERVICES, 0, 0);
210 return true;
211 }
212
ClearServiceProxy()213 void NetworkAbility::ClearServiceProxy()
214 {
215 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
216 nlpServiceProxy_ = nullptr;
217 }
218
NotifyConnected(const sptr<IRemoteObject> & remoteObject)219 void NetworkAbility::NotifyConnected(const sptr<IRemoteObject>& remoteObject)
220 {
221 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
222 nlpServiceProxy_ = remoteObject;
223 connectCondition_.notify_all();
224 }
225
NotifyDisConnected()226 void NetworkAbility::NotifyDisConnected()
227 {
228 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
229 connectCondition_.notify_all();
230 }
231
SendLocationRequest(WorkRecord & workrecord)232 LocationErrCode NetworkAbility::SendLocationRequest(WorkRecord &workrecord)
233 {
234 LocationRequest(workrecord);
235 return ERRCODE_SUCCESS;
236 }
237
SetEnable(bool state)238 LocationErrCode NetworkAbility::SetEnable(bool state)
239 {
240 LBSLOGD(NETWORK, "SetEnable: %{public}d", state);
241 int nlpEnableState = LocationConfigManager::GetInstance()->GetNlpEnableState();
242 if (!nlpEnableState) {
243 LBSLOGE(NETWORK, "nlpEnableState false");
244 state = false;
245 }
246 if (networkHandler_ == nullptr) {
247 LBSLOGE(NETWORK, "%{public}s networkHandler is nullptr", __func__);
248 return ERRCODE_SERVICE_UNAVAILABLE;
249 }
250 auto event = state ? AppExecFwk::InnerEvent::Get(EVENT_RESTART_ALL_LOCATION_REQUEST, 0) :
251 AppExecFwk::InnerEvent::Get(EVENT_STOP_ALL_LOCATION_REQUEST, 0);
252 networkHandler_->SendHighPriorityEvent(event);
253 return ERRCODE_SUCCESS;
254 }
255
CancelIdleState()256 bool NetworkAbility::CancelIdleState()
257 {
258 SystemAbilityState state = GetAbilityState();
259 if (state != SystemAbilityState::IDLE) {
260 return true;
261 }
262 bool ret = CancelIdle();
263 if (!ret) {
264 LBSLOGE(NETWORK, "%{public}s cancel idle failed!", __func__);
265 return false;
266 }
267 return true;
268 }
269
UnloadNetworkSystemAbility()270 void NetworkAbility::UnloadNetworkSystemAbility()
271 {
272 if (networkHandler_ == nullptr) {
273 LBSLOGE(NETWORK, "%{public}s networkHandler is nullptr", __func__);
274 return;
275 }
276 networkHandler_->RemoveTask(UNLOAD_NETWORK_TASK);
277 auto task = [this]() {
278 if (CheckIfNetworkConnecting()) {
279 return;
280 }
281 SaLoadWithStatistic::UnInitLocationSa(LOCATION_NETWORK_LOCATING_SA_ID);
282 };
283 if (networkHandler_ != nullptr) {
284 networkHandler_->PostTask(task, UNLOAD_NETWORK_TASK, RETRY_INTERVAL_OF_UNLOAD_SA);
285 }
286 }
287
CheckIfNetworkConnecting()288 bool NetworkAbility::CheckIfNetworkConnecting()
289 {
290 return IsMockEnabled() || !GetLocationMock().empty() || GetRequestNum() != 0;
291 }
292
RequestRecord(WorkRecord & workRecord,bool isAdded)293 void NetworkAbility::RequestRecord(WorkRecord &workRecord, bool isAdded)
294 {
295 if (!IsConnect()) {
296 std::string serviceName;
297 bool result = LocationConfigManager::GetInstance()->GetNlpServiceName(serviceName);
298 if (!result || serviceName.empty()) {
299 LBSLOGE(NETWORK, "get service name failed!");
300 return;
301 }
302 if (!CommonUtils::CheckAppInstalled(serviceName)) { // app is not installed
303 LBSLOGE(NETWORK, "nlp service is not available.");
304 return;
305 } else if (!ReConnectNlpService()) {
306 LBSLOGE(NETWORK, "nlp service is not ready.");
307 return;
308 }
309 }
310 if (isAdded) {
311 int nlpEnableState = LocationConfigManager::GetInstance()->GetNlpEnableState();
312 uint32_t tokenId = workRecord.GetTokenId(0);
313 uint32_t firstTokenId = workRecord.GetFirstTokenId(0);
314 bool ignoredSwtichPermission =
315 PermissionManager::CheckLocationSwitchIgnoredPermission(tokenId, firstTokenId);
316 if (!nlpEnableState && !ignoredSwtichPermission) { // enter when enablestated & ignoredPermission all false
317 LBSLOGE(NETWORK, "enablestated and ignoredSwtichPermission both false");
318 return;
319 }
320 RequestNetworkLocation(workRecord);
321 if (networkHandler_ != nullptr) {
322 networkHandler_->RemoveTask(DISCONNECT_NETWORK_TASK);
323 }
324 } else {
325 RemoveNetworkLocation(workRecord);
326 if (networkHandler_ == nullptr) {
327 return;
328 }
329 networkHandler_->RemoveTask(DISCONNECT_NETWORK_TASK);
330 auto disconnectTask = [this]() {
331 auto networkAbility = NetworkAbility::GetInstance();
332 if (networkAbility == nullptr) {
333 LBSLOGE(NETWORK, "OnRemoteDied: NetworkAbility is nullptr");
334 return;
335 };
336 networkAbility->DisconnectAbilityConnect();
337 };
338 networkHandler_->PostTask(disconnectTask, DISCONNECT_NETWORK_TASK, DELAY_DINCONNECT_MS);
339 }
340 }
341
DisconnectAbilityConnect()342 void NetworkAbility::DisconnectAbilityConnect()
343 {
344 std::unique_lock<ffrt::mutex> uniqueLock(connMutex_);
345 if (GetRequestNum() == 0 && conn_ != nullptr) {
346 LBSLOGI(NETWORK, "RequestRecord disconnect");
347 UnregisterNlpServiceDeathRecipient();
348 AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(conn_);
349 conn_ = nullptr;
350 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
351 nlpServiceProxy_ = nullptr;
352 LBSLOGD(NETWORK, "disconnect cloudService success!");
353 }
354 }
355
RequestNetworkLocation(WorkRecord & workRecord)356 bool NetworkAbility::RequestNetworkLocation(WorkRecord &workRecord)
357 {
358 LBSLOGW(NETWORK, "start network location, uuid: %{public}s", workRecord.GetUuid(0).c_str());
359 sptr<NetworkCallbackHost> callback = new (std::nothrow) NetworkCallbackHost();
360 if (callback == nullptr) {
361 LBSLOGE(NETWORK, "can not get valid callback.");
362 return false;
363 }
364 HookUtils::ExecuteHookWhenAddNetworkRequest(workRecord.GetUuid(0));
365 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
366 if (nlpServiceProxy_ == nullptr) {
367 LBSLOGE(NETWORK, "nlpProxy is nullptr.");
368 return false;
369 }
370 MessageParcel data;
371
372 MessageParcel reply;
373 MessageOption option;
374 data.WriteInterfaceToken(nlpServiceProxy_->GetInterfaceDescriptor());
375 data.WriteString16(Str8ToStr16(workRecord.GetUuid(0)));
376 data.WriteInt64(workRecord.GetTimeInterval(0) * MILLI_PER_SEC);
377 data.WriteInt32(workRecord.GetNlpRequestType(0));
378 data.WriteRemoteObject(callback->AsObject());
379 if (workRecord.GetName(0).size() == 0) {
380 data.WriteString16(Str8ToStr16(std::to_string(workRecord.GetUid(0)))); // uid
381 } else {
382 data.WriteString16(Str8ToStr16(workRecord.GetName(0))); // bundleName
383 }
384 int error = nlpServiceProxy_->SendRequest(REQUEST_NETWORK_LOCATION, data, reply, option);
385 if (error != ERR_OK) {
386 LBSLOGE(NETWORK, "SendRequest to cloud service failed. error = %{public}d", error);
387 return false;
388 }
389 return true;
390 }
391
RemoveNetworkLocation(WorkRecord & workRecord)392 bool NetworkAbility::RemoveNetworkLocation(WorkRecord &workRecord)
393 {
394 HookUtils::ExecuteHookWhenRemoveNetworkRequest(workRecord.GetUuid(0));
395 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
396 if (nlpServiceProxy_ == nullptr) {
397 LBSLOGE(NETWORK, "nlpProxy is nullptr.");
398 return false;
399 }
400 LBSLOGW(NETWORK, "stop network location, uuid: %{public}s", workRecord.GetUuid(0).c_str());
401 MessageParcel data;
402 MessageParcel reply;
403 MessageOption option;
404 data.WriteInterfaceToken(nlpServiceProxy_->GetInterfaceDescriptor());
405 data.WriteString16(Str8ToStr16(workRecord.GetUuid(0)));
406 data.WriteString16(Str8ToStr16(workRecord.GetName(0))); // bundleName
407 int error = nlpServiceProxy_->SendRequest(REMOVE_NETWORK_LOCATION, data, reply, option);
408 if (error != ERR_OK) {
409 LBSLOGE(NETWORK, "SendRequest to cloud service failed.");
410 return false;
411 }
412 return true;
413 }
414
EnableMock()415 LocationErrCode NetworkAbility::EnableMock()
416 {
417 if (!EnableLocationMock()) {
418 return LOCATION_ERRCODE_NOT_SUPPORTED;
419 }
420 return ERRCODE_SUCCESS;
421 }
422
DisableMock()423 LocationErrCode NetworkAbility::DisableMock()
424 {
425 if (!DisableLocationMock()) {
426 return LOCATION_ERRCODE_NOT_SUPPORTED;
427 }
428 return ERRCODE_SUCCESS;
429 }
430
IsMockEnabled()431 bool NetworkAbility::IsMockEnabled()
432 {
433 return IsLocationMocked();
434 }
435
SetMocked(const int timeInterval,const std::vector<std::shared_ptr<Location>> & location)436 LocationErrCode NetworkAbility::SetMocked(const int timeInterval,
437 const std::vector<std::shared_ptr<Location>> &location)
438 {
439 if (!SetMockedLocations(timeInterval, location)) {
440 return LOCATION_ERRCODE_NOT_SUPPORTED;
441 }
442 return ERRCODE_SUCCESS;
443 }
444
ProcessReportLocationMock()445 void NetworkAbility::ProcessReportLocationMock()
446 {
447 std::vector<std::shared_ptr<Location>> mockLocationArray = GetLocationMock();
448 if (mockLocationIndex_ < mockLocationArray.size()) {
449 ReportMockedLocation(mockLocationArray[mockLocationIndex_++]);
450 if (networkHandler_ != nullptr) {
451 networkHandler_->SendHighPriorityEvent(EVENT_REPORT_MOCK_LOCATION,
452 0, GetTimeIntervalMock() * EVENT_INTERVAL_UNITE);
453 }
454 } else {
455 ClearLocationMock();
456 mockLocationIndex_ = 0;
457 }
458 }
459
SendReportMockLocationEvent()460 void NetworkAbility::SendReportMockLocationEvent()
461 {
462 if (networkHandler_ == nullptr) {
463 return;
464 }
465 networkHandler_->SendHighPriorityEvent(EVENT_REPORT_MOCK_LOCATION, 0, 0);
466 }
467
ReportMockedLocation(const std::shared_ptr<Location> location)468 int32_t NetworkAbility::ReportMockedLocation(const std::shared_ptr<Location> location)
469 {
470 if ((IsLocationMocked() && !location->GetIsFromMock()) ||
471 (!IsLocationMocked() && location->GetIsFromMock())) {
472 LBSLOGE(NETWORK, "location mock is enabled, do not report network location!");
473 return ERR_OK;
474 }
475 location->SetTimeSinceBoot(CommonUtils::GetSinceBootTime());
476 location->SetTimeStamp(CommonUtils::GetCurrentTimeStamp() * MICRO_PER_MILLI);
477 location->SetLocationSourceType(LocationSourceType::NETWORK_TYPE);
478 ReportLocationInfo(NETWORK_ABILITY, location);
479 #ifdef FEATURE_PASSIVE_SUPPORT
480 ReportLocationInfo(PASSIVE_ABILITY, location);
481 #endif
482 return ERR_OK;
483 }
484
SaDumpInfo(std::string & result)485 void NetworkAbility::SaDumpInfo(std::string& result)
486 {
487 result += "Network Location enable status: false";
488 result += "\n";
489 }
490
Dump(int32_t fd,const std::vector<std::u16string> & args)491 int32_t NetworkAbility::Dump(int32_t fd, const std::vector<std::u16string>& args)
492 {
493 std::vector<std::string> vecArgs;
494 std::transform(args.begin(), args.end(), std::back_inserter(vecArgs), [](const std::u16string &arg) {
495 return Str16ToStr8(arg);
496 });
497
498 LocationDumper dumper;
499 std::string result;
500 dumper.NetWorkDump(SaDumpInfo, vecArgs, result);
501 if (!SaveStringToFd(fd, result)) {
502 LBSLOGE(NETWORK, "Network save string to fd failed!");
503 return ERR_OK;
504 }
505 return ERR_OK;
506 }
507
SendMessage(uint32_t code,MessageParcel & data,MessageParcel & reply)508 void NetworkAbility::SendMessage(uint32_t code, MessageParcel &data, MessageParcel &reply)
509 {
510 if (networkHandler_ == nullptr) {
511 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
512 return;
513 }
514 switch (code) {
515 case static_cast<uint32_t>(NetworkInterfaceCode::SEND_LOCATION_REQUEST): {
516 std::unique_ptr<WorkRecord> workrecord = WorkRecord::Unmarshalling(data);
517 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(code, workrecord);
518 if (networkHandler_->SendEvent(event)) {
519 reply.WriteInt32(ERRCODE_SUCCESS);
520 } else {
521 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
522 }
523 break;
524 }
525 case static_cast<uint32_t>(NetworkInterfaceCode::SET_MOCKED_LOCATIONS): {
526 if (!IsMockEnabled()) {
527 reply.WriteInt32(LOCATION_ERRCODE_NOT_SUPPORTED);
528 break;
529 }
530 int timeInterval = data.ReadInt32();
531 int locationSize = data.ReadInt32();
532 timeInterval = timeInterval < 0 ? 1 : timeInterval;
533 locationSize = locationSize > INPUT_ARRAY_LEN_MAX ? INPUT_ARRAY_LEN_MAX :
534 locationSize;
535 std::shared_ptr<std::vector<std::shared_ptr<Location>>> vcLoc =
536 std::make_shared<std::vector<std::shared_ptr<Location>>>();
537 for (int i = 0; i < locationSize; i++) {
538 vcLoc->push_back(Location::UnmarshallingShared(data));
539 }
540 AppExecFwk::InnerEvent::Pointer event =
541 AppExecFwk::InnerEvent::Get(code, vcLoc, timeInterval);
542 if (networkHandler_->SendEvent(event)) {
543 reply.WriteInt32(ERRCODE_SUCCESS);
544 } else {
545 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
546 }
547 break;
548 }
549 default:
550 break;
551 }
552 }
553
RegisterNlpServiceDeathRecipient()554 void NetworkAbility::RegisterNlpServiceDeathRecipient()
555 {
556 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
557 if (nlpServiceProxy_ == nullptr) {
558 LBSLOGE(NETWORK, "%{public}s: nlpServiceProxy_ is nullptr", __func__);
559 return;
560 }
561 if (nlpServiceRecipient_ == nullptr) {
562 nlpServiceRecipient_ = sptr<NlpServiceDeathRecipient>(new (std::nothrow) NlpServiceDeathRecipient());
563 }
564 nlpServiceProxy_->AddDeathRecipient(nlpServiceRecipient_);
565 LBSLOGI(NETWORK, "%{public}s: success", __func__);
566 }
567
UnregisterNlpServiceDeathRecipient()568 void NetworkAbility::UnregisterNlpServiceDeathRecipient()
569 {
570 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
571 LBSLOGI(NETWORK, "UnRegisterNLPServiceDeathRecipient enter");
572 if (nlpServiceProxy_ == nullptr) {
573 LBSLOGE(NETWORK, "%{public}s: nlpServiceProxy_ is nullptr", __func__);
574 return;
575 }
576 if (nlpServiceRecipient_ != nullptr) {
577 nlpServiceProxy_->RemoveDeathRecipient(nlpServiceRecipient_);
578 nlpServiceRecipient_ = nullptr;
579 }
580 }
581
IsConnect()582 bool NetworkAbility::IsConnect()
583 {
584 std::unique_lock<ffrt::mutex> uniqueLock(nlpServiceMutex_);
585 return nlpServiceProxy_ != nullptr;
586 }
587
RestartNlpRequests()588 void NetworkAbility::RestartNlpRequests()
589 {
590 if (GetRequestNum() > 0) {
591 if (networkHandler_ != nullptr) {
592 networkHandler_->SendHighPriorityEvent(EVENT_RESTART_ALL_LOCATION_REQUEST, 0, DELAY_RESTART_MS);
593 LBSLOGI(NETWORK, "CheckNetworkRequests needRecoverRequests");
594 }
595 }
596 }
597
NetworkHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)598 NetworkHandler::NetworkHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner) : EventHandler(runner)
599 {
600 InitNetworkEventProcessMap();
601 }
602
~NetworkHandler()603 NetworkHandler::~NetworkHandler() {}
604
InitNetworkEventProcessMap()605 void NetworkHandler::InitNetworkEventProcessMap()
606 {
607 if (networkEventProcessMap_.size() != 0) {
608 return;
609 }
610 networkEventProcessMap_[static_cast<uint32_t>(EVENT_REPORT_MOCK_LOCATION)] =
611 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleReportLocationMock(event); };
612 networkEventProcessMap_[static_cast<uint32_t>(EVENT_RESTART_ALL_LOCATION_REQUEST)] =
613 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleRestartAllLocationRequests(event); };
614 networkEventProcessMap_[static_cast<uint32_t>(EVENT_STOP_ALL_LOCATION_REQUEST)] =
615 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleStopAllLocationRequests(event); };
616 networkEventProcessMap_[static_cast<uint32_t>(EVENT_DISCONNECT_SERVICES)] =
617 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleClearServiceEvent(event); };
618 networkEventProcessMap_[static_cast<uint32_t>(NetworkInterfaceCode::SEND_LOCATION_REQUEST)] =
619 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleLocationRequest(event); };
620 networkEventProcessMap_[static_cast<uint32_t>(NetworkInterfaceCode::SET_MOCKED_LOCATIONS)] =
621 [this](const AppExecFwk::InnerEvent::Pointer& event) { HandleSetMocked(event); };
622 }
623
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)624 void NetworkHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event)
625 {
626 uint32_t eventId = event->GetInnerEventId();
627 LBSLOGD(NETWORK, "ProcessEvent event:%{public}d", eventId);
628
629 auto handleFunc = networkEventProcessMap_.find(eventId);
630 if (handleFunc != networkEventProcessMap_.end() && handleFunc->second != nullptr) {
631 auto memberFunc = handleFunc->second;
632 #ifdef LOCATION_HICOLLIE_ENABLE
633 int tid = gettid();
634 std::string moduleName = "NetworkHandler";
635 XCollieCallback callbackFunc = [moduleName, eventId, tid](void *) {
636 LBSLOGE(NETWORK, "TimeoutCallback tid:%{public}d moduleName:%{public}s excute eventId:%{public}u timeout.",
637 tid, moduleName.c_str(), eventId);
638 };
639 std::string dfxInfo = moduleName + "_" + std::to_string(eventId) + "_" + std::to_string(tid);
640 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer(dfxInfo, TIMEOUT_WATCHDOG, callbackFunc, nullptr,
641 HiviewDFX::XCOLLIE_FLAG_LOG|HiviewDFX::XCOLLIE_FLAG_RECOVERY);
642 memberFunc(event);
643 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
644 #else
645 memberFunc(event);
646 #endif
647 }
648 auto networkAbility = NetworkAbility::GetInstance();
649 networkAbility->UnloadNetworkSystemAbility();
650 }
651
HandleReportLocationMock(const AppExecFwk::InnerEvent::Pointer & event)652 void NetworkHandler::HandleReportLocationMock(const AppExecFwk::InnerEvent::Pointer& event)
653 {
654 auto networkAbility = NetworkAbility::GetInstance();
655 networkAbility->ProcessReportLocationMock();
656 }
657
HandleRestartAllLocationRequests(const AppExecFwk::InnerEvent::Pointer & event)658 void NetworkHandler::HandleRestartAllLocationRequests(const AppExecFwk::InnerEvent::Pointer& event)
659 {
660 auto networkAbility = NetworkAbility::GetInstance();
661 networkAbility->RestartAllLocationRequests();
662 }
663
HandleStopAllLocationRequests(const AppExecFwk::InnerEvent::Pointer & event)664 void NetworkHandler::HandleStopAllLocationRequests(const AppExecFwk::InnerEvent::Pointer& event)
665 {
666 auto networkAbility = NetworkAbility::GetInstance();
667 networkAbility->StopAllLocationRequests();
668 }
669
HandleLocationRequest(const AppExecFwk::InnerEvent::Pointer & event)670 void NetworkHandler::HandleLocationRequest(const AppExecFwk::InnerEvent::Pointer& event)
671 {
672 std::unique_ptr<WorkRecord> workrecord = event->GetUniqueObject<WorkRecord>();
673 if (workrecord != nullptr) {
674 auto networkAbility = NetworkAbility::GetInstance();
675 networkAbility->LocationRequest(*workrecord);
676 }
677 }
678
HandleClearServiceEvent(const AppExecFwk::InnerEvent::Pointer & event)679 void NetworkHandler::HandleClearServiceEvent(const AppExecFwk::InnerEvent::Pointer& event)
680 {
681 auto networkAbility = NetworkAbility::GetInstance();
682 networkAbility->ClearServiceProxy();
683 }
684
HandleSetMocked(const AppExecFwk::InnerEvent::Pointer & event)685 void NetworkHandler::HandleSetMocked(const AppExecFwk::InnerEvent::Pointer& event)
686 {
687 auto networkAbility = NetworkAbility::GetInstance();
688 int timeInterval = event->GetParam();
689 auto vcLoc = event->GetSharedObject<std::vector<std::shared_ptr<Location>>>();
690 if (vcLoc != nullptr) {
691 std::vector<std::shared_ptr<Location>> mockLocations;
692 for (auto it = vcLoc->begin(); it != vcLoc->end(); ++it) {
693 mockLocations.push_back(*it);
694 }
695 networkAbility->SetMocked(timeInterval, mockLocations);
696 }
697 }
698
NlpServiceDeathRecipient()699 NlpServiceDeathRecipient::NlpServiceDeathRecipient()
700 {
701 }
702
~NlpServiceDeathRecipient()703 NlpServiceDeathRecipient::~NlpServiceDeathRecipient()
704 {
705 }
706
OnRemoteDied(const wptr<IRemoteObject> & remote)707 void NlpServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
708 {
709 auto networkAbility = NetworkAbility::GetInstance();
710 if (networkAbility == nullptr) {
711 LBSLOGE(NETWORK, "OnRemoteDied: NetworkAbility is nullptr");
712 return;
713 }
714 networkAbility->ResetServiceProxy();
715 networkAbility->RestartNlpRequests();
716 }
717 } // namespace Location
718 } // namespace OHOS
719 #endif // FEATURE_NETWORK_SUPPORT
720