• 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.h"
17 
18 #include <cstring>
19 #include <sys/mman.h>
20 
21 #include <display_type.h>
22 #include <iservice_registry.h>
23 #include <securec.h>
24 #include <system_ability_definition.h>
25 #include <window_manager_service_client.h>
26 
27 #include "video_window.h"
28 #include "window_manager_controller_client.h"
29 #include "window_manager_hilog.h"
30 
31 namespace OHOS {
32 namespace {
33 sptr<IWindowManagerService> g_windowManagerService = nullptr;
34 }
35 
WindowBase(int32_t windowid,sptr<Surface> & surf)36 WindowBase::WindowBase(int32_t windowid, sptr<Surface>& surf)
37 {
38     WMLOG_I("DEBUG WindowBase");
39     m_windowid = windowid;
40     surface_ = surf;
41     BufferRequestConfig config = {
42         .width = 0,
43         .height = 0,
44         .strideAlignment = 0,
45         .format = 0,
46         .usage = 0,
47         .timeout = 0,
48     };
49     config_ = config;
50 }
51 
~WindowBase()52 WindowBase::~WindowBase()
53 {
54     WMLOG_I("DEBUG ~WindowBase");
55     surface_ = nullptr;
56 }
57 
GetRequestConfig(BufferRequestConfig & config)58 void WindowBase::GetRequestConfig(BufferRequestConfig &config)
59 {
60     config = config_;
61 }
62 
SetRequestConfig(BufferRequestConfig & config)63 void WindowBase::SetRequestConfig(BufferRequestConfig &config)
64 {
65     config_ = config;
66 }
67 
RegistWindowInfoChangeCb(funcWindowInfoChange cb)68 void WindowBase::RegistWindowInfoChangeCb(funcWindowInfoChange cb)
69 {
70     WMLOG_I("WindowBase::RegistWindowInfoChangeCb start");
71     LayerControllerClient::GetInstance()->RegistWindowInfoChangeCb(m_windowid, cb);
72     WMLOG_I("WindowBase::RegistWindowInfoChangeCb end");
73 }
74 
GetWindowID()75 int32_t WindowBase::GetWindowID()
76 {
77     return m_windowid;
78 }
79 
GetSurface()80 sptr<Surface> WindowBase::GetSurface()
81 {
82     return surface_;
83 }
84 
WindowManager()85 WindowManager::WindowManager()
86 {
87     WMLOG_I("DEBUG WindowManager");
88     init();
89 }
90 
~WindowManager()91 WindowManager::~WindowManager()
92 {
93     WMLOG_I("DEBUG ~WindowManager");
94     WMLOG_I("WindowManager::~WindowManager");
95 }
96 
97 sptr<WindowManager> WindowManager::instance = nullptr;
GetInstance()98 sptr<WindowManager> WindowManager::GetInstance()
99 {
100     if (instance == nullptr) {
101         static std::mutex mutex;
102         std::lock_guard<std::mutex> lock(mutex);
103         if (instance == nullptr) {
104             instance = new WindowManager();
105         }
106     }
107 
108     return instance;
109 }
110 
init()111 void WindowManager::init()
112 {
113     WMLOG_I("WindowManager::init start");
114     if (WlDisplay::GetInstance()->Connect(nullptr) == false) {
115         WMLOG_E("create display failed!");
116         exit(1);
117     }
118 
119     if (g_windowManagerService == nullptr) {
120         auto wmsc = WindowManagerServiceClient::GetInstance();
121         GSError wret = wmsc->Init();
122         if (wret != GSERROR_OK) {
123             WMLOG_E("WMService init failed");
124             fprintf(stderr, "WMService init failed");
125             exit(1);
126         }
127         g_windowManagerService = wmsc->GetService();
128     }
129     WMLOG_I("WindowManager::init end");
130 
131     if (LayerControllerClient::GetInstance()->init(g_windowManagerService) == false) {
132         exit(1);
133     }
134 }
135 
136 namespace {
CreateWlSurface(WindowConfig * config)137 sptr<WlSurface> CreateWlSurface(WindowConfig *config)
138 {
139     if (config == nullptr) {
140         WMLOG_I("WindowManager::CreateWindow config is nullptr");
141         return nullptr;
142     }
143 
144     auto wlSurface = WlSurfaceFactory::GetInstance()->Create();
145     if (wlSurface == nullptr) {
146         WMLOG_I("Error: CreateSurface WlSurfaceFactory::Create failed");
147         return nullptr;
148     }
149     return wlSurface;
150 }
151 }
152 
CreateWindow(WindowConfig * config)153 std::unique_ptr<Window> WindowManager::CreateWindow(WindowConfig *config)
154 {
155     WMLOG_I("WindowManager::CreateWindow start");
156     if (g_windowManagerService == nullptr) {
157         WMLOG_I("WindowManager::%{public}s g_windowManagerService is nullptr init again", __func__);
158         init();
159         if (g_windowManagerService == nullptr) {
160             WMLOG_I("WindowManager::%{public}s widow failed", __func__);
161             return nullptr;
162         }
163     }
164 
165     auto wlSurface = CreateWlSurface(config);
166     if (wlSurface == nullptr) {
167         return nullptr;
168     }
169 
170     auto wms = WindowManagerServer::GetInstance();
171     auto promise = wms->CreateWindow(wlSurface, 0, static_cast<WindowType>(config->type));
172     auto wminfo = promise->Await();
173     if (wminfo.wret != GSERROR_OK) {
174         WMLOG_E("Error: wms->CreateWindow failed, %{public}s", GSErrorStr(wminfo.wret).c_str());
175         return nullptr;
176     }
177     WMLOG_I("WindowManager::CreateWindow widow ID is %{public}d", wminfo.wid);
178 
179     config->pos_x = wminfo.x;
180     config->pos_y = wminfo.y;
181     config->width = wminfo.width;
182     config->height = wminfo.height;
183 
184     InnerWindowInfo *windowInfo = LayerControllerClient::GetInstance()->CreateWindow(wminfo.wid, *config);
185     if (windowInfo == nullptr) {
186         WMLOG_I("WindowManager::CreateWindow widow ID  %{public}d failed", wminfo.wid);
187         return nullptr;
188     }
189 
190     windowInfo->wlSurface = wlSurface;
191     windowInfo->wlSurface->SetUserData(&windowInfo->windowid);
192 
193     auto producer = windowInfo->surf->GetProducer();
194     sptr<Surface> surf = Surface::CreateSurfaceAsProducer(producer);
195     std::unique_ptr<Window> ret_win = std::make_unique<Window>(windowInfo->windowid, surf);
196 
197     BufferRequestConfig requestConfig = {
198         .width = wminfo.width,
199         .height = wminfo.height,
200         .strideAlignment = 0x8,
201         .format = config->format,
202         .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
203         .timeout = 0,
204     };
205     ret_win->SetRequestConfig(requestConfig);
206 
207     WMLOG_I("WindowManager::CreateWindow widow ID  %{public}d success", wminfo.wid);
208     return ret_win;
209 }
210 
CreateSubWindow(int32_t parentid,WindowConfig * config)211 std::unique_ptr<SubWindow> WindowManager::CreateSubWindow(int32_t parentid, WindowConfig *config)
212 {
213     WMLOG_I("WindowManager::CreateSubWindow start");
214     if (config == nullptr) {
215         WMLOG_I("WindowManager::CreateSubWindow config is nullptr");
216         return nullptr;
217     }
218 
219     if (g_windowManagerService == nullptr) {
220         WMLOG_I("WindowManager::%{public}s g_windowManagerService is nullptr init again", __func__);
221         init();
222         if (g_windowManagerService == nullptr) {
223             WMLOG_I("WindowManager::%{public}s widow failed", __func__);
224             return nullptr;
225         }
226     }
227 
228     config->subwindow = true;
229     config->parentid = parentid;
230 
231     constexpr uint32_t scale = 320;
232     static int32_t id = getpid() * scale - 1;
233     id++;
234     WMLOG_I("WindowManager::CreateSubWindow widow ID is %{public}d", id);
235 
236     InnerWindowInfo *windowInfo = LayerControllerClient::GetInstance()->CreateSubWindow(id, parentid, *config);
237     if (windowInfo == nullptr) {
238         WMLOG_I("WindowManager::CreateSubWindow widow ID  %{public}d failed", id);
239         return nullptr;
240     }
241 
242     std::unique_ptr<SubWindow> ret_win;
243     if (config->type != WINDOW_TYPE_VIDEO || windowInfo->voLayerId == -1U) {
244         auto producer = windowInfo->surf->GetProducer();
245         sptr<Surface> surf = Surface::CreateSurfaceAsProducer(producer);
246         ret_win = std::make_unique<SubWindow>(windowInfo->windowid, surf);
247     } else {
248         ret_win = std::make_unique<VideoWindow>(*windowInfo);
249     }
250     BufferRequestConfig requestConfig = {
251         .width = config->width,
252         .height = config->height,
253         .strideAlignment = 0x8,
254         .format = config->format,
255         .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
256         .timeout = 0,
257     };
258     ret_win->SetRequestConfig(requestConfig);
259     WMLOG_I("WindowManager::CreateSubWindow widow ID  %{public}d success", id);
260     return ret_win;
261 }
262 
StartShotScreen(IScreenShotCallback * cb)263 void WindowManager::StartShotScreen(IScreenShotCallback *cb)
264 {
265     WMLOG_I("WindowManager::StartShotScreen start type");
266     auto promise = g_windowManagerService->ShotScreen(0);
267     if (promise == nullptr) {
268         WMLOG_E("promise is nullptr");
269         return;
270     }
271 
272     auto then = [cb](const auto &wmsinfo) {
273         WMImageInfo wminfo = {
274             .wret = wmsinfo.wret,
275             .width = wmsinfo.width,
276             .height = wmsinfo.height,
277             .format = wmsinfo.format,
278             .size = wmsinfo.stride * wmsinfo.height,
279             .data = nullptr,
280         };
281         auto data = mmap(nullptr, wminfo.size, PROT_READ, MAP_SHARED, wmsinfo.fd, 0);
282         wminfo.data = data;
283 
284         cb->OnScreenShot(wminfo);
285 
286         // 0xffffffff
287         uint8_t *errPtr = nullptr;
288         errPtr--;
289         if (data != errPtr) {
290             munmap(data, wminfo.size);
291         }
292     };
293     promise->Then(then);
294 }
295 
StartShotWindow(int32_t id,IWindowShotCallback * cb)296 void WindowManager::StartShotWindow(int32_t id, IWindowShotCallback *cb)
297 {
298     WMLOG_I("WindowManager::StartShotWindow start winID = %{public}d", id);
299     auto promise = g_windowManagerService->ShotScreen(id);
300     if (promise == nullptr) {
301         WMLOG_E("promise is nullptr");
302         return;
303     }
304 
305     auto then = [cb](const auto &wmsinfo) {
306         WMImageInfo wminfo = {
307             .wret = wmsinfo.wret,
308             .width = wmsinfo.width,
309             .height = wmsinfo.height,
310             .format = wmsinfo.format,
311             .size = wmsinfo.stride * wmsinfo.height,
312             .data = nullptr,
313         };
314         auto data = mmap(nullptr, wminfo.size, PROT_READ, MAP_SHARED, wmsinfo.fd, 0);
315         wminfo.data = data;
316 
317         cb->OnWindowShot(wminfo);
318 
319         // 0xffffffff
320         uint8_t *errPtr = nullptr;
321         errPtr--;
322         if (data != errPtr) {
323             WMLOG_I("StartShotScreen memset_s failed");
324         }
325 
326         if (data != errPtr) {
327             munmap(data, wminfo.size);
328         }
329     };
330     promise->Then(then);
331 }
332 
GetMaxWidth()333 int32_t WindowManager::GetMaxWidth()
334 {
335     WMLOG_I("WindowManager::GetMaxWidth start");
336     return LayerControllerClient::GetInstance()->GetMaxWidth();
337 }
338 
GetMaxHeight()339 int32_t WindowManager::GetMaxHeight()
340 {
341     WMLOG_I("WindowManager::GetMaxHeigth start");
342     return LayerControllerClient::GetInstance()->GetMaxHeight();
343 }
344 
SwitchTop(int32_t windowId)345 void WindowManager::SwitchTop(int32_t windowId)
346 {
347     WMLOG_I("WindowsManager::SwitchTop start id(%{public}d)", windowId);
348     if (g_windowManagerService != nullptr) {
349         g_windowManagerService->SwitchTop(windowId);
350     }
351     WMLOG_I("WindowsManager::SwitchTop end");
352 }
353 
DestroyWindow(int32_t windowId)354 void WindowManager::DestroyWindow(int32_t windowId)
355 {
356     WMLOG_I("WindowsManager::DestroyWindow start id(%{public}d)", windowId);
357     LayerControllerClient::GetInstance()->DestroyWindow(windowId);
358     WMLOG_I("WindowsManager::DestroyWindow end");
359 }
360 
Window(int32_t windowid,sptr<Surface> & surf)361 Window::Window(int32_t windowid, sptr<Surface>& surf) : WindowBase(windowid, surf)
362 {
363     WMLOG_I("DEBUG Window");
364 }
365 
~Window()366 Window::~Window()
367 {
368     WMLOG_I("DEBUG ~Window id(%{public}d)", m_windowid);
369     LayerControllerClient::GetInstance()->DestroyWindow(m_windowid);
370 }
371 
Move(int32_t x,int32_t y)372 void Window::Move(int32_t x, int32_t y)
373 {
374     WMLOG_I("Window::Move start");
375     LayerControllerClient::GetInstance()->Move(m_windowid, x, y);
376     WMLOG_I("Window::Move end");
377 }
378 
Hide()379 void Window::Hide()
380 {
381     WMLOG_I("Window::Hide start");
382     LayerControllerClient::GetInstance()->Hide(m_windowid);
383     WMLOG_I("Window::Hide end");
384 }
385 
Show()386 void Window::Show()
387 {
388     WMLOG_I("Window::Show start");
389     LayerControllerClient::GetInstance()->Show(m_windowid);
390     WMLOG_I("Window::Show end");
391 }
392 
SwitchTop()393 void Window::SwitchTop()
394 {
395     WMLOG_I("Window::SwitchTop start");
396     if (g_windowManagerService) {
397         g_windowManagerService->SwitchTop(m_windowid);
398     }
399     WMLOG_I("Window::SwitchTop end");
400 }
401 
ReSize(int32_t width,int32_t height)402 void Window::ReSize(int32_t width, int32_t height)
403 {
404     WMLOG_I("Window::Resize start");
405     config_.width = width;
406     config_.height = height;
407     LayerControllerClient::GetInstance()->ReSize(m_windowid, width, height);
408     WMLOG_I("Window::Resize end");
409 }
410 
Rotate(rotateType type)411 void Window::Rotate(rotateType type)
412 {
413     WMLOG_I("Window::Rotate start");
414     LayerControllerClient::GetInstance()->Rotate(m_windowid, static_cast<int32_t>(type));
415     WMLOG_I("Window::Rotate end");
416 }
417 
ChangeWindowType(WindowType type)418 void Window::ChangeWindowType(WindowType type)
419 {
420     WMLOG_I("Window::ChangeWindowType start");
421     LayerControllerClient::GetInstance()->ChangeWindowType(m_windowid, type);
422     WMLOG_I("Window::ChangeWindowType end");
423 }
424 
RegistOnWindowCreateCb(void (* cb)(uint32_t pid))425 void Window::RegistOnWindowCreateCb(void(* cb)(uint32_t pid))
426 {
427     LayerControllerClient::GetInstance()->RegistOnWindowCreateCb(m_windowid, cb);
428 }
429 
SubWindow(int32_t windowid,sptr<Surface> & surf)430 SubWindow::SubWindow(int32_t windowid, sptr<Surface>& surf) : WindowBase(windowid, surf)
431 {
432     WMLOG_I("DEBUG SubWindow");
433 }
434 
~SubWindow()435 SubWindow::~SubWindow()
436 {
437     WMLOG_I("DEBUG ~SubWindow id(%{public}d)", m_windowid);
438     LayerControllerClient::GetInstance()->DestroyWindow(m_windowid);
439 }
440 
Move(int32_t x,int32_t y)441 void SubWindow::Move(int32_t x, int32_t y)
442 {
443     WMLOG_I("Window::Move start");
444     LayerControllerClient::GetInstance()->Move(m_windowid, x, y);
445     WMLOG_I("Window::Move end");
446 }
447 
SetSubWindowSize(int32_t width,int32_t height)448 void SubWindow::SetSubWindowSize(int32_t width, int32_t height)
449 {
450     WMLOG_I("Window::SetSubWindowSize start");
451     LayerControllerClient::GetInstance()->ReSize(m_windowid, width, height);
452     config_.width = width;
453     config_.height = height;
454     WMLOG_I("Window::SetSubWindowSize end");
455 }
456 }
457