1 /*
2 * Copyright (c) 2021-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 "sensor_agent_proxy.h"
17
18 #include <cstring>
19
20 #include "print_sensor_data.h"
21 #include "securec.h"
22 #include "sensor_errors.h"
23 #include "sensor_service_client.h"
24 #undef LOG_TAG
25 #define LOG_TAG "SensorAgentProxy"
26 using namespace OHOS::HiviewDFX;
27 namespace OHOS {
28 namespace Sensors {
29 namespace {
30 constexpr uint32_t MAX_SENSOR_LIST_SIZE = 0Xffff;
31 std::mutex sensorInfoMutex_;
32 SensorInfo *sensorInfos_ = nullptr;
33 std::mutex sensorActiveInfoMutex_;
34 SensorActiveInfo *sensorActiveInfos_ = nullptr;
35 int32_t sensorInfoCount_ = 0;
36 } // namespace
37
38 #define SEN_CLIENT SensorServiceClient::GetInstance()
39 std::recursive_mutex SensorAgentProxy::subscribeMutex_;
40 std::mutex SensorAgentProxy::chanelMutex_;
41
SensorAgentProxy()42 SensorAgentProxy::SensorAgentProxy()
43 : dataChannel_(new (std::nothrow) SensorDataChannel())
44 {}
45
~SensorAgentProxy()46 SensorAgentProxy::~SensorAgentProxy()
47 {
48 CALL_LOG_ENTER;
49 ClearSensorInfos();
50 }
51
GetSubscribeUserCallback(int32_t sensorId)52 std::set<RecordSensorCallback> SensorAgentProxy::GetSubscribeUserCallback(int32_t sensorId)
53 {
54 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
55 auto iter = subscribeMap_.find(sensorId);
56 if (iter == subscribeMap_.end()) {
57 SEN_HILOGE("Sensor is not subscribed");
58 return {};
59 }
60 std::set<RecordSensorCallback> callback;
61 for (const auto &it : iter->second) {
62 auto ret = callback.insert(it->callback);
63 if (!ret.second) {
64 SEN_HILOGE("callback insert fail");
65 }
66 }
67 return callback;
68 }
69
HandleSensorData(SensorEvent * events,int32_t num,void * data)70 void SensorAgentProxy::HandleSensorData(SensorEvent *events,
71 int32_t num, void *data) __attribute__((no_sanitize("cfi")))
72 {
73 CHKPV(events);
74 if (num <= 0) {
75 SEN_HILOGE("events is null or num is invalid");
76 return;
77 }
78 SensorEvent eventStream;
79 for (int32_t i = 0; i < num; ++i) {
80 eventStream = events[i];
81 auto callbacks = GetSubscribeUserCallback(eventStream.sensorTypeId);
82 for (const auto &callback : callbacks) {
83 CHKPV(callback);
84 callback(&eventStream);
85 PrintSensorData::GetInstance().ControlSensorClientPrint(callback, eventStream);
86 }
87 }
88 }
89
SetIsChannelCreated(bool isChannelCreated)90 void SensorAgentProxy::SetIsChannelCreated(bool isChannelCreated)
91 {
92 CALL_LOG_ENTER;
93 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
94 isChannelCreated_ = isChannelCreated;
95 }
96
CreateSensorDataChannel()97 int32_t SensorAgentProxy::CreateSensorDataChannel()
98 {
99 CALL_LOG_ENTER;
100 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
101 if (isChannelCreated_) {
102 SEN_HILOGI("The channel has already been created");
103 return ERR_OK;
104 }
105 CHKPR(dataChannel_, INVALID_POINTER);
106 auto ret = dataChannel_->CreateSensorDataChannel([this] (SensorEvent *events, int32_t num, void *data) {
107 this->HandleSensorData(events, num, data);
108 }, nullptr);
109 if (ret != ERR_OK) {
110 SEN_HILOGE("Create data channel failed, ret:%{public}d", ret);
111 return ret;
112 }
113 ret = SEN_CLIENT.TransferDataChannel(dataChannel_);
114 if (ret != ERR_OK) {
115 auto destroyRet = dataChannel_->DestroySensorDataChannel();
116 SEN_HILOGE("Transfer data channel failed, ret:%{public}d, destroyRet:%{public}d", ret, destroyRet);
117 return ret;
118 }
119 isChannelCreated_ = true;
120 return ERR_OK;
121 }
122
DestroySensorDataChannel()123 int32_t SensorAgentProxy::DestroySensorDataChannel()
124 {
125 CALL_LOG_ENTER;
126 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
127 if (!isChannelCreated_) {
128 SEN_HILOGI("Channel has been destroyed");
129 return ERR_OK;
130 }
131 CHKPR(dataChannel_, INVALID_POINTER);
132 int32_t ret = dataChannel_->DestroySensorDataChannel();
133 if (ret != ERR_OK) {
134 SEN_HILOGE("Destroy data channel failed, ret:%{public}d", ret);
135 return ret;
136 }
137 ret = SEN_CLIENT.DestroyDataChannel();
138 if (ret != ERR_OK) {
139 SEN_HILOGE("Destroy service data channel fail, ret:%{public}d", ret);
140 return ret;
141 }
142 isChannelCreated_ = false;
143 return ERR_OK;
144 }
145
ActivateSensor(int32_t sensorId,const SensorUser * user)146 int32_t SensorAgentProxy::ActivateSensor(int32_t sensorId, const SensorUser *user)
147 {
148 CHKPR(user, OHOS::Sensors::ERROR);
149 CHKPR(user->callback, OHOS::Sensors::ERROR);
150 if (samplingInterval_ < 0 || reportInterval_ < 0) {
151 SEN_HILOGE("SamplingPeriod or reportInterval_ is invalid");
152 return ERROR;
153 }
154 if (!SEN_CLIENT.IsValid(sensorId)) {
155 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
156 return PARAMETER_ERROR;
157 }
158 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
159 if (subscribeMap_.find(sensorId) == subscribeMap_.end()) {
160 SEN_HILOGE("Subscribe sensorId first");
161 return ERROR;
162 }
163 auto& subscribeSet = subscribeMap_[sensorId];
164 if (subscribeSet.find(user) == subscribeSet.end()) {
165 SEN_HILOGE("Subscribe user first");
166 return ERROR;
167 }
168 int32_t ret = SEN_CLIENT.EnableSensor(sensorId, samplingInterval_, reportInterval_);
169 if (ret != 0) {
170 SEN_HILOGE("Enable sensor failed, ret:%{public}d", ret);
171 subscribeSet.erase(user);
172 if (subscribeSet.empty()) {
173 subscribeMap_.erase(sensorId);
174 }
175 return ret;
176 }
177 return ret;
178 }
179
DeactivateSensor(int32_t sensorId,const SensorUser * user)180 int32_t SensorAgentProxy::DeactivateSensor(int32_t sensorId, const SensorUser *user)
181 {
182 CHKPR(user, OHOS::Sensors::ERROR);
183 CHKPR(user->callback, OHOS::Sensors::ERROR);
184 if (!SEN_CLIENT.IsValid(sensorId)) {
185 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
186 return PARAMETER_ERROR;
187 }
188 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
189 if (subscribeMap_.find(sensorId) == subscribeMap_.end()) {
190 SEN_HILOGE("Subscribe sensorId first");
191 return OHOS::Sensors::ERROR;
192 }
193 auto& subscribeSet = subscribeMap_[sensorId];
194 if (subscribeSet.find(user) == subscribeSet.end()) {
195 SEN_HILOGE("Subscribe user first");
196 return OHOS::Sensors::ERROR;
197 }
198 auto status = unsubscribeMap_[sensorId].insert(user);
199 if (!status.second) {
200 SEN_HILOGD("User has been unsubscribed");
201 }
202 subscribeSet.erase(user);
203 if (subscribeSet.empty()) {
204 subscribeMap_.erase(sensorId);
205 int32_t ret = SEN_CLIENT.DisableSensor(sensorId);
206 if (ret != 0) {
207 SEN_HILOGE("DisableSensor failed, ret:%{public}d", ret);
208 return ret;
209 }
210 }
211 return OHOS::Sensors::SUCCESS;
212 }
213
SetBatch(int32_t sensorId,const SensorUser * user,int64_t samplingInterval,int64_t reportInterval)214 int32_t SensorAgentProxy::SetBatch(int32_t sensorId, const SensorUser *user, int64_t samplingInterval,
215 int64_t reportInterval)
216 {
217 CHKPR(user, OHOS::Sensors::ERROR);
218 if (!SEN_CLIENT.IsValid(sensorId)) {
219 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
220 return PARAMETER_ERROR;
221 }
222 if (samplingInterval < 0 || reportInterval < 0) {
223 SEN_HILOGE("samplingInterval or reportInterval is invalid");
224 return OHOS::Sensors::ERROR;
225 }
226 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
227 if (subscribeMap_.find(sensorId) == subscribeMap_.end()) {
228 SEN_HILOGE("Subscribe sensorId first");
229 return OHOS::Sensors::ERROR;
230 }
231 auto& subscribeSet = subscribeMap_[sensorId];
232 if (subscribeSet.find(user) == subscribeSet.end()) {
233 SEN_HILOGE("Subscribe user first");
234 return OHOS::Sensors::ERROR;
235 }
236 samplingInterval_ = samplingInterval;
237 reportInterval_ = reportInterval;
238 return OHOS::Sensors::SUCCESS;
239 }
240
SubscribeSensor(int32_t sensorId,const SensorUser * user)241 int32_t SensorAgentProxy::SubscribeSensor(int32_t sensorId, const SensorUser *user)
242 {
243 SEN_HILOGI("In, sensorId:%{public}d", sensorId);
244 CHKPR(user, OHOS::Sensors::ERROR);
245 CHKPR(user->callback, OHOS::Sensors::ERROR);
246 if (!SEN_CLIENT.IsValid(sensorId)) {
247 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
248 return PARAMETER_ERROR;
249 }
250 int32_t ret = CreateSensorDataChannel();
251 if (ret != ERR_OK) {
252 SEN_HILOGE("Create sensor data chanel failed");
253 return OHOS::Sensors::ERROR;
254 }
255 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
256 auto status = subscribeMap_[sensorId].insert(user);
257 if (!status.second) {
258 SEN_HILOGD("User has been subscribed");
259 }
260 if (PrintSensorData::GetInstance().IsContinuousType(sensorId)) {
261 PrintSensorData::GetInstance().SavePrintUserInfo(user->callback);
262 }
263 return OHOS::Sensors::SUCCESS;
264 }
265
IsSubscribeMapEmpty() const266 bool SensorAgentProxy::IsSubscribeMapEmpty() const
267 {
268 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
269 return subscribeMap_.empty();
270 }
271
UnsubscribeSensor(int32_t sensorId,const SensorUser * user)272 int32_t SensorAgentProxy::UnsubscribeSensor(int32_t sensorId, const SensorUser *user)
273 {
274 SEN_HILOGI("In, sensorId:%{public}d", sensorId);
275 CHKPR(user, OHOS::Sensors::ERROR);
276 CHKPR(user->callback, OHOS::Sensors::ERROR);
277 if (!SEN_CLIENT.IsValid(sensorId)) {
278 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
279 return PARAMETER_ERROR;
280 }
281 {
282 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
283 if (unsubscribeMap_.find(sensorId) == unsubscribeMap_.end()) {
284 SEN_HILOGE("Deactivate sensorId first");
285 return OHOS::Sensors::ERROR;
286 }
287 auto& unsubscribeSet = unsubscribeMap_[sensorId];
288 if (unsubscribeSet.find(user) == unsubscribeSet.end()) {
289 SEN_HILOGE("Deactivate user first");
290 return OHOS::Sensors::ERROR;
291 }
292 unsubscribeSet.erase(user);
293 if (unsubscribeSet.empty()) {
294 unsubscribeMap_.erase(sensorId);
295 }
296 }
297 if (IsSubscribeMapEmpty()) {
298 int32_t ret = DestroySensorDataChannel();
299 if (ret != ERR_OK) {
300 SEN_HILOGE("Destroy data channel fail, ret:%{public}d", ret);
301 return ret;
302 }
303 }
304 if (PrintSensorData::GetInstance().IsContinuousType(sensorId)) {
305 PrintSensorData::GetInstance().RemovePrintUserInfo(user->callback);
306 }
307 return OHOS::Sensors::SUCCESS;
308 }
309
SetMode(int32_t sensorId,const SensorUser * user,int32_t mode)310 int32_t SensorAgentProxy::SetMode(int32_t sensorId, const SensorUser *user, int32_t mode)
311 {
312 CHKPR(user, OHOS::Sensors::ERROR);
313 CHKPR(user->callback, OHOS::Sensors::ERROR);
314 if (!SEN_CLIENT.IsValid(sensorId)) {
315 SEN_HILOGE("sensorId is invalid, %{public}d", sensorId);
316 return ERROR;
317 }
318 std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
319 if (subscribeMap_.find(sensorId) == subscribeMap_.end()) {
320 SEN_HILOGE("Subscribe sensorId first");
321 return OHOS::Sensors::ERROR;
322 }
323 auto& subscribeSet = subscribeMap_[sensorId];
324 if (subscribeSet.find(user) == subscribeSet.end()) {
325 SEN_HILOGE("Subscribe user first");
326 return OHOS::Sensors::ERROR;
327 }
328 return OHOS::Sensors::SUCCESS;
329 }
330
ClearSensorInfos() const331 void SensorAgentProxy::ClearSensorInfos() const
332 {
333 if (sensorActiveInfos_ != nullptr) {
334 free(sensorActiveInfos_);
335 sensorActiveInfos_ = nullptr;
336 }
337 CHKPV(sensorInfos_);
338 free(sensorInfos_);
339 sensorInfos_ = nullptr;
340 }
341
ConvertSensorInfos() const342 int32_t SensorAgentProxy::ConvertSensorInfos() const
343 {
344 CALL_LOG_ENTER;
345 std::vector<Sensor> sensorList = SEN_CLIENT.GetSensorList();
346 if (sensorList.empty()) {
347 SEN_HILOGE("Get sensor lists failed");
348 return ERROR;
349 }
350 size_t count = sensorList.size();
351 if (count > MAX_SENSOR_LIST_SIZE) {
352 SEN_HILOGE("The number of sensors exceeds the maximum value");
353 return ERROR;
354 }
355 sensorInfos_ = (SensorInfo *)malloc(sizeof(SensorInfo) * count);
356 CHKPR(sensorInfos_, ERROR);
357 for (size_t i = 0; i < count; ++i) {
358 SensorInfo *sensorInfo = sensorInfos_ + i;
359 errno_t ret = strcpy_s(sensorInfo->sensorName, NAME_MAX_LEN,
360 sensorList[i].GetSensorName().c_str());
361 CHKCR(ret == EOK, ERROR);
362 ret = strcpy_s(sensorInfo->vendorName, NAME_MAX_LEN,
363 sensorList[i].GetVendorName().c_str());
364 CHKCR(ret == EOK, ERROR);
365 ret = strcpy_s(sensorInfo->hardwareVersion, VERSION_MAX_LEN,
366 sensorList[i].GetHardwareVersion().c_str());
367 CHKCR(ret == EOK, ERROR);
368 ret = strcpy_s(sensorInfo->firmwareVersion, VERSION_MAX_LEN,
369 sensorList[i].GetFirmwareVersion().c_str());
370 CHKCR(ret == EOK, ERROR);
371 sensorInfo->sensorId = sensorList[i].GetSensorId();
372 sensorInfo->sensorTypeId = sensorList[i].GetSensorTypeId();
373 sensorInfo->maxRange = sensorList[i].GetMaxRange();
374 sensorInfo->precision = sensorList[i].GetResolution();
375 sensorInfo->power = sensorList[i].GetPower();
376 sensorInfo->minSamplePeriod = sensorList[i].GetMinSamplePeriodNs();
377 sensorInfo->maxSamplePeriod = sensorList[i].GetMaxSamplePeriodNs();
378 }
379 sensorInfoCount_ = static_cast<int32_t>(count);
380 return SUCCESS;
381 }
382
GetAllSensors(SensorInfo ** sensorInfo,int32_t * count) const383 int32_t SensorAgentProxy::GetAllSensors(SensorInfo **sensorInfo, int32_t *count) const
384 {
385 CALL_LOG_ENTER;
386 CHKPR(sensorInfo, OHOS::Sensors::ERROR);
387 CHKPR(count, OHOS::Sensors::ERROR);
388 std::lock_guard<std::mutex> listLock(sensorInfoMutex_);
389 if (sensorInfos_ == nullptr) {
390 int32_t ret = ConvertSensorInfos();
391 if (ret != SUCCESS) {
392 SEN_HILOGE("Convert sensor lists failed");
393 ClearSensorInfos();
394 return ERROR;
395 }
396 }
397 *sensorInfo = sensorInfos_;
398 *count = sensorInfoCount_;
399 return SUCCESS;
400 }
401
SuspendSensors(int32_t pid)402 int32_t SensorAgentProxy::SuspendSensors(int32_t pid)
403 {
404 CALL_LOG_ENTER;
405 if (pid < 0) {
406 SEN_HILOGE("Pid is invalid, pid:%{public}d", pid);
407 return PARAMETER_ERROR;
408 }
409 int32_t ret = SEN_CLIENT.SuspendSensors(pid);
410 if (ret != ERR_OK) {
411 SEN_HILOGD("Suspend sensors failed, ret:%{public}d", ret);
412 }
413 return ret;
414 }
415
ResumeSensors(int32_t pid)416 int32_t SensorAgentProxy::ResumeSensors(int32_t pid)
417 {
418 CALL_LOG_ENTER;
419 if (pid < 0) {
420 SEN_HILOGE("Pid is invalid, pid:%{public}d", pid);
421 return PARAMETER_ERROR;
422 }
423 int32_t ret = SEN_CLIENT.ResumeSensors(pid);
424 if (ret != ERR_OK) {
425 SEN_HILOGD("Resume sensors failed, ret:%{public}d", ret);
426 }
427 return ret;
428 }
429
GetSensorActiveInfos(int32_t pid,SensorActiveInfo ** sensorActiveInfos,int32_t * count) const430 int32_t SensorAgentProxy::GetSensorActiveInfos(int32_t pid,
431 SensorActiveInfo **sensorActiveInfos, int32_t *count) const
432 {
433 CALL_LOG_ENTER;
434 if (pid < 0) {
435 SEN_HILOGE("Pid is invalid, pid:%{public}d", pid);
436 return PARAMETER_ERROR;
437 }
438 CHKPR(sensorActiveInfos, OHOS::Sensors::ERROR);
439 CHKPR(count, OHOS::Sensors::ERROR);
440 std::lock_guard<std::mutex> sensorActiveInfoLock(sensorActiveInfoMutex_);
441 if (sensorActiveInfos_ != nullptr) {
442 free(sensorActiveInfos_);
443 sensorActiveInfos_ = nullptr;
444 }
445 std::vector<ActiveInfo> activeInfoList;
446 int32_t ret = SEN_CLIENT.GetActiveInfoList(pid, activeInfoList);
447 if (ret != ERR_OK) {
448 SEN_HILOGE("Get active info list failed, ret:%{public}d", ret);
449 return ret;
450 }
451 if (activeInfoList.empty()) {
452 SEN_HILOGD("Active info list is empty");
453 *sensorActiveInfos = nullptr;
454 *count = 0;
455 return ERR_OK;
456 }
457 size_t activeInfoCount = activeInfoList.size();
458 if (activeInfoCount > MAX_SENSOR_LIST_SIZE) {
459 SEN_HILOGE("The number of active info exceeds the maximum value, count:%{public}zu", activeInfoCount);
460 return ERROR;
461 }
462 sensorActiveInfos_ = (SensorActiveInfo *)malloc(sizeof(SensorActiveInfo) * activeInfoCount);
463 CHKPR(sensorActiveInfos_, ERROR);
464 for (size_t i = 0; i < activeInfoCount; ++i) {
465 SensorActiveInfo *curActiveInfo = sensorActiveInfos_ + i;
466 curActiveInfo->pid = activeInfoList[i].GetPid();
467 curActiveInfo->sensorId = activeInfoList[i].GetSensorId();
468 curActiveInfo->samplingPeriodNs = activeInfoList[i].GetSamplingPeriodNs();
469 curActiveInfo->maxReportDelayNs = activeInfoList[i].GetMaxReportDelayNs();
470 }
471 *sensorActiveInfos = sensorActiveInfos_;
472 *count = static_cast<int32_t>(activeInfoCount);
473 return ERR_OK;
474 }
475
Register(SensorActiveInfoCB callback)476 int32_t SensorAgentProxy::Register(SensorActiveInfoCB callback)
477 {
478 CHKPR(callback, OHOS::Sensors::ERROR);
479 CHKPR(dataChannel_, INVALID_POINTER);
480 int32_t ret = SEN_CLIENT.Register(callback, dataChannel_);
481 if (ret != ERR_OK) {
482 SEN_HILOGE("Register sensor active info callback failed, ret:%{public}d", ret);
483 }
484 return ret;
485 }
486
Unregister(SensorActiveInfoCB callback)487 int32_t SensorAgentProxy::Unregister(SensorActiveInfoCB callback)
488 {
489 CHKPR(callback, OHOS::Sensors::ERROR);
490 int32_t ret = SEN_CLIENT.Unregister(callback);
491 if (ret != ERR_OK) {
492 SEN_HILOGE("Unregister sensor active info callback failed, ret:%{public}d", ret);
493 }
494 return ret;
495 }
496
ResetSensors() const497 int32_t SensorAgentProxy::ResetSensors() const
498 {
499 int32_t ret = SEN_CLIENT.ResetSensors();
500 if (ret != ERR_OK) {
501 SEN_HILOGE("Reset sensors failed, ret:%{public}d", ret);
502 }
503 return ret;
504 }
505 } // namespace Sensors
506 } // namespace OHOS