1 /*
2  * Copyright (C) 2023 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 "locator_agent.h"
17 #include "locationhub_ipc_interface_code.h"
18 #include "location_sa_load_manager.h"
19 #include "system_ability_definition.h"
20 #include "if_system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "location_log.h"
23 
24 namespace OHOS {
25 namespace Location {
GetInstance()26 LocatorAgentManager* LocatorAgentManager::GetInstance()
27 {
28     static LocatorAgentManager data;
29     return &data;
30 }
31 
LocatorAgentManager()32 LocatorAgentManager::LocatorAgentManager()
33 {
34     nmeaCallbackHost_ =
35         sptr<NativeNmeaCallbackHost>(new (std::nothrow) NativeNmeaCallbackHost());
36     gnssCallbackHost_ =
37         sptr<NativeSvCallbackHost>(new (std::nothrow) NativeSvCallbackHost());
38     locationCallbackHost_ =
39         sptr<NativeLocationCallbackHost>(new (std::nothrow) NativeLocationCallbackHost());
40 }
41 
~LocatorAgentManager()42 LocatorAgentManager::~LocatorAgentManager()
43 {}
44 
StartGnssLocating(const LocationCallbackIfaces & callback)45 void LocatorAgentManager::StartGnssLocating(const LocationCallbackIfaces& callback)
46 {
47     if (locationCallbackHost_ == nullptr) {
48         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
49         return;
50     }
51     auto proxy = GetLocatorAgent();
52     if (proxy == nullptr) {
53         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
54         return;
55     }
56     locationCallbackHost_->SetCallback(callback);
57     auto locatorCallback = sptr<ILocatorCallback>(locationCallbackHost_);
58     LocationErrCode ret = proxy->StartGnssLocating(locatorCallback);
59     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
60 }
61 
StopGnssLocating()62 void LocatorAgentManager::StopGnssLocating()
63 {
64     auto proxy = GetLocatorAgent();
65     if (proxy == nullptr) {
66         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
67         return;
68     }
69     auto locatorCallback = sptr<ILocatorCallback>(locationCallbackHost_);
70     LocationErrCode ret = proxy->StopGnssLocating(locatorCallback);
71     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
72 }
73 
RegisterGnssStatusCallback(const SvStatusCallbackIfaces & callback)74 void LocatorAgentManager::RegisterGnssStatusCallback(const SvStatusCallbackIfaces& callback)
75 {
76     if (gnssCallbackHost_ == nullptr) {
77         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
78         return;
79     }
80     auto proxy = GetLocatorAgent();
81     if (proxy == nullptr) {
82         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
83         return;
84     }
85     gnssCallbackHost_->SetCallback(callback);
86     auto gnssCallback = sptr<IGnssStatusCallback>(gnssCallbackHost_);
87     LocationErrCode ret = proxy->RegisterGnssStatusCallback(gnssCallback);
88     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
89 }
90 
UnregisterGnssStatusCallback()91 void LocatorAgentManager::UnregisterGnssStatusCallback()
92 {
93     auto proxy = GetLocatorAgent();
94     if (proxy == nullptr) {
95         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
96         return;
97     }
98     auto gnssCallback = sptr<IGnssStatusCallback>(gnssCallbackHost_);
99     LocationErrCode ret = proxy->UnregisterGnssStatusCallback(gnssCallback);
100     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
101 }
102 
RegisterNmeaMessageCallback(const GnssNmeaCallbackIfaces & callback)103 void LocatorAgentManager::RegisterNmeaMessageCallback(const GnssNmeaCallbackIfaces& callback)
104 {
105     if (nmeaCallbackHost_ == nullptr) {
106         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
107         return;
108     }
109     auto proxy = GetLocatorAgent();
110     if (proxy == nullptr) {
111         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
112         return;
113     }
114     nmeaCallbackHost_->SetCallback(callback);
115     auto nmeaCallback = sptr<INmeaMessageCallback>(nmeaCallbackHost_);
116     LocationErrCode ret = proxy->RegisterNmeaMessageCallback(nmeaCallback);
117     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
118 }
119 
UnregisterNmeaMessageCallback()120 void LocatorAgentManager::UnregisterNmeaMessageCallback()
121 {
122     auto proxy = GetLocatorAgent();
123     if (proxy == nullptr) {
124         LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
125         return;
126     }
127     auto nmeaCallback = sptr<INmeaMessageCallback>(nmeaCallbackHost_);
128     LocationErrCode ret = proxy->UnregisterNmeaMessageCallback(nmeaCallback);
129     LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret);
130 }
131 
GetLocatorAgent()132 sptr<LocatorAgent> LocatorAgentManager::GetLocatorAgent()
133 {
134     std::unique_lock<std::mutex> lock(mutex_, std::defer_lock);
135     lock.lock();
136     if (client_ != nullptr) {
137         LBSLOGI(LOCATOR_STANDARD, "%{public}s get proxy success.", __func__);
138         lock.unlock();
139         return client_;
140     }
141     lock.unlock();
142     sptr<IRemoteObject> saObject = CheckLocatorSystemAbilityLoaded();
143     return InitLocatorAgent(saObject);
144 }
145 
TryLoadLocatorSystemAbility()146 bool LocatorAgentManager::TryLoadLocatorSystemAbility()
147 {
148     auto instance = LocationSaLoadManager::GetInstance();
149     if (instance == nullptr) {
150         LBSLOGE(LOCATOR_STANDARD, "%{public}s get instance failed.", __func__);
151         return false;
152     }
153     if (instance->LoadLocationSa(LOCATION_LOCATOR_SA_ID) != ERRCODE_SUCCESS) {
154         LBSLOGE(LOCATOR_STANDARD, "%{public}s load sa failed.", __func__);
155         return false;
156     }
157     return true;
158 }
159 
InitLocatorAgent(sptr<IRemoteObject> & saObject)160 sptr<LocatorAgent> LocatorAgentManager::InitLocatorAgent(sptr<IRemoteObject>& saObject)
161 {
162     if (saObject == nullptr) {
163         return nullptr;
164     }
165     std::unique_lock<std::mutex> lock(mutex_);
166     recipient_ = sptr<LocatorAgentDeathRecipient>(new (std::nothrow) LocatorAgentDeathRecipient(*this));
167     if ((saObject->IsProxyObject()) && (!saObject->AddDeathRecipient(recipient_))) {
168         LBSLOGE(LOCATOR_STANDARD, "%{public}s: deathRecipient add failed.", __func__);
169         return nullptr;
170     }
171     LBSLOGI(LOCATOR_STANDARD, "%{public}s: client reset success.", __func__);
172     client_ = sptr<LocatorAgent>(new (std::nothrow) LocatorAgent(saObject));
173     return client_;
174 }
175 
CheckLocatorSystemAbilityLoaded()176 sptr<IRemoteObject> LocatorAgentManager::CheckLocatorSystemAbilityLoaded()
177 {
178     sptr<ISystemAbilityManager> samgr =
179         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
180     if (samgr == nullptr) {
181         LBSLOGE(LOCATOR_STANDARD, "%{public}s: get samgr failed.", __func__);
182         return nullptr;
183     }
184 
185     sptr<IRemoteObject> saObject = samgr->CheckSystemAbility(LOCATION_LOCATOR_SA_ID);
186     if (saObject == nullptr) {
187         if (!TryLoadLocatorSystemAbility()) {
188             return nullptr;
189         }
190         saObject = samgr->CheckSystemAbility(LOCATION_LOCATOR_SA_ID);
191         if (saObject == nullptr) {
192             return nullptr;
193         }
194     }
195     return saObject;
196 }
197 
ResetLocatorAgent(const wptr<IRemoteObject> & remote)198 void LocatorAgentManager::ResetLocatorAgent(const wptr<IRemoteObject> &remote)
199 {
200     std::unique_lock<std::mutex> lock(mutex_);
201     if (remote == nullptr) {
202         LBSLOGE(LOCATOR_STANDARD, "%{public}s: remote is nullptr.", __func__);
203         return;
204     }
205     if (client_ == nullptr) {
206         LBSLOGE(LOCATOR_STANDARD, "%{public}s: proxy is nullptr.", __func__);
207         return;
208     }
209     if (remote.promote() != nullptr) {
210         remote.promote()->RemoveDeathRecipient(recipient_);
211     }
212     client_ = nullptr;
213 }
214 
LocatorAgent(const sptr<IRemoteObject> & impl)215 LocatorAgent::LocatorAgent(const sptr<IRemoteObject> &impl)
216     : IRemoteProxy<ILocator>(impl)
217 {
218 }
219 
StartGnssLocating(sptr<ILocatorCallback> & callback)220 LocationErrCode LocatorAgent::StartGnssLocating(sptr<ILocatorCallback>& callback)
221 {
222     if (callback == nullptr) {
223         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
224         return ERRCODE_INVALID_PARAM;
225     }
226     auto requestConfig = std::make_unique<RequestConfig>();
227     requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX);
228     requestConfig->SetScenario(SCENE_UNSET);
229     requestConfig->SetFixNumber(0);
230 
231     MessageParcel data;
232     MessageParcel reply;
233     data.WriteInterfaceToken(GetDescriptor());
234     requestConfig->Marshalling(data);
235     data.WriteObject<IRemoteObject>(callback->AsObject());
236     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::START_LOCATING),
237         data, reply);
238 }
239 
StopGnssLocating(sptr<ILocatorCallback> & callback)240 LocationErrCode LocatorAgent::StopGnssLocating(sptr<ILocatorCallback>& callback)
241 {
242     if (callback == nullptr) {
243         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
244         return ERRCODE_INVALID_PARAM;
245     }
246     MessageParcel data;
247     MessageParcel reply;
248     data.WriteInterfaceToken(GetDescriptor());
249     data.WriteObject<IRemoteObject>(callback->AsObject());
250     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::STOP_LOCATING),
251         data, reply);
252 }
253 
RegisterNmeaMessageCallback(const sptr<INmeaMessageCallback> & callback)254 LocationErrCode LocatorAgent::RegisterNmeaMessageCallback(const sptr<INmeaMessageCallback>& callback)
255 {
256     if (callback == nullptr) {
257         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
258         return ERRCODE_INVALID_PARAM;
259     }
260     MessageParcel data;
261     MessageParcel reply;
262     data.WriteInterfaceToken(GetDescriptor());
263     data.WriteObject<IRemoteObject>(callback->AsObject());
264     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::REG_NMEA_CALLBACK_V9),
265         data, reply);
266 }
267 
UnregisterNmeaMessageCallback(const sptr<INmeaMessageCallback> & callback)268 LocationErrCode LocatorAgent::UnregisterNmeaMessageCallback(const sptr<INmeaMessageCallback>& callback)
269 {
270     if (callback == nullptr) {
271         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
272         return ERRCODE_INVALID_PARAM;
273     }
274     MessageParcel data;
275     MessageParcel reply;
276     data.WriteInterfaceToken(GetDescriptor());
277     data.WriteObject<IRemoteObject>(callback->AsObject());
278     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::UNREG_NMEA_CALLBACK_V9),
279         data, reply);
280 }
281 
RegisterGnssStatusCallback(const sptr<IGnssStatusCallback> & callback)282 LocationErrCode LocatorAgent::RegisterGnssStatusCallback(const sptr<IGnssStatusCallback>& callback)
283 {
284     if (callback == nullptr) {
285         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
286         return ERRCODE_INVALID_PARAM;
287     }
288     MessageParcel data;
289     MessageParcel reply;
290     data.WriteInterfaceToken(GetDescriptor());
291     data.WriteObject<IRemoteObject>(callback->AsObject());
292     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::REG_GNSS_STATUS_CALLBACK),
293         data, reply);
294 }
295 
UnregisterGnssStatusCallback(const sptr<IGnssStatusCallback> & callback)296 LocationErrCode LocatorAgent::UnregisterGnssStatusCallback(const sptr<IGnssStatusCallback>& callback)
297 {
298     if (callback == nullptr) {
299         LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__);
300         return ERRCODE_INVALID_PARAM;
301     }
302     MessageParcel data;
303     MessageParcel reply;
304     data.WriteInterfaceToken(GetDescriptor());
305     data.WriteObject<IRemoteObject>(callback->AsObject());
306     return SendRequestToStub(static_cast<int>(LocatorInterfaceCode::UNREG_GNSS_STATUS_CALLBACK),
307         data, reply);
308 }
309 
SendRequestToStub(const int msgId,MessageParcel & data,MessageParcel & reply)310 LocationErrCode LocatorAgent::SendRequestToStub(const int msgId, MessageParcel& data, MessageParcel& reply)
311 {
312     MessageOption option;
313     sptr<IRemoteObject> remote = Remote();
314     if (remote == nullptr) {
315         LBSLOGE(LOCATOR_STANDARD, "%{public}s remote is null", __func__);
316         return ERRCODE_SERVICE_UNAVAILABLE;
317     }
318     int error = remote->SendRequest(msgId, data, reply, option);
319     if (error != NO_ERROR) {
320         LBSLOGE(LOCATOR_STANDARD,
321             "msgid = %{public}d, SendRequestToStub error: %{public}d", msgId, error);
322         return ERRCODE_SERVICE_UNAVAILABLE;
323     }
324     return LocationErrCode(reply.ReadInt32());
325 }
326 }
327 }
328