1 /* 2 * Copyright (c) 2023 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 INTERFACES_NAPI_KITS_DRAG_CONTROLLER_DRAG_PREVIEW_H 17 #define INTERFACES_NAPI_KITS_DRAG_CONTROLLER_DRAG_PREVIEW_H 18 19 #include "interfaces/napi/kits/utils/napi_utils.h" 20 #include "js_native_api.h" 21 #include "js_native_api_types.h" 22 #include "jsnapi.h" 23 #include "napi/native_common.h" 24 #include "native_engine/impl/ark/ark_native_engine.h" 25 #include "native_value.h" 26 #include "node_api.h" 27 28 #include "base/log/log_wrapper.h" 29 #include "base/msdp/device_status/interfaces/innerkits/interaction/include/interaction_manager.h" 30 #include "bridge/common/utils/utils.h" 31 #include "core/common/ace_engine.h" 32 #include "frameworks/core/components/common/properties/color.h" 33 34 namespace OHOS::Ace::Napi { 35 using PreviewType = Msdp::DeviceStatus::PreviewType; 36 using PreviewStyle = Msdp::DeviceStatus::PreviewStyle; 37 using PreviewAnimation = Msdp::DeviceStatus::PreviewAnimation; 38 namespace { 39 constexpr int32_t argCount1 = 1; 40 constexpr int32_t argCount2 = 2; 41 constexpr int32_t DEFAULT_DURATION_VALUE = 1000; 42 } // namespace 43 44 class DragPreview { 45 public: 46 DragPreview() = default; 47 ~DragPreview() = default; 48 SetForegroundColor(napi_env env,napi_callback_info info)49 static napi_value SetForegroundColor(napi_env env, napi_callback_info info) 50 { 51 napi_handle_scope scope = nullptr; 52 napi_open_handle_scope(env, &scope); 53 CHECK_NULL_RETURN(scope, nullptr); 54 size_t argc = argCount1; 55 napi_value argv[argCount1] = { 0 }; 56 napi_value result = nullptr; 57 void* data = nullptr; 58 napi_get_cb_info(env, info, &argc, argv, &result, &data); 59 NAPI_ASSERT(env, argc == argCount1, "require 1 parameter"); 60 61 Color foregroundColor; 62 if (!ParseColor(env, argv[0], foregroundColor)) { 63 LOGE("Parse foregroundColor failed"); 64 return nullptr; 65 } 66 67 DragPreview* dragPreview = nullptr; 68 napi_unwrap(env, result, (void**)&dragPreview); 69 70 dragPreview->SetColor(foregroundColor); 71 LOGI("foregroundColor is %{public}x", dragPreview->previewStyle_.foregroundColor); 72 if (!dragPreview->hasAnimation_) { 73 int32_t instanceId = Container::CurrentId(); 74 auto container = AceEngine::Get().GetContainer(instanceId); 75 auto taskExecutor = container->GetTaskExecutor(); 76 taskExecutor->PostTask( 77 [previewStyle = dragPreview->previewStyle_]() { 78 int32_t ret = Msdp::DeviceStatus::InteractionManager:: 79 GetInstance()->UpdatePreviewStyle(previewStyle); 80 if (ret != 0) { 81 LOGE("Update preview style failed"); 82 return; 83 }; 84 }, 85 TaskExecutor::TaskType::JS); 86 dragPreview->previewStyle_.types.clear(); 87 } 88 napi_close_handle_scope(env, scope); 89 return nullptr; 90 } 91 Animate(napi_env env,napi_callback_info info)92 static napi_value Animate(napi_env env, napi_callback_info info) 93 { 94 napi_handle_scope scope = nullptr; 95 napi_open_handle_scope(env, &scope); 96 CHECK_NULL_RETURN(scope, nullptr); 97 size_t argc = argCount2; 98 napi_value argv[argCount2] = { 0 }; 99 napi_value result = nullptr; 100 void* data = nullptr; 101 napi_get_cb_info(env, info, &argc, argv, &result, &data); 102 NAPI_ASSERT(env, argc == argCount2, "require 2 parameter"); 103 104 DragPreview* dragPreview = nullptr; 105 napi_unwrap(env, result, (void**)&dragPreview); 106 dragPreview->hasAnimation_ = true; 107 PreviewAnimation previewAnimation; 108 ParseAnimationInfo(env, argv[0], previewAnimation); 109 110 napi_call_function(env, nullptr, argv[1], 0, nullptr, nullptr); 111 int32_t instanceId = Container::CurrentId(); 112 auto container = AceEngine::Get().GetContainer(instanceId); 113 auto taskExecutor = container->GetTaskExecutor(); 114 taskExecutor->PostTask( 115 [previewStyle = dragPreview->previewStyle_, previewAnimation]() { 116 int32_t ret = Msdp::DeviceStatus::InteractionManager:: 117 GetInstance()->UpdatePreviewStyleWithAnimation(previewStyle, previewAnimation); 118 if (ret != 0) { 119 LOGE("Update preview style with animation failed"); 120 return; 121 }; 122 }, 123 TaskExecutor::TaskType::JS); 124 dragPreview->hasAnimation_ = false; 125 dragPreview->previewStyle_.types.clear(); 126 return nullptr; 127 } 128 NapiSerializer(napi_env & env,napi_value & result)129 void NapiSerializer(napi_env& env, napi_value& result) 130 { 131 napi_status status = napi_wrap( 132 env, result, this, 133 [](napi_env env, void* data, void* hint) { 134 DragPreview* dragPreview = static_cast<DragPreview*>(data); 135 if (dragPreview != nullptr) { 136 delete dragPreview; 137 } 138 }, 139 nullptr, nullptr); 140 if (status != napi_ok) { 141 LOGE("napi_wrap failed"); 142 return; 143 } 144 /* insert callback functions */ 145 const char* funName = "setForegroundColor"; 146 napi_value funcValue = nullptr; 147 napi_create_function(env, funName, NAPI_AUTO_LENGTH, SetForegroundColor, nullptr, &funcValue); 148 napi_set_named_property(env, result, funName, funcValue); 149 150 funName = "animate"; 151 napi_create_function(env, funName, NAPI_AUTO_LENGTH, Animate, nullptr, &funcValue); 152 napi_set_named_property(env, result, funName, funcValue); 153 } 154 private: SetColor(const Color & color)155 void SetColor(const Color& color) 156 { 157 auto iter = std::find(previewStyle_.types.begin(), previewStyle_.types.end(), 158 PreviewType::FOREGROUND_COLOR); 159 if (iter == previewStyle_.types.end()) { 160 previewStyle_.types.emplace_back(PreviewType::FOREGROUND_COLOR); 161 } 162 previewStyle_.foregroundColor = color.GetValue(); 163 } 164 ParseAnimationInfo(napi_env env,napi_value object,PreviewAnimation & animationInfo)165 static napi_value ParseAnimationInfo(napi_env env, napi_value object, PreviewAnimation& animationInfo) 166 { 167 CHECK_NULL_RETURN(object, nullptr); 168 napi_valuetype valueType = napi_undefined; 169 bool hasProperty = false; 170 double durationValue = 0; 171 napi_has_named_property(env, object, "duration", &hasProperty); 172 if (!hasProperty) { 173 animationInfo.duration = DEFAULT_DURATION_VALUE; 174 } else { 175 napi_value durationNApi = nullptr; 176 napi_get_named_property(env, object, "duration", &durationNApi); 177 napi_typeof(env, durationNApi, &valueType); 178 NAPI_ASSERT(env, valueType == napi_number, "The type of duration is incorrect"); 179 napi_status status = napi_get_value_double(env, durationNApi, &durationValue); 180 NAPI_ASSERT(env, status == napi_ok, "Parse duration failed"); 181 if (GreatOrEqual(durationValue, INT32_MAX)) { 182 durationValue = INT32_MAX; 183 } else if (LessOrEqual(durationValue, 0)) { 184 durationValue = 0; 185 } 186 animationInfo.duration = static_cast<int32_t>(durationValue); 187 } 188 LOGI("animationInfo duration is %{public}d", animationInfo.duration); 189 190 napi_has_named_property(env, object, "curve", &hasProperty); 191 if (!hasProperty) { 192 ParseCurveInfo(Curves::EASE_IN_OUT->ToString(), animationInfo.curveName, animationInfo.curve); 193 return nullptr; 194 } 195 napi_value curveNApi = nullptr; 196 napi_get_named_property(env, object, "curve", &curveNApi); 197 ParseCurve(env, curveNApi, animationInfo.curveName, animationInfo.curve); 198 return nullptr; 199 } 200 PreviewStyle previewStyle_ { {}, 0, -1, -1, -1 }; 201 bool hasAnimation_ { false }; 202 }; 203 } // namespace OHOS::Ace::Napi 204 #endif // #define INTERFACES_NAPI_KITS_DRAG_CONTROLLER_DRAG_PREVIEW_H