/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H #define FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H #include #include #include #include "native_engine/native_engine.h" #include "js_runtime.h" namespace OHOS { namespace AbilityRuntime { template inline T* ConvertNativeValueTo(NativeValue* value) { return (value != nullptr) ? static_cast(value->GetInterface(T::INTERFACE_ID)) : nullptr; } template inline constexpr size_t ArraySize(T (&)[N]) noexcept { return N; } template inline NativeValue* CreateJsValue(NativeEngine& engine, const T& value) { using ValueType = std::remove_cv_t>; if constexpr (std::is_same_v) { return engine.CreateBoolean(value); } else if constexpr (std::is_arithmetic_v) { return engine.CreateNumber(value); } else if constexpr (std::is_same_v) { return engine.CreateString(value.c_str(), value.length()); } else if constexpr (std::is_enum_v) { return engine.CreateNumber(static_cast>(value)); } return engine.CreateUndefined(); } template inline bool ConvertFromJsValue(NativeEngine& engine, NativeValue* jsValue, T& value) { if (jsValue == nullptr) { return false; } using ValueType = std::remove_cv_t>; if constexpr (std::is_same_v) { auto boolValue = ConvertNativeValueTo(jsValue); if (boolValue == nullptr) { return false; } value = *boolValue; return true; } else if constexpr (std::is_arithmetic_v) { auto numberValue = ConvertNativeValueTo(jsValue); if (numberValue == nullptr) { return false; } value = *numberValue; return true; } else if constexpr (std::is_same_v) { auto stringValue = ConvertNativeValueTo(jsValue); if (stringValue == nullptr) { return false; } size_t len = stringValue->GetLength() + 1; auto buffer = std::make_unique(len); size_t strLength = 0; stringValue->GetCString(buffer.get(), len, &strLength); value = buffer.get(); return true; } else if constexpr (std::is_enum_v) { auto numberValue = ConvertNativeValueTo(jsValue); if (numberValue == nullptr) { return false; } value = static_cast(static_cast>(*numberValue)); return true; } } template NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector& data) { NativeValue* arrayValue = engine.CreateArray(data.size()); NativeArray* array = ConvertNativeValueTo(arrayValue); uint32_t index = 0; for (const T& item : data) { array->SetElement(index++, CreateJsValue(engine, item)); } return arrayValue; } NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string()); void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name, NativeCallback func); void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter); void* GetNativePointerFromCallbackInfo(NativeEngine* engine, NativeCallbackInfo* info, const char* name); void SetNamedNativePointer( NativeEngine& engine, NativeObject& object, const char* name, void* ptr, NativeFinalize func); void* GetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name); template T* CheckParamsAndGetThis(NativeEngine* engine, NativeCallbackInfo* info, const char* name = nullptr) { return static_cast(GetNativePointerFromCallbackInfo(engine, info, name)); } class HandleScope final { public: explicit HandleScope(JsRuntime& jsRuntime); explicit HandleScope(NativeEngine& engine); ~HandleScope(); NativeValue* Escape(NativeValue* value); HandleScope(const HandleScope&) = delete; HandleScope(HandleScope&&) = delete; HandleScope& operator=(const HandleScope&) = delete; HandleScope& operator=(HandleScope&&) = delete; private: NativeScopeManager* scopeManager_ = nullptr; NativeScope* nativeScope_ = nullptr; }; class AsyncTask final { public: using ExecuteCallback = std::function; using CompleteCallback = std::function; static void Schedule(NativeEngine& engine, std::unique_ptr&& task); AsyncTask(NativeDeferred* deferred, std::unique_ptr&& execute, std::unique_ptr&& complete); AsyncTask(NativeReference* callbackRef, std::unique_ptr&& execute, std::unique_ptr&& complete); ~AsyncTask(); void Resolve(NativeEngine& engine, NativeValue* value); void Reject(NativeEngine& engine, NativeValue* error); private: static void Execute(NativeEngine* engine, void* data); static void Complete(NativeEngine* engine, int32_t status, void* data); bool Start(NativeEngine& engine); std::unique_ptr deferred_; std::unique_ptr callbackRef_; std::unique_ptr work_; std::unique_ptr execute_; std::unique_ptr complete_; }; std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, AsyncTask::ExecuteCallback&& execute, AsyncTask::CompleteCallback&& complete, NativeValue** result); std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, AsyncTask::ExecuteCallback&& execute, nullptr_t, NativeValue** result); std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, nullptr_t, AsyncTask::CompleteCallback&& complete, NativeValue** result); std::unique_ptr CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam, nullptr_t, nullptr_t, NativeValue** result); } // namespace AbilityRuntime } // namespace OHOS #endif // FOUNDATION_OHOS_ABILITYRUNTIME_JS_RUNTIME_UTILS_H