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 #ifndef CAMERA_NAPI_AUTO_REF_H 17 #define CAMERA_NAPI_AUTO_REF_H 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <memory> 22 23 #include "js_native_api.h" 24 #include "js_native_api_types.h" 25 #include "napi/native_api.h" 26 #include "node_api.h" 27 #include "node_api_types.h" 28 29 namespace OHOS { 30 namespace CameraStandard { 31 struct AutoRef { 32 public: AutoRefAutoRef33 AutoRef(napi_env env, napi_value callback, bool isOnce) : isOnce_(isOnce), env_(env) 34 { 35 (void)napi_create_reference(env_, callback, 1, &callbackRef_); 36 napi_create_string_utf8(env, "~AutoRef", NAPI_AUTO_LENGTH, &tsfnName_); 37 } 38 AutoRefAutoRef39 AutoRef(const AutoRef& other) 40 { 41 isOnce_ = other.isOnce_; 42 env_ = other.env_; 43 callbackRef_ = other.callbackRef_; 44 tsfnName_ = other.tsfnName_; 45 if (env_ != nullptr && callbackRef_ != nullptr) { 46 (void)napi_reference_ref(env_, callbackRef_, nullptr); 47 } 48 } 49 50 AutoRef& operator=(const AutoRef& other) 51 { 52 AutoRef tmp(other); 53 std::swap(isOnce_, tmp.isOnce_); 54 std::swap(env_, tmp.env_); 55 std::swap(callbackRef_, tmp.callbackRef_); 56 std::swap(tsfnName_, tmp.tsfnName_); 57 return *this; 58 } 59 ~AutoRefAutoRef60 ~AutoRef() 61 { 62 if (callbackRef_ == nullptr) { 63 return; 64 } 65 napi_threadsafe_function tsfn = nullptr; 66 napi_status status = napi_create_threadsafe_function( 67 env_, nullptr, nullptr, tsfnName_, 0, 1, nullptr, nullptr, nullptr, 68 [](napi_env env, napi_value js_cb, void* context, void* data) { 69 if (data == nullptr) { 70 return; 71 } 72 napi_ref callbackRef = static_cast<napi_ref>(data); 73 (void)napi_reference_unref(env, callbackRef, nullptr); 74 }, 75 &tsfn); 76 if (status != napi_ok) { 77 return; 78 } 79 napi_call_threadsafe_function(tsfn, callbackRef_, napi_tsfn_nonblocking); 80 napi_release_threadsafe_function(tsfn, napi_tsfn_release); 81 } 82 GetCallbackFunctionAutoRef83 napi_value GetCallbackFunction() 84 { 85 if (env_ == nullptr || callbackRef_ == nullptr) { 86 return nullptr; 87 } 88 napi_value callback = nullptr; 89 if (napi_get_reference_value(env_, callbackRef_, &callback) == napi_ok) { 90 return callback; 91 } 92 return nullptr; 93 } 94 95 bool isOnce_ = false; 96 97 private: 98 napi_env env_ = nullptr; 99 napi_ref callbackRef_ = nullptr; 100 napi_value tsfnName_ = nullptr; 101 }; 102 } // namespace CameraStandard 103 } // namespace OHOS 104 #endif