1 /*
2  * Copyright (c) 2020-2021 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 "input_manager_service.h"
17 
18 #include "gfx_utils/graphic_log.h"
19 
20 namespace OHOS {
21 InputEventHub* InputManagerService::hub_ = nullptr;
22 InputEventDistributer InputManagerService::distributer_;
23 pthread_t InputManagerService::distributerThread_ = -1;
24 int32_t InputManagerService::distributerThreadCreated_;
25 std::queue<RawEvent> InputManagerService::eventQueue_;
26 pthread_mutex_t InputManagerService::lock_;
27 pthread_cond_t InputManagerService::nonEmpty_;
28 pthread_cond_t InputManagerService::nonFull_;
29 
GetInstance()30 InputManagerService* InputManagerService::GetInstance()
31 {
32     static InputManagerService instance;
33     return &instance;
34 }
35 
Run()36 void InputManagerService::Run()
37 {
38     hub_ = InputEventHub::GetInstance();
39 
40     hub_->RegisterReadCallback(ReadCallback);
41     hub_->SetUp();
42     distributerThreadCreated_ = pthread_create(&distributerThread_, nullptr, Distribute, nullptr);
43     if (!distributerThreadCreated_) {
44         pthread_detach(distributerThread_);
45     }
46 }
47 
Stop()48 void InputManagerService::Stop()
49 {
50     hub_->TearDown();
51 }
52 
~InputManagerService()53 InputManagerService::~InputManagerService()
54 {
55     pthread_mutex_destroy(&lock_);
56     pthread_cond_destroy(&nonEmpty_);
57     pthread_cond_destroy(&nonFull_);
58 }
59 
ReadCallback(const RawEvent * event)60 void InputManagerService::ReadCallback(const RawEvent* event)
61 {
62     if (event == nullptr) {
63         return;
64     }
65     pthread_mutex_lock(&lock_);
66     while (eventQueue_.size() == MAX_EVENT_SIZE) {
67         pthread_cond_wait(&nonFull_, &lock_);
68     }
69     // push events into queue
70     eventQueue_.push(event[0]);
71     pthread_mutex_unlock(&lock_);
72     pthread_cond_signal(&nonEmpty_);
73 }
74 
Distribute(void * args)75 void* InputManagerService::Distribute(void* args)
76 {
77     GRAPHIC_LOGI("InputManagerService::Distribute Ready to read distribute!");
78     while (true) {
79         pthread_mutex_lock(&lock_);
80         while (eventQueue_.size() == 0) {
81             pthread_cond_wait(&nonEmpty_, &lock_);
82         }
83         // pop events from queue
84         RawEvent events[MAX_INPUT_DEVICE_NUM];
85         int32_t len = (eventQueue_.size() > MAX_EVENT_SIZE) ? MAX_EVENT_SIZE : eventQueue_.size();
86         for (int32_t i = 0; i < len; i++) {
87             events[i] = eventQueue_.front();
88             eventQueue_.pop();
89         }
90         distributer_.Distribute(events, len);
91         pthread_mutex_unlock(&lock_);
92         pthread_cond_signal(&nonFull_);
93     }
94     return nullptr;
95 }
96 } // namespace OHOS
97