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