1 /*
2 * Copyright (c) 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 "frame.h"
17 #include <linux/input.h>
18 #include "log/log.h"
19 #include "updater_ui_const.h"
20 #include "view.h"
21
22 namespace updater {
23 using namespace std;
24 extern int g_textLabelNum;
25 extern Frame *g_menuFrame;
26
Frame(unsigned int w,unsigned int h,View::PixelFormat pixType,SurfaceDev * sfDev)27 Frame::Frame(unsigned int w, unsigned int h, View::PixelFormat pixType, SurfaceDev *sfDev)
28 {
29 this->CreateBuffer(w, h, pixType);
30 this->startX_ = 0;
31 this->startY_ = 0;
32 sfDev_ = sfDev;
33 listIndex_ = 0;
34 flushFlag_ = false;
35 #ifndef UPDATER_UT
36 flushLoop_ = std::thread(&Frame::FlushThreadLoop, this);
37 flushLoop_.detach();
38 #endif
39 #ifdef CONVERT_RL_SLIDE_TO_CLICK
40 keyProcessLoop_ = std::thread(&Frame::ProcessKeyLoop, this);
41 keyProcessLoop_.detach();
42 #endif
43 currentActionIndex_ = 0;
44 }
45
~Frame()46 Frame::~Frame()
47 {
48 needStop_ = true;
49 std::unique_lock<std::mutex> locker(mutex_);
50 flushFlag_ = true;
51 viewMapList_.clear();
52 }
53
FlushThreadLoop()54 void Frame::FlushThreadLoop()
55 {
56 while (!needStop_) {
57 std::unique_lock<std::mutex> locker(mutex_);
58 while (!flushFlag_) {
59 mCondFlush_.wait(mutex_, [&] {
60 return flushFlag_;
61 });
62 }
63 if (!IsVisiable()) {
64 flushFlag_ = false;
65 continue;
66 }
67 SyncBuffer();
68 frameMutex_.lock();
69 std::map<View*, int>::iterator iter;
70 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
71 View* tmpView = (*iter).first;
72 if (tmpView->IsVisiable()) {
73 void* bufTmp = tmpView->GetBuffer();
74 DrawSubView(tmpView->startX_, tmpView->startY_, tmpView->viewWidth_, tmpView->viewHeight_, bufTmp);
75 }
76 }
77 frameMutex_.unlock();
78 sfDev_->Flip(this->GetBuffer());
79 flushFlag_ = false;
80 }
81 }
82
ProcessKeyLoop()83 void Frame::ProcessKeyLoop()
84 {
85 while (!needStop_) {
86 std::unique_lock<std::mutex> locker(keyMutex_);
87 if (!keyEventNotify_) {
88 mCondKey_.wait(keyMutex_, [&] {
89 return keyEventNotify_;
90 });
91 }
92 if (!IsVisiable()) {
93 continue;
94 }
95 int key = keyFifo_.front();
96 keyFifo_.pop_front();
97 DoEvent(key);
98 keyEventNotify_ = false;
99 }
100 }
101
ViewRegister(View * view)102 void Frame::ViewRegister(View *view)
103 {
104 std::unique_lock<std::mutex> locker(frameMutex_);
105 view->SetViewId(frameViewId + listIndex_);
106 viewMapList_.insert(std::make_pair(view, frameViewId + listIndex_));
107 if (view->IsFocusAble()) {
108 maxActionIndex_++;
109 LOG(INFO) << "---";
110 }
111 listIndex_++;
112 }
113
OnDraw()114 void Frame::OnDraw()
115 {
116 std::unique_lock<std::mutex> locker(mutex_);
117 flushFlag_ = true;
118 mCondFlush_.notify_all();
119 }
120
UpFoucs()121 void Frame::UpFoucs()
122 {
123 currentActionIndex_--;
124 if (currentActionIndex_ == -1) {
125 currentActionIndex_ = 0;
126 return;
127 }
128
129 frameMutex_.lock();
130 int actionIndexTemp = 0;
131 std::map<View*, int>::iterator iter;
132 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
133 View* tmpView = (*iter).first;
134 if (tmpView->IsVisiable() && tmpView->IsFocusAble()) {
135 if (actionIndexTemp == currentActionIndex_) {
136 frameMutex_.unlock();
137 tmpView->OnFocus(true);
138 frameMutex_.lock();
139 }
140 if (actionIndexTemp == currentActionIndex_ + 1) {
141 frameMutex_.unlock();
142 tmpView->OnFocus(false);
143 frameMutex_.lock();
144 break;
145 }
146 }
147 actionIndexTemp++;
148 }
149 frameMutex_.unlock();
150 }
151
DownFoucs()152 void Frame::DownFoucs()
153 {
154 UPDATER_CHECK_ONLY_RETURN(currentActionIndex_ != g_textLabelNum, return);
155 int actionIndexTemp = 0;
156 frameMutex_.lock();
157 std::map<View*, int>::iterator iter;
158 currentActionIndex_++;
159 View *view = nullptr;
160 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
161 View *tmpView = (*iter).first;
162 if (tmpView->IsVisiable() && tmpView->IsFocusAble()) {
163 if (actionIndexTemp == currentActionIndex_ - 1) {
164 frameMutex_.unlock();
165 tmpView->OnFocus(false);
166 frameMutex_.lock();
167 }
168 view = tmpView;
169 if (currentActionIndex_ == g_textLabelNum && view != nullptr) {
170 currentActionIndex_ = 0;
171 frameMutex_.unlock();
172 view->OnFocus(false);
173 frameMutex_.lock();
174 }
175 if (actionIndexTemp == currentActionIndex_) {
176 frameMutex_.unlock();
177 tmpView->OnFocus(true);
178 frameMutex_.lock();
179 break;
180 }
181 } else {
182 if (tmpView->IsVisiable() && tmpView->IsFocusAble()) {
183 frameMutex_.unlock();
184 tmpView->OnFocus(false);
185 frameMutex_.lock();
186 }
187 }
188 actionIndexTemp++;
189 }
190 if (iter == viewMapList_.end()) {
191 currentActionIndex_ = 0;
192 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
193 View* tmpView = (*iter).first;
194 if (tmpView->IsVisiable() && tmpView->IsFocusAble()) {
195 tmpView->OnFocus(true);
196 break;
197 }
198 }
199 }
200 frameMutex_.unlock();
201 }
202
SendKey(int key)203 void Frame::SendKey(int key)
204 {
205 frameMutex_.lock();
206 int actionIndexTemp = 0;
207 std::map<View*, int>::iterator iter;
208 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
209 View* tmpView = (*iter).first;
210 if (tmpView->IsVisiable() && tmpView->IsFocusAble()) {
211 if (actionIndexTemp == currentActionIndex_) {
212 frameMutex_.unlock();
213 tmpView->OnKeyEvent(key);
214 frameMutex_.lock();
215 break;
216 }
217 }
218 actionIndexTemp++;
219 }
220 frameMutex_.unlock();
221 }
222
DoEvent(int key)223 void Frame::DoEvent(int key)
224 {
225 UPDATER_ERROR_CHECK(IsVisiable(), "Is not visable", return);
226 UPDATER_ERROR_CHECK(!IsFocusAble(), "Is not fouces", return);
227 switch (key) {
228 case KEY_UP:
229 LOG(INFO) << "DispatchKeyEvent KEY_UP";
230 UpFoucs();
231 break;
232 case KEY_DOWN:
233 LOG(INFO) << "DispatchKeyEvent KEY_DOWN";
234 DownFoucs();
235 break;
236 case KEY_POWER:
237 LOG(INFO) << "DispatchKeyEvent KEY_POWER";
238 SendKey(key);
239 break;
240 default:
241 break;
242 }
243 }
244
DispatchKeyEvent(int key)245 void Frame::DispatchKeyEvent(int key)
246 {
247 UPDATER_CHECK_ONLY_RETURN(IsVisiable(), return);
248 std::unique_lock<std::mutex> locker(keyMutex_);
249 keyFifo_.push_back(key);
250 keyEventNotify_ = true;
251 mCondKey_.notify_all();
252 }
253
DispatchKeyEvent(int id,int event)254 void Frame::DispatchKeyEvent(int id, int event)
255 {
256 bool isClicked = (keyEvent_ == event);
257 keyEvent_ = event;
258 if (isClicked) {
259 return;
260 }
261 if (!g_menuFrame->IsVisiable()) {
262 event = -1;
263 }
264 switch (event) {
265 case INVALID_EVENT:
266 LOG(INFO) << "DispatchKeyEvent invalid";
267 break;
268 case PRESS_EVENT:
269 btnId_ = id;
270 PressEvent();
271 LOG(INFO) << "DispatchKeyEvent press";
272 break;
273 case RELEASE_EVENT:
274 btnId_ = id;
275 ReleaseEvent();
276 LOG(INFO) << "DispatchKeyEvent release";
277 break;
278 default:
279 break;
280 }
281 }
282
ReleaseEvent()283 void Frame::ReleaseEvent()
284 {
285 frameMutex_.lock();
286 std::map<View*, int>::iterator iter;
287 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
288 View* tmpView = (*iter).first;
289 if (tmpView->IsVisiable() && btnId_ == tmpView->GetViewId()) {
290 if (!g_menuFrame->IsVisiable()) {
291 return;
292 }
293 frameMutex_.unlock();
294 tmpView->OnKeyEvent(KEY_POWER);
295 tmpView->OnFocus(false);
296 frameMutex_.lock();
297 break;
298 }
299 }
300 frameMutex_.unlock();
301 }
302
PressEvent()303 void Frame::PressEvent()
304 {
305 frameMutex_.lock();
306 std::map<View*, int>::iterator iter;
307 for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) {
308 View* tmpView = (*iter).first;
309 if (tmpView->IsVisiable() && btnId_ == tmpView->GetViewId()) {
310 if (!g_menuFrame->IsVisiable()) {
311 return;
312 }
313 frameMutex_.unlock();
314 tmpView->OnFocus(true);
315 frameMutex_.lock();
316 break;
317 }
318 }
319 frameMutex_.unlock();
320 }
321 } // namespace updater