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