• 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 <uv.h>
17 
18 #include "mode/video_session_for_sys_napi.h"
19 #include "ability/camera_ability_napi.h"
20 #include "napi/native_common.h"
21 #include "camera_napi_object_types.h"
22 
23 namespace OHOS {
24 namespace CameraStandard {
25 using namespace std;
26 
27 thread_local napi_ref VideoSessionForSysNapi::sConstructor_ = nullptr;
28 
VideoSessionForSysNapi()29 VideoSessionForSysNapi::VideoSessionForSysNapi() : env_(nullptr)
30 {
31 }
~VideoSessionForSysNapi()32 VideoSessionForSysNapi::~VideoSessionForSysNapi()
33 {
34     MEDIA_DEBUG_LOG("~VideoSessionForSysNapi is called");
35 }
VideoSessionForSysNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)36 void VideoSessionForSysNapi::VideoSessionForSysNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
37 {
38     MEDIA_DEBUG_LOG("VideoSessionForSysNapiDestructor is called");
39     VideoSessionForSysNapi* cameraObj = reinterpret_cast<VideoSessionForSysNapi*>(nativeObject);
40     if (cameraObj != nullptr) {
41         delete cameraObj;
42     }
43 }
Init(napi_env env,napi_value exports)44 napi_value VideoSessionForSysNapi::Init(napi_env env, napi_value exports)
45 {
46     MEDIA_DEBUG_LOG("Init is called");
47     napi_status status;
48     napi_value ctorObj;
49 
50     std::vector<std::vector<napi_property_descriptor>> descriptors = { camera_process_props, flash_props,
51         auto_exposure_props, focus_props, zoom_props, filter_props, beauty_props, color_effect_props, macro_props,
52         color_management_props, stabilization_props, preconfig_props, camera_output_capability_props,
53         camera_ability_props, aperture_props, color_reservation_props };
54     std::vector<napi_property_descriptor> video_session_props = CameraNapiUtils::GetPropertyDescriptor(descriptors);
55     status = napi_define_class(env, VIDEO_SESSION_FOR_SYS_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
56                                VideoSessionForSysNapiConstructor, nullptr,
57                                video_session_props.size(),
58                                video_session_props.data(), &ctorObj);
59     if (status == napi_ok) {
60         int32_t refCount = 1;
61         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
62         if (status == napi_ok) {
63             status = napi_set_named_property(env, exports, VIDEO_SESSION_FOR_SYS_NAPI_CLASS_NAME, ctorObj);
64             if (status == napi_ok) {
65                 return exports;
66             }
67         }
68     }
69     MEDIA_ERR_LOG("Init call Failed!");
70     return nullptr;
71 }
72 
CreateCameraSession(napi_env env)73 napi_value VideoSessionForSysNapi::CreateCameraSession(napi_env env)
74 {
75     MEDIA_DEBUG_LOG("CreateCameraSession is called");
76     CAMERA_SYNC_TRACE;
77     napi_status status;
78     napi_value result = nullptr;
79     napi_value constructor;
80     status = napi_get_reference_value(env, sConstructor_, &constructor);
81     if (status == napi_ok) {
82         sCameraSession_ = CameraManager::GetInstance()->CreateCaptureSession(SceneMode::VIDEO);
83         if (sCameraSession_ == nullptr) {
84             MEDIA_ERR_LOG("Failed to create Video session instance");
85             napi_get_undefined(env, &result);
86             return result;
87         }
88         status = napi_new_instance(env, constructor, 0, nullptr, &result);
89         sCameraSession_ = nullptr;
90         if (status == napi_ok && result != nullptr) {
91             MEDIA_DEBUG_LOG("success to create Video session napi instance");
92             return result;
93         } else {
94             MEDIA_ERR_LOG("Failed to create Video session napi instance");
95         }
96     }
97     MEDIA_ERR_LOG("Failed to create Video session napi instance last");
98     napi_get_undefined(env, &result);
99     return result;
100 }
101 
VideoSessionForSysNapiConstructor(napi_env env,napi_callback_info info)102 napi_value VideoSessionForSysNapi::VideoSessionForSysNapiConstructor(napi_env env, napi_callback_info info)
103 {
104     MEDIA_DEBUG_LOG("VideoSessionForSysNapiConstructor is called");
105     napi_status status;
106     napi_value result = nullptr;
107     napi_value thisVar = nullptr;
108 
109     napi_get_undefined(env, &result);
110     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
111 
112     if (status == napi_ok && thisVar != nullptr) {
113         std::unique_ptr<VideoSessionForSysNapi> obj = std::make_unique<VideoSessionForSysNapi>();
114         obj->env_ = env;
115         if (sCameraSession_ == nullptr) {
116             MEDIA_ERR_LOG("sCameraSession_ is null");
117             return result;
118         }
119         obj->videoSession_ = static_cast<VideoSession*>(sCameraSession_.GetRefPtr());
120         obj->cameraSession_ = obj->videoSession_;
121         if (obj->videoSession_ == nullptr) {
122             MEDIA_ERR_LOG("videoSession_ is null");
123             return result;
124         }
125         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
126             VideoSessionForSysNapi::VideoSessionForSysNapiDestructor, nullptr, nullptr);
127         if (status == napi_ok) {
128             obj.release();
129             return thisVar;
130         } else {
131             MEDIA_ERR_LOG("VideoSessionForSysNapi Failure wrapping js to native napi");
132         }
133     }
134     MEDIA_ERR_LOG("VideoSessionForSysNapi call Failed!");
135     return result;
136 }
137 
RegisterFocusTrackingInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)138 void VideoSessionForSysNapi::RegisterFocusTrackingInfoCallbackListener(const std::string& eventName,
139     napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
140 {
141     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
142     CHECK_ERROR_RETURN_LOG(videoSession_ == nullptr, "%{public}s videoSession is nullptr!", __FUNCTION__);
143     if (focusTrackingInfoCallback_ == nullptr) {
144         focusTrackingInfoCallback_ = std::make_shared<FocusTrackingCallbackListener>(env);
145         videoSession_->SetFocusTrackingInfoCallback(focusTrackingInfoCallback_);
146     }
147     focusTrackingInfoCallback_->SaveCallbackReference(eventName, callback, isOnce);
148 }
149 
UnregisterFocusTrackingInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)150 void VideoSessionForSysNapi::UnregisterFocusTrackingInfoCallbackListener(const std::string& eventName,
151     napi_env env, napi_value callback, const std::vector<napi_value>& args)
152 {
153     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
154     CHECK_ERROR_RETURN_LOG(focusTrackingInfoCallback_ == nullptr,
155         "%{public}s focusTrackingInfoCallback_ is nullptr", __FUNCTION__);
156     focusTrackingInfoCallback_->RemoveCallbackRef(eventName, callback);
157 }
158 
OnFocusTrackingInfoAvailable(FocusTrackingInfo & focusTrackingInfo) const159 void FocusTrackingCallbackListener::OnFocusTrackingInfoAvailable(FocusTrackingInfo &focusTrackingInfo) const
160 {
161     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
162     OnFocusTrackingInfoCallbackAsync(focusTrackingInfo);
163 }
164 
OnFocusTrackingInfoCallbackAsync(FocusTrackingInfo & focusTrackingInfo) const165 void FocusTrackingCallbackListener::OnFocusTrackingInfoCallbackAsync(FocusTrackingInfo &focusTrackingInfo) const
166 {
167     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
168 
169     uv_loop_s* loop = nullptr;
170     napi_get_uv_event_loop(env_, &loop);
171     CHECK_ERROR_RETURN_LOG(!loop, "%{public}s: failed to get event loop", __FUNCTION__);
172 
173     uv_work_t* work = new(std::nothrow) uv_work_t;
174     CHECK_ERROR_RETURN_LOG(!work, "%{public}s: failed to allocate work", __FUNCTION__);
175 
176     std::unique_ptr<FocusTrackingCallbackInfo> callback =
177         std::make_unique<FocusTrackingCallbackInfo>(focusTrackingInfo, shared_from_this());
178     work->data = callback.get();
179     int ret = uv_queue_work_with_qos(
180         loop, work, [] (uv_work_t* work) {},
181         [] (uv_work_t* work, int status) {
182         FocusTrackingCallbackInfo* callback = reinterpret_cast<FocusTrackingCallbackInfo *>(work->data);
183         if (callback) {
184             auto listener = callback->listener_.lock();
185             if (listener != nullptr) {
186                 listener->OnFocusTrackingInfoCallback(callback->focusTrackingInfo_);
187             }
188             delete callback;
189         }
190         delete work;
191     }, uv_qos_user_initiated);
192     if (ret) {
193         MEDIA_ERR_LOG("%{public}s: failed to execute work", __FUNCTION__);
194         delete work;
195     } else {
196         callback.release();
197     }
198 }
199 
OnFocusTrackingInfoCallback(FocusTrackingInfo & focusTrackingInfo) const200 void FocusTrackingCallbackListener::OnFocusTrackingInfoCallback(FocusTrackingInfo &focusTrackingInfo) const
201 {
202     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
203 
204     napi_value result[ARGS_ONE] = { nullptr };
205     napi_value retVal = nullptr;
206 
207     result[PARAM0] = CameraNapiFocusTrackingInfo(focusTrackingInfo).GenerateNapiValue(env_);
208 
209     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
210     ExecuteCallback("focusTrackingInfoAvailable", callbackNapiPara);
211 }
212 } // namespace CameraStandard
213 } // namespace OHOS
214