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