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_request.h"
17 #include <parcel.h>
18 #include "common_utils.h"
19 #ifdef NOTIFICATION_ENABLE
20 #include "notification_request.h"
21 #endif
22
23 namespace OHOS {
24 namespace Location {
GeofenceRequest()25 GeofenceRequest::GeofenceRequest()
26 {
27 callback_ = nullptr;
28 scenario_ = -1;
29 fenceId_ = -1;
30 uid_ = 0;
31 appAliveStatus_ = true;
32 }
33
GeofenceRequest(GeofenceRequest & geofenceRequest)34 GeofenceRequest::GeofenceRequest(GeofenceRequest& geofenceRequest)
35 {
36 this->SetGeofence(geofenceRequest.GetGeofence());
37 this->SetScenario(geofenceRequest.GetScenario());
38 Parcel agentParcelData;
39 geofenceRequest.GetWantAgentParcelData(agentParcelData);
40 this->SetWantAgentParcelData(agentParcelData);
41 this->SetGeofenceTransitionEventList(geofenceRequest.GetGeofenceTransitionEventList());
42 #ifdef NOTIFICATION_ENABLE
43 this->SetNotificationRequestList(geofenceRequest.GetNotificationRequestList());
44 #endif
45 this->SetGeofenceTransitionCallback(geofenceRequest.GetGeofenceTransitionCallback());
46 this->SetFenceId(geofenceRequest.GetFenceId());
47 this->SetBundleName(geofenceRequest.GetBundleName());
48 }
49
~GeofenceRequest()50 GeofenceRequest::~GeofenceRequest() {}
51
GetGeofence()52 GeoFence GeofenceRequest::GetGeofence()
53 {
54 return geofence_;
55 }
56
SetGeofence(GeoFence geofence)57 void GeofenceRequest::SetGeofence(GeoFence geofence)
58 {
59 geofence_ = geofence;
60 }
61
GetScenario()62 int GeofenceRequest::GetScenario()
63 {
64 return scenario_;
65 }
66
SetScenario(int scenario)67 void GeofenceRequest::SetScenario(int scenario)
68 {
69 scenario_ = scenario;
70 }
71
SetWantAgentParcelData(const Parcel & data)72 void GeofenceRequest::SetWantAgentParcelData(const Parcel& data)
73 {
74 std::vector<char>().swap(wantAgentBuffer_);
75 char *first = reinterpret_cast<char*>(data.GetData());
76 char *last = first + data.GetDataSize();
77 wantAgentBuffer_.assign(first, last);
78 }
79
GetWantAgentParcelData(Parcel & data)80 bool GeofenceRequest::GetWantAgentParcelData(Parcel& data)
81 {
82 if (wantAgentBuffer_.empty()) {
83 return false;
84 }
85 void* tempBuffer = malloc(wantAgentBuffer_.size());
86 if (tempBuffer == NULL) {
87 return false;
88 }
89 errno_t ret = memcpy_s(tempBuffer, wantAgentBuffer_.size(), wantAgentBuffer_.data(), wantAgentBuffer_.size());
90 if (ret != EOK) {
91 LBSLOGE(LOCATOR, "memcpy_s failed, error code:%{public}d", ret);
92 free(tempBuffer);
93 return false;
94 }
95 bool result = data.ParseFrom(reinterpret_cast<uintptr_t>(tempBuffer), wantAgentBuffer_.size());
96 if (!result) {
97 LBSLOGE(LOCATOR, "ParseFrom failed");
98 free(tempBuffer);
99 return false;
100 }
101 return result;
102 }
103
GetGeofenceTransitionEventList()104 std::vector<GeofenceTransitionEvent> GeofenceRequest::GetGeofenceTransitionEventList()
105 {
106 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
107 return transitionStatusList_;
108 }
109
SetGeofenceTransitionEvent(GeofenceTransitionEvent status)110 void GeofenceRequest::SetGeofenceTransitionEvent(GeofenceTransitionEvent status)
111 {
112 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
113 transitionStatusList_.push_back(status);
114 }
115
SetGeofenceTransitionEventList(std::vector<GeofenceTransitionEvent> statusList)116 void GeofenceRequest::SetGeofenceTransitionEventList(std::vector<GeofenceTransitionEvent> statusList)
117 {
118 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
119 for (auto it = statusList.begin(); it != statusList.end(); ++it) {
120 transitionStatusList_.push_back(*it);
121 }
122 }
123
124 #ifdef NOTIFICATION_ENABLE
GetNotificationRequestList()125 std::vector<std::shared_ptr<OHOS::Notification::NotificationRequest>> GeofenceRequest::GetNotificationRequestList()
126 {
127 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
128 return notificationRequestList_;
129 }
130
SetNotificationRequest(std::shared_ptr<OHOS::Notification::NotificationRequest> request)131 void GeofenceRequest::SetNotificationRequest(std::shared_ptr<OHOS::Notification::NotificationRequest> request)
132 {
133 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
134 notificationRequestList_.push_back(request);
135 }
136
SetNotificationRequestList(std::vector<std::shared_ptr<OHOS::Notification::NotificationRequest>> requestList)137 void GeofenceRequest::SetNotificationRequestList(
138 std::vector<std::shared_ptr<OHOS::Notification::NotificationRequest>> requestList)
139 {
140 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
141 for (auto it = requestList.begin(); it != requestList.end(); ++it) {
142 notificationRequestList_.push_back(*it);
143 }
144 }
145 #endif
146
SetGeofenceTransitionCallback(const sptr<IRemoteObject> & callback)147 void GeofenceRequest::SetGeofenceTransitionCallback(const sptr<IRemoteObject>& callback)
148 {
149 callback_ = callback;
150 }
151
GetGeofenceTransitionCallback()152 sptr<IRemoteObject> GeofenceRequest::GetGeofenceTransitionCallback()
153 {
154 return callback_;
155 }
156
GetFenceId()157 int GeofenceRequest::GetFenceId()
158 {
159 return fenceId_;
160 }
161
SetFenceId(int fenceId)162 void GeofenceRequest::SetFenceId(int fenceId)
163 {
164 fenceId_ = fenceId;
165 }
166
GetBundleName()167 const std::string& GeofenceRequest::GetBundleName()
168 {
169 return bundleName_;
170 }
171
SetBundleName(const std::string & bundleName)172 void GeofenceRequest::SetBundleName(const std::string& bundleName)
173 {
174 bundleName_ = bundleName;
175 }
176
GetUid()177 int32_t GeofenceRequest::GetUid()
178 {
179 return uid_;
180 }
181
SetUid(int32_t uid)182 void GeofenceRequest::SetUid(int32_t uid)
183 {
184 uid_ = uid;
185 }
186
GetAppAliveStatus()187 bool GeofenceRequest::GetAppAliveStatus()
188 {
189 return appAliveStatus_;
190 }
191
GetRequestExpirationTime()192 int64_t GeofenceRequest::GetRequestExpirationTime()
193 {
194 return requestExpirationTime_;
195 }
196
SetRequestExpirationTime(int64_t requestExpirationTime)197 void GeofenceRequest::SetRequestExpirationTime(int64_t requestExpirationTime)
198 {
199 requestExpirationTime_ = requestExpirationTime;
200 }
201
SetAppAliveStatus(bool appAliveStatus)202 void GeofenceRequest::SetAppAliveStatus(bool appAliveStatus)
203 {
204 appAliveStatus_ = appAliveStatus;
205 }
206
ReadFromParcel(Parcel & data)207 void GeofenceRequest::ReadFromParcel(Parcel& data)
208 {
209 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
210 scenario_ = data.ReadInt32();
211 geofence_.latitude = data.ReadDouble();
212 geofence_.longitude = data.ReadDouble();
213 geofence_.radius = data.ReadDouble();
214 geofence_.expiration = data.ReadDouble();
215 geofence_.coordinateSystemType = static_cast<CoordinateSystemType>(data.ReadInt32());
216 int monitorGeofenceTransitionSize = data.ReadInt32();
217 if (monitorGeofenceTransitionSize > MAX_TRANSITION_SIZE) {
218 LBSLOGE(LOCATOR, "fence transition list size should not be greater than 3");
219 return;
220 }
221 for (int i = 0; i < monitorGeofenceTransitionSize; i++) {
222 transitionStatusList_.push_back(static_cast<GeofenceTransitionEvent>(data.ReadInt32()));
223 }
224 #ifdef NOTIFICATION_ENABLE
225 int requestSize = data.ReadInt32();
226 if (requestSize > MAX_NOTIFICATION_REQUEST_LIST_SIZE) {
227 LBSLOGE(LOCATOR, "request size should not be greater than 3");
228 return;
229 }
230 for (int i = 0; i < requestSize; i++) {
231 std::shared_ptr<OHOS::Notification::NotificationRequest> request(
232 OHOS::Notification::NotificationRequest::Unmarshalling(data));
233 if (request != nullptr) {
234 notificationRequestList_.push_back(request);
235 }
236 }
237 #endif
238 callback_ = data.ReadObject<IRemoteObject>();
239 data.ReadString(bundleName_);
240 uid_ = data.ReadInt32();
241 uint32_t size = data.ReadUint32();
242 const uint8_t *bufferPtr = data.ReadBuffer(size);
243 std::vector<char>().swap(wantAgentBuffer_);
244 if (bufferPtr != nullptr) {
245 wantAgentBuffer_.assign(bufferPtr, bufferPtr + size);
246 bufferPtr = nullptr;
247 }
248 }
249
Marshalling(Parcel & parcel) const250 bool GeofenceRequest::Marshalling(Parcel& parcel) const
251 {
252 std::unique_lock<std::mutex> lock(geofenceRequestMutex_);
253 parcel.WriteInt32(scenario_);
254 parcel.WriteDouble(geofence_.latitude);
255 parcel.WriteDouble(geofence_.longitude);
256 parcel.WriteDouble(geofence_.radius);
257 parcel.WriteDouble(geofence_.expiration);
258 parcel.WriteInt32(static_cast<int>(geofence_.coordinateSystemType));
259 if (transitionStatusList_.size() > MAX_TRANSITION_SIZE) {
260 LBSLOGE(LOCATOR, "fence transition list size should not be greater than 3");
261 return false;
262 }
263 parcel.WriteInt32(transitionStatusList_.size());
264 for (size_t i = 0; i < transitionStatusList_.size(); i++) {
265 parcel.WriteInt32(static_cast<int>(transitionStatusList_[i]));
266 }
267 #ifdef NOTIFICATION_ENABLE
268 parcel.WriteInt32(notificationRequestList_.size());
269 if (notificationRequestList_.size() > MAX_NOTIFICATION_REQUEST_LIST_SIZE) {
270 LBSLOGE(LOCATOR, "request size should not be greater than 3");
271 return false;
272 }
273 for (size_t i = 0; i < notificationRequestList_.size(); i++) {
274 notificationRequestList_[i]->Marshalling(parcel);
275 }
276 #endif
277 parcel.WriteRemoteObject(callback_);
278 parcel.WriteString(bundleName_);
279 parcel.WriteInt32(uid_);
280 parcel.WriteUint32(wantAgentBuffer_.size());
281 parcel.WriteBuffer(wantAgentBuffer_.data(), wantAgentBuffer_.size());
282 return true;
283 }
284
UnmarshallingShared(Parcel & parcel)285 std::shared_ptr<GeofenceRequest> GeofenceRequest::UnmarshallingShared(Parcel& parcel)
286 {
287 std::shared_ptr<GeofenceRequest> geofenceRequest = std::make_shared<GeofenceRequest>();
288 geofenceRequest->ReadFromParcel(parcel);
289 return geofenceRequest;
290 }
291
Unmarshalling(Parcel & parcel)292 GeofenceRequest* GeofenceRequest::Unmarshalling(Parcel& parcel)
293 {
294 auto geofenceRequest = new GeofenceRequest();
295 geofenceRequest->ReadFromParcel(parcel);
296 return geofenceRequest;
297 }
298 } // namespace Location
299 } // namespace OHOS