• 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, effect_suggestion_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             CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
65         }
66     }
67     MEDIA_ERR_LOG("Init call Failed!");
68     return nullptr;
69 }
70 
CreateCameraSession(napi_env env)71 napi_value VideoSessionForSysNapi::CreateCameraSession(napi_env env)
72 {
73     MEDIA_DEBUG_LOG("CreateCameraSession is called");
74     CAMERA_SYNC_TRACE;
75     napi_status status;
76     napi_value result = nullptr;
77     napi_value constructor;
78     status = napi_get_reference_value(env, sConstructor_, &constructor);
79     if (status == napi_ok) {
80         sCameraSession_ = CameraManager::GetInstance()->CreateCaptureSession(SceneMode::VIDEO);
81         if (sCameraSession_ == nullptr) {
82             MEDIA_ERR_LOG("Failed to create Video session instance");
83             napi_get_undefined(env, &result);
84             return result;
85         }
86         status = napi_new_instance(env, constructor, 0, nullptr, &result);
87         sCameraSession_ = nullptr;
88         if (status == napi_ok && result != nullptr) {
89             MEDIA_DEBUG_LOG("success to create Video session napi instance");
90             return result;
91         } else {
92             MEDIA_ERR_LOG("Failed to create Video session napi instance");
93         }
94     }
95     MEDIA_ERR_LOG("Failed to create Video session napi instance last");
96     napi_get_undefined(env, &result);
97     return result;
98 }
99 
VideoSessionForSysNapiConstructor(napi_env env,napi_callback_info info)100 napi_value VideoSessionForSysNapi::VideoSessionForSysNapiConstructor(napi_env env, napi_callback_info info)
101 {
102     MEDIA_DEBUG_LOG("VideoSessionForSysNapiConstructor is called");
103     napi_status status;
104     napi_value result = nullptr;
105     napi_value thisVar = nullptr;
106 
107     napi_get_undefined(env, &result);
108     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
109 
110     if (status == napi_ok && thisVar != nullptr) {
111         std::unique_ptr<VideoSessionForSysNapi> obj = std::make_unique<VideoSessionForSysNapi>();
112         obj->env_ = env;
113         CHECK_ERROR_RETURN_RET_LOG(sCameraSession_ == nullptr, result, "sCameraSession_ is null");
114         obj->videoSession_ = static_cast<VideoSession*>(sCameraSession_.GetRefPtr());
115         obj->cameraSession_ = obj->videoSession_;
116         CHECK_ERROR_RETURN_RET_LOG(obj->videoSession_ == nullptr, result, "videoSession_ is null");
117         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
118             VideoSessionForSysNapi::VideoSessionForSysNapiDestructor, nullptr, nullptr);
119         if (status == napi_ok) {
120             obj.release();
121             return thisVar;
122         } else {
123             MEDIA_ERR_LOG("VideoSessionForSysNapi Failure wrapping js to native napi");
124         }
125     }
126     MEDIA_ERR_LOG("VideoSessionForSysNapi call Failed!");
127     return result;
128 }
129 
RegisterFocusTrackingInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)130 void VideoSessionForSysNapi::RegisterFocusTrackingInfoCallbackListener(const std::string& eventName,
131     napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
132 {
133     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
134     CHECK_ERROR_RETURN_LOG(videoSession_ == nullptr, "%{public}s videoSession is nullptr!", __FUNCTION__);
135     if (focusTrackingInfoCallback_ == nullptr) {
136         focusTrackingInfoCallback_ = std::make_shared<FocusTrackingCallbackListener>(env);
137         videoSession_->SetFocusTrackingInfoCallback(focusTrackingInfoCallback_);
138     }
139     focusTrackingInfoCallback_->SaveCallbackReference(eventName, callback, isOnce);
140 }
141 
UnregisterFocusTrackingInfoCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)142 void VideoSessionForSysNapi::UnregisterFocusTrackingInfoCallbackListener(const std::string& eventName,
143     napi_env env, napi_value callback, const std::vector<napi_value>& args)
144 {
145     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
146     CHECK_ERROR_RETURN_LOG(focusTrackingInfoCallback_ == nullptr,
147         "%{public}s focusTrackingInfoCallback_ is nullptr", __FUNCTION__);
148     focusTrackingInfoCallback_->RemoveCallbackRef(eventName, callback);
149 }
150 
OnFocusTrackingInfoAvailable(FocusTrackingInfo & focusTrackingInfo) const151 void FocusTrackingCallbackListener::OnFocusTrackingInfoAvailable(FocusTrackingInfo &focusTrackingInfo) const
152 {
153     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
154     OnFocusTrackingInfoCallbackAsync(focusTrackingInfo);
155 }
156 
OnFocusTrackingInfoCallbackAsync(FocusTrackingInfo & focusTrackingInfo) const157 void FocusTrackingCallbackListener::OnFocusTrackingInfoCallbackAsync(FocusTrackingInfo &focusTrackingInfo) const
158 {
159     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
160     std::unique_ptr<FocusTrackingCallbackInfo> callback =
161         std::make_unique<FocusTrackingCallbackInfo>(focusTrackingInfo, shared_from_this());
162     FocusTrackingCallbackInfo *event = callback.get();
163     auto task = [event] () {
164         FocusTrackingCallbackInfo* callback = reinterpret_cast<FocusTrackingCallbackInfo *>(event);
165         if (callback) {
166             auto listener = callback->listener_.lock();
167             if (listener != nullptr) {
168                 listener->OnFocusTrackingInfoCallback(callback->focusTrackingInfo_);
169             }
170             delete callback;
171         }
172     };
173     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
174         MEDIA_ERR_LOG("%{public}s: failed to execute work", __FUNCTION__);
175     } else {
176         callback.release();
177     }
178 }
179 
OnFocusTrackingInfoCallback(FocusTrackingInfo & focusTrackingInfo) const180 void FocusTrackingCallbackListener::OnFocusTrackingInfoCallback(FocusTrackingInfo &focusTrackingInfo) const
181 {
182     MEDIA_DEBUG_LOG("%{public}s is called", __FUNCTION__);
183 
184     napi_value result[ARGS_ONE] = { nullptr };
185     napi_value retVal = nullptr;
186 
187     result[PARAM0] = CameraNapiFocusTrackingInfo(focusTrackingInfo).GenerateNapiValue(env_);
188 
189     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_ONE, .argv = result, .result = &retVal };
190     ExecuteCallback("focusTrackingInfoAvailable", callbackNapiPara);
191 }
192 
RegisterLightStatusCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)193 void VideoSessionForSysNapi::RegisterLightStatusCallbackListener(
194     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
195 {
196     MEDIA_INFO_LOG("VideoSessionForSysNapi::RegisterLightStatusCallbackListener called");
197     if (lightStatusCallback_ == nullptr) {
198         lightStatusCallback_ = std::make_shared<LightStatusCallbackListener>(env);
199         videoSession_->SetLightStatusCallback(lightStatusCallback_);
200         videoSession_->SetLightStatus(0);
201     }
202     lightStatusCallback_->SaveCallbackReference(eventName, callback, isOnce);
203 }
204 
UnregisterLightStatusCallbackListener(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)205 void VideoSessionForSysNapi::UnregisterLightStatusCallbackListener(
206     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
207 {
208     MEDIA_INFO_LOG("VideoSessionForSysNapi::UnregisterLightStatusCallbackListener is called");
209     if (lightStatusCallback_ == nullptr) {
210         MEDIA_DEBUG_LOG("abilityCallback is null");
211     } else {
212         lightStatusCallback_->RemoveCallbackRef(eventName, callback);
213     }
214 }
215 
OnLightStatusChangedCallbackAsync(LightStatus & status) const216 void LightStatusCallbackListener::OnLightStatusChangedCallbackAsync(LightStatus &status) const
217 {
218     MEDIA_INFO_LOG("OnLightStatusChangedCallbackAsync is called");
219     std::unique_ptr<LightStatusChangedCallback> callback =
220         std::make_unique<LightStatusChangedCallback>(status, shared_from_this());
221     LightStatusChangedCallback *event = callback.get();
222     auto task = [event] () {
223         LightStatusChangedCallback* callback = reinterpret_cast<LightStatusChangedCallback *>(event);
224         if (callback) {
225             MEDIA_DEBUG_LOG("the light status is %{public}d", callback->status_.status);
226             auto listener = callback->listener_.lock();
227             if (listener != nullptr) {
228                 listener->OnLightStatusChangedCallback(callback->status_);
229             }
230             delete callback;
231         }
232     };
233     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
234         MEDIA_ERR_LOG("failed to execute work");
235     } else {
236         callback.release();
237     }
238 }
239 
OnLightStatusChangedCallback(LightStatus & status) const240 void LightStatusCallbackListener::OnLightStatusChangedCallback(LightStatus &status) const
241 {
242     MEDIA_DEBUG_LOG("OnLightStatusChangedCallback is called, light status is %{public}d", status.status);
243     ExecuteCallbackScopeSafe("lightStatusChange", [&]() {
244         napi_value errCode = CameraNapiUtils::GetUndefinedValue(env_);
245         napi_value result;
246         napi_create_uint32(env_, status.status, &result);
247         return ExecuteCallbackData(env_, errCode, result);
248     });
249 }
250 
OnLightStatusChanged(LightStatus & status)251 void LightStatusCallbackListener::OnLightStatusChanged(LightStatus &status)
252 {
253     MEDIA_DEBUG_LOG("OnLightStatusChanged is called, lightStatus: %{public}d", status.status);
254     OnLightStatusChangedCallbackAsync(status);
255 }
256 } // namespace CameraStandard
257 } // namespace OHOS
258