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 "mode/mode_manager_napi.h"
17
18 #include "camera_napi_object_types.h"
19 #include "input/camera_manager_napi.h"
20 #include "input/camera_napi.h"
21 #include "napi/native_common.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
25 using namespace std;
26 thread_local napi_ref ModeManagerNapi::sConstructor_ = nullptr;
27 thread_local uint32_t ModeManagerNapi::modeManagerTaskId = MODE_MANAGER_TASKID;
28
29 namespace {
GetCameraDeviceFromNapiCameraInfoObj(napi_env env,napi_value napiCameraInfoObj)30 sptr<CameraDevice> GetCameraDeviceFromNapiCameraInfoObj(napi_env env, napi_value napiCameraInfoObj)
31 {
32 napi_value napiCameraId = nullptr;
33 if (napi_get_named_property(env, napiCameraInfoObj, "cameraId", &napiCameraId) != napi_ok) {
34 return nullptr;
35 }
36 std::string cameraId = CameraNapiUtils::GetStringArgument(env, napiCameraId);
37 return CameraManager::GetInstance()->GetCameraDeviceFromId(cameraId);
38 }
39 }
40
ModeManagerNapi()41 ModeManagerNapi::ModeManagerNapi() : env_(nullptr)
42 {
43 MEDIA_DEBUG_LOG("ModeManagerNapi::ModeManagerNapi is called");
44 }
45
~ModeManagerNapi()46 ModeManagerNapi::~ModeManagerNapi()
47 {
48 MEDIA_DEBUG_LOG("~ModeManagerNapi is called");
49 }
50
51 // Constructor callback
ModeManagerNapiConstructor(napi_env env,napi_callback_info info)52 napi_value ModeManagerNapi::ModeManagerNapiConstructor(napi_env env, napi_callback_info info)
53 {
54 MEDIA_DEBUG_LOG("ModeManagerNapiConstructor is called");
55 napi_status status;
56 napi_value result = nullptr;
57 napi_value thisVar = nullptr;
58
59 napi_get_undefined(env, &result);
60 CAMERA_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
61
62 if (status == napi_ok && thisVar != nullptr) {
63 std::unique_ptr<ModeManagerNapi> obj = std::make_unique<ModeManagerNapi>();
64 obj->env_ = env;
65 obj->modeManager_ = CameraManager::GetInstance();
66 if (obj->modeManager_ == nullptr) {
67 MEDIA_ERR_LOG("Failure wrapping js to native napi, obj->modeManager_ null");
68 return result;
69 }
70 status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
71 ModeManagerNapi::ModeManagerNapiDestructor, nullptr, nullptr);
72 if (status == napi_ok) {
73 obj.release();
74 return thisVar;
75 } else {
76 MEDIA_ERR_LOG("Failure wrapping js to native napi");
77 }
78 }
79 MEDIA_ERR_LOG("ModeManagerNapiConstructor call Failed!");
80 return result;
81 }
82
ModeManagerNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)83 void ModeManagerNapi::ModeManagerNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint)
84 {
85 MEDIA_DEBUG_LOG("ModeManagerNapiDestructor is called");
86 ModeManagerNapi* camera = reinterpret_cast<ModeManagerNapi*>(nativeObject);
87 if (camera != nullptr) {
88 delete camera;
89 }
90 }
91
Init(napi_env env,napi_value exports)92 napi_value ModeManagerNapi::Init(napi_env env, napi_value exports)
93 {
94 MEDIA_DEBUG_LOG("Init is called");
95 napi_status status;
96 napi_value ctorObj;
97 napi_property_descriptor mode_mgr_properties[] = {
98 DECLARE_NAPI_FUNCTION("getSupportedModes", GetSupportedModes),
99 DECLARE_NAPI_FUNCTION("getSupportedOutputCapability", GetSupportedOutputCapability),
100 DECLARE_NAPI_FUNCTION("createCaptureSession", CreateCameraSessionInstance),
101 };
102
103 status = napi_define_class(env, MODE_MANAGER_NAPI_CLASS_NAME, NAPI_AUTO_LENGTH,
104 ModeManagerNapiConstructor, nullptr,
105 sizeof(mode_mgr_properties) / sizeof(mode_mgr_properties[PARAM0]),
106 mode_mgr_properties, &ctorObj);
107 if (status == napi_ok) {
108 int32_t refCount = 1;
109 if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
110 status = napi_set_named_property(env, exports, MODE_MANAGER_NAPI_CLASS_NAME, ctorObj);
111 if (status == napi_ok) {
112 return exports;
113 }
114 }
115 }
116 MEDIA_ERR_LOG("Init call Failed!");
117 return nullptr;
118 }
119
CreateModeManager(napi_env env)120 napi_value ModeManagerNapi::CreateModeManager(napi_env env)
121 {
122 MEDIA_INFO_LOG("CreateModeManager is called");
123 napi_status status;
124 napi_value result = nullptr;
125 napi_value ctor;
126
127 status = napi_get_reference_value(env, sConstructor_, &ctor);
128 if (status == napi_ok) {
129 status = napi_new_instance(env, ctor, 0, nullptr, &result);
130 if (status == napi_ok) {
131 return result;
132 } else {
133 MEDIA_ERR_LOG("New instance could not be obtained");
134 }
135 }
136 napi_get_undefined(env, &result);
137 MEDIA_ERR_LOG("CreateModeManager call Failed!");
138 return result;
139 }
140
CreateCameraSessionInstance(napi_env env,napi_callback_info info)141 napi_value ModeManagerNapi::CreateCameraSessionInstance(napi_env env, napi_callback_info info)
142 {
143 MEDIA_INFO_LOG("CreateCameraSessionInstance is called");
144 napi_status status;
145 napi_value result = nullptr;
146 size_t argc = ARGS_ONE;
147 napi_value argv[ARGS_ONE];
148 napi_value thisVar = nullptr;
149
150 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
151
152 napi_get_undefined(env, &result);
153
154 ModeManagerNapi* modeManagerNapi = nullptr;
155 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&modeManagerNapi));
156 if (status != napi_ok || modeManagerNapi == nullptr) {
157 MEDIA_ERR_LOG("napi_unwrap failure!");
158 return nullptr;
159 }
160
161 int32_t jsModeName;
162 napi_get_value_int32(env, argv[PARAM0], &jsModeName);
163 MEDIA_INFO_LOG("ModeManagerNapi::CreateCameraSessionInstance mode = %{public}d", jsModeName);
164 switch (jsModeName) {
165 case JsSceneMode::JS_CAPTURE:
166 result = PhotoSessionNapi::CreateCameraSession(env);
167 break;
168 case JsSceneMode::JS_VIDEO:
169 result = VideoSessionNapi::CreateCameraSession(env);
170 break;
171 case JsSceneMode::JS_PORTRAIT:
172 result = PortraitSessionNapi::CreateCameraSession(env);
173 break;
174 case JsSceneMode::JS_NIGHT:
175 result = NightSessionNapi::CreateCameraSession(env);
176 break;
177 case JS_SECURE_CAMERA:
178 result = SecureCameraSessionNapi::CreateCameraSession(env);
179 break;
180 case JsSceneMode::JS_PANORAMA_PHOTO:
181 result = PanoramaSessionNapi::CreateCameraSession(env);
182 break;
183 default:
184 MEDIA_ERR_LOG("ModeManagerNapi::CreateCameraSessionInstance mode = %{public}d not supported", jsModeName);
185 break;
186 }
187 return result;
188 }
189
CreateSceneModeJSArray(napi_env env,napi_status status,std::vector<SceneMode> nativeArray)190 static napi_value CreateSceneModeJSArray(napi_env env, napi_status status,
191 std::vector<SceneMode> nativeArray)
192 {
193 MEDIA_DEBUG_LOG("CreateSceneModeJSArray is called");
194 napi_value jsArray = nullptr;
195 napi_value item = nullptr;
196
197 if (nativeArray.empty()) {
198 MEDIA_ERR_LOG("nativeArray is empty");
199 }
200
201 status = napi_create_array(env, &jsArray);
202 if (status == napi_ok) {
203 for (size_t i = 0; i < nativeArray.size(); i++) {
204 napi_create_int32(env, nativeArray[i], &item);
205 if (napi_set_element(env, jsArray, i, item) != napi_ok) {
206 MEDIA_ERR_LOG("Failed to create profile napi wrapper object");
207 return nullptr;
208 }
209 }
210 }
211 return jsArray;
212 }
213
GetSupportedModes(napi_env env,napi_callback_info info)214 napi_value ModeManagerNapi::GetSupportedModes(napi_env env, napi_callback_info info)
215 {
216 MEDIA_INFO_LOG("GetSupportedModes is called");
217 napi_status status;
218 napi_value result = nullptr;
219 size_t argc = ARGS_ONE;
220 napi_value argv[ARGS_ONE];
221 napi_value thisVar = nullptr;
222 napi_value jsResult = nullptr;
223 ModeManagerNapi* modeManagerNapi = nullptr;
224 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
225
226 napi_get_undefined(env, &result);
227 sptr<CameraDevice> cameraInfo = GetCameraDeviceFromNapiCameraInfoObj(env, argv[PARAM0]);
228 if (cameraInfo == nullptr) {
229 MEDIA_ERR_LOG("Could not able to read cameraId argument!");
230 return result;
231 }
232
233 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&modeManagerNapi));
234 if (status == napi_ok && modeManagerNapi != nullptr) {
235 std::vector<SceneMode> modeObjList = modeManagerNapi->modeManager_->GetSupportedModes(cameraInfo);
236 MEDIA_INFO_LOG("ModeManagerNapi::GetSupportedModes size=[%{public}zu]", modeObjList.size());
237 jsResult = CreateSceneModeJSArray(env, status, modeObjList);
238 if (status == napi_ok) {
239 return jsResult;
240 } else {
241 MEDIA_ERR_LOG("Failed to get modeObjList!, errorCode : %{public}d", status);
242 }
243 } else {
244 MEDIA_ERR_LOG("GetSupportedModes call Failed!");
245 }
246 return result;
247 }
248
GetSupportedOutputCapability(napi_env env,napi_callback_info info)249 napi_value ModeManagerNapi::GetSupportedOutputCapability(napi_env env, napi_callback_info info)
250 {
251 MEDIA_INFO_LOG("GetSupportedOutputCapability is called");
252 napi_status status;
253
254 napi_value result = nullptr;
255 size_t argc = ARGS_TWO;
256 napi_value argv[ARGS_TWO] = {0};
257 napi_value thisVar = nullptr;
258 ModeManagerNapi* modeManagerNapi = nullptr;
259
260 CAMERA_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar);
261
262 napi_get_undefined(env, &result);
263 status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&modeManagerNapi));
264 if (status != napi_ok || modeManagerNapi == nullptr) {
265 MEDIA_ERR_LOG("napi_unwrap() failure!");
266 return result;
267 }
268
269 sptr<CameraDevice> cameraInfo = GetCameraDeviceFromNapiCameraInfoObj(env, argv[PARAM0]);
270 if (cameraInfo == nullptr) {
271 MEDIA_ERR_LOG("Could not able to read cameraId argument!");
272 return result;
273 }
274
275 int32_t sceneMode;
276 napi_get_value_int32(env, argv[PARAM1], &sceneMode);
277 MEDIA_INFO_LOG("ModeManagerNapi::GetSupportedOutputCapability mode = %{public}d", sceneMode);
278
279 sptr<CameraOutputCapability> outputCapability = nullptr;
280 auto cameraManager = CameraManager::GetInstance();
281 switch (sceneMode) {
282 case JS_CAPTURE:
283 outputCapability = cameraManager->GetSupportedOutputCapability(cameraInfo, SceneMode::CAPTURE);
284 break;
285 case JS_VIDEO:
286 outputCapability = cameraManager->GetSupportedOutputCapability(cameraInfo, SceneMode::VIDEO);
287 break;
288 case JS_PORTRAIT:
289 outputCapability = cameraManager->GetSupportedOutputCapability(cameraInfo, SceneMode::PORTRAIT);
290 break;
291 case JS_NIGHT:
292 outputCapability = cameraManager->GetSupportedOutputCapability(cameraInfo, SceneMode::NIGHT);
293 break;
294 case JS_SECURE_CAMERA:
295 outputCapability = cameraManager->GetSupportedOutputCapability(cameraInfo, SceneMode::SECURE);
296 break;
297 default:
298 MEDIA_ERR_LOG("ModeManagerNapi::CreateCameraSessionInstance mode = %{public}d not supported", sceneMode);
299 break;
300 }
301 if (outputCapability != nullptr) {
302 result = CameraNapiObjCameraOutputCapability(*outputCapability).GenerateNapiValue(env);
303 }
304 return result;
305 }
306 } // namespace CameraStandard
307 } // namespace OHOS
308