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 #include "interaction_manager.h" 28 29 #include "base/log/log_wrapper.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 ARG_COUNT_1 = 1; 40 constexpr int32_t ARG_COUNT_2 = 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 = ARG_COUNT_1; 55 napi_value argv[ARG_COUNT_1] = { 0 }; 56 napi_value result = nullptr; 57 void* data = nullptr; 58 napi_get_cb_info(env, info, &argc, argv, &result, &data); 59 if (argc != ARG_COUNT_1) { 60 TAG_LOGE(AceLogTag::ACE_DRAG, "require 1 parameter"); 61 napi_close_handle_scope(env, scope); 62 return nullptr; 63 } 64 65 Color foregroundColor; 66 if (!ParseColor(env, argv[0], foregroundColor)) { 67 LOGE("Parse foregroundColor failed"); 68 napi_close_handle_scope(env, scope); 69 return nullptr; 70 } 71 72 DragPreview* dragPreview = nullptr; 73 napi_unwrap(env, result, (void**)&dragPreview); 74 if (dragPreview == nullptr) { 75 LOGE("dragPreview is nullptr"); 76 napi_close_handle_scope(env, scope); 77 return nullptr; 78 } 79 dragPreview->SetColor(foregroundColor); 80 LOGI("foregroundColor is %{public}x", dragPreview->previewStyle_.foregroundColor); 81 if (!dragPreview->hasAnimation_) { 82 int32_t instanceId = Container::CurrentId(); 83 auto container = AceEngine::Get().GetContainer(instanceId); 84 auto taskExecutor = container->GetTaskExecutor(); 85 taskExecutor->PostTask( 86 [previewStyle = dragPreview->previewStyle_]() { 87 int32_t ret = Msdp::DeviceStatus::InteractionManager:: 88 GetInstance()->UpdatePreviewStyle(previewStyle); 89 if (ret != 0) { 90 LOGE("Update preview style failed"); 91 return; 92 }; 93 }, 94 TaskExecutor::TaskType::JS, "ArkUIDragUpdatePreviewStyle"); 95 dragPreview->previewStyle_.types.clear(); 96 } 97 napi_close_handle_scope(env, scope); 98 return nullptr; 99 } 100 Animate(napi_env env,napi_callback_info info)101 static napi_value Animate(napi_env env, napi_callback_info info) 102 { 103 napi_handle_scope scope = nullptr; 104 napi_open_handle_scope(env, &scope); 105 CHECK_NULL_RETURN(scope, nullptr); 106 size_t argc = ARG_COUNT_2; 107 napi_value argv[ARG_COUNT_2] = { 0 }; 108 napi_value result = nullptr; 109 void* data = nullptr; 110 napi_get_cb_info(env, info, &argc, argv, &result, &data); 111 if (argc != ARG_COUNT_2) { 112 TAG_LOGE(AceLogTag::ACE_DRAG, "require 2 parameter"); 113 napi_close_handle_scope(env, scope); 114 return nullptr; 115 } 116 117 DragPreview* dragPreview = nullptr; 118 napi_unwrap(env, result, (void**)&dragPreview); 119 if (dragPreview == nullptr) { 120 LOGE("dragPreview is nullptr"); 121 napi_close_handle_scope(env, scope); 122 return nullptr; 123 } 124 dragPreview->hasAnimation_ = true; 125 PreviewAnimation previewAnimation; 126 ParseAnimationInfo(env, argv[0], previewAnimation); 127 128 napi_call_function(env, nullptr, argv[1], 0, nullptr, nullptr); 129 int32_t instanceId = Container::CurrentId(); 130 auto container = AceEngine::Get().GetContainer(instanceId); 131 auto taskExecutor = container->GetTaskExecutor(); 132 taskExecutor->PostTask( 133 [previewStyle = dragPreview->previewStyle_, previewAnimation]() { 134 int32_t ret = Msdp::DeviceStatus::InteractionManager:: 135 GetInstance()->UpdatePreviewStyleWithAnimation(previewStyle, previewAnimation); 136 if (ret != 0) { 137 LOGE("Update preview style with animation failed"); 138 return; 139 }; 140 }, 141 TaskExecutor::TaskType::JS, "ArkUIDragUpdatePreviewAnimationStyle"); 142 dragPreview->hasAnimation_ = false; 143 dragPreview->previewStyle_.types.clear(); 144 napi_close_handle_scope(env, scope); 145 return nullptr; 146 } 147 NapiSerializer(napi_env & env,napi_value & result)148 void NapiSerializer(napi_env& env, napi_value& result) 149 { 150 napi_status status = napi_wrap( 151 env, result, this, 152 [](napi_env env, void* data, void* hint) { 153 DragPreview* dragPreview = static_cast<DragPreview*>(data); 154 if (dragPreview != nullptr) { 155 delete dragPreview; 156 } 157 }, 158 nullptr, nullptr); 159 if (status != napi_ok) { 160 LOGE("napi_wrap failed"); 161 return; 162 } 163 /* insert callback functions */ 164 const char* funName = "setForegroundColor"; 165 napi_value funcValue = nullptr; 166 napi_create_function(env, funName, NAPI_AUTO_LENGTH, SetForegroundColor, nullptr, &funcValue); 167 napi_set_named_property(env, result, funName, funcValue); 168 169 funName = "animate"; 170 napi_create_function(env, funName, NAPI_AUTO_LENGTH, Animate, nullptr, &funcValue); 171 napi_set_named_property(env, result, funName, funcValue); 172 } 173 private: SetColor(const Color & color)174 void SetColor(const Color& color) 175 { 176 auto iter = std::find(previewStyle_.types.begin(), previewStyle_.types.end(), 177 PreviewType::FOREGROUND_COLOR); 178 if (iter == previewStyle_.types.end()) { 179 previewStyle_.types.emplace_back(PreviewType::FOREGROUND_COLOR); 180 } 181 previewStyle_.foregroundColor = color.GetValue(); 182 } 183 ParseAnimationInfo(napi_env env,napi_value object,PreviewAnimation & animationInfo)184 static napi_value ParseAnimationInfo(napi_env env, napi_value object, PreviewAnimation& animationInfo) 185 { 186 CHECK_NULL_RETURN(object, nullptr); 187 napi_valuetype valueType = napi_undefined; 188 bool hasProperty = false; 189 double durationValue = 0; 190 napi_has_named_property(env, object, "duration", &hasProperty); 191 if (!hasProperty) { 192 animationInfo.duration = DEFAULT_DURATION_VALUE; 193 } else { 194 napi_value durationNApi = nullptr; 195 napi_get_named_property(env, object, "duration", &durationNApi); 196 napi_typeof(env, durationNApi, &valueType); 197 NAPI_ASSERT(env, valueType == napi_number, "The type of duration is incorrect"); 198 napi_status status = napi_get_value_double(env, durationNApi, &durationValue); 199 NAPI_ASSERT(env, status == napi_ok, "Parse duration failed"); 200 if (GreatOrEqual(durationValue, INT32_MAX)) { 201 durationValue = INT32_MAX; 202 } else if (LessOrEqual(durationValue, 0)) { 203 durationValue = 0; 204 } 205 animationInfo.duration = static_cast<int32_t>(durationValue); 206 } 207 LOGI("animationInfo duration is %{public}d", animationInfo.duration); 208 209 napi_has_named_property(env, object, "curve", &hasProperty); 210 if (!hasProperty) { 211 ParseCurveInfo(Curves::EASE_IN_OUT->ToString(), animationInfo.curveName, animationInfo.curve); 212 return nullptr; 213 } 214 napi_value curveNApi = nullptr; 215 napi_get_named_property(env, object, "curve", &curveNApi); 216 ParseCurve(env, curveNApi, animationInfo.curveName, animationInfo.curve); 217 return nullptr; 218 } 219 PreviewStyle previewStyle_ { {}, 0, -1, -1, -1 }; 220 bool hasAnimation_ { false }; 221 }; 222 } // namespace OHOS::Ace::Napi 223 #endif // #define INTERFACES_NAPI_KITS_DRAG_CONTROLLER_DRAG_PREVIEW_H