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