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