1 /*
2 * Copyright (c) 2022 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 "devicestatus_sensor_rdb.h"
17
18 #include <string>
19 #include <cerrno>
20 #include <sys/epoll.h>
21 #include <sys/timerfd.h>
22 #include <unistd.h>
23 #include <linux/netlink.h>
24
25 #include "devicestatus_common.h"
26
27 using namespace OHOS::NativeRdb;
28 namespace OHOS {
29 namespace Msdp {
30 namespace {
31 const std::string DATABASE_NAME = "/data/MsdpStub.db";
32 constexpr int32_t TIMER_INTERVAL = 3;
33 constexpr int32_t ERR_INVALID_FD = -1;
34 constexpr int32_t READ_RDB_WAIT_TIME = 30;
35 std::unique_ptr<DevicestatusSensorRdb> g_msdpRdb = std::make_unique<DevicestatusSensorRdb>();
36 constexpr int32_t ERR_NG = -1;
37 DevicestatusSensorRdb* g_rdb;
38 }
39
Init()40 bool DevicestatusSensorRdb::Init()
41 {
42 DEV_HILOGD(SERVICE, "Enter");
43 InitRdbStore();
44 InitTimer();
45 StartThread();
46 DEV_HILOGD(SERVICE, "Exit");
47 return true;
48 }
49
InitRdbStore()50 void DevicestatusSensorRdb::InitRdbStore()
51 {}
52
RegisterCallback(const std::shared_ptr<DevicestatusSensorHdiCallback> & callback)53 void DevicestatusSensorRdb::RegisterCallback(const std::shared_ptr<DevicestatusSensorHdiCallback>& callback)
54 {
55 callbacksImpl_ = callback;
56 }
57
UnregisterCallback()58 void DevicestatusSensorRdb::UnregisterCallback()
59 {
60 callbacksImpl_ = nullptr;
61 }
62
Enable()63 void DevicestatusSensorRdb::Enable()
64 {
65 DEV_HILOGD(SERVICE, "Enter");
66 Init();
67 SubscribeHallSensor();
68 DEV_HILOGD(SERVICE, "Exit");
69 }
70
Disable()71 void DevicestatusSensorRdb::Disable()
72 {
73 DEV_HILOGD(SERVICE, "Enter");
74 CloseTimer();
75 UnSubscribeHallSensor();
76 DEV_HILOGD(SERVICE, "Exit");
77 }
78
79
NotifyMsdpImpl(const DevicestatusDataUtils::DevicestatusData & data)80 ErrCode DevicestatusSensorRdb::NotifyMsdpImpl(const DevicestatusDataUtils::DevicestatusData& data)
81 {
82 DEV_HILOGD(SERVICE, "Enter");
83 if (g_rdb == nullptr) {
84 DEV_HILOGD(SERVICE, "g_rdb is nullptr");
85 return ERR_NG;
86 }
87 if (g_rdb->GetCallbacksImpl() == nullptr) {
88 DEV_HILOGD(SERVICE, "callbacksImpl is nullptr");
89 return ERR_NG;
90 }
91 g_rdb->GetCallbacksImpl()->OnSensorHdiResult(data);
92
93 return ERR_OK;
94 }
95
SaveRdbData(const DevicestatusDataUtils::DevicestatusData & data)96 DevicestatusDataUtils::DevicestatusData DevicestatusSensorRdb::SaveRdbData(
97 const DevicestatusDataUtils::DevicestatusData& data)
98 {
99 for (auto iter = rdbDataMap_.begin(); iter != rdbDataMap_.end(); ++iter) {
100 if (iter->first == data.type) {
101 if (iter->second != data.value) {
102 notifyFlag_ = true;
103 iter->second = data.value;
104 }
105 DEV_HILOGD(SERVICE, "data is not changed");
106 return data;
107 }
108 }
109
110 rdbDataMap_.insert(std::make_pair(data.type, data.value));
111 notifyFlag_ = true;
112
113 DEV_HILOGD(SERVICE, "devicestatusType_ = %{public}d, devicestatusStatus_ = %{public}d",
114 devicestatusType_, devicestatusStatus_);
115
116 return data;
117 }
118
TrigerData(const std::unique_ptr<NativeRdb::ResultSet> & resultSet)119 int32_t DevicestatusSensorRdb::TrigerData(const std::unique_ptr<NativeRdb::ResultSet> &resultSet)
120 {
121 int32_t columnIndex;
122 int32_t intVal;
123
124 if (resultSet == nullptr) {
125 DEV_HILOGE(SERVICE, "resultSet is nullprt");
126 return -1;
127 }
128 int32_t ret = resultSet->GetColumnIndex("ID", columnIndex);
129 DEV_HILOGD(SERVICE, "TrigerDatabaseObserver GetColumnIndex = %{public}d", columnIndex);
130 if (ret != ERR_OK) {
131 DEV_HILOGE(SERVICE, "CheckID: GetColumnIndex failed");
132 return -1;
133 }
134 ret = resultSet->GetInt(columnIndex, intVal);
135 DEV_HILOGD(SERVICE, "ret = %{public}d, id = %{public}d", ret, intVal);
136 if (ret != ERR_OK) {
137 DEV_HILOGE(SERVICE, "CheckID: GetValue failed");
138 return -1;
139 }
140
141 ret = resultSet->GetColumnIndex("DEVICESTATUS_TYPE", columnIndex);
142 DEV_HILOGD(SERVICE, "DEVICESTATUS_TYPE GetColumnIndex = %{public}d", columnIndex);
143 if (ret != ERR_OK) {
144 DEV_HILOGE(SERVICE, "CheckDevicestatusType: GetColumnIndex failed");
145 return -1;
146 }
147 ret = resultSet->GetInt(columnIndex, intVal);
148 DEV_HILOGD(SERVICE, "ret = %{public}d, DevicestatusType = %{public}d", ret, intVal);
149 devicestatusType_ = intVal;
150 if (ret != ERR_OK) {
151 DEV_HILOGE(SERVICE, "CheckDevicestatusType: GetValue failed");
152 return -1;
153 }
154
155 ret = resultSet->GetColumnIndex("DEVICESTATUS_STATUS", columnIndex);
156 DEV_HILOGD(SERVICE, "DEVICESTATUS_STATUS GetColumnIndex = %{public}d", columnIndex);
157 if (ret != ERR_OK) {
158 DEV_HILOGE(SERVICE, "CheckDevicestatusStatus: GetColumnIndex failed");
159 return -1;
160 }
161 ret = resultSet->GetInt(columnIndex, intVal);
162 DEV_HILOGD(SERVICE, "ret = %{public}d, DevicestatusStatus = %{public}d", ret, intVal);
163 devicestatusStatus_ = intVal;
164 if (ret != ERR_OK) {
165 DEV_HILOGE(SERVICE, "CheckDevicestatusStatus: GetValue failed");
166 return -1;
167 }
168
169 return ERR_OK;
170 }
171
TrigerDatabaseObserver()172 int32_t DevicestatusSensorRdb::TrigerDatabaseObserver()
173 {
174 DEV_HILOGD(SERVICE, "Enter");
175
176 if (store_ == nullptr) {
177 sleep(READ_RDB_WAIT_TIME);
178 InitRdbStore();
179 return -1;
180 }
181
182 std::unique_ptr<ResultSet> resultSet =
183 store_->QuerySql("SELECT * FROM DEVICESTATUSSENSOR WHERE ID = (SELECT max(ID) from DEVICESTATUSSENSOR)");
184
185 if (resultSet == nullptr) {
186 DEV_HILOGE(SERVICE, "database is not exist");
187 return -1;
188 }
189
190 int32_t ret = resultSet->GoToFirstRow();
191 DEV_HILOGD(SERVICE, "GoToFirstRow = %{public}d", ret);
192 if (ret != ERR_OK) {
193 sleep(READ_RDB_WAIT_TIME);
194 DEV_HILOGE(SERVICE, "database observer is null");
195 return -1;
196 }
197
198 if (TrigerData(resultSet) != ERR_OK) {
199 DEV_HILOGE(SERVICE, "triger data failed");
200 return -1;
201 }
202
203 ret = resultSet->Close();
204 if (ret != ERR_OK) {
205 DEV_HILOGE(SERVICE, "close database observer failed");
206 return -1;
207 }
208
209 DevicestatusDataUtils::DevicestatusData data;
210 data.type = (DevicestatusDataUtils::DevicestatusType)devicestatusType_;
211 data.value = (DevicestatusDataUtils::DevicestatusValue)devicestatusStatus_;
212
213 SaveRdbData(data);
214 DEV_HILOGD(SERVICE, "notifyFlag_ is %{public}d", notifyFlag_);
215 if (notifyFlag_) {
216 NotifyMsdpImpl(data);
217 notifyFlag_ = false;
218 }
219
220 return ERR_OK;
221 }
222
SubscribeHallSensor()223 void DevicestatusSensorRdb::SubscribeHallSensor()
224 {
225 DEV_HILOGD(SERVICE, "Enter");
226
227 DEV_HILOGD(SERVICE, "Exit");
228 }
229
UnSubscribeHallSensor()230 void DevicestatusSensorRdb::UnSubscribeHallSensor()
231 {
232 DEV_HILOGD(SERVICE, "Enter");
233
234 DEV_HILOGD(SERVICE, "Exit");
235 }
236
InitTimer()237 void DevicestatusSensorRdb::InitTimer()
238 {
239 DEV_HILOGD(SERVICE, "Enter");
240 epFd_ = epoll_create1(EPOLL_CLOEXEC);
241 if (epFd_ == -1) {
242 DEV_HILOGD(SERVICE, "create epoll fd failed");
243 return;
244 }
245 timerFd_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
246 if (timerFd_ == ERR_INVALID_FD) {
247 DEV_HILOGD(SERVICE, "create timer fd failed");
248 return;
249 }
250 SetTimerInterval(TIMER_INTERVAL);
251 fcntl(timerFd_, F_SETFL, O_NONBLOCK);
252 callbacks_.insert(std::make_pair(timerFd_, &DevicestatusSensorRdb::TimerCallback));
253 if (RegisterTimerCallback(timerFd_, EVENT_TIMER_FD)) {
254 DEV_HILOGD(SERVICE, "register timer fd failed");
255 return;
256 }
257 }
258
SetTimerInterval(int32_t interval)259 void DevicestatusSensorRdb::SetTimerInterval(int32_t interval)
260 {
261 struct itimerspec itval;
262
263 if (timerFd_ == ERR_INVALID_FD) {
264 DEV_HILOGE(SERVICE, "create timer fd failed");
265 return;
266 }
267
268 timerInterval_ = interval;
269
270 if (interval < 0) {
271 interval = 0;
272 }
273
274 itval.it_interval.tv_sec = interval;
275 itval.it_interval.tv_nsec = 0;
276 itval.it_value.tv_sec = interval;
277 itval.it_value.tv_nsec = 0;
278
279 if (timerfd_settime(timerFd_, 0, &itval, nullptr) == -1) {
280 DEV_HILOGD(SERVICE, "set timer failed");
281 return;
282 }
283
284 return;
285 }
286
CloseTimer()287 void DevicestatusSensorRdb::CloseTimer()
288 {
289 DEV_HILOGD(SERVICE, "Enter");
290 close(timerFd_);
291 DEV_HILOGD(SERVICE, "Exit");
292 }
293
TimerCallback()294 void DevicestatusSensorRdb::TimerCallback()
295 {
296 unsigned long long timers;
297 if (read(timerFd_, &timers, sizeof(timers)) == -1) {
298 DEV_HILOGD(SERVICE, "read timer fd failed");
299 return;
300 }
301 TrigerDatabaseObserver();
302 }
303
RegisterTimerCallback(const int32_t fd,const EventType et)304 int32_t DevicestatusSensorRdb::RegisterTimerCallback(const int32_t fd, const EventType et)
305 {
306 DEV_HILOGD(SERVICE, "Enter");
307 struct epoll_event ev;
308
309 ev.events = EPOLLIN;
310 if (et == EVENT_TIMER_FD) {
311 ev.events |= EPOLLWAKEUP;
312 }
313
314 ev.data.ptr = reinterpret_cast<void*>(this);
315 ev.data.fd = fd;
316 if (epoll_ctl(epFd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
317 DEV_HILOGD(SERVICE, "epoll_ctl failed, error num =%{public}d", errno);
318 return -1;
319 }
320
321 return 0;
322 }
323
StartThread()324 void DevicestatusSensorRdb::StartThread()
325 {
326 DEV_HILOGD(SERVICE, "Enter");
327 std::make_unique<std::thread>(&DevicestatusSensorRdb::LoopingThreadEntry, this)->detach();
328 }
329
LoopingThreadEntry()330 void DevicestatusSensorRdb::LoopingThreadEntry()
331 {
332 size_t cbct = callbacks_.size();
333 struct epoll_event events[cbct];
334
335 while (true) {
336 int32_t timeout = -1;
337
338 int32_t nevents = epoll_wait(epFd_, events, cbct, timeout);
339 if (nevents == -1) {
340 continue;
341 }
342 for (int32_t n = 0; n < nevents; ++n) {
343 if (events[n].data.ptr) {
344 DevicestatusSensorRdb *func = const_cast<DevicestatusSensorRdb *>(this);
345 (callbacks_.find(events[n].data.fd)->second)(func);
346 }
347 }
348 }
349 }
350
OnCreate(RdbStore & store)351 int32_t HelperCallback::OnCreate(RdbStore &store)
352 {
353 DEV_HILOGD(SERVICE, "Enter");
354 return ERR_OK;
355 }
356
OnUpgrade(RdbStore & store,int32_t oldVersion,int32_t newVersion)357 int32_t HelperCallback::OnUpgrade(RdbStore &store, int32_t oldVersion, int32_t newVersion)
358 {
359 DEV_HILOGD(SERVICE, "Enter");
360 return ERR_OK;
361 }
362
Create(void)363 extern "C" DevicestatusSensorInterface *Create(void)
364 {
365 DEV_HILOGD(SERVICE, "Enter");
366 g_rdb = new DevicestatusSensorRdb();
367 return g_rdb;
368 }
369
Destroy(DevicestatusSensorInterface * algorithm)370 extern "C" void Destroy(DevicestatusSensorInterface* algorithm)
371 {
372 DEV_HILOGD(SERVICE, "Enter");
373 delete algorithm;
374 }
375 }
376 }
377