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