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 "window_manager_controller_client.h"
17
18 #include <map>
19 #include <queue>
20
21 #include "video_window.h"
22 #include "window_manager_define.h"
23 #include "window_manager_hilog.h"
24
25 namespace OHOS {
26 namespace {
27 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "WindowManagerClient" };
28 } // namespace
29
30 #define LOCK(mutexName) \
31 std::lock_guard<std::mutex> lock(mutexName)
32
GetInstance()33 sptr<LayerControllerClient> LayerControllerClient::GetInstance()
34 {
35 if (instance == nullptr) {
36 static std::mutex mutex;
37 std::lock_guard<std::mutex> lock(mutex);
38 if (instance == nullptr) {
39 instance = new LayerControllerClient();
40 }
41 }
42 return instance;
43 }
44
LayerControllerClient()45 LayerControllerClient::LayerControllerClient()
46 {
47 WMLOG_I("DEBUG LayerControllerClient");
48 }
49
~LayerControllerClient()50 LayerControllerClient::~LayerControllerClient()
51 {
52 WMLOG_I("DEBUG ~LayerControllerClient");
53 }
54
init(sptr<IWindowManagerService> & service)55 bool LayerControllerClient::init(sptr<IWindowManagerService> &service)
56 {
57 if (isInit) {
58 return true;
59 }
60
61 if (service == nullptr) {
62 WMLOG_E("service is nullptr");
63 return false;
64 }
65 wms = service;
66
67 WlDMABufferFactory::GetInstance()->Init();
68 WlSHMBufferFactory::GetInstance()->Init();
69 WlSurfaceFactory::GetInstance()->Init();
70 WlSubsurfaceFactory::GetInstance()->Init();
71 WindowManagerServer::GetInstance()->Init();
72
73 WaylandService::GetInstance()->Start();
74 WlDisplay::GetInstance()->Roundtrip();
75 WlDisplay::GetInstance()->Roundtrip();
76
77 pthread_t tid1;
78 pthread_create(&tid1, NULL, LayerControllerClient::thread_display_dispatch, this);
79 isInit = true;
80 return true;
81 }
82
ChangeWindowType(int32_t id,WindowType type)83 void LayerControllerClient::ChangeWindowType(int32_t id, WindowType type)
84 {
85 LOCK(mutex);
86 WMLOG_I("LayerControllerClient::ChangeWindowType id=%{public}d,type=%{public}d", id, type);
87
88 InnerWindowInfo *wininfo = GetInnerWindowInfoFromId((uint32_t)id);
89 if (wininfo == nullptr) {
90 WMLOGFE("id: %{public}d, window info is nullptr", id);
91 return;
92 }
93
94 if (type == wininfo->windowconfig.type) {
95 WMLOG_E("LayerControllerClient::ChangeWindowType window type is no need change");
96 return;
97 }
98
99 wms->SetWindowType(id, type);
100 }
101
OnWlBufferRelease(struct wl_buffer * wbuffer,int32_t fence)102 void LayerControllerClient::OnWlBufferRelease(struct wl_buffer *wbuffer, int32_t fence)
103 {
104 sptr<Surface> surf = nullptr;
105 sptr<SurfaceBuffer> sbuffer = nullptr;
106 if (WlBufferCache::GetInstance()->GetSurfaceBuffer(wbuffer, surf, sbuffer)) {
107 if (surf != nullptr && sbuffer != nullptr) {
108 surf->ReleaseBuffer(sbuffer, fence);
109 }
110 }
111 }
112
CreateWlBuffer(sptr<Surface> & surf,uint32_t windowId)113 void LayerControllerClient::CreateWlBuffer(sptr<Surface>& surf, uint32_t windowId)
114 {
115 LOCK(mutex);
116 WMLOG_I("LayerControllerClient::CreateWlBuffer id=%{public}d", windowId);
117
118 sptr<SurfaceBuffer> buffer;
119 int32_t flushFence;
120 int64_t timestamp;
121 Rect damage;
122 GSError ret = surf->AcquireBuffer(buffer, flushFence, timestamp, damage);
123 if (ret != GSERROR_OK) {
124 WMLOG_I("LayerControllerClient::CreateWlBuffer AcquireBuffer failed");
125 return;
126 }
127
128 InnerWindowInfo *windowInfo = GetInnerWindowInfoFromId((uint32_t)windowId);
129 if (windowInfo == nullptr) {
130 WMLOGFE("id: %{public}d, window info is nullptr", windowId);
131 return;
132 }
133
134 auto bc = WlBufferCache::GetInstance();
135 auto wbuffer = bc->GetWlBuffer(surf, buffer);
136 if (wbuffer == nullptr) {
137 auto dmaWlBuffer = WlDMABufferFactory::GetInstance()->Create(buffer->GetBufferHandle());
138 if (dmaWlBuffer == nullptr) {
139 WMLOG_E("Create DMA Buffer Failed");
140 ret = surf->ReleaseBuffer(buffer, -1);
141 if (ret != GSERROR_OK) {
142 WMLOG_W("ReleaseBuffer failed");
143 }
144 return;
145 }
146 dmaWlBuffer->OnRelease(this);
147
148 wbuffer = dmaWlBuffer;
149 bc->AddWlBuffer(wbuffer, surf, buffer);
150 }
151
152 if (wbuffer) {
153 auto br = windowInfo->wlSurface->GetBufferRelease();
154 wbuffer->SetBufferRelease(br);
155 windowInfo->wlSurface->Attach(wbuffer, 0, 0);
156 windowInfo->wlSurface->SetAcquireFence(flushFence);
157 windowInfo->wlSurface->Damage(damage.x, damage.y, damage.w, damage.h);
158 windowInfo->wlSurface->Commit();
159 WlDisplay::GetInstance()->Flush();
160 }
161 WMLOG_I("LayerControllerClient::CreateWlBuffer end");
162 }
163
thread_display_dispatch(void * param)164 void *LayerControllerClient::thread_display_dispatch(void *param)
165 {
166 WMLOG_I("LayerControllerClient::thread_display_dispatch start");
167 while (true) {
168 int32_t ret = WlDisplay::GetInstance()->Dispatch();
169 if (ret == -1) {
170 WMLOG_I("LayerControllerClient::thread_display_dispatch error, errno: %{public}d", errno);
171 break;
172 }
173 }
174 return nullptr;
175 }
176
CreateSurface(int32_t id)177 bool LayerControllerClient::CreateSurface(int32_t id)
178 {
179 WMLOG_I("CreateSurface (windowid = %{public}d) start", id);
180
181 InnerWindowInfo *windowInfo
182 = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
183 if (windowInfo == nullptr) {
184 WMLOGFE("id: %{public}d, window info is nullptr", id);
185 return false;
186 }
187
188 windowInfo->surf = Surface::CreateSurfaceAsConsumer();
189 if (windowInfo->surf) {
190 windowInfo->listener = new SurfaceListener(windowInfo->surf, id);
191 if (windowInfo->listener == nullptr) {
192 WMLOG_E("windowInfo->listener new failed");
193 }
194 windowInfo->surf->RegisterConsumerListener(windowInfo->listener);
195
196 int width = LayerControllerClient::GetInstance()->GetMaxWidth();
197 int height = LayerControllerClient::GetInstance()->GetMaxHeight();
198 windowInfo->surf->SetDefaultWidthAndHeight(width, height);
199 }
200 WMLOG_I("CreateSurface (windowid = %{public}d) end", id);
201 return true;
202 }
203
CreateWindow(int32_t id,WindowConfig & config)204 InnerWindowInfo *LayerControllerClient::CreateWindow(int32_t id, WindowConfig &config)
205 {
206 LOCK(mutex);
207 WMLOG_I("LayerControllerClient::CreateWindow start");
208
209 InnerWindowInfo newInfo = {
210 .windowconfig = config,
211 .windowid = id,
212 .layerid = config.type * LAYER_ID_TYPE_OFSSET + LAYER_ID_APP_TYPE_BASE,
213 .width = config.width,
214 .height = config.height,
215 .pos_x = config.pos_x,
216 .pos_y = config.pos_y,
217 };
218
219 {
220 LOCK(windowListMutex);
221 m_windowList.push_back(newInfo);
222 }
223 CreateSurface(id);
224
225 auto info = GetInnerWindowInfoFromId(id);
226 info->logListener = LogListener::GetInstance()->AddListener(&info->windowid);
227 return info;
228 }
229
230 namespace {
GetSubInnerWindowInfo(InnerWindowInfo & info,const int subid,const int parentid,const WindowConfig & config)231 void GetSubInnerWindowInfo(InnerWindowInfo &info,
232 const int subid, const int parentid, const WindowConfig &config)
233 {
234 info.windowconfig = config;
235 info.windowid = subid;
236 info.parentid = parentid;
237 info.subwidow = true;
238 info.width = config.width;
239 info.height = config.height;
240 info.pos_x = config.pos_x;
241 info.pos_y = config.pos_y;
242 info.voLayerId = -1U;
243 info.windowInfoChangeCb = nullptr;
244 }
245
CreateVideoSubWindow(InnerWindowInfo & newSubInfo)246 bool CreateVideoSubWindow(InnerWindowInfo &newSubInfo)
247 {
248 uint32_t voLayerId = -1U;
249 sptr<Surface> surf = nullptr;
250 int32_t ret = VideoWindow::CreateLayer(newSubInfo, voLayerId, surf);
251 if (ret == 0) {
252 newSubInfo.voLayerId = voLayerId;
253 newSubInfo.surf = surf;
254
255 newSubInfo.wlBuffer = WlSHMBufferFactory::GetInstance()->Create(
256 newSubInfo.width, newSubInfo.height, WL_SHM_FORMAT_XRGB8888);
257 if (newSubInfo.wlBuffer == nullptr) {
258 WMLOG_I("CreateVideoSubWindow CreateShmBuffer failed");
259 return false;
260 }
261
262 if (newSubInfo.windowconfig.type == WINDOW_TYPE_VIDEO) {
263 newSubInfo.wlSurface->SetSurfaceType(WL_SURFACE_TYPE_VIDEO);
264 }
265
266 newSubInfo.wlSurface->Attach(newSubInfo.wlBuffer, 0, 0);
267 newSubInfo.wlSurface->Damage(0, 0, newSubInfo.width, newSubInfo.height);
268 newSubInfo.wlSurface->Commit();
269 return true;
270 }
271
272 WMLOG_I("CreateVideoSubWindow VideoWindow::CreateLayer failed");
273 return false;
274 }
275 }
276
CreateSubWindow(int32_t subid,int32_t parentid,WindowConfig & config)277 InnerWindowInfo *LayerControllerClient::CreateSubWindow(int32_t subid, int32_t parentid, WindowConfig &config)
278 {
279 LOCK(mutex);
280 WMLOG_I("%{public}s start parentID is %{public}d, subid is %{public}d",
281 "LayerControllerClient::CreateSubWindow", parentid, subid);
282
283 InnerWindowInfo *parentInnerWindowInfo
284 = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)parentid);
285 if (parentInnerWindowInfo == nullptr) {
286 WMLOGFE("id: %{public}d, window info is nullptr", parentid);
287 return nullptr;
288 }
289
290 InnerWindowInfo newSubInfo = {};
291 GetSubInnerWindowInfo(newSubInfo, subid, parentid, config);
292
293 newSubInfo.wlSurface = WlSurfaceFactory::GetInstance()->Create();
294 if (newSubInfo.wlSurface == nullptr) {
295 WMLOG_I("CreateSubWindow createwlSubSuface (subid = %{public}d) failed", subid);
296 return nullptr;
297 }
298
299 newSubInfo.wlSubsurf = WlSubsurfaceFactory::GetInstance()->Create(
300 newSubInfo.wlSurface, parentInnerWindowInfo->wlSurface);
301 if (newSubInfo.wlSubsurf) {
302 newSubInfo.wlSubsurf->SetPosition(newSubInfo.pos_x, newSubInfo.pos_y);
303 newSubInfo.wlSubsurf->SetDesync();
304 }
305 WMLOG_I("CreateSubWindow createwlSubSuface (subid = %{public}d) success", subid);
306
307 if (newSubInfo.windowconfig.type != WINDOW_TYPE_VIDEO) {
308 newSubInfo.surf = Surface::CreateSurfaceAsConsumer();
309 if (newSubInfo.surf) {
310 newSubInfo.listener = new SurfaceListener(newSubInfo.surf, subid);
311 if (newSubInfo.listener == nullptr) {
312 WMLOG_E("newSubInfo.listener new failed");
313 }
314 newSubInfo.surf->RegisterConsumerListener(newSubInfo.listener);
315 }
316 } else {
317 if (!CreateVideoSubWindow(newSubInfo)) {
318 return nullptr;
319 }
320 }
321
322 {
323 LOCK(windowListMutex);
324 m_windowList.push_back(newSubInfo);
325 }
326
327 parentInnerWindowInfo->childIDList.push_back(subid);
328 WMLOG_E("LayerControllerClient::CreateSubWindow END");
329 return GetInnerWindowInfoFromId(subid);
330 }
331
RegistWindowInfoChangeCb(int id,funcWindowInfoChange cb)332 void LayerControllerClient::RegistWindowInfoChangeCb(int id, funcWindowInfoChange cb)
333 {
334 LOCK(mutex);
335 WMLOG_I("LayerControllerClient::%{public}s begin", __func__);
336 if (cb) {
337 WMLOG_I("LayerControllerClient::RegistWindowInfoChangeCb OK");
338 InnerWindowInfo *windowInfo = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
339 if (windowInfo == nullptr) {
340 WMLOGFE("id: %{public}d, window info is nullptr", id);
341 return;
342 }
343 windowInfo->windowInfoChangeCb = cb;
344 }
345 }
346
RegistOnWindowCreateCb(int32_t id,void (* cb)(uint32_t pid))347 void LayerControllerClient::RegistOnWindowCreateCb(int32_t id, void(* cb)(uint32_t pid))
348 {
349 LOCK(mutex);
350 InnerWindowInfo *info = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
351 if (info == nullptr) {
352 WMLOGFE("id: %{public}d, window info is nullptr", id);
353 return;
354 }
355 info->onWindowCreateCb = cb;
356 }
357
SendWindowCreate(uint32_t pid)358 void LayerControllerClient::SendWindowCreate(uint32_t pid)
359 {
360 for (auto it = m_windowList.begin(); it != m_windowList.end(); it++) {
361 if (it->onWindowCreateCb) {
362 it->onWindowCreateCb(pid);
363 }
364 }
365 }
366
SetSubSurfaceSize(int32_t id,int32_t width,int32_t height)367 void LayerControllerClient::SetSubSurfaceSize(int32_t id, int32_t width, int32_t height)
368 {
369 WMLOG_E("%{public}s start id(%{public}d) width(%{public}d) height(%{public}d)",
370 "LayerControllerClient::SetSubSurfaceSize", id, width, height);
371
372 InnerWindowInfo *windowInfo = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
373 if (windowInfo == nullptr) {
374 WMLOGFE("id: %{public}d, window info is nullptr", id);
375 return;
376 }
377 if (windowInfo->subwidow == true) {
378 windowInfo->wlSurface->Commit();
379 }
380 }
381
DestroyWindow(int32_t id)382 void LayerControllerClient::DestroyWindow(int32_t id)
383 {
384 LOCK(mutex);
385
386 std::queue<uint32_t> q;
387 q.push(id);
388 while (!q.empty()) {
389 uint32_t id = q.front();
390 q.pop();
391
392 InnerWindowInfo *info = GetInnerWindowInfoFromId(id);
393 if (info) {
394 for (auto jt = info->childIDList.begin(); jt != info->childIDList.end(); jt++) {
395 q.push(*jt);
396 }
397 }
398
399 RemoveInnerWindowInfo(id);
400 }
401 return;
402 }
403
Move(int32_t id,int32_t x,int32_t y)404 void LayerControllerClient::Move(int32_t id, int32_t x, int32_t y)
405 {
406 LOCK(mutex);
407
408 InnerWindowInfo *wininfo = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
409 if (wininfo == nullptr) {
410 WMLOGFE("id: %{public}d, window info is nullptr", id);
411 return;
412 }
413 wininfo->pos_x = x;
414 wininfo->pos_y = y;
415 wininfo->windowconfig.pos_x = x;
416 wininfo->windowconfig.pos_y = y;
417
418 if (wininfo->subwidow) {
419 wininfo->wlSubsurf->SetPosition(x, y);
420 } else {
421 WMLOG_I("LayerControllerClient::Move id(%{public}d) x(%{public}d) y(%{public}d)", id, x, y);
422 wms->Move(id, x, y);
423 }
424
425 struct WindowInfo info = {
426 .width = wininfo->width,
427 .height = wininfo->height,
428 .pos_x = wininfo->pos_x,
429 .pos_y = wininfo->pos_y
430 };
431
432 if (wininfo->windowInfoChangeCb) {
433 wininfo->windowInfoChangeCb(info);
434 }
435 }
436
ReSize(int32_t id,int32_t width,int32_t height)437 void LayerControllerClient::ReSize(int32_t id, int32_t width, int32_t height)
438 {
439 WMLOG_I("LayerControllerClient::ReSize id(%{public}d) width(%{public}d) width(%{public}d)", id, width, height);
440 LOCK(mutex);
441
442 InnerWindowInfo *wininfo = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
443 if (wininfo == nullptr) {
444 WMLOGFE("id: %{public}d, window info is nullptr", id);
445 return;
446 }
447 wininfo->windowconfig.width = width;
448 wininfo->windowconfig.height = height;
449 wininfo->width = width;
450 wininfo->height = height;
451
452 if (wininfo->subwidow) {
453 SetSubSurfaceSize(id, width, height);
454 } else {
455 wms->Resize(id, width, height);
456 }
457
458 struct WindowInfo info = {
459 .width = wininfo->width,
460 .height = wininfo->height,
461 .pos_x = wininfo->pos_x,
462 .pos_y = wininfo->pos_y
463 };
464
465 if (wininfo->windowInfoChangeCb) {
466 wininfo->windowInfoChangeCb(info);
467 }
468 }
469
Show(int32_t id)470 void LayerControllerClient::Show(int32_t id)
471 {
472 LOCK(mutex);
473 WMLOG_I("LayerControllerClient::Show id=%{public}d", id);
474 wms->Show(id);
475 }
476
Hide(int32_t id)477 void LayerControllerClient::Hide(int32_t id)
478 {
479 LOCK(mutex);
480 WMLOG_I("LayerControllerClient::Hide id=%{public}d", id);
481 wms->Hide(id);
482 }
483
Rotate(int32_t id,int32_t type)484 void LayerControllerClient::Rotate(int32_t id, int32_t type)
485 {
486 LOCK(mutex);
487 WMLOG_I("LayerControllerClient::Rotate id=%{public}d type=%{public}d start", id, type);
488 InnerWindowInfo *wininfo = LayerControllerClient::GetInstance()->GetInnerWindowInfoFromId((uint32_t)id);
489 if (wininfo == nullptr) {
490 WMLOGFE("id: %{public}d, window info is nullptr", id);
491 return;
492 }
493 wininfo->wlSurface->SetBufferTransform(static_cast<wl_output_transform>(type));
494 wininfo->wlSurface->Commit();
495 }
496
GetMaxWidth()497 int32_t LayerControllerClient::GetMaxWidth()
498 {
499 if (m_screenWidth == 0) {
500 std::vector<WMDisplayInfo> displays;
501 wms->GetDisplays(displays);
502 if (displays.size() != 0) {
503 m_screenWidth = displays[0].width;
504 m_screenHeight = displays[0].height;
505 }
506 }
507 WMLOG_I("LayerControllerClient::GetMaxWidth m_screenWidth=%{public}d", m_screenWidth);
508 return m_screenWidth;
509 }
510
GetMaxHeight()511 int32_t LayerControllerClient::GetMaxHeight()
512 {
513 if (m_screenHeight == 0) {
514 std::vector<WMDisplayInfo> displays;
515 wms->GetDisplays(displays);
516 if (displays.size() != 0) {
517 m_screenWidth = displays[0].width;
518 m_screenHeight = displays[0].height;
519 }
520 }
521 WMLOG_I("LayerControllerClient::GetMaxHeight m_screenHeight=%{public}d", m_screenHeight);
522 return m_screenHeight;
523 }
524
ProcessWindowInfo(InnerWindowInfo & info,sptr<IWindowManagerService> & wms)525 void ProcessWindowInfo(InnerWindowInfo &info, sptr<IWindowManagerService> &wms)
526 {
527 int layerid = WINDOW_LAYER_DEFINE_NORMAL_ID;
528 layerid += info.windowconfig.type * LAYER_ID_TYPE_OFSSET;
529 if (info.subwidow) {
530 if (info.windowconfig.type == WINDOW_TYPE_VIDEO) {
531 VideoWindow::DestroyLayer(info.voLayerId);
532 }
533 } else {
534 wms->DestroyWindow(info.windowid);
535 }
536
537 if (info.surf) {
538 info.surf->CleanCache();
539 }
540
541 LogListener::GetInstance()->RemoveListener(info.logListener);
542 }
543
RemoveInnerWindowInfo(uint32_t id)544 void LayerControllerClient::RemoveInnerWindowInfo(uint32_t id)
545 {
546 LOCK(windowListMutex);
547
548 for (auto it = m_windowList.begin(); it != m_windowList.end(); it++) {
549 if (it->windowid == id) {
550 ProcessWindowInfo(*it, wms);
551 m_windowList.erase(it);
552 it--;
553 break;
554 }
555 }
556 }
557
GetInnerWindowInfoFromId(uint32_t windowid)558 InnerWindowInfo *LayerControllerClient::GetInnerWindowInfoFromId(uint32_t windowid)
559 {
560 LOCK(windowListMutex);
561 for (auto &info : m_windowList) {
562 if (info.windowid == windowid) {
563 return &info;
564 }
565 }
566
567 return nullptr;
568 }
569
SurfaceListener(sptr<Surface> & surf,uint32_t windowid)570 SurfaceListener::SurfaceListener(sptr<Surface>& surf, uint32_t windowid)
571 {
572 WMLOG_I("DEBUG SurfaceListener");
573 surface_ = surf;
574 windowid_ = windowid;
575 }
576
~SurfaceListener()577 SurfaceListener::~SurfaceListener()
578 {
579 WMLOG_I("DEBUG ~SurfaceListener");
580 surface_ = nullptr;
581 }
582
OnBufferAvailable()583 void SurfaceListener::OnBufferAvailable()
584 {
585 WMLOG_I("OnBufferAvailable");
586 auto surf = surface_.promote();
587 if (surf) {
588 LayerControllerClient::GetInstance()->CreateWlBuffer(surf, windowid_);
589 } else {
590 WMLOG_E("surf.promote failed");
591 }
592 }
593 }
594