• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 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 "output/deferred_photo_proxy_napi.h"
17 
18 #include "camera_log.h"
19 #include "deferred_photo_proxy.h"
20 #include "hilog/log.h"
21 #include "image_napi.h"
22 #include "napi/native_common.h"
23 #include "photo_proxy.h"
24 #include "pixel_map_napi.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 thread_local napi_ref DeferredPhotoProxyNapi::sConstructor_ = nullptr;
29 thread_local uint32_t DeferredPhotoProxyNapi::deferredPhotoProxyTaskId = DEFERRED_PHOTO_PROXY_TASKID;
DeferredPhotoProxyNapi()30 DeferredPhotoProxyNapi::DeferredPhotoProxyNapi() : env_(nullptr)
31 {
32 }
33 
~DeferredPhotoProxyNapi()34 DeferredPhotoProxyNapi::~DeferredPhotoProxyNapi()
35 {
36     MEDIA_DEBUG_LOG("~DeferredPhotoProxyNapi is called");
37 }
38 
39 // Constructor callback
DeferredPhotoProxyNapiConstructor(napi_env env,napi_callback_info info)40 napi_value DeferredPhotoProxyNapi::DeferredPhotoProxyNapiConstructor(napi_env env, napi_callback_info info)
41 {
42     MEDIA_DEBUG_LOG("DeferredPhotoProxyNapiConstructor is called");
43     napi_status status;
44     napi_value result = nullptr;
45     napi_value thisVar = nullptr;
46     napi_get_undefined(env, &result);
47     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
48     if (status == napi_ok && thisVar != nullptr) {
49         std::unique_ptr<DeferredPhotoProxyNapi> obj = std::make_unique<DeferredPhotoProxyNapi>();
50         obj->env_ = env;
51 
52         obj->deferredPhotoProxy_ = static_cast<DeferredPhotoProxy*>(sPhotoProxy_.GetRefPtr());
53         obj->photoProxy_ = obj->deferredPhotoProxy_;
54         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
55                            DeferredPhotoProxyNapi::DeferredPhotoProxyNapiDestructor, nullptr, nullptr);
56         if (status == napi_ok) {
57             obj.release();
58             return thisVar;
59         } else {
60             MEDIA_ERR_LOG("Failure wrapping js to native napi");
61         }
62     }
63     MEDIA_ERR_LOG("DeferredPhotoProxyNapiConstructor call Failed!");
64     return result;
65 }
66 
DeferredPhotoProxyNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)67 void DeferredPhotoProxyNapi::DeferredPhotoProxyNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
68 {
69     MEDIA_DEBUG_LOG("DeferredPhotoProxyNapiDestructor is called");
70     DeferredPhotoProxyNapi* deferredPhotoProxy = reinterpret_cast<DeferredPhotoProxyNapi*>(nativeObject);
71     if (deferredPhotoProxy != nullptr) {
72         delete deferredPhotoProxy;
73     }
74 }
75 
Init(napi_env env,napi_value exports)76 napi_value DeferredPhotoProxyNapi::Init(napi_env env, napi_value exports)
77 {
78     MEDIA_DEBUG_LOG("Init is called");
79     napi_status status;
80     napi_value ctorObj;
81     int32_t refCount = 1;
82 
83     napi_property_descriptor deferred_photo_proxy_properties[] = {
84         // DeferredPhotoProxy
85         DECLARE_NAPI_FUNCTION("getThumbnail", GetThumbnail),
86         DECLARE_NAPI_FUNCTION("release", Release),
87     };
88 
89     status = napi_define_class(env, DEFERRED_PHOTO_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
90         DeferredPhotoProxyNapiConstructor, nullptr,
91         sizeof(deferred_photo_proxy_properties) / sizeof(deferred_photo_proxy_properties[PARAM0]),
92         deferred_photo_proxy_properties, &ctorObj);
93     if (status == napi_ok) {
94         if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
95             status = napi_set_named_property(env, exports, DEFERRED_PHOTO_NAPI_CLASS_NAME, ctorObj);
96             CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
97         }
98     }
99     MEDIA_ERR_LOG("Init call Failed!");
100     return nullptr;
101 }
102 
CreateDeferredPhotoProxy(napi_env env,sptr<DeferredPhotoProxy> deferredPhotoProxy)103 napi_value DeferredPhotoProxyNapi::CreateDeferredPhotoProxy(napi_env env, sptr<DeferredPhotoProxy> deferredPhotoProxy)
104 {
105     MEDIA_DEBUG_LOG("CreateDeferredPhotoProxy is called");
106     CAMERA_SYNC_TRACE;
107     napi_status status;
108     napi_value result = nullptr;
109     napi_value constructor;
110     napi_get_undefined(env, &result);
111     status = napi_get_reference_value(env, sConstructor_, &constructor);
112     if (status == napi_ok) {
113         sPhotoProxy_ = deferredPhotoProxy;
114         status = napi_new_instance(env, constructor, 0, nullptr, &result);
115         sPhotoProxy_ = nullptr;
116         if (status == napi_ok && result != nullptr) {
117             return result;
118         } else {
119             MEDIA_ERR_LOG("Failed to create deferredPhotoProxy obj instance");
120         }
121     }
122     napi_get_undefined(env, &result);
123     MEDIA_ERR_LOG("CreateDeferredPhotoProxy call Failed");
124     return result;
125 }
126 
GetThumbnail(napi_env env,napi_callback_info info)127 napi_value DeferredPhotoProxyNapi::GetThumbnail(napi_env env, napi_callback_info info)
128 {
129     MEDIA_INFO_LOG("GetThumbnail is called");
130     napi_status status;
131     napi_value result = nullptr;
132     napi_value resource = nullptr;
133     size_t argc = ARGS_ZERO;
134     napi_value argv[ARGS_ZERO];
135     napi_value thisVar = nullptr;
136     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
137     napi_get_undefined(env, &result);
138     std::unique_ptr<DeferredPhotoProxAsyncContext> asyncContext = std::make_unique<DeferredPhotoProxAsyncContext>();
139     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
140     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
141         CAMERA_NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
142         CAMERA_NAPI_CREATE_RESOURCE_NAME(env, resource, "GetThumbnail");
143         status = napi_create_async_work(
144             env, nullptr, resource,
145             [](napi_env env, void* data) {
146                 auto context = static_cast<DeferredPhotoProxAsyncContext*>(data);
147                 context->status = false;
148                 // Start async trace
149                 context->funcName = "DeferredPhotoProxyNapi::GetThumbnail";
150                 context->taskId = CameraNapiUtils::IncrementAndGet(deferredPhotoProxyTaskId);
151                 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
152                 if (context->objectInfo != nullptr) {
153                     context->status = true;
154                 }
155             },
156             DeferredPhotoAsyncTaskComplete, static_cast<void*>(asyncContext.get()), &asyncContext->work);
157         if (status != napi_ok) {
158             MEDIA_ERR_LOG("Failed to create napi_create_async_work for DeferredPhotoProxyNapi::GetThumbnail");
159             napi_get_undefined(env, &result);
160         } else {
161             napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
162             asyncContext.release();
163         }
164     } else {
165         MEDIA_ERR_LOG("GetThumbnail call Failed!");
166     }
167     return result;
168 }
169 
DeferredPhotoAsyncTaskComplete(napi_env env,napi_status status,void * data)170 void DeferredPhotoProxyNapi::DeferredPhotoAsyncTaskComplete(napi_env env, napi_status status, void* data)
171 {
172     auto context = static_cast<DeferredPhotoProxAsyncContext*>(data);
173     CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
174     void* fdAddr = context->objectInfo->deferredPhotoProxy_->GetFileDataAddr();
175     int32_t thumbnailWidth = context->objectInfo->deferredPhotoProxy_->GetWidth();
176     int32_t thumbnailHeight = context->objectInfo->deferredPhotoProxy_->GetHeight();
177     Media::InitializationOptions opts;
178     opts.srcPixelFormat = Media::PixelFormat::RGBA_8888;
179     opts.pixelFormat = Media::PixelFormat::RGBA_8888;
180     opts.size = { .width = thumbnailWidth, .height = thumbnailHeight };
181     MEDIA_INFO_LOG("thumbnailWidth:%{public}d, thumbnailheight: %{public}d",
182         thumbnailWidth, thumbnailHeight);
183     auto pixelMap = Media::PixelMap::Create(static_cast<const uint32_t*>(fdAddr),
184         thumbnailWidth * thumbnailHeight * 4, 0, thumbnailWidth, opts, true);
185     napi_value thumbnail = Media::PixelMapNapi::CreatePixelMap(env, std::move(pixelMap));
186     napi_resolve_deferred(env, context->deferred, thumbnail);
187     napi_delete_async_work(env, context->work);
188     delete context;
189 }
190 
Release(napi_env env,napi_callback_info info)191 napi_value DeferredPhotoProxyNapi::Release(napi_env env, napi_callback_info info)
192 {
193     MEDIA_INFO_LOG("Release is called");
194     napi_status status;
195     napi_value result = nullptr;
196     napi_value resource = nullptr;
197     size_t argc = ARGS_ZERO;
198     napi_value argv[ARGS_ZERO];
199     napi_value thisVar = nullptr;
200     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
201     napi_get_undefined(env, &result);
202     std::unique_ptr<DeferredPhotoProxAsyncContext> asyncContext = std::make_unique<DeferredPhotoProxAsyncContext>();
203     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
204     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
205         CAMERA_NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
206         CAMERA_NAPI_CREATE_RESOURCE_NAME(env, resource, "Release");
207         status = napi_create_async_work(
208             env, nullptr, resource,
209             [](napi_env env, void* data) {
210                 auto context = static_cast<DeferredPhotoProxAsyncContext*>(data);
211                 context->status = false;
212                 // Start async trace
213                 context->funcName = "DeferredPhotoProxyNapi::Release";
214                 context->taskId = CameraNapiUtils::IncrementAndGet(deferredPhotoProxyTaskId);
215                 CAMERA_START_ASYNC_TRACE(context->funcName, context->taskId);
216                 if (context->objectInfo != nullptr) {
217                     context->status = true;
218                 }
219             },
220             [](napi_env env, napi_status status, void* data) {
221                 auto context = static_cast<DeferredPhotoProxAsyncContext*>(data);
222                 CAMERA_FINISH_ASYNC_TRACE(context->funcName, context->taskId);
223                 napi_value result = nullptr;
224                 napi_get_undefined(env, &result);
225                 napi_resolve_deferred(env, context->deferred, result);
226                 napi_delete_async_work(env, context->work);
227                 delete context->objectInfo;
228                 delete context;
229             }, static_cast<void*>(asyncContext.get()), &asyncContext->work);
230         if (status != napi_ok) {
231             MEDIA_ERR_LOG("Failed to create napi_create_async_work for DeferredPhotoProxyNapi::Release");
232             napi_get_undefined(env, &result);
233         } else {
234             napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
235             asyncContext.release();
236         }
237     } else {
238         MEDIA_ERR_LOG("Release call Failed!");
239     }
240     return result;
241 }
242 } // namespace CameraStandard
243 } // namespace OHOS