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