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