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 #ifdef DEVICE_STATUS_SENSOR_ENABLE
17 #include "devicestatus_algorithm_manager.h"
18 
19 #include <cerrno>
20 #include <string>
21 
22 #include <linux/netlink.h>
23 #include <sys/epoll.h>
24 #include <sys/timerfd.h>
25 #include <unistd.h>
26 
27 #include "devicestatus_common.h"
28 #include "devicestatus_define.h"
29 
30 #undef LOG_TAG
31 #define LOG_TAG "AlgoMgr"
32 
33 namespace OHOS {
34 namespace Msdp {
35 namespace DeviceStatus {
36 
StartSensor(Type type)37 bool AlgoMgr::StartSensor(Type type)
38 {
39     CALL_DEBUG_ENTER;
40     int32_t sensorType = GetSensorTypeId(type);
41     if (sensorType == RET_ERR) {
42         FI_HILOGE("Failed to get sensorType");
43         return false;
44     }
45     if (!CheckSensorTypeId(sensorType)) {
46         FI_HILOGE("Sensor type mismatch");
47         return false;
48     }
49 
50     SENSOR_DATA_CB.Init();
51     if (!SENSOR_DATA_CB.RegisterCallbackSensor(sensorType)) {
52         FI_HILOGE("Failed to register callback sensor");
53         return false;
54     }
55 
56     return true;
57 }
58 
RegisterCallback(std::shared_ptr<MsdpAlgoCallback> callback)59 ErrCode AlgoMgr::RegisterCallback(std::shared_ptr<MsdpAlgoCallback> callback)
60 {
61     CALL_DEBUG_ENTER;
62     std::lock_guard lock(mutex_);
63     switch (algoType_) {
64         case Type::TYPE_ABSOLUTE_STILL: {
65             if (still_ != nullptr) {
66                 still_->RegisterCallback(callback);
67             }
68             break;
69         }
70         case Type::TYPE_HORIZONTAL_POSITION: {
71             if (horizontalPosition_ != nullptr) {
72                 horizontalPosition_->RegisterCallback(callback);
73             }
74             break;
75         }
76         case Type::TYPE_VERTICAL_POSITION: {
77             if (verticalPosition_ != nullptr) {
78                 verticalPosition_->RegisterCallback(callback);
79             }
80             break;
81         }
82         default: {
83             FI_HILOGE("Unsupported algorithm type");
84             return RET_ERR;
85         }
86     }
87     return RET_OK;
88 }
89 
UnregisterCallback()90 ErrCode AlgoMgr::UnregisterCallback()
91 {
92     CALL_DEBUG_ENTER;
93     return RET_OK;
94 }
95 
CheckSensorTypeId(int32_t sensorTypeId)96 bool AlgoMgr::CheckSensorTypeId(int32_t sensorTypeId)
97 {
98     int32_t count = -1;
99     SensorInfo *sensorInfo = nullptr;
100     int32_t ret = GetAllSensors(&sensorInfo, &count);
101     if (ret != 0) {
102         FI_HILOGE("Get all sensors failed");
103         return false;
104     }
105     SensorInfo *pt = sensorInfo + count;
106     for (SensorInfo *ps = sensorInfo; ps < pt; ++ps) {
107         if (ps->sensorTypeId == sensorTypeId) {
108             FI_HILOGI("Get sensor sensorTypeId: %{public}d", sensorTypeId);
109             return true;
110         }
111     }
112     FI_HILOGE("Get sensor failed");
113     return false;
114 }
115 
GetSensorTypeId(Type type)116 int32_t AlgoMgr::GetSensorTypeId(Type type)
117 {
118     FI_HILOGI("Get sensor type: %{public}d", type);
119     switch (type) {
120         case Type::TYPE_ABSOLUTE_STILL: {
121             return SensorTypeId::SENSOR_TYPE_ID_ACCELEROMETER;
122         }
123         case Type::TYPE_HORIZONTAL_POSITION: {
124             return SensorTypeId::SENSOR_TYPE_ID_ACCELEROMETER;
125         }
126         case Type::TYPE_VERTICAL_POSITION: {
127             return SensorTypeId::SENSOR_TYPE_ID_ACCELEROMETER;
128         }
129         default: {
130             FI_HILOGW("GetSensorTypeId failed");
131             break;
132         }
133     }
134     return RET_ERR;
135 }
136 
Enable(Type type)137 ErrCode AlgoMgr::Enable(Type type)
138 {
139     CALL_DEBUG_ENTER;
140     if (!StartSensor(type)) {
141         FI_HILOGE("sensor init failed");
142         return RET_ERR;
143     }
144     std::lock_guard lock(mutex_);
145     switch (type) {
146         case Type::TYPE_ABSOLUTE_STILL: {
147             if (still_ == nullptr) {
148                 FI_HILOGE("still_ is nullptr");
149                 still_ = std::make_shared<AlgoAbsoluteStill>();
150                 still_->Init(type);
151                 callAlgoNums_[type] = 0;
152             }
153             callAlgoNums_[type]++;
154             break;
155         }
156         case Type::TYPE_HORIZONTAL_POSITION: {
157             if (horizontalPosition_ == nullptr) {
158                 FI_HILOGE("horizontalPosition_ is nullptr");
159                 horizontalPosition_ = std::make_shared<AlgoHorizontal>();
160                 horizontalPosition_->Init(type);
161                 callAlgoNums_[type] = 0;
162             }
163             callAlgoNums_[type]++;
164             break;
165         }
166         case Type::TYPE_VERTICAL_POSITION: {
167             if (verticalPosition_ == nullptr) {
168                 FI_HILOGE("verticalPosition_ is nullptr");
169                 verticalPosition_ = std::make_shared<AlgoVertical>();
170                 verticalPosition_->Init(type);
171                 callAlgoNums_[type] = 0;
172             }
173             callAlgoNums_[type]++;
174             break;
175         }
176         default: {
177             FI_HILOGE("Unsupported algorithm type");
178             return RET_ERR;
179         }
180     }
181     algoType_ = type;
182     return RET_OK;
183 }
184 
Disable(Type type)185 ErrCode AlgoMgr::Disable(Type type)
186 {
187     CALL_DEBUG_ENTER;
188     std::lock_guard lock(mutex_);
189     callAlgoNums_[type]--;
190     FI_HILOGI("callAlgoNums_:%{public}d", callAlgoNums_[type]);
191     if (callAlgoNums_[type] != 0) {
192         FI_HILOGE("callAlgoNums_[type] is not zero");
193         return RET_ERR;
194     }
195     switch (type) {
196         case Type::TYPE_ABSOLUTE_STILL: {
197             if (still_ != nullptr) {
198                 FI_HILOGD("still_ is not nullptr");
199                 still_->Unsubscribe(type);
200                 still_ = nullptr;
201             }
202             break;
203         }
204         case Type::TYPE_HORIZONTAL_POSITION: {
205             if (horizontalPosition_ != nullptr) {
206                 FI_HILOGD("horizontalPosition_ is not nullptr");
207                 horizontalPosition_->Unsubscribe(type);
208                 horizontalPosition_ = nullptr;
209             }
210             break;
211         }
212         case Type::TYPE_VERTICAL_POSITION: {
213             if (verticalPosition_ != nullptr) {
214                 FI_HILOGD("verticalPosition_ is not nullptr");
215                 verticalPosition_->Unsubscribe(type);
216                 verticalPosition_ = nullptr;
217             }
218             break;
219         }
220         default: {
221             FI_HILOGE("Unsupported algorithm type");
222             break;
223         }
224     }
225     callAlgoNums_.erase(type);
226     UnregisterSensor(type);
227     return RET_OK;
228 }
229 
DisableCount(Type type)230 ErrCode AlgoMgr::DisableCount(Type type)
231 {
232     CALL_DEBUG_ENTER;
233     return RET_OK;
234 }
235 
UnregisterSensor(Type type)236 ErrCode AlgoMgr::UnregisterSensor(Type type)
237 {
238     CALL_DEBUG_ENTER;
239     int32_t sensorType = GetSensorTypeId(type);
240     if (sensorType == RET_ERR) {
241         FI_HILOGE("Failed to get sensorType");
242         return false;
243     }
244     if (!SENSOR_DATA_CB.UnregisterCallbackSensor(sensorType)) {
245         FI_HILOGE("Failed to unregister callback sensor");
246         return false;
247     }
248     return true;
249 }
250 
Create(void)251 extern "C" IMsdp *Create(void)
252 {
253     CALL_DEBUG_ENTER;
254     return new (std::nothrow) AlgoMgr();
255 }
256 
Destroy(const IMsdp * algorithm)257 extern "C" void Destroy(const IMsdp* algorithm)
258 {
259     CALL_DEBUG_ENTER;
260     if (algorithm != nullptr) {
261         FI_HILOGD("algorithm is not nullptr");
262         delete algorithm;
263     }
264 }
265 } // namespace DeviceStatus
266 } // namespace Msdp
267 } // namespace OHOS
268 #endif // DEVICE_STATUS_SENSOR_ENABLE
269