1 /*
2  * Copyright (C) 2024 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 "geofence_sdk.h"
17 #include "location_sa_load_manager.h"
18 #include "system_ability_definition.h"
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "location_log.h"
22 
23 namespace OHOS {
24 namespace Location {
GetInstance()25 GeofenceManager* GeofenceManager::GetInstance()
26 {
27     static GeofenceManager data;
28     return &data;
29 }
30 
GeofenceManager()31 GeofenceManager::GeofenceManager()
32 {
33 }
34 
~GeofenceManager()35 GeofenceManager::~GeofenceManager()
36 {}
37 
ResetGeofenceSdkProxy(const wptr<IRemoteObject> & remote)38 void GeofenceManager::ResetGeofenceSdkProxy(const wptr<IRemoteObject> &remote)
39 {
40     if (remote == nullptr) {
41         LBSLOGE(GEOFENCE_SDK, "%{public}s: remote is nullptr.", __func__);
42         return;
43     }
44     if (client_ == nullptr || !isServerExist_) {
45         LBSLOGE(GEOFENCE_SDK, "%{public}s: proxy is nullptr.", __func__);
46         return;
47     }
48     if (remote.promote() != nullptr) {
49         remote.promote()->RemoveDeathRecipient(recipient_);
50     }
51     isServerExist_ = false;
52     LBSLOGI(GEOFENCE_SDK, "%{public}s: finish.", __func__);
53 }
54 
GetProxy()55 sptr<GeofenceSdk> GeofenceManager::GetProxy()
56 {
57     std::unique_lock<std::mutex> lock(mutex_);
58     if (client_ != nullptr && isServerExist_) {
59         return client_;
60     }
61 
62     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
63     if (sam == nullptr) {
64         LBSLOGE(GEOFENCE_SDK, "%{public}s: get samgr failed.", __func__);
65         return nullptr;
66     }
67     sptr<IRemoteObject> obj = sam->CheckSystemAbility(LOCATION_LOCATOR_SA_ID);
68     if (obj == nullptr) {
69         LBSLOGE(GEOFENCE_SDK, "%{public}s: get remote service failed.", __func__);
70         return nullptr;
71     }
72     recipient_ = sptr<GeofenceManagerDeathRecipient>(new (std::nothrow) GeofenceManagerDeathRecipient(*this));
73     if ((obj->IsProxyObject()) && (!obj->AddDeathRecipient(recipient_))) {
74         LBSLOGE(GEOFENCE_SDK, "%{public}s: deathRecipient add failed.", __func__);
75         return nullptr;
76     }
77     isServerExist_ = true;
78     client_ = sptr<GeofenceSdk>(new (std::nothrow) GeofenceSdk(obj));
79     return client_;
80 }
81 
AddFenceV9(std::shared_ptr<GeofenceRequest> & request)82 LocationErrCode GeofenceManager::AddFenceV9(std::shared_ptr<GeofenceRequest> &request)
83 {
84     if (!SaLoadWithStatistic::InitLocationSa(LOCATION_LOCATOR_SA_ID)) {
85         return ERRCODE_SERVICE_UNAVAILABLE;
86     }
87     LBSLOGD(GEOFENCE_SDK, "GeofenceManager::AddFenceV9()");
88     sptr<GeofenceSdk> proxy = GetProxy();
89     if (proxy == nullptr) {
90         LBSLOGE(GEOFENCE_SDK, "%{public}s get proxy failed.", __func__);
91         return ERRCODE_SERVICE_UNAVAILABLE;
92     }
93     LocationErrCode errCode = proxy->AddFenceV9(request);
94     return errCode;
95 }
96 
RemoveFenceV9(std::shared_ptr<GeofenceRequest> & request)97 LocationErrCode GeofenceManager::RemoveFenceV9(std::shared_ptr<GeofenceRequest> &request)
98 {
99     if (!SaLoadWithStatistic::InitLocationSa(LOCATION_LOCATOR_SA_ID)) {
100         return ERRCODE_SERVICE_UNAVAILABLE;
101     }
102     LBSLOGD(GEOFENCE_SDK, "GeofenceManager::RemoveFenceV9()");
103     sptr<GeofenceSdk> proxy = GetProxy();
104     if (proxy == nullptr) {
105         LBSLOGE(GEOFENCE_SDK, "%{public}s get proxy failed.", __func__);
106         return ERRCODE_SERVICE_UNAVAILABLE;
107     }
108     LocationErrCode errCode = proxy->RemoveFenceV9(request);
109     return errCode;
110 }
111 
AddGnssGeofence(std::shared_ptr<GeofenceRequest> & request)112 LocationErrCode GeofenceManager::AddGnssGeofence(std::shared_ptr<GeofenceRequest>& request)
113 {
114     if (!SaLoadWithStatistic::InitLocationSa(LOCATION_LOCATOR_SA_ID)) {
115         return ERRCODE_SERVICE_UNAVAILABLE;
116     }
117     sptr<GeofenceSdk> proxy = GetProxy();
118     if (proxy == nullptr) {
119         LBSLOGE(GEOFENCE_SDK, "%{public}s get proxy failed.", __func__);
120         return ERRCODE_SERVICE_UNAVAILABLE;
121     }
122     LocationErrCode errCode = proxy->AddGnssGeofence(request);
123     return errCode;
124 }
125 
RemoveGnssGeofence(std::shared_ptr<GeofenceRequest> & request)126 LocationErrCode GeofenceManager::RemoveGnssGeofence(std::shared_ptr<GeofenceRequest>& request)
127 {
128     if (!SaLoadWithStatistic::InitLocationSa(LOCATION_LOCATOR_SA_ID)) {
129         return ERRCODE_SERVICE_UNAVAILABLE;
130     }
131     LBSLOGD(GEOFENCE_SDK, "GeofenceManager::RemoveGnssGeofence()");
132     sptr<GeofenceSdk> proxy = GetProxy();
133     if (proxy == nullptr) {
134         LBSLOGE(GEOFENCE_SDK, "%{public}s get proxy failed.", __func__);
135         return ERRCODE_SERVICE_UNAVAILABLE;
136     }
137     LocationErrCode errCode = proxy->RemoveGnssGeofence(request);
138     return errCode;
139 }
140 
GetGeofenceSupportedCoordTypes(std::vector<CoordinateSystemType> & coordinateSystemTypes)141 LocationErrCode GeofenceManager::GetGeofenceSupportedCoordTypes(
142     std::vector<CoordinateSystemType>& coordinateSystemTypes)
143 {
144     if (!SaLoadWithStatistic::InitLocationSa(LOCATION_LOCATOR_SA_ID)) {
145         return ERRCODE_SERVICE_UNAVAILABLE;
146     }
147     LBSLOGD(GEOFENCE_SDK, "GeofenceManager::%{public}s", __func__);
148     sptr<GeofenceSdk> proxy = GetProxy();
149     if (proxy == nullptr) {
150         LBSLOGE(GEOFENCE_SDK, "%{public}s get proxy failed.", __func__);
151         return ERRCODE_SERVICE_UNAVAILABLE;
152     }
153     return proxy->GetGeofenceSupportedCoordTypes(coordinateSystemTypes);
154 }
155 
GeofenceSdk(const sptr<IRemoteObject> & impl)156 GeofenceSdk::GeofenceSdk(const sptr<IRemoteObject> &impl)
157     : IRemoteProxy<ILocator>(impl)
158 {
159 }
160 
AddFenceV9(std::shared_ptr<GeofenceRequest> & request)161 LocationErrCode GeofenceSdk::AddFenceV9(std::shared_ptr<GeofenceRequest>& request)
162 {
163     return HandleGnssfenceRequest(LocatorInterfaceCode::ADD_FENCE, request);
164 }
165 
RemoveFenceV9(std::shared_ptr<GeofenceRequest> & request)166 LocationErrCode GeofenceSdk::RemoveFenceV9(std::shared_ptr<GeofenceRequest>& request)
167 {
168     return HandleGnssfenceRequest(LocatorInterfaceCode::REMOVE_FENCE, request);
169 }
170 
HandleGnssfenceRequest(LocatorInterfaceCode code,std::shared_ptr<GeofenceRequest> & request)171 LocationErrCode GeofenceSdk::HandleGnssfenceRequest(
172     LocatorInterfaceCode code, std::shared_ptr<GeofenceRequest>& request)
173 {
174     if (request == nullptr) {
175         return ERRCODE_INVALID_PARAM;
176     }
177     MessageParcel data;
178     MessageParcel reply;
179     if (!data.WriteInterfaceToken(GetDescriptor())) {
180         LBSLOGE(GEOFENCE_SDK, "%{public}s WriteInterfaceToken failed", __func__);
181         return ERRCODE_SERVICE_UNAVAILABLE;
182     }
183     request->Marshalling(data);
184     LocationErrCode errorCode = SendMsgWithDataReplyV9(static_cast<int>(code), data, reply);
185     LBSLOGI(GEOFENCE_SDK, "Transact ErrCodes = %{public}d", errorCode);
186     return errorCode;
187 }
188 
AddGnssGeofence(std::shared_ptr<GeofenceRequest> & request)189 LocationErrCode GeofenceSdk::AddGnssGeofence(std::shared_ptr<GeofenceRequest>& request)
190 {
191     return HandleGnssfenceRequest(LocatorInterfaceCode::ADD_GNSS_GEOFENCE, request);
192 }
193 
RemoveGnssGeofence(std::shared_ptr<GeofenceRequest> & request)194 LocationErrCode GeofenceSdk::RemoveGnssGeofence(std::shared_ptr<GeofenceRequest>& request)
195 {
196     if (request == nullptr) {
197         return ERRCODE_INVALID_PARAM;
198     }
199     MessageParcel data;
200     MessageParcel reply;
201     if (!data.WriteInterfaceToken(GetDescriptor())) {
202         return ERRCODE_SERVICE_UNAVAILABLE;
203     }
204     data.WriteInt32(request->GetFenceId());
205     LocationErrCode errorCode = SendMsgWithDataReplyV9(
206         static_cast<int>(LocatorInterfaceCode::REMOVE_GNSS_GEOFENCE), data, reply);
207     LBSLOGI(GEOFENCE_SDK, "Transact ErrCodes = %{public}d", errorCode);
208     return errorCode;
209 }
210 
GetGeofenceSupportedCoordTypes(std::vector<CoordinateSystemType> & coordinateSystemTypes)211 LocationErrCode GeofenceSdk::GetGeofenceSupportedCoordTypes(
212     std::vector<CoordinateSystemType>& coordinateSystemTypes)
213 {
214     MessageParcel data;
215     if (!data.WriteInterfaceToken(GetDescriptor())) {
216         return ERRCODE_SERVICE_UNAVAILABLE;
217     }
218     MessageParcel reply;
219     LocationErrCode errorCode = SendMsgWithDataReplyV9(
220         static_cast<int>(LocatorInterfaceCode::GET_GEOFENCE_SUPPORT_COORDINATE_SYSTEM_TYPE), data, reply);
221     LBSLOGD(GEOFENCE_SDK, "Proxy::%{public}s Transact ErrCodes = %{public}d", __func__, errorCode);
222     int size = reply.ReadInt32();
223     size = size > COORDINATE_SYSTEM_TYPE_SIZE ? COORDINATE_SYSTEM_TYPE_SIZE : size;
224     for (int i = 0; i < size; i++) {
225         int coordinateSystemType = reply.ReadInt32();
226         coordinateSystemTypes.push_back(static_cast<CoordinateSystemType>(coordinateSystemType));
227     }
228     return errorCode;
229 }
230 
SendMsgWithDataReplyV9(const int msgId,MessageParcel & data,MessageParcel & reply)231 LocationErrCode GeofenceSdk::SendMsgWithDataReplyV9(const int msgId, MessageParcel& data, MessageParcel& reply)
232 {
233     MessageOption option;
234     sptr<IRemoteObject> remote = Remote();
235     if (remote == nullptr) {
236         LBSLOGE(GEOFENCE_SDK, "SendMsgWithDataReply remote is null");
237         return ERRCODE_SERVICE_UNAVAILABLE;
238     }
239     LBSLOGI(GEOFENCE_SDK, "%{public}s: %{public}d", __func__, msgId);
240     int error = remote->SendRequest(msgId, data, reply, option);
241     if (error != NO_ERROR) {
242         LBSLOGE(GEOFENCE_SDK, "msgid = %{public}d, send request error: %{public}d", msgId, error);
243         return ERRCODE_SERVICE_UNAVAILABLE;
244     }
245     return LocationErrCode(reply.ReadInt32());
246 }
247 }
248 }
249