• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_data_callback.h"
17 
18 #include <cmath>
19 #include <cstdio>
20 
21 #include "devicestatus_common.h"
22 
23 namespace OHOS {
24 namespace Msdp {
25 namespace {
26 constexpr int32_t RATE_MILLISEC  = 100100100;
27 } // namespace
28 
~SensorDataCallback()29 SensorDataCallback::~SensorDataCallback()
30 {
31     std::lock_guard<std::mutex> lock(mutex_);
32     algoMap_.clear();
33     alive_ = false;
34     if (algorithmThread_ == nullptr) {
35         DEV_HILOGE(SERVICE, "algorithmThread_ is nullptr");
36         return;
37     }
38     if (!algorithmThread_->joinable()) {
39         DEV_HILOGE(SERVICE, "thread join fail");
40         return;
41     }
42     sem_post(&sem_);
43     algorithmThread_->join();
44     accelDataList_.clear();
45 }
46 
Init()47 void SensorDataCallback::Init()
48 {
49     DEV_HILOGI(SERVICE, "SensorDataCallback is initiated");
50     std::lock_guard<std::mutex> lock(mutex_);
51     if (algorithmThread_ == nullptr) {
52         DEV_HILOGE(SERVICE, "algorithmThread_ is nullptr, create");
53         algorithmThread_ = std::make_unique<std::thread>(&SensorDataCallback::AlgorithmLoop, this);
54     }
55 }
56 
Unregister()57 bool SensorDataCallback::Unregister()
58 {
59     DEV_HILOGI(SERVICE, "Unregister");
60     bool ret = UnregisterCallbackSensor(SensorTypeId::SENSOR_TYPE_ID_ACCELEROMETER);
61     if (!ret) {
62         DEV_HILOGE(SERVICE, "UnregisterCallbackSensor failed");
63         return false;
64     }
65     alive_ = false;
66     if (!algorithmThread_->joinable()) {
67         DEV_HILOGE(SERVICE, "thread join fail");
68         return false;
69     }
70     sem_post(&sem_);
71     algorithmThread_->join();
72     return ret;
73 }
74 
SubscribeSensorEvent(int32_t sensorTypeId,SensorCallback callback)75 bool SensorDataCallback::SubscribeSensorEvent(int32_t sensorTypeId, SensorCallback callback)
76 {
77     DEV_HILOGI(SERVICE, "SubscribeSensorEvent");
78     std::lock_guard<std::mutex> lock(mutex_);
79     auto ret = algoMap_.insert(std::pair(sensorTypeId, callback));
80     if (!ret.second) {
81         DEV_HILOGE(SERVICE, "SensorCallback is duplicated");
82         return false;
83     }
84     DEV_HILOGI(SERVICE, "Exit");
85     return false;
86 }
87 
UnsubscribeSensorEvent(int32_t sensorTypeId,SensorCallback callback)88 bool SensorDataCallback::UnsubscribeSensorEvent(int32_t sensorTypeId, SensorCallback callback)
89 {
90     DEV_HILOGI(SERVICE, "UnsubscribeSensorEvent");
91     std::lock_guard<std::mutex> lock(mutex_);
92     auto callbackIter = algoMap_.find(sensorTypeId);
93     if (callbackIter != algoMap_.end()) {
94         DEV_HILOGE(SERVICE, "erase sensorTypeId:%{public}d", sensorTypeId);
95         algoMap_.erase(sensorTypeId);
96     }
97     DEV_HILOGI(SERVICE, "exit");
98     return true;
99 }
100 
NotifyCallback(int32_t sensorTypeId,AccelData * data)101 bool SensorDataCallback::NotifyCallback(int32_t sensorTypeId, AccelData* data)
102 {
103     if (data == nullptr) {
104         DEV_HILOGE(SERVICE, "data is nullptr");
105         return false;
106     }
107     std::lock_guard<std::mutex> lock(mutex_);
108     for (auto iter = algoMap_.begin(); iter != algoMap_.end(); ++iter) {
109         (iter->second)(sensorTypeId, data);
110     }
111     return true;
112 }
113 
PushData(int32_t sensorTypeId,uint8_t * data)114 bool SensorDataCallback::PushData(int32_t sensorTypeId, uint8_t* data)
115 {
116     if (data == nullptr) {
117         DEV_HILOGE(SERVICE, "data is nullptr");
118         return false;
119     }
120     AccelData* acclData = reinterpret_cast<AccelData*>(data);
121     if ((abs(acclData->x) > ACC_VALID_THRHD) ||
122         (abs(acclData->y) > ACC_VALID_THRHD) ||
123         (abs(acclData->z) > ACC_VALID_THRHD)) {
124         DEV_HILOGE(SERVICE, "Acc data is invalid");
125         return false;
126     }
127     std::lock_guard<std::mutex> lock(mutex_);
128     accelDataList_.emplace_back(*acclData);
129     sem_post(&sem_);
130     return true;
131 }
132 
PopData(int32_t sensorTypeId,AccelData & data)133 bool SensorDataCallback::PopData(int32_t sensorTypeId, AccelData& data)
134 {
135     if (sensorTypeId != SENSOR_TYPE_ID_ACCELEROMETER) {
136         DEV_HILOGE(SERVICE, "invalid sensorTypeId:%{public}d", sensorTypeId);
137         return false;
138     }
139     std::lock_guard<std::mutex> lock(mutex_);
140     if (accelDataList_.empty()) {
141         DEV_HILOGD(SERVICE, "No accel data");
142         return false;
143     }
144     data = accelDataList_.front();
145     accelDataList_.pop_front();
146     return true;
147 }
148 
SensorDataCallbackImpl(SensorEvent * event)149 static void SensorDataCallbackImpl(SensorEvent *event)
150 {
151     if (event == nullptr) {
152         DEV_HILOGE(SERVICE, "SensorDataCallbackImpl event is nullptr");
153         return;
154     }
155     SensorDataCallback::GetInstance().PushData(event->sensorTypeId, event->data);
156 }
157 
RegisterCallbackSensor(int32_t sensorTypeId)158 bool SensorDataCallback::RegisterCallbackSensor(int32_t sensorTypeId)
159 {
160     std::lock_guard<std::mutex> lock(mutex_);
161     user_.callback = SensorDataCallbackImpl;
162     int32_t ret = SubscribeSensor(sensorTypeId, &user_);
163     if (ret != 0) {
164         DEV_HILOGE(SERVICE, "SubscribeSensor failed");
165         return false;
166     }
167     ret = SetBatch(sensorTypeId, &user_, RATE_MILLISEC, RATE_MILLISEC);
168     if (ret != 0) {
169         DEV_HILOGE(SERVICE, "SetBatch failed");
170         return false;
171     }
172     ret = ActivateSensor(sensorTypeId, &user_);
173     if (ret != 0) {
174         DEV_HILOGE(SERVICE, "ActivateSensor failed");
175         return false;
176     }
177     return true;
178 }
179 
UnregisterCallbackSensor(int32_t sensorTypeId)180 bool SensorDataCallback::UnregisterCallbackSensor(int32_t sensorTypeId)
181 {
182     DEV_HILOGI(SERVICE, "enter");
183     std::lock_guard<std::mutex> lock(mutex_);
184     if (user_.callback == nullptr) {
185         DEV_HILOGE(SERVICE, "callback is nullptr");
186         return false;
187     }
188     int32_t ret = DeactivateSensor(sensorTypeId, &user_);
189     if (ret != 0) {
190         DEV_HILOGE(SERVICE, "DeactivateSensor failed");
191         return false;
192     }
193     ret = UnsubscribeSensor(sensorTypeId, &user_);
194     if (ret != 0) {
195         DEV_HILOGE(SERVICE, "UnsubscribeSensor failed");
196         return false;
197     }
198     return true;
199 }
200 
AlgorithmLoop()201 void SensorDataCallback::AlgorithmLoop()
202 {
203     DEV_HILOGI(SERVICE, "enter");
204     while (alive_) {
205         sem_wait(&sem_);
206         HandleSensorEvent();
207     }
208     DEV_HILOGI(SERVICE, "exit");
209 }
210 
HandleSensorEvent()211 void SensorDataCallback::HandleSensorEvent()
212 {
213     DEV_HILOGI(SERVICE, "enter");
214     AccelData acclData;
215     if (PopData(SENSOR_TYPE_ID_ACCELEROMETER, acclData)) {
216         NotifyCallback(SENSOR_TYPE_ID_ACCELEROMETER, static_cast<AccelData*>(&acclData));
217     }
218 }
219 } // namespace Msdp
220 } // namespace OHOS
221