1 /*
2  * Copyright (c) 2024 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 "adapter/mmi_adapter.h"
17 
18 #include <mutex>
19 #include <thread>
20 #include <sys/prctl.h>
21 
22 #include "dtbschedmgr_log.h"
23 #include "mission/dms_continue_send_manager.h"
24 
25 namespace OHOS {
26 namespace DistributedSchedule {
27 
28 namespace {
29 const std::string TAG = "MMIAdapter";
30 const std::string MMI_ADAPTER = "mmi_adapter";
31 const std::string FREEZE_MMI_EVENT_TASK = "task_freeze_mmi_event";
32 constexpr int32_t FREEZE_MMI_EVENT_INTERVAL = 5000;
33 }
34 
35 IMPLEMENT_SINGLE_INSTANCE(MMIAdapter);
36 
Init()37 void MMIAdapter::Init()
38 {
39     HILOGI("Init");
40     if (eventHandler_ != nullptr) {
41         HILOGI("Already inited, end.");
42         return;
43     }
44     mmiCallback_ = std::make_shared<MMIAdapter::MMIEventCallback>();
45     eventThread_ = std::thread(&MMIAdapter::StartEvent, this);
46     std::unique_lock<std::mutex> lock(eventMutex_);
47     eventCon_.wait(lock, [this] {
48         return eventHandler_ != nullptr;
49     });
50 }
51 
StartEvent()52 void MMIAdapter::StartEvent()
53 {
54     HILOGI("StartEvent start");
55     prctl(PR_SET_NAME, MMI_ADAPTER.c_str());
56     auto runner = AppExecFwk::EventRunner::Create(false);
57     if (runner == nullptr) {
58         HILOGE("create runner failed!");
59         return;
60     }
61     {
62         std::lock_guard<std::mutex> lock(eventMutex_);
63         eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
64     }
65     eventCon_.notify_one();
66     runner->Run();
67     HILOGI("StartEvent end");
68 }
69 
UnInit()70 void MMIAdapter::UnInit()
71 {
72     HILOGI("UnInit start");
73     if (eventHandler_ != nullptr && eventHandler_->GetEventRunner() != nullptr) {
74         eventHandler_->GetEventRunner()->Stop();
75         eventThread_.join();
76         eventHandler_ = nullptr;
77     } else {
78         HILOGE("eventHandler_ or eventRunner is nullptr");
79     }
80     HILOGI("UnInit end");
81 }
82 
AddMMIListener()83 int32_t MMIAdapter::AddMMIListener()
84 {
85     HILOGD("AddMMIListener called");
86     int32_t ret = MMI::InputManager::GetInstance()->AddMonitor(mmiCallback_);
87     HILOGD("AddMMIListener result: %{public}d", ret);
88     isMMIFreezed_ = false;
89     return ret;
90 }
91 
RemoveMMIListener(int32_t monitorId)92 void MMIAdapter::RemoveMMIListener(int32_t monitorId)
93 {
94     HILOGD("RemoveMMIListener called, monitor id = %{public}d", monitorId);
95     MMI::InputManager::GetInstance()->RemoveMonitor(monitorId);
96     return;
97 }
98 
PostRawMMIEvent()99 void MMIAdapter::PostRawMMIEvent()
100 {
101     auto func = [this]() {
102         HandleRawMMIEvent();
103     };
104     if (eventHandler_ != nullptr) {
105         eventHandler_->PostTask(func);
106     } else {
107         HILOGE("eventHandler_ is nullptr");
108     }
109 }
110 
PostUnfreezeMMIEvent()111 void MMIAdapter::PostUnfreezeMMIEvent()
112 {
113     auto func = [this]() {
114         HandleUnfreezeMMIEvent();
115     };
116     if (eventHandler_ != nullptr) {
117         eventHandler_->PostTask(func, FREEZE_MMI_EVENT_TASK, FREEZE_MMI_EVENT_INTERVAL);
118     } else {
119         HILOGE("eventHandler_ is nullptr");
120     }
121 }
122 
HandleRawMMIEvent()123 void MMIAdapter::HandleRawMMIEvent()
124 {
125     if (isMMIFreezed_) {
126         return;
127     }
128     isMMIFreezed_ = true;
129     DMSContinueSendMgr::GetInstance().OnMMIEvent();
130     PostUnfreezeMMIEvent();
131 }
132 
HandleUnfreezeMMIEvent()133 void MMIAdapter::HandleUnfreezeMMIEvent()
134 {
135     isMMIFreezed_ = false;
136 }
137 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const138 void MMIAdapter::MMIEventCallback::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
139 {
140     MMIAdapter::GetInstance().PostRawMMIEvent();
141 }
142 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const143 void MMIAdapter::MMIEventCallback::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
144 {
145     MMIAdapter::GetInstance().PostRawMMIEvent();
146 }
147 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const148 void MMIAdapter::MMIEventCallback::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const
149 {
150     MMIAdapter::GetInstance().PostRawMMIEvent();
151 }
152 } // namespace DistributedSchedule
153 } // namespace OHOS
154