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