• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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