1 /*
2  * Copyright (c) 2021-2022 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 "native_window.h"
17 
18 #include <cstdint>
19 #include <map>
20 #include <cinttypes>
21 #include <securec.h>
22 #include "buffer_log.h"
23 #include "window.h"
24 #include "surface_type.h"
25 #include "surface_utils.h"
26 #include "sync_fence.h"
27 #include "ipc_inner_object.h"
28 #include "external_window.h"
29 #include "metadata_helper.h"
30 
31 #ifndef WEAK_ALIAS
32     #define WEAK_ALIAS(old, new) \
33         extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))
34 #endif
35 
36 using namespace OHOS;
37 using namespace HDI::Display::Graphic::Common::V1_0;
38 static std::unordered_map<OH_NativeBuffer_ColorSpace, CM_ColorSpaceType> NATIVE_COLORSPACE_TO_HDI_MAP = {
39     {OH_COLORSPACE_NONE, CM_COLORSPACE_NONE},
40     {OH_COLORSPACE_BT601_EBU_FULL, CM_BT601_EBU_FULL},
41     {OH_COLORSPACE_BT601_SMPTE_C_FULL, CM_BT601_SMPTE_C_FULL},
42     {OH_COLORSPACE_BT709_FULL, CM_BT709_FULL},
43     {OH_COLORSPACE_BT2020_HLG_FULL, CM_BT2020_HLG_FULL},
44     {OH_COLORSPACE_BT2020_PQ_FULL, CM_BT2020_PQ_FULL},
45     {OH_COLORSPACE_BT601_EBU_LIMIT, CM_BT601_EBU_LIMIT},
46     {OH_COLORSPACE_BT601_SMPTE_C_LIMIT, CM_BT601_SMPTE_C_LIMIT},
47     {OH_COLORSPACE_BT709_LIMIT, CM_BT709_LIMIT},
48     {OH_COLORSPACE_BT2020_HLG_LIMIT, CM_BT2020_HLG_LIMIT},
49     {OH_COLORSPACE_BT2020_PQ_LIMIT, CM_BT2020_PQ_LIMIT},
50     {OH_COLORSPACE_SRGB_FULL, CM_SRGB_FULL},
51     {OH_COLORSPACE_P3_FULL, CM_P3_FULL},
52     {OH_COLORSPACE_P3_HLG_FULL, CM_P3_HLG_FULL},
53     {OH_COLORSPACE_P3_PQ_FULL, CM_P3_PQ_FULL},
54     {OH_COLORSPACE_ADOBERGB_FULL, CM_ADOBERGB_FULL},
55     {OH_COLORSPACE_SRGB_LIMIT, CM_SRGB_LIMIT},
56     {OH_COLORSPACE_P3_LIMIT, CM_P3_LIMIT},
57     {OH_COLORSPACE_P3_HLG_LIMIT, CM_P3_HLG_LIMIT},
58     {OH_COLORSPACE_P3_PQ_LIMIT, CM_P3_PQ_LIMIT},
59     {OH_COLORSPACE_ADOBERGB_LIMIT, CM_ADOBERGB_LIMIT},
60     {OH_COLORSPACE_LINEAR_SRGB, CM_LINEAR_SRGB},
61     {OH_COLORSPACE_LINEAR_BT709, CM_LINEAR_BT709},
62     {OH_COLORSPACE_LINEAR_P3, CM_LINEAR_P3},
63     {OH_COLORSPACE_LINEAR_BT2020, CM_LINEAR_BT2020},
64     {OH_COLORSPACE_DISPLAY_SRGB, CM_DISPLAY_SRGB},
65     {OH_COLORSPACE_DISPLAY_P3_SRGB, CM_DISPLAY_P3_SRGB},
66     {OH_COLORSPACE_DISPLAY_P3_HLG, CM_DISPLAY_P3_HLG},
67     {OH_COLORSPACE_DISPLAY_P3_PQ, CM_DISPLAY_P3_PQ},
68     {OH_COLORSPACE_DISPLAY_BT2020_SRGB, CM_DISPLAY_BT2020_SRGB},
69     {OH_COLORSPACE_DISPLAY_BT2020_HLG, CM_DISPLAY_BT2020_HLG},
70     {OH_COLORSPACE_DISPLAY_BT2020_PQ, CM_DISPLAY_BT2020_PQ}
71 };
72 
73 static std::unordered_map<OH_NativeBuffer_MetadataType, CM_HDR_Metadata_Type> NATIVE_METADATATYPE_TO_HDI_MAP = {
74     {OH_VIDEO_HDR_HLG, CM_VIDEO_HLG},
75     {OH_VIDEO_HDR_HDR10, CM_VIDEO_HDR10},
76     {OH_VIDEO_HDR_VIVID, CM_VIDEO_HDR_VIVID},
77 };
78 
79 namespace {
80     constexpr int32_t INVALID_PARAM = -1;
81     constexpr int32_t META_DATA_MAX_SIZE = 3000;
82     constexpr int32_t DAMAGES_MAX_SIZE = 1000;
83     constexpr int32_t MAXIMUM_LENGTH_OF_APP_FRAMEWORK = 64;
84 }
85 
CreateNativeWindowFromSurface(void * pSurface)86 OHNativeWindow* CreateNativeWindowFromSurface(void* pSurface)
87 {
88     if (pSurface == nullptr) {
89         return nullptr;
90     }
91 
92     OHNativeWindow* nativeWindow = new OHNativeWindow();
93     nativeWindow->surface =
94                 *reinterpret_cast<OHOS::sptr<OHOS::Surface> *>(pSurface);
95     if (nativeWindow->surface == nullptr) {
96         BLOGE("window surface is null");
97         delete nativeWindow;
98         return nullptr;
99     }
100     OHOS::BufferRequestConfig *windowConfig = nativeWindow->surface->GetWindowConfig();
101     if (windowConfig == nullptr) {
102         BLOGE("windowConfig is null, uniqueId: %{public}" PRIu64 ".", nativeWindow->surface->GetUniqueId());
103         delete nativeWindow;
104         return nullptr;
105     }
106     windowConfig->width = nativeWindow->surface->GetDefaultWidth();
107     windowConfig->height = nativeWindow->surface->GetDefaultHeight();
108     windowConfig->usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
109     windowConfig->format = GRAPHIC_PIXEL_FMT_RGBA_8888;
110     windowConfig->strideAlignment = 8;   // default stride is 8
111     windowConfig->timeout = 3000;        // default timeout is 3000 ms
112     windowConfig->colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
113     windowConfig->transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
114 
115     NativeObjectReference(nativeWindow);
116     auto utils = SurfaceUtils::GetInstance();
117     utils->AddNativeWindow(nativeWindow->surface->GetUniqueId(), nativeWindow);
118     nativeWindow->surface->SetWptrNativeWindowToPSurface(nativeWindow);
119     return nativeWindow;
120 }
121 
DestoryNativeWindow(OHNativeWindow * window)122 void DestoryNativeWindow(OHNativeWindow *window)
123 {
124     if (window == nullptr) {
125         return;
126     }
127     // unreference nativewindow object
128     NativeObjectUnreference(window);
129 }
130 
CreateNativeWindowBufferFromSurfaceBuffer(void * pSurfaceBuffer)131 OHNativeWindowBuffer* CreateNativeWindowBufferFromSurfaceBuffer(void* pSurfaceBuffer)
132 {
133     if (pSurfaceBuffer == nullptr) {
134         return nullptr;
135     }
136     OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
137     nwBuffer->sfbuffer = *reinterpret_cast<OHOS::sptr<OHOS::SurfaceBuffer> *>(pSurfaceBuffer);
138     NativeObjectReference(nwBuffer);
139     return nwBuffer;
140 }
141 
CreateNativeWindowBufferFromNativeBuffer(OH_NativeBuffer * nativeBuffer)142 OHNativeWindowBuffer* CreateNativeWindowBufferFromNativeBuffer(OH_NativeBuffer* nativeBuffer)
143 {
144     if (nativeBuffer == nullptr) {
145         return nullptr;
146     }
147     OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
148     OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer(reinterpret_cast<OHOS::SurfaceBuffer *>(nativeBuffer));
149     nwBuffer->sfbuffer = surfaceBuffer;
150 
151     NativeObjectReference(nwBuffer);
152     return nwBuffer;
153 }
154 
DestroyNativeWindowBuffer(OHNativeWindowBuffer * buffer)155 void DestroyNativeWindowBuffer(OHNativeWindowBuffer* buffer)
156 {
157     if (buffer == nullptr) {
158         return;
159     }
160     NativeObjectUnreference(buffer);
161 }
162 
NativeWindowRequestBuffer(OHNativeWindow * window,OHNativeWindowBuffer ** buffer,int * fenceFd)163 int32_t NativeWindowRequestBuffer(OHNativeWindow *window,
164     OHNativeWindowBuffer **buffer, int *fenceFd)
165 {
166     if (window == nullptr || buffer == nullptr || fenceFd == nullptr) {
167         return OHOS::SURFACE_ERROR_INVALID_PARAM;
168     }
169     OHOS::sptr<OHOS::SurfaceBuffer> sfbuffer;
170     OHOS::sptr<OHOS::SyncFence> releaseFence = OHOS::SyncFence::InvalidFence();
171     BLOGE_CHECK_AND_RETURN_RET(window->surface != nullptr, SURFACE_ERROR_ERROR, "window surface is null");
172     int32_t ret;
173     int32_t requestWidth = window->surface->GetRequestWidth();
174     int32_t requestHeight = window->surface->GetRequestHeight();
175     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
176     if (requestWidth != 0 && requestHeight != 0) {
177         OHOS::BufferRequestConfig config;
178         if (memcpy_s(&config, sizeof(OHOS::BufferRequestConfig), windowConfig,
179             sizeof(OHOS::BufferRequestConfig)) != EOK) {
180             BLOGE("memcpy_s failed, uniqueId: %{public}" PRIu64 ".", window->surface->GetUniqueId());
181             return OHOS::SURFACE_ERROR_UNKOWN;
182         }
183         config.width = requestWidth;
184         config.height = requestHeight;
185         ret = window->surface->RequestBuffer(sfbuffer, releaseFence, config);
186     } else {
187         ret = window->surface->RequestBuffer(sfbuffer, releaseFence, *windowConfig);
188     }
189     if (ret != OHOS::GSError::SURFACE_ERROR_OK || sfbuffer == nullptr) {
190         BLOGE("RequestBuffer ret:%{public}d, uniqueId: %{public}" PRIu64 ".",
191                 ret, window->surface->GetUniqueId());
192         return ret;
193     }
194     uint32_t seqNum = sfbuffer->GetSeqNum();
195     if (window->bufferCache_.find(seqNum) == window->bufferCache_.end()) {
196         OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
197         nwBuffer->sfbuffer = sfbuffer;
198         nwBuffer->uiTimestamp = window->uiTimestamp;
199         *buffer = nwBuffer;
200         // Add to cache
201         NativeObjectReference(nwBuffer);
202         window->bufferCache_[seqNum] = nwBuffer;
203     } else {
204         *buffer = window->bufferCache_[seqNum];
205         (*buffer)->uiTimestamp = window->uiTimestamp;
206     }
207     *fenceFd = releaseFence->Dup();
208     return OHOS::SURFACE_ERROR_OK;
209 }
210 
NativeWindowFlushBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer,int fenceFd,struct Region region)211 int32_t NativeWindowFlushBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer,
212     int fenceFd, struct Region region)
213 {
214     if (window == nullptr || buffer == nullptr || window->surface == nullptr) {
215         return OHOS::SURFACE_ERROR_INVALID_PARAM;
216     }
217 
218     OHOS::BufferFlushConfigWithDamages config;
219     if ((region.rectNumber <= DAMAGES_MAX_SIZE) && (region.rectNumber > 0) && (region.rects != nullptr)) {
220         config.damages.reserve(region.rectNumber);
221         for (int32_t i = 0; i < region.rectNumber; i++) {
222             OHOS::Rect damage = {
223                 .x = region.rects[i].x,
224                 .y = region.rects[i].y,
225                 .w = static_cast<int32_t>(region.rects[i].w),
226                 .h = static_cast<int32_t>(region.rects[i].h),
227             };
228             config.damages.emplace_back(damage);
229         }
230         config.timestamp = buffer->uiTimestamp;
231     } else {
232         OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
233         config.damages.reserve(1);
234         OHOS::Rect damage = {
235             .x = 0,
236             .y = 0,
237             .w = windowConfig->width,
238             .h = windowConfig->height,
239         };
240         config.damages.emplace_back(damage);
241         config.timestamp = buffer->uiTimestamp;
242     }
243     config.desiredPresentTimestamp = window->desiredPresentTimestamp;
244     OHOS::sptr<OHOS::SyncFence> acquireFence = new OHOS::SyncFence(fenceFd);
245     int32_t ret = window->surface->FlushBuffer(buffer->sfbuffer, acquireFence, config);
246     if (ret != OHOS::GSError::SURFACE_ERROR_OK) {
247         BLOGE("FlushBuffer failed, ret:%{public}d, uniqueId: %{public}" PRIu64 ".",
248             ret, window->surface->GetUniqueId());
249         return ret;
250     }
251 
252     auto it = std::find_if(window->bufferCache_.begin(), window->bufferCache_.end(),
253         [buffer](const std::pair<uint32_t, NativeWindowBuffer*>& element) {
254             return element.second == buffer;
255         });
256     if (it != window->bufferCache_.end()) {
257         window->lastBufferSeqNum = it->first;
258     }
259 
260     return OHOS::SURFACE_ERROR_OK;
261 }
262 
GetLastFlushedBuffer(OHNativeWindow * window,OHNativeWindowBuffer ** buffer,int * fenceFd,float matrix[16])263 int32_t GetLastFlushedBuffer(OHNativeWindow *window, OHNativeWindowBuffer **buffer, int *fenceFd, float matrix[16])
264 {
265     if (window == nullptr || buffer == nullptr || window->surface == nullptr || fenceFd == nullptr) {
266         return OHOS::SURFACE_ERROR_INVALID_PARAM;
267     }
268     OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
269     OHOS::sptr<OHOS::SyncFence> acquireFence = OHOS::SyncFence::InvalidFence();
270     int32_t ret = window->surface->GetLastFlushedBuffer(nwBuffer->sfbuffer, acquireFence, matrix, false);
271     if (ret != OHOS::GSError::SURFACE_ERROR_OK || nwBuffer->sfbuffer == nullptr) {
272         BLOGE("GetLastFlushedBuffer fail, uniqueId: %{public}" PRIu64 ".", window->surface->GetUniqueId());
273         delete nwBuffer;
274         nwBuffer = nullptr;
275         return ret;
276     }
277     *buffer = nwBuffer;
278     NativeObjectReference(nwBuffer);
279     *fenceFd = acquireFence->Dup();
280     return OHOS::SURFACE_ERROR_OK;
281 }
282 
NativeWindowAttachBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer)283 int32_t NativeWindowAttachBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer)
284 {
285     if (window == nullptr || buffer == nullptr) {
286         return OHOS::SURFACE_ERROR_INVALID_PARAM;
287     }
288     BLOGE_CHECK_AND_RETURN_RET(window->surface != nullptr, SURFACE_ERROR_INVALID_PARAM, "window surface is null");
289     return window->surface->AttachBufferToQueue(buffer->sfbuffer);
290 }
291 
NativeWindowDetachBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer)292 int32_t NativeWindowDetachBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer)
293 {
294     if (window == nullptr || buffer == nullptr) {
295         return OHOS::SURFACE_ERROR_INVALID_PARAM;
296     }
297     BLOGE_CHECK_AND_RETURN_RET(window->surface != nullptr, SURFACE_ERROR_INVALID_PARAM, "window surface is null");
298     return window->surface->DetachBufferFromQueue(buffer->sfbuffer);
299 }
300 
NativeWindowCancelBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer)301 int32_t NativeWindowCancelBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer)
302 {
303     if (window == nullptr || buffer == nullptr) {
304         return OHOS::SURFACE_ERROR_INVALID_PARAM;
305     }
306     BLOGE_CHECK_AND_RETURN_RET(window->surface != nullptr, SURFACE_ERROR_INVALID_PARAM, "window surface is null");
307     window->surface->CancelBuffer(buffer->sfbuffer);
308     return OHOS::GSERROR_OK;
309 }
310 
HandleNativeWindowSetUsage(OHNativeWindow * window,va_list args)311 static void HandleNativeWindowSetUsage(OHNativeWindow *window, va_list args)
312 {
313     uint64_t usage = va_arg(args, uint64_t);
314     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
315     windowConfig->usage = usage;
316 }
317 
HandleNativeWindowSetBufferGeometry(OHNativeWindow * window,va_list args)318 static void HandleNativeWindowSetBufferGeometry(OHNativeWindow *window, va_list args)
319 {
320     int32_t width = va_arg(args, int32_t);
321     int32_t height = va_arg(args, int32_t);
322     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
323     windowConfig->height = height;
324     windowConfig->width = width;
325 }
326 
HandleNativeWindowSetFormat(OHNativeWindow * window,va_list args)327 static void HandleNativeWindowSetFormat(OHNativeWindow *window, va_list args)
328 {
329     int32_t format = va_arg(args, int32_t);
330     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
331     windowConfig->format = format;
332 }
333 
HandleNativeWindowSetStride(OHNativeWindow * window,va_list args)334 static void HandleNativeWindowSetStride(OHNativeWindow *window, va_list args)
335 {
336     int32_t stride = va_arg(args, int32_t);
337     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
338     windowConfig->strideAlignment = stride;
339 }
340 
HandleNativeWindowSetTimeout(OHNativeWindow * window,va_list args)341 static void HandleNativeWindowSetTimeout(OHNativeWindow *window, va_list args)
342 {
343     int32_t timeout = va_arg(args, int32_t);
344     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
345     windowConfig->timeout = timeout;
346 }
347 
HandleNativeWindowSetColorGamut(OHNativeWindow * window,va_list args)348 static void HandleNativeWindowSetColorGamut(OHNativeWindow *window, va_list args)
349 {
350     int32_t colorGamut = va_arg(args, int32_t);
351     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
352     windowConfig->colorGamut = static_cast<GraphicColorGamut>(colorGamut);
353 }
354 
HandleNativeWindowSetTransform(OHNativeWindow * window,va_list args)355 static void HandleNativeWindowSetTransform(OHNativeWindow *window, va_list args)
356 {
357     int32_t transform = va_arg(args, int32_t);
358     window->surface->SetTransform(static_cast<GraphicTransformType>(transform));
359     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
360     windowConfig->transform = static_cast<GraphicTransformType>(transform);
361 }
362 
HandleNativeWindowSetUiTimestamp(OHNativeWindow * window,va_list args)363 static void HandleNativeWindowSetUiTimestamp(OHNativeWindow *window, va_list args)
364 {
365     uint64_t uiTimestamp = va_arg(args, uint64_t);
366     window->uiTimestamp = static_cast<int64_t>(uiTimestamp);
367 }
368 
HandleNativeWindowSetDesiredPresentTimestamp(OHNativeWindow * window,va_list args)369 static void HandleNativeWindowSetDesiredPresentTimestamp(OHNativeWindow *window, va_list args)
370 {
371     int64_t desiredPresentTimestamp = va_arg(args, int64_t);
372     window->desiredPresentTimestamp = desiredPresentTimestamp;
373 }
374 
HandleNativeWindowSetSurfaceSourceType(OHNativeWindow * window,va_list args)375 static void HandleNativeWindowSetSurfaceSourceType(OHNativeWindow *window, va_list args)
376 {
377     OHSurfaceSource sourceType = va_arg(args, OHSurfaceSource);
378     window->surface->SetSurfaceSourceType(sourceType);
379 }
380 
HandleNativeWindowSetSurfaceAppFrameworkType(OHNativeWindow * window,va_list args)381 static void HandleNativeWindowSetSurfaceAppFrameworkType(OHNativeWindow *window, va_list args)
382 {
383     char* appFrameworkType = va_arg(args, char*);
384     if (appFrameworkType != nullptr) {
385         std::string typeStr(appFrameworkType);
386         window->surface->SetSurfaceAppFrameworkType(typeStr);
387     }
388 }
389 
HandleNativeWindowGetUsage(OHNativeWindow * window,va_list args)390 static void HandleNativeWindowGetUsage(OHNativeWindow *window, va_list args)
391 {
392     uint64_t *value = va_arg(args, uint64_t*);
393     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
394     uint64_t usage = windowConfig->usage;
395     *value = usage;
396 }
397 
HandleNativeWindowGetBufferGeometry(OHNativeWindow * window,va_list args)398 static void HandleNativeWindowGetBufferGeometry(OHNativeWindow *window, va_list args)
399 {
400     int32_t *height = va_arg(args, int32_t*);
401     int32_t *width = va_arg(args, int32_t*);
402     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
403     *height = windowConfig->height;
404     *width = windowConfig->width;
405 }
406 
HandleNativeWindowGetFormat(OHNativeWindow * window,va_list args)407 static void HandleNativeWindowGetFormat(OHNativeWindow *window, va_list args)
408 {
409     int32_t *format = va_arg(args, int32_t*);
410     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
411     *format = windowConfig->format;
412 }
413 
HandleNativeWindowGetStride(OHNativeWindow * window,va_list args)414 static void HandleNativeWindowGetStride(OHNativeWindow *window, va_list args)
415 {
416     int32_t *stride = va_arg(args, int32_t*);
417     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
418     *stride = windowConfig->strideAlignment;
419 }
420 
HandleNativeWindowGetTimeout(OHNativeWindow * window,va_list args)421 static void HandleNativeWindowGetTimeout(OHNativeWindow *window, va_list args)
422 {
423     int32_t *timeout = va_arg(args, int32_t*);
424     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
425     *timeout = windowConfig->timeout;
426 }
427 
HandleNativeWindowGetColorGamut(OHNativeWindow * window,va_list args)428 static void HandleNativeWindowGetColorGamut(OHNativeWindow *window, va_list args)
429 {
430     int32_t *colorGamut = va_arg(args, int32_t*);
431     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
432     *colorGamut = static_cast<int32_t>(windowConfig->colorGamut);
433 }
434 
HandleNativeWindowGetTransform(OHNativeWindow * window,va_list args)435 static void HandleNativeWindowGetTransform(OHNativeWindow *window, va_list args)
436 {
437     int32_t *transform = va_arg(args, int32_t*);
438     *transform = static_cast<int32_t>(window->surface->GetTransform());
439 }
440 
HandleNativeWindowGetBufferQueueSize(OHNativeWindow * window,va_list args)441 static void HandleNativeWindowGetBufferQueueSize(OHNativeWindow *window, va_list args)
442 {
443     int32_t *bufferQueueSize = va_arg(args, int32_t*);
444     *bufferQueueSize = static_cast<int32_t>(window->surface->GetQueueSize());
445 }
446 
HandleNativeWindowGetSurfaceSourceType(OHNativeWindow * window,va_list args)447 static void HandleNativeWindowGetSurfaceSourceType(OHNativeWindow *window, va_list args)
448 {
449     OHSurfaceSource *sourceType = va_arg(args, OHSurfaceSource*);
450     *sourceType = window->surface->GetSurfaceSourceType();
451 }
452 
HandleNativeWindowGetSurfaceAppFrameworkType(OHNativeWindow * window,va_list args)453 static void HandleNativeWindowGetSurfaceAppFrameworkType(OHNativeWindow *window, va_list args)
454 {
455     const char **appFrameworkType = va_arg(args, const char**);
456     if (appFrameworkType != nullptr) {
457         std::string typeStr = window->surface->GetSurfaceAppFrameworkType();
458         std::call_once(window->appFrameworkTypeOnceFlag_, [&]() {
459             window->appFrameworkType_ = new char[MAXIMUM_LENGTH_OF_APP_FRAMEWORK + 1]();
460         });
461         if (strcpy_s(window->appFrameworkType_, typeStr.size() + 1, typeStr.c_str()) != 0) {
462             BLOGE("strcpy app framework type name failed.");
463             return;
464         }
465         *appFrameworkType = window->appFrameworkType_;
466     }
467 }
468 
HandleNativeWindowSetHdrWhitePointBrightness(OHNativeWindow * window,va_list args)469 static void HandleNativeWindowSetHdrWhitePointBrightness(OHNativeWindow *window, va_list args)
470 {
471     float hdrWhitePointBrightness = static_cast<float>(va_arg(args, double));
472     window->surface->SetHdrWhitePointBrightness(hdrWhitePointBrightness);
473 }
474 
HandleNativeWindowSetSdrWhitePointBrightness(OHNativeWindow * window,va_list args)475 static void HandleNativeWindowSetSdrWhitePointBrightness(OHNativeWindow *window, va_list args)
476 {
477     float sdrWhitePointBrightness = static_cast<float>(va_arg(args, double));
478     window->surface->SetSdrWhitePointBrightness(sdrWhitePointBrightness);
479 }
480 
481 static std::map<int, std::function<void(OHNativeWindow*, va_list)>> operationMap = {
482     {SET_USAGE, HandleNativeWindowSetUsage},
483     {SET_BUFFER_GEOMETRY, HandleNativeWindowSetBufferGeometry},
484     {SET_FORMAT, HandleNativeWindowSetFormat},
485     {SET_STRIDE, HandleNativeWindowSetStride},
486     {SET_TIMEOUT, HandleNativeWindowSetTimeout},
487     {SET_COLOR_GAMUT, HandleNativeWindowSetColorGamut},
488     {SET_TRANSFORM, HandleNativeWindowSetTransform},
489     {SET_UI_TIMESTAMP, HandleNativeWindowSetUiTimestamp},
490     {SET_SOURCE_TYPE, HandleNativeWindowSetSurfaceSourceType},
491     {SET_APP_FRAMEWORK_TYPE, HandleNativeWindowSetSurfaceAppFrameworkType},
492     {GET_USAGE, HandleNativeWindowGetUsage},
493     {GET_BUFFER_GEOMETRY, HandleNativeWindowGetBufferGeometry},
494     {GET_FORMAT, HandleNativeWindowGetFormat},
495     {GET_STRIDE, HandleNativeWindowGetStride},
496     {GET_TIMEOUT, HandleNativeWindowGetTimeout},
497     {GET_COLOR_GAMUT, HandleNativeWindowGetColorGamut},
498     {GET_TRANSFORM, HandleNativeWindowGetTransform},
499     {GET_BUFFERQUEUE_SIZE, HandleNativeWindowGetBufferQueueSize},
500     {GET_SOURCE_TYPE, HandleNativeWindowGetSurfaceSourceType},
501     {GET_APP_FRAMEWORK_TYPE, HandleNativeWindowGetSurfaceAppFrameworkType},
502     {SET_HDR_WHITE_POINT_BRIGHTNESS, HandleNativeWindowSetHdrWhitePointBrightness},
503     {SET_SDR_WHITE_POINT_BRIGHTNESS, HandleNativeWindowSetSdrWhitePointBrightness},
504     {SET_DESIRED_PRESENT_TIMESTAMP, HandleNativeWindowSetDesiredPresentTimestamp},
505 };
506 
InternalHandleNativeWindowOpt(OHNativeWindow * window,int code,va_list args)507 static int32_t InternalHandleNativeWindowOpt(OHNativeWindow *window, int code, va_list args)
508 {
509     auto it = operationMap.find(code);
510     if (it != operationMap.end()) {
511         it->second(window, args);
512     }
513     return OHOS::GSERROR_OK;
514 }
515 
NativeWindowHandleOpt(OHNativeWindow * window,int code,...)516 int32_t NativeWindowHandleOpt(OHNativeWindow *window, int code, ...)
517 {
518     if (window == nullptr || window->surface == nullptr) {
519         return OHOS::SURFACE_ERROR_INVALID_PARAM;
520     }
521     va_list args;
522     va_start(args, code);
523     InternalHandleNativeWindowOpt(window, code, args);
524     va_end(args);
525     return OHOS::GSERROR_OK;
526 }
527 
GetBufferHandleFromNative(OHNativeWindowBuffer * buffer)528 BufferHandle *GetBufferHandleFromNative(OHNativeWindowBuffer *buffer)
529 {
530     if (buffer == nullptr || buffer->sfbuffer == nullptr) {
531         return nullptr;
532     }
533     return buffer->sfbuffer->GetBufferHandle();
534 }
535 
GetNativeObjectMagic(void * obj)536 int32_t GetNativeObjectMagic(void *obj)
537 {
538     if (obj == nullptr) {
539         return INVALID_PARAM;
540     }
541     NativeWindowMagic* nativeWindowMagic = reinterpret_cast<NativeWindowMagic *>(obj);
542     return nativeWindowMagic->magic;
543 }
544 
NativeObjectReference(void * obj)545 int32_t NativeObjectReference(void *obj)
546 {
547     if (obj == nullptr) {
548         return OHOS::SURFACE_ERROR_INVALID_PARAM;
549     }
550     switch (GetNativeObjectMagic(obj)) {
551         case NATIVE_OBJECT_MAGIC_WINDOW:
552         case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
553             break;
554         default:
555             BLOGE("magic illegal: %{public}d", GetNativeObjectMagic(obj));
556             return OHOS::SURFACE_ERROR_INVALID_PARAM;
557     }
558     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
559     ref->IncStrongRef(ref);
560     return OHOS::GSERROR_OK;
561 }
562 
NativeObjectUnreference(void * obj)563 int32_t NativeObjectUnreference(void *obj)
564 {
565     if (obj == nullptr) {
566         return OHOS::SURFACE_ERROR_INVALID_PARAM;
567     }
568     switch (GetNativeObjectMagic(obj)) {
569         case NATIVE_OBJECT_MAGIC_WINDOW:
570         case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
571             break;
572         default:
573             BLOGE("magic illegal: %{public}d", GetNativeObjectMagic(obj));
574             return OHOS::SURFACE_ERROR_INVALID_PARAM;
575     }
576     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
577     ref->DecStrongRef(ref);
578     return OHOS::GSERROR_OK;
579 }
580 
NativeWindowSetScalingMode(OHNativeWindow * window,uint32_t sequence,OHScalingMode scalingMode)581 int32_t NativeWindowSetScalingMode(OHNativeWindow *window, uint32_t sequence, OHScalingMode scalingMode)
582 {
583     if (window == nullptr || window->surface == nullptr ||
584         scalingMode < OHScalingMode::OH_SCALING_MODE_FREEZE ||
585         scalingMode > OHScalingMode::OH_SCALING_MODE_NO_SCALE_CROP) {
586         return OHOS::SURFACE_ERROR_INVALID_PARAM;
587     }
588     return window->surface->SetScalingMode(sequence, static_cast<ScalingMode>(scalingMode));
589 }
590 
NativeWindowSetScalingModeV2(OHNativeWindow * window,OHScalingModeV2 scalingMode)591 int32_t NativeWindowSetScalingModeV2(OHNativeWindow *window, OHScalingModeV2 scalingMode)
592 {
593     if (window == nullptr || window->surface == nullptr ||
594         scalingMode < OHScalingModeV2::OH_SCALING_MODE_FREEZE_V2 ||
595         scalingMode > OHScalingModeV2::OH_SCALING_MODE_SCALE_FIT_V2) {
596         return OHOS::GSERROR_INVALID_ARGUMENTS;
597     }
598     return window->surface->SetScalingMode(static_cast<ScalingMode>(scalingMode));
599 }
600 
NativeWindowSetMetaData(OHNativeWindow * window,uint32_t sequence,int32_t size,const OHHDRMetaData * metaData)601 int32_t NativeWindowSetMetaData(OHNativeWindow *window, uint32_t sequence, int32_t size,
602                                 const OHHDRMetaData *metaData)
603 {
604     if (window == nullptr || window->surface == nullptr || size <= 0 || metaData == nullptr) {
605         return OHOS::SURFACE_ERROR_INVALID_PARAM;
606     }
607 
608     std::vector<GraphicHDRMetaData> data(reinterpret_cast<const GraphicHDRMetaData *>(metaData),
609                                          reinterpret_cast<const GraphicHDRMetaData *>(metaData) + size);
610     return window->surface->SetMetaData(sequence, data);
611 }
612 
NativeWindowSetMetaDataSet(OHNativeWindow * window,uint32_t sequence,OHHDRMetadataKey key,int32_t size,const uint8_t * metaData)613 int32_t NativeWindowSetMetaDataSet(OHNativeWindow *window, uint32_t sequence, OHHDRMetadataKey key,
614                                    int32_t size, const uint8_t *metaData)
615 {
616     if (window == nullptr || window->surface == nullptr ||
617         key < OHHDRMetadataKey::OH_METAKEY_RED_PRIMARY_X || key > OHHDRMetadataKey::OH_METAKEY_HDR_VIVID ||
618         size <= 0 || metaData == nullptr) {
619         return OHOS::SURFACE_ERROR_INVALID_PARAM;
620     }
621     std::vector<uint8_t> data(metaData, metaData + size);
622     return window->surface->SetMetaDataSet(sequence, static_cast<GraphicHDRMetadataKey>(key), data);
623 }
624 
NativeWindowSetTunnelHandle(OHNativeWindow * window,const OHExtDataHandle * handle)625 int32_t NativeWindowSetTunnelHandle(OHNativeWindow *window, const OHExtDataHandle *handle)
626 {
627     if (window == nullptr || window->surface == nullptr || handle == nullptr) {
628         return OHOS::SURFACE_ERROR_INVALID_PARAM;
629     }
630     return window->surface->SetTunnelHandle(reinterpret_cast<const OHOS::GraphicExtDataHandle*>(handle));
631 }
632 
GetSurfaceId(OHNativeWindow * window,uint64_t * surfaceId)633 int32_t GetSurfaceId(OHNativeWindow *window, uint64_t *surfaceId)
634 {
635     if (window == nullptr || surfaceId == nullptr) {
636         return OHOS::SURFACE_ERROR_INVALID_PARAM;
637     }
638 
639     *surfaceId = window->surface->GetUniqueId();
640     return OHOS::GSERROR_OK;
641 }
642 
CreateNativeWindowFromSurfaceId(uint64_t surfaceId,OHNativeWindow ** window)643 int32_t CreateNativeWindowFromSurfaceId(uint64_t surfaceId, OHNativeWindow **window)
644 {
645     if (window == nullptr) {
646         return OHOS::SURFACE_ERROR_INVALID_PARAM;
647     }
648 
649     auto utils = SurfaceUtils::GetInstance();
650     *window = reinterpret_cast<OHNativeWindow*>(utils->GetNativeWindow(surfaceId));
651     if (*window != nullptr) {
652         NativeObjectReference(*window);
653         BLOGD("get nativeWindow from cache, uniqueId: %{public}" PRIu64 ".", surfaceId);
654         return OHOS::GSERROR_OK;
655     }
656 
657     OHNativeWindow *nativeWindow = new(std::nothrow) OHNativeWindow();
658     if (nativeWindow == nullptr) {
659         return OHOS::SURFACE_ERROR_NOMEM;
660     }
661     nativeWindow->surface = utils->GetSurface(surfaceId);
662     if (nativeWindow->surface == nullptr) {
663         BLOGE("window surface is null, surfaceId: %{public}" PRIu64 ".", surfaceId);
664         delete nativeWindow;
665         return OHOS::SURFACE_ERROR_INVALID_PARAM;
666     }
667 
668     NativeObjectReference(nativeWindow);
669     utils->AddNativeWindow(nativeWindow->surface->GetUniqueId(), nativeWindow);
670     nativeWindow->surface->SetWptrNativeWindowToPSurface(nativeWindow);
671     *window = nativeWindow;
672     return OHOS::GSERROR_OK;
673 }
674 
NativeWindowGetTransformHint(OHNativeWindow * window,OH_NativeBuffer_TransformType * transform)675 int32_t NativeWindowGetTransformHint(OHNativeWindow *window, OH_NativeBuffer_TransformType *transform)
676 {
677     if (window == nullptr || window->surface == nullptr || transform == nullptr) {
678         return OHOS::SURFACE_ERROR_INVALID_PARAM;
679     }
680     *transform = static_cast<OH_NativeBuffer_TransformType>(window->surface->GetTransformHint());
681     return OHOS::GSERROR_OK;
682 }
683 
NativeWindowSetTransformHint(OHNativeWindow * window,OH_NativeBuffer_TransformType transform)684 int32_t NativeWindowSetTransformHint(OHNativeWindow *window, OH_NativeBuffer_TransformType transform)
685 {
686     if (window == nullptr || window->surface == nullptr) {
687         return OHOS::SURFACE_ERROR_INVALID_PARAM;
688     }
689     return window->surface->SetTransformHint(static_cast<OHOS::GraphicTransformType>(transform));
690 }
691 
NativeWindowGetDefaultWidthAndHeight(OHNativeWindow * window,int32_t * width,int32_t * height)692 int32_t NativeWindowGetDefaultWidthAndHeight(OHNativeWindow *window, int32_t *width, int32_t *height)
693 {
694     if (window == nullptr || window->surface == nullptr || width == nullptr || height == nullptr) {
695         return OHOS::SURFACE_ERROR_INVALID_PARAM;
696     }
697     OHOS::BufferRequestConfig *windowConfig = window->surface->GetWindowConfig();
698     if (windowConfig->width != 0 && windowConfig->height != 0) {
699         *width = windowConfig->width;
700         *height = windowConfig->height;
701     } else {
702         *width = window->surface->GetDefaultWidth();
703         *height = window->surface->GetDefaultHeight();
704     }
705     return OHOS::GSERROR_OK;
706 }
707 
NativeWindowSetRequestWidthAndHeight(OHNativeWindow * window,int32_t width,int32_t height)708 int32_t NativeWindowSetRequestWidthAndHeight(OHNativeWindow *window, int32_t width, int32_t height)
709 {
710     if (window == nullptr || window->surface == nullptr) {
711         return OHOS::SURFACE_ERROR_INVALID_PARAM;
712     }
713     window->surface->SetRequestWidthAndHeight(width, height);
714     return OHOS::GSERROR_OK;
715 }
716 
NativeWindowSetBufferHold(OHNativeWindow * window)717 void NativeWindowSetBufferHold(OHNativeWindow *window)
718 {
719     if (window == nullptr || window->surface == nullptr) {
720         return;
721     }
722     window->surface->SetBufferHold(true);
723 }
724 
NativeWindowWriteToParcel(OHNativeWindow * window,OHIPCParcel * parcel)725 int32_t NativeWindowWriteToParcel(OHNativeWindow *window, OHIPCParcel *parcel)
726 {
727     if (window == nullptr) {
728         return OHOS::SURFACE_ERROR_INVALID_PARAM;
729     }
730     if (parcel == nullptr || parcel->msgParcel == nullptr) {
731         return OHOS::SURFACE_ERROR_INVALID_PARAM;
732     }
733     sptr<OHOS::Surface> windowSurface = window->surface;
734     if (windowSurface == nullptr) {
735         BLOGE("windowSurface is nullptr");
736         return OHOS::SURFACE_ERROR_INVALID_PARAM;
737     }
738     auto producer = windowSurface->GetProducer();
739     (parcel->msgParcel)->WriteRemoteObject(producer->AsObject());
740     return OHOS::GSERROR_OK;
741 }
742 
NativeWindowReadFromParcel(OHIPCParcel * parcel,OHNativeWindow ** window)743 int32_t NativeWindowReadFromParcel(OHIPCParcel *parcel, OHNativeWindow **window)
744 {
745     if (parcel == nullptr || parcel->msgParcel == nullptr || window == nullptr) {
746         return OHOS::SURFACE_ERROR_INVALID_PARAM;
747     }
748     sptr<OHOS::IRemoteObject> surfaceObject = (parcel->msgParcel)->ReadRemoteObject();
749     if (surfaceObject == nullptr) {
750         BLOGE("surfaceObject is nullptr");
751         return OHOS::SURFACE_ERROR_INVALID_PARAM;
752     }
753     sptr<OHOS::IBufferProducer> bp = iface_cast<IBufferProducer>(surfaceObject);
754     sptr <OHOS::Surface> windowSurface = OHOS::Surface::CreateSurfaceAsProducer(bp);
755     if (windowSurface == nullptr) {
756         BLOGE("windowSurface is nullptr");
757         return OHOS::SURFACE_ERROR_INVALID_PARAM;
758     }
759     auto utils = SurfaceUtils::GetInstance();
760     *window = reinterpret_cast<OHNativeWindow*>(utils->GetNativeWindow(windowSurface->GetUniqueId()));
761     if (*window == nullptr) {
762         *window = CreateNativeWindowFromSurface(&windowSurface);
763     }
764     return OHOS::GSERROR_OK;
765 }
766 
GetLastFlushedBufferV2(OHNativeWindow * window,OHNativeWindowBuffer ** buffer,int * fenceFd,float matrix[16])767 int32_t GetLastFlushedBufferV2(OHNativeWindow *window, OHNativeWindowBuffer **buffer, int *fenceFd, float matrix[16])
768 {
769     if (window == nullptr || buffer == nullptr || fenceFd == nullptr || window->surface == nullptr) {
770         return OHOS::SURFACE_ERROR_INVALID_PARAM;
771     }
772     OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
773     OHOS::sptr<OHOS::SyncFence> acquireFence = OHOS::SyncFence::InvalidFence();
774     int32_t ret = window->surface->GetLastFlushedBuffer(nwBuffer->sfbuffer, acquireFence, matrix, true);
775     if (ret != OHOS::GSError::SURFACE_ERROR_OK || nwBuffer->sfbuffer == nullptr) {
776         BLOGE("GetLastFlushedBuffer fail, ret: %{public}d, uniqueId: %{public}" PRIu64 ".",
777             ret, window->surface->GetUniqueId());
778         delete nwBuffer;
779         nwBuffer = nullptr;
780         return ret;
781     }
782     *buffer = nwBuffer;
783     NativeObjectReference(nwBuffer);
784     *fenceFd = acquireFence->Dup();
785     return OHOS::SURFACE_ERROR_OK;
786 }
787 
NativeWindowDisconnect(OHNativeWindow * window)788 int32_t NativeWindowDisconnect(OHNativeWindow *window)
789 {
790     if (window == nullptr) {
791         return OHOS::SURFACE_ERROR_INVALID_PARAM;
792     }
793     sptr<OHOS::Surface> windowSurface = window->surface;
794     if (windowSurface == nullptr) {
795         BLOGE("windowSurface is nullptr");
796         return OHOS::SURFACE_ERROR_INVALID_PARAM;
797     }
798     return windowSurface->Disconnect();
799 }
800 
OH_NativeWindow_SetColorSpace(OHNativeWindow * window,OH_NativeBuffer_ColorSpace colorSpace)801 int32_t OH_NativeWindow_SetColorSpace(OHNativeWindow *window, OH_NativeBuffer_ColorSpace colorSpace)
802 {
803     if (window == nullptr || NATIVE_COLORSPACE_TO_HDI_MAP.find(colorSpace) == NATIVE_COLORSPACE_TO_HDI_MAP.end()) {
804         return OHOS::SURFACE_ERROR_INVALID_PARAM;
805     }
806     std::string param = std::to_string(NATIVE_COLORSPACE_TO_HDI_MAP[colorSpace]);
807     GSError ret = GSERROR_OK;
808     if (window->surface != nullptr && param != window->surface->GetUserData("ATTRKEY_COLORSPACE_INFO")) {
809         ret = window->surface->SetUserData("ATTRKEY_COLORSPACE_INFO", param);
810     }
811     if (ret != OHOS::SURFACE_ERROR_OK) {
812         BLOGE("SetColorSpaceType failed!, ret: %d", ret);
813         return OHOS::SURFACE_ERROR_UNKOWN;
814     }
815     return OHOS::SURFACE_ERROR_OK;
816 }
817 
OH_NativeWindow_GetColorSpace(OHNativeWindow * window,OH_NativeBuffer_ColorSpace * colorSpace)818 int32_t OH_NativeWindow_GetColorSpace(OHNativeWindow *window, OH_NativeBuffer_ColorSpace *colorSpace)
819 {
820     if (window == nullptr || colorSpace == nullptr) {
821         return OHOS::SURFACE_ERROR_INVALID_PARAM;
822     }
823     CM_ColorSpaceType colorSpaceType = CM_COLORSPACE_NONE;
824     if (window->surface != nullptr) {
825         std::string value = window->surface->GetUserData("ATTRKEY_COLORSPACE_INFO");
826         if (value.empty()) {
827             BLOGE("no colorspace!");
828             return OHOS::SURFACE_ERROR_UNKOWN;
829         }
830         colorSpaceType = static_cast<CM_ColorSpaceType>(atoi(value.c_str()));
831         auto it = std::find_if(NATIVE_COLORSPACE_TO_HDI_MAP.begin(), NATIVE_COLORSPACE_TO_HDI_MAP.end(),
832             [colorSpaceType](const std::pair<OH_NativeBuffer_ColorSpace, CM_ColorSpaceType>& element) {
833                 return element.second == colorSpaceType;
834             });
835         if (it != NATIVE_COLORSPACE_TO_HDI_MAP.end()) {
836             *colorSpace = it->first;
837             return OHOS::SURFACE_ERROR_OK;
838         }
839     }
840     BLOGE("the colorSpace does not support it.");
841     return OHOS::SURFACE_ERROR_UNKOWN;
842 }
843 
OH_NativeWindow_SetMetadataValue(OHNativeWindow * window,OH_NativeBuffer_MetadataKey metadataKey,int32_t size,uint8_t * metadata)844 int32_t OH_NativeWindow_SetMetadataValue(OHNativeWindow *window, OH_NativeBuffer_MetadataKey metadataKey,
845     int32_t size, uint8_t *metadata)
846 {
847     if (window == nullptr || metadata == nullptr || size <= 0 || size > META_DATA_MAX_SIZE ||
848         window->surface == nullptr) {
849         return OHOS::SURFACE_ERROR_INVALID_PARAM;
850     }
851     GSError ret = GSERROR_OK;
852     std::vector<uint8_t> mD(metadata, metadata + size);
853     std::string param;
854     if (metadataKey == OH_HDR_DYNAMIC_METADATA) {
855         param.assign(mD.begin(), mD.end());
856         if (param != window->surface->GetUserData("OH_HDR_DYNAMIC_METADATA")) {
857             ret = window->surface->SetUserData("OH_HDR_DYNAMIC_METADATA", param);
858         }
859     } else if (metadataKey == OH_HDR_STATIC_METADATA) {
860         param.assign(mD.begin(), mD.end());
861         if (param != window->surface->GetUserData("OH_HDR_STATIC_METADATA")) {
862             ret = window->surface->SetUserData("OH_HDR_STATIC_METADATA", param);
863         }
864     } else if (metadataKey == OH_HDR_METADATA_TYPE) {
865         OH_NativeBuffer_MetadataType hdrMetadataType = static_cast<OH_NativeBuffer_MetadataType>(*metadata);
866         param = std::to_string(NATIVE_METADATATYPE_TO_HDI_MAP[hdrMetadataType]);
867         if (param != window->surface->GetUserData("OH_HDR_METADATA_TYPE")) {
868             ret = window->surface->SetUserData("OH_HDR_METADATA_TYPE", param);
869         }
870     } else {
871         BLOGE("the metadataKey does not support it.");
872         return OHOS::SURFACE_ERROR_NOT_SUPPORT;
873     }
874     if (GSErrorStr(ret) == "<500 api call failed>with low error <Not supported>") {
875         return OHOS::SURFACE_ERROR_NOT_SUPPORT;
876     } else if (ret != OHOS::SURFACE_ERROR_OK) {
877         BLOGE("SetHDRMetadata failed!, ret: %d", ret);
878         return OHOS::SURFACE_ERROR_UNKOWN;
879     }
880     return OHOS::SURFACE_ERROR_OK;
881 }
882 
OH_NativeWindow_GetMatedataValueType(OHNativeWindow * window,int32_t * size,uint8_t ** metadata)883 static GSError OH_NativeWindow_GetMatedataValueType(OHNativeWindow *window, int32_t *size, uint8_t **metadata)
884 {
885     std::string value = window->surface->GetUserData("OH_HDR_METADATA_TYPE");
886     CM_HDR_Metadata_Type hdrMetadataType = CM_METADATA_NONE;
887     hdrMetadataType = static_cast<CM_HDR_Metadata_Type>(atoi(value.c_str()));
888     auto it = std::find_if(NATIVE_METADATATYPE_TO_HDI_MAP.begin(), NATIVE_METADATATYPE_TO_HDI_MAP.end(),
889     [hdrMetadataType](const std::pair<OH_NativeBuffer_MetadataType, CM_HDR_Metadata_Type>& element) {
890         return element.second == hdrMetadataType;
891     });
892     if (it != NATIVE_METADATATYPE_TO_HDI_MAP.end()) {
893         *size = sizeof(OH_NativeBuffer_MetadataType);
894         *metadata = new uint8_t[*size];
895         errno_t err = memcpy_s(*metadata, *size, &(it->first), *size);
896         if (err != 0) {
897             delete[] *metadata;
898             *metadata = nullptr;
899             BLOGE("memcpy_s failed! , ret: %d", err);
900             return OHOS::SURFACE_ERROR_UNKOWN;
901         }
902         return OHOS::SURFACE_ERROR_OK;
903     }
904     BLOGE("the hdrMetadataType does not support it.");
905     return OHOS::SURFACE_ERROR_NOT_SUPPORT;
906 }
907 
OH_NativeWindow_GetMetadataValue(OHNativeWindow * window,OH_NativeBuffer_MetadataKey metadataKey,int32_t * size,uint8_t ** metadata)908 int32_t OH_NativeWindow_GetMetadataValue(OHNativeWindow *window, OH_NativeBuffer_MetadataKey metadataKey,
909     int32_t *size, uint8_t **metadata)
910 {
911     if (window == nullptr || metadata == nullptr || size == nullptr || window->surface == nullptr) {
912         return OHOS::SURFACE_ERROR_INVALID_PARAM;
913     }
914     GSError ret = GSERROR_OK;
915     std::vector<uint8_t> mD;
916     if (metadataKey == OH_HDR_DYNAMIC_METADATA) {
917         std::string value = window->surface->GetUserData("OH_HDR_DYNAMIC_METADATA");
918         mD.resize(value.size());
919         mD.assign(value.begin(), value.end());
920     } else if (metadataKey == OH_HDR_STATIC_METADATA) {
921         std::string value = window->surface->GetUserData("OH_HDR_STATIC_METADATA");
922         mD.resize(value.size());
923         mD.assign(value.begin(), value.end());
924     } else if (metadataKey == OH_HDR_METADATA_TYPE) {
925         ret = OH_NativeWindow_GetMatedataValueType(window, size, metadata);
926         return ret;
927     } else {
928         BLOGE("the metadataKey does not support it.");
929         return OHOS::SURFACE_ERROR_UNKOWN;
930     }
931     if (GSErrorStr(ret) == "<500 api call failed>with low error <Not supported>") {
932         return OHOS::SURFACE_ERROR_NOT_SUPPORT;
933     } else if (ret != OHOS::SURFACE_ERROR_OK) {
934         BLOGE("SetHDRSMetadata failed! , ret: %d", ret);
935         return OHOS::SURFACE_ERROR_UNKOWN;
936     }
937     *size = mD.size();
938     *metadata = new uint8_t[mD.size()];
939     if (!mD.empty()) {
940         errno_t err = memcpy_s(*metadata, mD.size(), &mD[0], mD.size());
941         if (err != 0) {
942             delete[] *metadata;
943             *metadata = nullptr;
944             BLOGE("memcpy_s failed! , ret: %d", err);
945             return OHOS::SURFACE_ERROR_UNKOWN;
946         }
947     } else {
948         delete[] *metadata;
949         *metadata = nullptr;
950         BLOGE("new metadata failed!");
951         return OHOS::SURFACE_ERROR_UNKOWN;
952     }
953     return OHOS::SURFACE_ERROR_OK;
954 }
955 
NativeWindow()956 NativeWindow::NativeWindow() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW), surface(nullptr)
957 {
958 }
959 
~NativeWindow()960 NativeWindow::~NativeWindow()
961 {
962     if (surface != nullptr) {
963         auto utils = SurfaceUtils::GetInstance();
964         utils->RemoveNativeWindow(surface->GetUniqueId());
965     }
966 
967     for (auto &[seqNum, buffer] : bufferCache_) {
968         NativeObjectUnreference(buffer);
969     }
970     surface = nullptr;
971     bufferCache_.clear();
972     std::call_once(appFrameworkTypeOnceFlag_, [] {});
973     if (appFrameworkType_ != nullptr) {
974         delete[] appFrameworkType_;
975         appFrameworkType_ = nullptr;
976     }
977 }
978 
~NativeWindowBuffer()979 NativeWindowBuffer::~NativeWindowBuffer()
980 {
981     sfbuffer = nullptr;
982 }
983 
NativeWindowBuffer()984 NativeWindowBuffer::NativeWindowBuffer() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW_BUFFER), sfbuffer(nullptr)
985 {
986 }
987 
988 WEAK_ALIAS(CreateNativeWindowFromSurface, OH_NativeWindow_CreateNativeWindow);
989 WEAK_ALIAS(DestoryNativeWindow, OH_NativeWindow_DestroyNativeWindow);
990 WEAK_ALIAS(CreateNativeWindowBufferFromSurfaceBuffer, OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer);
991 WEAK_ALIAS(CreateNativeWindowBufferFromNativeBuffer, OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer);
992 WEAK_ALIAS(DestroyNativeWindowBuffer, OH_NativeWindow_DestroyNativeWindowBuffer);
993 WEAK_ALIAS(NativeWindowRequestBuffer, OH_NativeWindow_NativeWindowRequestBuffer);
994 WEAK_ALIAS(NativeWindowFlushBuffer, OH_NativeWindow_NativeWindowFlushBuffer);
995 WEAK_ALIAS(GetLastFlushedBuffer, OH_NativeWindow_GetLastFlushedBuffer);
996 WEAK_ALIAS(NativeWindowAttachBuffer, OH_NativeWindow_NativeWindowAttachBuffer);
997 WEAK_ALIAS(NativeWindowDetachBuffer, OH_NativeWindow_NativeWindowDetachBuffer);
998 WEAK_ALIAS(NativeWindowCancelBuffer, OH_NativeWindow_NativeWindowAbortBuffer);
999 WEAK_ALIAS(NativeWindowHandleOpt, OH_NativeWindow_NativeWindowHandleOpt);
1000 WEAK_ALIAS(GetBufferHandleFromNative, OH_NativeWindow_GetBufferHandleFromNative);
1001 WEAK_ALIAS(NativeObjectReference, OH_NativeWindow_NativeObjectReference);
1002 WEAK_ALIAS(NativeObjectUnreference, OH_NativeWindow_NativeObjectUnreference);
1003 WEAK_ALIAS(GetNativeObjectMagic, OH_NativeWindow_GetNativeObjectMagic);
1004 WEAK_ALIAS(NativeWindowSetScalingMode, OH_NativeWindow_NativeWindowSetScalingMode);
1005 WEAK_ALIAS(NativeWindowSetScalingModeV2, OH_NativeWindow_NativeWindowSetScalingModeV2);
1006 WEAK_ALIAS(NativeWindowSetMetaData, OH_NativeWindow_NativeWindowSetMetaData);
1007 WEAK_ALIAS(NativeWindowSetMetaDataSet, OH_NativeWindow_NativeWindowSetMetaDataSet);
1008 WEAK_ALIAS(NativeWindowSetTunnelHandle, OH_NativeWindow_NativeWindowSetTunnelHandle);
1009 WEAK_ALIAS(GetSurfaceId, OH_NativeWindow_GetSurfaceId);
1010 WEAK_ALIAS(CreateNativeWindowFromSurfaceId, OH_NativeWindow_CreateNativeWindowFromSurfaceId);
1011 WEAK_ALIAS(NativeWindowSetBufferHold, OH_NativeWindow_SetBufferHold);
1012 WEAK_ALIAS(NativeWindowWriteToParcel, OH_NativeWindow_WriteToParcel);
1013 WEAK_ALIAS(NativeWindowReadFromParcel, OH_NativeWindow_ReadFromParcel);
1014 WEAK_ALIAS(GetLastFlushedBufferV2, OH_NativeWindow_GetLastFlushedBufferV2);
1015 
1016