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