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