• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifdef FEATURE_NETWORK_SUPPORT
17 #include "network_ability.h"
18 #include <file_ex.h>
19 #include <thread>
20 #include "ability_connect_callback_interface.h"
21 #include "ability_connect_callback_stub.h"
22 #include "ability_manager_client.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "want_agent_helper.h"
27 
28 #include "common_utils.h"
29 #include "location_config_manager.h"
30 #include "location_dumper.h"
31 #include "location_log.h"
32 #include "location_sa_load_manager.h"
33 #include "network_callback_host.h"
34 #include "locationhub_ipc_interface_code.h"
35 
36 namespace OHOS {
37 namespace Location {
38 const uint32_t EVENT_REPORT_LOCATION = 0x0100;
39 const uint32_t EVENT_INTERVAL_UNITE = 1000;
40 constexpr uint32_t WAIT_MS = 100;
41 const int MAX_RETRY_COUNT = 5;
42 const bool REGISTER_RESULT = NetworkAbility::MakeAndRegisterAbility(
43     DelayedSingleton<NetworkAbility>::GetInstance().get());
44 
NetworkAbility()45 NetworkAbility::NetworkAbility() : SystemAbility(LOCATION_NETWORK_LOCATING_SA_ID, true)
46 {
47     SetAbility(NETWORK_ABILITY);
48     networkHandler_ = std::make_shared<NetworkHandler>(AppExecFwk::EventRunner::Create(true));
49     LBSLOGI(NETWORK, "ability constructed.");
50 }
51 
~NetworkAbility()52 NetworkAbility::~NetworkAbility() {}
53 
OnStart()54 void NetworkAbility::OnStart()
55 {
56     if (state_ == ServiceRunningState::STATE_RUNNING) {
57         LBSLOGI(NETWORK, "ability has already started.");
58         return;
59     }
60     if (!Init()) {
61         LBSLOGE(NETWORK, "failed to init ability");
62         OnStop();
63         return;
64     }
65     state_ = ServiceRunningState::STATE_RUNNING;
66     LBSLOGI(NETWORK, "OnStart start ability success.");
67 }
68 
OnStop()69 void NetworkAbility::OnStop()
70 {
71     state_ = ServiceRunningState::STATE_NOT_START;
72     registerToAbility_ = false;
73     LBSLOGI(NETWORK, "OnStop ability stopped.");
74 }
75 
Init()76 bool NetworkAbility::Init()
77 {
78     if (!registerToAbility_) {
79         if (!Publish(AsObject())) {
80             LBSLOGE(NETWORK, "Init Publish failed!");
81             return false;
82         }
83         registerToAbility_ = true;
84     }
85     return true;
86 }
87 
88 class AbilityConnection : public AAFwk::AbilityConnectionStub {
89 public:
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)90     void OnAbilityConnectDone(
91         const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode) override
92     {
93         std::string uri = element.GetURI();
94         LBSLOGD(NETWORK, "Connected uri is %{public}s, result is %{public}d.", uri.c_str(), resultCode);
95         if (resultCode != ERR_OK) {
96             return;
97         }
98         DelayedSingleton<NetworkAbility>::GetInstance().get()->NotifyConnected(remoteObject);
99     }
100 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int)101     void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int) override
102     {
103         std::string uri = element.GetURI();
104         LBSLOGD(NETWORK, "Disconnected uri is %{public}s.", uri.c_str());
105         DelayedSingleton<NetworkAbility>::GetInstance().get()->NotifyDisConnected();
106     }
107 };
108 
ConnectNlpService()109 bool NetworkAbility::ConnectNlpService()
110 {
111     LBSLOGD(NETWORK, "start ConnectNlpService");
112     std::unique_lock<std::mutex> uniqueLock(mutex_);
113     if (!nlpServiceReady_) {
114         AAFwk::Want connectionWant;
115         std::string serviceName;
116         bool result = LocationConfigManager::GetInstance().GetNlpServiceName(serviceName);
117         if (!result || serviceName.empty()) {
118             LBSLOGE(NETWORK, "get service name failed!");
119             return false;
120         }
121         std::string abilityName;
122         bool res = LocationConfigManager::GetInstance().GetNlpAbilityName(abilityName);
123         if (!res || abilityName.empty()) {
124             LBSLOGE(NETWORK, "get service name failed!");
125             return false;
126         }
127         connectionWant.SetElementName(serviceName, abilityName);
128         sptr<AAFwk::IAbilityConnection> conn = new (std::nothrow) AbilityConnection();
129         if (conn == nullptr) {
130             LBSLOGE(NETWORK, "get connection failed!");
131             return false;
132         }
133         int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(connectionWant, conn, -1);
134         if (ret != ERR_OK) {
135             LBSLOGE(NETWORK, "Connect cloud service failed!");
136             return false;
137         }
138 
139         auto waitStatus = connectCondition_.wait_for(
140             uniqueLock, std::chrono::seconds(CONNECT_TIME_OUT), [this]() { return nlpServiceReady_; });
141         if (!waitStatus) {
142             LBSLOGE(NETWORK, "Connect cloudService timeout!");
143             return false;
144         }
145     }
146     return true;
147 }
148 
ReConnectNlpService()149 bool NetworkAbility::ReConnectNlpService()
150 {
151     int retryCount = 0;
152     if (nlpServiceReady_) {
153         LBSLOGI(NETWORK, "Connect success!");
154         return true;
155     }
156     while (retryCount < MAX_RETRY_COUNT) {
157         retryCount++;
158         bool ret = ConnectNlpService();
159         if (ret) {
160             LBSLOGI(NETWORK, "Connect success!");
161             return true;
162         }
163         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
164     }
165     return false;
166 }
167 
NotifyConnected(const sptr<IRemoteObject> & remoteObject)168 void NetworkAbility::NotifyConnected(const sptr<IRemoteObject>& remoteObject)
169 {
170     std::unique_lock<std::mutex> uniqueLock(mutex_);
171     nlpServiceReady_ = true;
172     nlpServiceProxy_ = remoteObject;
173     connectCondition_.notify_all();
174 }
175 
NotifyDisConnected()176 void NetworkAbility::NotifyDisConnected()
177 {
178     std::unique_lock<std::mutex> uniqueLock(mutex_);
179     nlpServiceReady_ = false;
180     nlpServiceProxy_ = nullptr;
181     connectCondition_.notify_all();
182 }
183 
SendLocationRequest(WorkRecord & workrecord)184 LocationErrCode NetworkAbility::SendLocationRequest(WorkRecord &workrecord)
185 {
186     LocationRequest(workrecord);
187     return ERRCODE_SUCCESS;
188 }
189 
SetEnable(bool state)190 LocationErrCode NetworkAbility::SetEnable(bool state)
191 {
192     if (state) {
193         Enable(true, AsObject());
194         return ERRCODE_SUCCESS;
195     }
196     if (!CheckIfNetworkConnecting()) {
197         Enable(false, AsObject());
198     }
199     return ERRCODE_SUCCESS;
200 }
201 
UnloadNetworkSystemAbility()202 void NetworkAbility::UnloadNetworkSystemAbility()
203 {
204     auto locationSaLoadManager = DelayedSingleton<LocationSaLoadManager>::GetInstance();
205     if (locationSaLoadManager == nullptr) {
206         return;
207     }
208 
209     if (!CheckIfNetworkConnecting()) {
210         locationSaLoadManager->UnloadLocationSa(LOCATION_NETWORK_LOCATING_SA_ID);
211     }
212 }
213 
CheckIfNetworkConnecting()214 bool NetworkAbility::CheckIfNetworkConnecting()
215 {
216     return IsMockEnabled() || !GetLocationMock().empty() || GetRequestNum() != 0;
217 }
218 
SelfRequest(bool state)219 LocationErrCode NetworkAbility::SelfRequest(bool state)
220 {
221     LBSLOGI(NETWORK, "SelfRequest %{public}d", state);
222     HandleSelfRequest(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), state);
223     return ERRCODE_SUCCESS;
224 }
225 
RequestRecord(WorkRecord & workRecord,bool isAdded)226 void NetworkAbility::RequestRecord(WorkRecord &workRecord, bool isAdded)
227 {
228     if (!nlpServiceReady_) {
229         std::string serviceName;
230         bool result = LocationConfigManager::GetInstance().GetNlpServiceName(serviceName);
231         if (!result || serviceName.empty()) {
232             LBSLOGE(NETWORK, "get service name failed!");
233             return;
234         }
235         if (!CommonUtils::CheckAppInstalled(serviceName)) { // app is not installed
236             LBSLOGE(NETWORK, "nlp service is not available.");
237             return;
238         } else if (!ReConnectNlpService()) {
239             LBSLOGE(NETWORK, "nlp service is not ready.");
240             return;
241         }
242     }
243     std::unique_lock<std::mutex> uniqueLock(mutex_);
244     if (nlpServiceProxy_ == nullptr) {
245         LBSLOGE(NETWORK, "nlpProxy is nullptr.");
246         return;
247     }
248     MessageParcel data;
249     MessageParcel reply;
250     MessageOption option;
251     if (isAdded) {
252         LBSLOGD(NETWORK, "start network location");
253         sptr<NetworkCallbackHost> callback = new (std::nothrow) NetworkCallbackHost();
254         if (callback == nullptr) {
255             LBSLOGE(NETWORK, "can not get valid callback.");
256             return;
257         }
258         data.WriteString16(Str8ToStr16(workRecord.GetUuid(0)));
259         data.WriteInt64(workRecord.GetTimeInterval(0) * SEC_TO_MILLI_SEC);
260         data.WriteInt32(LocationRequestType::PRIORITY_TYPE_BALANCED_POWER_ACCURACY);
261         data.WriteRemoteObject(callback->AsObject());
262         data.WriteString16(Str8ToStr16(workRecord.GetName(0))); // bundleName
263         int error = nlpServiceProxy_->SendRequest(REQUEST_NETWORK_LOCATION, data, reply, option);
264         if (error != ERR_OK) {
265             LBSLOGE(NETWORK, "SendRequest to cloud service failed.");
266             return;
267         }
268     } else {
269         LBSLOGD(NETWORK, "stop network location");
270         data.WriteString16(Str8ToStr16(workRecord.GetUuid(0)));
271         data.WriteString16(Str8ToStr16(workRecord.GetName(0))); // bundleName
272         int error = nlpServiceProxy_->SendRequest(REMOVE_NETWORK_LOCATION, data, reply, option);
273         if (error != ERR_OK) {
274             LBSLOGE(NETWORK, "SendRequest to cloud service failed.");
275             return;
276         }
277     }
278 }
279 
EnableMock()280 LocationErrCode NetworkAbility::EnableMock()
281 {
282     if (!EnableLocationMock()) {
283         return ERRCODE_NOT_SUPPORTED;
284     }
285     return ERRCODE_SUCCESS;
286 }
287 
DisableMock()288 LocationErrCode NetworkAbility::DisableMock()
289 {
290     if (!DisableLocationMock()) {
291         return ERRCODE_NOT_SUPPORTED;
292     }
293     return ERRCODE_SUCCESS;
294 }
295 
IsMockEnabled()296 bool NetworkAbility::IsMockEnabled()
297 {
298     return IsLocationMocked();
299 }
300 
SetMocked(const int timeInterval,const std::vector<std::shared_ptr<Location>> & location)301 LocationErrCode NetworkAbility::SetMocked(const int timeInterval,
302     const std::vector<std::shared_ptr<Location>> &location)
303 {
304     if (!SetMockedLocations(timeInterval, location)) {
305         return ERRCODE_NOT_SUPPORTED;
306     }
307     return ERRCODE_SUCCESS;
308 }
309 
ProcessReportLocationMock()310 void NetworkAbility::ProcessReportLocationMock()
311 {
312     std::vector<std::shared_ptr<Location>> mockLocationArray = GetLocationMock();
313     if (mockLocationIndex_ < mockLocationArray.size()) {
314         ReportMockedLocation(mockLocationArray[mockLocationIndex_++]);
315         if (networkHandler_ != nullptr) {
316             networkHandler_->SendHighPriorityEvent(EVENT_REPORT_LOCATION,
317                 0, GetTimeIntervalMock() * EVENT_INTERVAL_UNITE);
318         }
319     } else {
320         ClearLocationMock();
321         mockLocationIndex_ = 0;
322     }
323 }
324 
SendReportMockLocationEvent()325 void NetworkAbility::SendReportMockLocationEvent()
326 {
327     if (networkHandler_ == nullptr) {
328         return;
329     }
330     networkHandler_->SendHighPriorityEvent(EVENT_REPORT_LOCATION, 0, 0);
331 }
332 
ReportMockedLocation(const std::shared_ptr<Location> location)333 int32_t NetworkAbility::ReportMockedLocation(const std::shared_ptr<Location> location)
334 {
335     if ((IsLocationMocked() && !location->GetIsFromMock()) ||
336         (!IsLocationMocked() && location->GetIsFromMock())) {
337         LBSLOGE(NETWORK, "location mock is enabled, do not report gnss location!");
338         return ERR_OK;
339     }
340     ReportLocationInfo(NETWORK_ABILITY, location);
341 #ifdef FEATURE_PASSIVE_SUPPORT
342     ReportLocationInfo(PASSIVE_ABILITY, location);
343 #endif
344     return ERR_OK;
345 }
346 
SaDumpInfo(std::string & result)347 void NetworkAbility::SaDumpInfo(std::string& result)
348 {
349     result += "Network Location enable status: false";
350     result += "\n";
351 }
352 
Dump(int32_t fd,const std::vector<std::u16string> & args)353 int32_t NetworkAbility::Dump(int32_t fd, const std::vector<std::u16string>& args)
354 {
355     std::vector<std::string> vecArgs;
356     std::transform(args.begin(), args.end(), std::back_inserter(vecArgs), [](const std::u16string &arg) {
357         return Str16ToStr8(arg);
358     });
359 
360     LocationDumper dumper;
361     std::string result;
362     dumper.NetWorkDump(SaDumpInfo, vecArgs, result);
363     if (!SaveStringToFd(fd, result)) {
364         LBSLOGE(NETWORK, "Network save string to fd failed!");
365         return ERR_OK;
366     }
367     return ERR_OK;
368 }
369 
SendMessage(uint32_t code,MessageParcel & data,MessageParcel & reply)370 void NetworkAbility::SendMessage(uint32_t code, MessageParcel &data, MessageParcel &reply)
371 {
372     if (networkHandler_ == nullptr) {
373         reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
374         return;
375     }
376     switch (code) {
377         case static_cast<uint32_t>(NetworkInterfaceCode::SEND_LOCATION_REQUEST): {
378             std::unique_ptr<WorkRecord> workrecord = WorkRecord::Unmarshalling(data);
379             AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(code, workrecord);
380             if (networkHandler_->SendEvent(event)) {
381                 reply.WriteInt32(ERRCODE_SUCCESS);
382             } else {
383                 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
384             }
385             break;
386         }
387         case static_cast<uint32_t>(NetworkInterfaceCode::SET_MOCKED_LOCATIONS): {
388             if (!IsMockEnabled()) {
389                 reply.WriteInt32(ERRCODE_NOT_SUPPORTED);
390                 break;
391             }
392             int timeInterval = data.ReadInt32();
393             int locationSize = data.ReadInt32();
394             timeInterval = timeInterval < 0 ? 1 : timeInterval;
395             locationSize = locationSize > INPUT_ARRAY_LEN_MAX ? INPUT_ARRAY_LEN_MAX :
396                 locationSize;
397             std::shared_ptr<std::vector<std::shared_ptr<Location>>> vcLoc =
398                 std::make_shared<std::vector<std::shared_ptr<Location>>>();
399             for (int i = 0; i < locationSize; i++) {
400                 vcLoc->push_back(Location::UnmarshallingShared(data));
401             }
402             AppExecFwk::InnerEvent::Pointer event =
403                 AppExecFwk::InnerEvent::Get(code, vcLoc, timeInterval);
404             if (networkHandler_->SendEvent(event)) {
405                 reply.WriteInt32(ERRCODE_SUCCESS);
406             } else {
407                 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
408             }
409             break;
410         }
411         case static_cast<uint32_t>(NetworkInterfaceCode::SELF_REQUEST): {
412             int64_t param = data.ReadBool() ? 1 : 0;
413             networkHandler_->SendEvent(code, param, 0) ? reply.WriteInt32(ERRCODE_SUCCESS) :
414                 reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
415             break;
416         }
417         default:
418             break;
419     }
420 }
421 
NetworkHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)422 NetworkHandler::NetworkHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner) : EventHandler(runner) {}
423 
~NetworkHandler()424 NetworkHandler::~NetworkHandler() {}
425 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)426 void NetworkHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event)
427 {
428     auto networkAbility = DelayedSingleton<NetworkAbility>::GetInstance();
429     if (networkAbility == nullptr) {
430         LBSLOGE(NETWORK, "ProcessEvent: NetworkAbility is nullptr");
431         return;
432     }
433     uint32_t eventId = event->GetInnerEventId();
434     LBSLOGI(NETWORK, "ProcessEvent event:%{public}d", eventId);
435     switch (eventId) {
436         case EVENT_REPORT_LOCATION: {
437             networkAbility->ProcessReportLocationMock();
438             break;
439         }
440         case static_cast<uint32_t>(NetworkInterfaceCode::SEND_LOCATION_REQUEST): {
441             std::unique_ptr<WorkRecord> workrecord = event->GetUniqueObject<WorkRecord>();
442             if (workrecord != nullptr) {
443                 networkAbility->LocationRequest(*workrecord);
444             }
445             break;
446         }
447         case static_cast<uint32_t>(NetworkInterfaceCode::SET_MOCKED_LOCATIONS): {
448             int timeInterval = event->GetParam();
449             auto vcLoc = event->GetSharedObject<std::vector<std::shared_ptr<Location>>>();
450             if (vcLoc != nullptr) {
451                 std::vector<std::shared_ptr<Location>> mockLocations;
452                 for (auto it = vcLoc->begin(); it != vcLoc->end(); ++it) {
453                     mockLocations.push_back(*it);
454                 }
455                 networkAbility->SetMocked(timeInterval, mockLocations);
456             }
457             break;
458         }
459         case static_cast<uint32_t>(NetworkInterfaceCode::SELF_REQUEST): {
460             bool state = event->GetParam();
461             networkAbility->SelfRequest(state);
462             // no need unload sa, return
463             return;
464         }
465         default:
466             break;
467     }
468     networkAbility->UnloadNetworkSystemAbility();
469 }
470 } // namespace Location
471 } // namespace OHOS
472 #endif // FEATURE_NETWORK_SUPPORT
473