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