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