• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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 "camera_napi_security_utils.h"
17 #include "camera_napi_param_parser.h"
18 #include "uv.h"
19 #include "mode/slow_motion_session_napi.h"
20 #include "napi/native_node_api.h"
21 
22 namespace OHOS {
23 namespace CameraStandard {
24 using namespace std;
25 
26 thread_local napi_ref SlowMotionSessionNapi::sConstructor_ = nullptr;
27 
OnSlowMotionStateCbAsync(const SlowMotionState state) const28 void SlowMotionStateListener::OnSlowMotionStateCbAsync(const SlowMotionState state) const
29 {
30     MEDIA_DEBUG_LOG("OnSlowMotionStateCbAsync is called");
31     std::unique_ptr<SlowMotionStateListenerInfo> callbackInfo =
32         std::make_unique<SlowMotionStateListenerInfo>(state, shared_from_this());
33     SlowMotionStateListenerInfo *event = callbackInfo.get();
34     auto task = [event]() {
35         SlowMotionStateListenerInfo* callbackInfo = reinterpret_cast<SlowMotionStateListenerInfo *>(event);
36         if (callbackInfo) {
37             auto listener = callbackInfo->listener_.lock();
38             CHECK_EXECUTE(listener != nullptr, listener->OnSlowMotionStateCb(callbackInfo->state_));
39             delete callbackInfo;
40         }
41     };
42     if (napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
43         MEDIA_ERR_LOG("failed to execute work");
44     } else {
45         callbackInfo.release();
46     }
47 }
48 
OnSlowMotionStateCb(const SlowMotionState state) const49 void SlowMotionStateListener::OnSlowMotionStateCb(const SlowMotionState state) const
50 {
51     MEDIA_DEBUG_LOG("OnSlowMotionStateCb is called, state: %{public}d", state);
52     napi_value result[ARGS_TWO] = {nullptr, nullptr};
53     napi_value retVal;
54     napi_get_undefined(env_, &result[PARAM0]);
55     napi_create_int32(env_, state, &result[PARAM1]);
56     ExecuteCallbackNapiPara callbackNapiPara { .recv = nullptr, .argc = ARGS_TWO, .argv = result, .result = &retVal };
57     ExecuteCallback("slowMotionStatus", callbackNapiPara);
58 }
59 
OnSlowMotionState(SlowMotionState state)60 void SlowMotionStateListener::OnSlowMotionState(SlowMotionState state)
61 {
62     OnSlowMotionStateCbAsync(state);
63 }
64 
SlowMotionSessionNapi()65 SlowMotionSessionNapi::SlowMotionSessionNapi() : env_(nullptr)
66 {
67 }
68 
~SlowMotionSessionNapi()69 SlowMotionSessionNapi::~SlowMotionSessionNapi()
70 {
71     MEDIA_DEBUG_LOG("~SlowMotionSessionNapi is called");
72 }
73 
SlowMotionSessionNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)74 void SlowMotionSessionNapi::SlowMotionSessionNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
75 {
76     MEDIA_DEBUG_LOG("SlowMotionSessionNapiDestructor is called");
77     SlowMotionSessionNapi* cameraObj = reinterpret_cast<SlowMotionSessionNapi*>(nativeObject);
78     if (cameraObj != nullptr) {
79         delete cameraObj;
80     }
81 }
82 
Init(napi_env env,napi_value exports)83 napi_value SlowMotionSessionNapi::Init(napi_env env, napi_value exports)
84 {
85     MEDIA_DEBUG_LOG("Init is called");
86     napi_status status;
87     napi_value ctorObj;
88     std::vector<napi_property_descriptor> slow_motion_props = {
89         DECLARE_NAPI_FUNCTION("isSlowMotionDetectionSupported", IsSlowMotionDetectionSupported),
90         DECLARE_NAPI_FUNCTION("setSlowMotionDetectionArea", SetSlowMotionDetectionArea)
91     };
92     std::vector<std::vector<napi_property_descriptor>> descriptors = {camera_process_props, flash_props,
93         auto_exposure_props, focus_props, zoom_props, filter_props, slow_motion_props};
94     std::vector<napi_property_descriptor> slow_motion_session_props =
95         CameraNapiUtils::GetPropertyDescriptor(descriptors);
96     status = napi_define_class(env, SLOW_MOTION_SESSION_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
97                                SlowMotionSessionNapiConstructor, nullptr,
98                                slow_motion_session_props.size(),
99                                slow_motion_session_props.data(), &ctorObj);
100     if (status == napi_ok) {
101         int32_t refCount = 1;
102         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
103         if (status == napi_ok) {
104             status = napi_set_named_property(env, exports, SLOW_MOTION_SESSION_NAPI_CLASS_NAME, ctorObj);
105             CHECK_ERROR_RETURN_RET(status == napi_ok, exports);
106         } else {
107             MEDIA_ERR_LOG("napi_create_reference Failed!");
108         }
109     }
110     MEDIA_ERR_LOG("Init call Failed!");
111     return nullptr;
112 }
113 
CreateCameraSession(napi_env env)114 napi_value SlowMotionSessionNapi::CreateCameraSession(napi_env env)
115 {
116     MEDIA_DEBUG_LOG("CreateCameraSession is called");
117     CAMERA_SYNC_TRACE;
118     napi_status status;
119     napi_value result = nullptr;
120     napi_value constructor;
121     status = napi_get_reference_value(env, sConstructor_, &constructor);
122     if (status == napi_ok) {
123         sCameraSession_ = CameraManager::GetInstance()->CreateCaptureSession(SceneMode::SLOW_MOTION);
124         if (sCameraSession_ == nullptr) {
125             MEDIA_ERR_LOG("Failed to create SlowMotion session instance");
126             napi_get_undefined(env, &result);
127             return result;
128         }
129         status = napi_new_instance(env, constructor, 0, nullptr, &result);
130         sCameraSession_ = nullptr;
131         if (status == napi_ok && result != nullptr) {
132             MEDIA_DEBUG_LOG("success to create slow motion session napi instance");
133             return result;
134         } else {
135             MEDIA_ERR_LOG("Failed to create slow motion session napi instance");
136         }
137     }
138     MEDIA_ERR_LOG("Failed to create slow motion session napi instance last");
139     napi_get_undefined(env, &result);
140     return result;
141 }
142 
SlowMotionSessionNapiConstructor(napi_env env,napi_callback_info info)143 napi_value SlowMotionSessionNapi::SlowMotionSessionNapiConstructor(napi_env env, napi_callback_info info)
144 {
145     MEDIA_DEBUG_LOG("SlowMotionSessionNapiConstructor is called");
146     napi_status status;
147     napi_value result = nullptr;
148     napi_value thisVar = nullptr;
149 
150     napi_get_undefined(env, &result);
151     CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
152 
153     if (status == napi_ok && thisVar != nullptr) {
154         std::unique_ptr<SlowMotionSessionNapi> obj = std::make_unique<SlowMotionSessionNapi>();
155         obj->env_ = env;
156         CHECK_ERROR_RETURN_RET_LOG(sCameraSession_ == nullptr, result, "sCameraSession is null");
157         obj->slowMotionSession_ = static_cast<SlowMotionSession*>(sCameraSession_.GetRefPtr());
158         obj->cameraSession_ = obj->slowMotionSession_;
159         CHECK_ERROR_RETURN_RET_LOG(obj->slowMotionSession_ == nullptr, result, "slowMotionSession is null");
160         status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
161             SlowMotionSessionNapi::SlowMotionSessionNapiDestructor, nullptr, nullptr);
162         if (status == napi_ok) {
163             obj.release();
164             return thisVar;
165         } else {
166             MEDIA_ERR_LOG("SlowMotionSessionNapi Failure wrapping js to native napi");
167         }
168     }
169     MEDIA_ERR_LOG("SlowMotionSessionNapi call Failed!");
170     return result;
171 }
172 
IsSlowMotionDetectionSupported(napi_env env,napi_callback_info info)173 napi_value SlowMotionSessionNapi::IsSlowMotionDetectionSupported(napi_env env, napi_callback_info info)
174 {
175     MEDIA_INFO_LOG("IsSlowMotionDetectionSupported is called");
176     napi_value result = CameraNapiUtils::GetUndefinedValue(env);
177     CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
178         "SystemApi IsSlowMotionDetectionSupported is called!");
179     SlowMotionSessionNapi* slowMotionSessionNapi = nullptr;
180     CameraNapiParamParser jsParamParser(env, info, slowMotionSessionNapi);
181     CHECK_ERROR_RETURN_RET_LOG(!jsParamParser.AssertStatus(INVALID_ARGUMENT, "parse parameter occur error"),
182         result, "IsSlowMotionDetectionSupported parse parameter occur error");
183     if (slowMotionSessionNapi != nullptr && slowMotionSessionNapi->slowMotionSession_ != nullptr) {
184         bool isSupported = slowMotionSessionNapi->slowMotionSession_->IsSlowMotionDetectionSupported();
185         napi_get_boolean(env, isSupported, &result);
186     } else {
187         MEDIA_ERR_LOG("IsSlowMotionDetectionSupported call Failed!");
188     }
189     return result;
190 }
191 
GetDoubleProperty(napi_env env,napi_value param,const std::string & propertyName,double & propertyValue)192 napi_value SlowMotionSessionNapi::GetDoubleProperty(napi_env env, napi_value param, const std::string& propertyName,
193     double& propertyValue)
194 {
195     napi_status status;
196     napi_value property;
197     status = napi_get_named_property(env, param, propertyName.c_str(), &property);
198     CHECK_ERROR_RETURN_RET(status != napi_ok, nullptr);
199     status = napi_get_value_double(env, property, &propertyValue);
200     CHECK_ERROR_RETURN_RET(status != napi_ok, nullptr);
201     return property;
202 }
203 
SetSlowMotionDetectionArea(napi_env env,napi_callback_info info)204 napi_value SlowMotionSessionNapi::SetSlowMotionDetectionArea(napi_env env, napi_callback_info info)
205 {
206     MEDIA_INFO_LOG("SetSlowMotionDetectionArea is called");
207     napi_value result = CameraNapiUtils::GetUndefinedValue(env);
208     CHECK_ERROR_RETURN_RET_LOG(!CameraNapiSecurity::CheckSystemApp(env), result,
209         "SystemApi SetSlowMotionDetectionArea is called!");
210     SlowMotionSessionNapi* slowMotionSessionNapi = nullptr;
211     napi_status status;
212     size_t argc = ARGS_ONE;
213     napi_value argv[ARGS_ONE] = {0};
214     napi_value thisVar = nullptr;
215     double topLeftX;
216     double topLeftY;
217     double width;
218     double height;
219 
220     CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
221 
222     if ((GetDoubleProperty(env, argv[PARAM0], "topLeftX", topLeftX) == nullptr) ||
223         (GetDoubleProperty(env, argv[PARAM0], "topLeftY", topLeftY) == nullptr) ||
224         (GetDoubleProperty(env, argv[PARAM0], "width", width) == nullptr) ||
225         (GetDoubleProperty(env, argv[PARAM0], "height", height) == nullptr)) {
226         return result;
227     }
228 
229     Rect rect = (Rect) {topLeftX, topLeftY, width, height};
230     napi_get_undefined(env, &result);
231     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&slowMotionSessionNapi));
232     if (status == napi_ok && slowMotionSessionNapi != nullptr && slowMotionSessionNapi->slowMotionSession_ != nullptr) {
233         slowMotionSessionNapi->slowMotionSession_->SetSlowMotionDetectionArea(rect);
234     } else {
235         MEDIA_ERR_LOG("SetSlowMotionDetectionArea call Failed!");
236     }
237     return result;
238 }
239 
RegisterSlowMotionStateCb(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args,bool isOnce)240 void SlowMotionSessionNapi::RegisterSlowMotionStateCb(
241     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args, bool isOnce)
242 {
243     MEDIA_INFO_LOG("RegisterSlowMotionStateCb is called");
244     if (slowMotionStateListener_ == nullptr) {
245         shared_ptr<SlowMotionStateListener> slowMotionStateListenerTemp =
246             static_pointer_cast<SlowMotionStateListener>(slowMotionSession_->GetApplicationCallback());
247         if (slowMotionStateListenerTemp == nullptr) {
248             slowMotionStateListenerTemp = make_shared<SlowMotionStateListener>(env);
249             slowMotionSession_->SetCallback(slowMotionStateListenerTemp);
250         }
251         slowMotionStateListener_ = slowMotionStateListenerTemp;
252     }
253     slowMotionStateListener_->SaveCallbackReference(eventName, callback, isOnce);
254     MEDIA_INFO_LOG("RegisterSlowMotionStateCb success");
255 }
256 
UnregisterSlowMotionStateCb(const std::string & eventName,napi_env env,napi_value callback,const std::vector<napi_value> & args)257 void SlowMotionSessionNapi::UnregisterSlowMotionStateCb(
258     const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args)
259 {
260     MEDIA_INFO_LOG("UnregisterSlowMotionStateCb is called");
261     if (slowMotionStateListener_ == nullptr) {
262         MEDIA_ERR_LOG("slowMotionStateListener_ is null");
263     } else {
264         slowMotionStateListener_->RemoveCallbackRef(eventName, callback);
265     }
266 }
267 } // namespace CameraStandard
268 } // namespace OHOS