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 #include "devicestatus_algorithm_manager.h"
16
17 #include <cerrno>
18 #include <string>
19
20 #include <linux/netlink.h>
21 #include <sys/epoll.h>
22 #include <sys/timerfd.h>
23 #include <unistd.h>
24
25 #include "devicestatus_common.h"
26 #include "devicestatus_data_define.h"
27
28 namespace OHOS {
29 namespace Msdp {
StartSensor(DevicestatusDataUtils::DevicestatusType type)30 bool AlgoMgr::StartSensor(DevicestatusDataUtils::DevicestatusType type)
31 {
32 DEV_HILOGI(SERVICE, "Enter");
33 std::optional<int32_t> sensorIdKey = GetSensorTypeId(type);
34 if (!sensorIdKey) {
35 DEV_HILOGE(SERVICE, "Get sensor type id failed");
36 return false;
37 }
38 int32_t sensorType = sensorIdKey.value();
39 if (!CheckSensorTypeId(sensorType)) {
40 DEV_HILOGE(SERVICE, "Sensor type mismatch");
41 return false;
42 }
43
44 SensorDataCallback::GetInstance().Init();
45 if (!SensorDataCallback::GetInstance().RegisterCallbackSensor(sensorType)) {
46 DEV_HILOGE(SERVICE, "Failed to register callback sensor");
47 return false;
48 }
49
50 return true;
51 }
52
RegisterCallback(std::shared_ptr<DevicestatusMsdpInterface::MsdpAlgorithmCallback> callback)53 ErrCode AlgoMgr::RegisterCallback(std::shared_ptr<DevicestatusMsdpInterface::MsdpAlgorithmCallback> callback)
54 {
55 DEV_HILOGI(SERVICE, "Enter");
56 std::lock_guard<std::mutex> lock(mutex_);
57 switch (algoType_) {
58 case DevicestatusDataUtils::TYPE_STILL: {
59 if (still_ != nullptr) {
60 still_->RegisterCallback(callback);
61 }
62 break;
63 }
64 case DevicestatusDataUtils::TYPE_RELATIVE_STILL: {
65 if (relativeStill_ != nullptr) {
66 relativeStill_->RegisterCallback(callback);
67 }
68 break;
69 }
70 default: {
71 DEV_HILOGE(SERVICE, "Unsupported algorithm type");
72 return RET_ERR;
73 }
74 }
75 return RET_OK;
76 }
77
UnregisterCallback()78 ErrCode AlgoMgr::UnregisterCallback()
79 {
80 DEV_HILOGI(SERVICE, "Enter");
81 std::lock_guard<std::mutex> lock(mutex_);
82 switch (algoType_) {
83 case DevicestatusDataUtils::TYPE_STILL: {
84 if (still_ != nullptr) {
85 still_->UnregisterCallback();
86 }
87 break;
88 }
89 case DevicestatusDataUtils::TYPE_RELATIVE_STILL: {
90 if (relativeStill_ != nullptr) {
91 relativeStill_->UnregisterCallback();
92 }
93 break;
94 }
95 default: {
96 DEV_HILOGE(SERVICE, "Unsupported algorithm type");
97 return RET_ERR;
98 }
99 }
100 return RET_OK;
101 }
102
CheckSensorTypeId(int32_t sensorTypeId)103 bool AlgoMgr::CheckSensorTypeId(int32_t sensorTypeId)
104 {
105 int32_t count = -1;
106 SensorInfo *sensorInfo = nullptr;
107 int32_t ret = GetAllSensors(&sensorInfo, &count);
108 if (ret != 0) {
109 DEV_HILOGE(SERVICE, "Get all sensors failed");
110 return false;
111 }
112 SensorInfo *pt = sensorInfo + count;
113 for (SensorInfo *ps = sensorInfo; ps < pt; ++ps) {
114 if (sensorInfo->sensorTypeId == sensorTypeId) {
115 return true;
116 }
117 }
118 DEV_HILOGW(SERVICE, "Get sensor failed");
119 return false;
120 }
121
GetSensorTypeId(DevicestatusDataUtils::DevicestatusType type)122 std::optional<int32_t> AlgoMgr::GetSensorTypeId(DevicestatusDataUtils::DevicestatusType type)
123 {
124 DEV_HILOGI(SERVICE, "Enter");
125 switch (type) {
126 case DevicestatusDataUtils::TYPE_STILL:
127 case DevicestatusDataUtils::TYPE_RELATIVE_STILL: {
128 return std::make_optional(SensorTypeId::SENSOR_TYPE_ID_ACCELEROMETER);
129 }
130 default: {
131 DEV_HILOGW(SERVICE, "GetSensorTypeId failed");
132 break;
133 }
134 }
135 return std::nullopt;
136 }
137
Enable(DevicestatusDataUtils::DevicestatusType type)138 ErrCode AlgoMgr::Enable(DevicestatusDataUtils::DevicestatusType type)
139 {
140 DEV_HILOGI(SERVICE, "Enter");
141 std::lock_guard<std::mutex> lock(mutex_);
142 if (!StartSensor(type)) {
143 DEV_HILOGE(SERVICE, "sensor init failed");
144 return RET_ERR;
145 }
146 switch (type) {
147 case DevicestatusDataUtils::TYPE_STILL: {
148 if (still_ == nullptr) {
149 still_ = std::make_shared<AlgoAbsoluteStill>();
150 }
151 still_->Init(type);
152 break;
153 }
154 case DevicestatusDataUtils::TYPE_RELATIVE_STILL: {
155 if (relativeStill_ == nullptr) {
156 relativeStill_ = std::make_shared<AlgoRelativeStill>();
157 }
158 relativeStill_->Init(type);
159 break;
160 }
161 default: {
162 DEV_HILOGE(SERVICE, "Unsupported algorithm type");
163 return RET_ERR;
164 }
165 }
166 algoType_ = type;
167 DEV_HILOGI(SERVICE, "Exit");
168 return RET_OK;
169 }
170
Disable(DevicestatusDataUtils::DevicestatusType type)171 ErrCode AlgoMgr::Disable(DevicestatusDataUtils::DevicestatusType type)
172 {
173 DEV_HILOGI(SERVICE, "Enter");
174 std::lock_guard<std::mutex> lock(mutex_);
175 switch (type) {
176 case DevicestatusDataUtils::TYPE_STILL: {
177 if (still_ != nullptr) {
178 DEV_HILOGE(SERVICE, "still_ is not nullptr");
179 still_->Unsubscribe(type);
180 still_ = nullptr;
181 }
182 break;
183 }
184 case DevicestatusDataUtils::TYPE_RELATIVE_STILL: {
185 if (relativeStill_ != nullptr) {
186 DEV_HILOGE(SERVICE, "relativeStill_ is not nullptr");
187 relativeStill_->Unsubscribe(type);
188 relativeStill_ = nullptr;
189 }
190 break;
191 }
192 default: {
193 DEV_HILOGE(SERVICE, "Unsupported algorithm type");
194 return RET_ERR;
195 }
196 }
197 if (UnregisterSensor(type) != RET_OK) {
198 DEV_HILOGE(SERVICE, "Failed to unregister sensor");
199 return RET_ERR;
200 }
201 algoType_ = type;
202 return RET_OK;
203 }
204
UnregisterSensor(DevicestatusDataUtils::DevicestatusType type)205 ErrCode AlgoMgr::UnregisterSensor(DevicestatusDataUtils::DevicestatusType type)
206 {
207 DEV_HILOGI(SERVICE, "Enter");
208 std::optional<int32_t> sensorIdKey = GetSensorTypeId(type);
209 if (!sensorIdKey) {
210 DEV_HILOGE(SERVICE, "Get sensor type id failed");
211 return false;
212 }
213 int32_t sensorType = sensorIdKey.value();
214 if (!SensorDataCallback::GetInstance().UnregisterCallbackSensor(sensorType)) {
215 DEV_HILOGE(SERVICE, "Failed to unregister callback sensor");
216 return RET_ERR;
217 }
218 DEV_HILOGI(SERVICE, "Exit");
219 return RET_OK;
220 }
221
Create(void)222 extern "C" DevicestatusMsdpInterface *Create(void)
223 {
224 DEV_HILOGI(SERVICE, "Create algorithm library");
225 return new (std::nothrow) AlgoMgr();
226 }
227
Destroy(const DevicestatusMsdpInterface * algorithm)228 extern "C" void Destroy(const DevicestatusMsdpInterface* algorithm)
229 {
230 DEV_HILOGD(SERVICE, "Enter");
231 if (algorithm != nullptr) {
232 DEV_HILOGI(SERVICE, "Destroy algorithm library");
233 delete algorithm;
234 }
235 }
236 } // namespace Msdp
237 } // namespace OHOS
238