1/* 2 * Copyright (c) 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#include "knuckle_drawing_manager.h" 17 18#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 19#include "animation/rs_particle_params.h" 20#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 21#include "image/bitmap.h" 22#include "image_source.h" 23#include "image_type.h" 24#include "image_utils.h" 25#ifndef USE_ROSEN_DRAWING 26#include "pipeline/rs_recording_canvas.h" 27#else 28#include "ui/rs_canvas_drawing_node.h" 29#endif // USE_ROSEN_DRAWING 30 31#include "define_multimodal.h" 32#include "i_multimodal_input_connect.h" 33#include "mmi_log.h" 34#include "parameters.h" 35#include "setting_datashare.h" 36#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 37#include "timer_manager.h" 38#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 39#include "touch_drawing_manager.h" 40 41#undef MMI_LOG_TAG 42#define MMI_LOG_TAG "KnuckleDrawingManager" 43 44namespace OHOS { 45namespace MMI { 46namespace { 47constexpr int32_t DEFAULT_VALUE { -1 }; 48constexpr int32_t MAX_POINTER_NUM { 5 }; 49constexpr int32_t MID_POINT { 2 }; 50constexpr int32_t POINT_INDEX0 { 0 }; 51constexpr int32_t POINT_INDEX1 { 1 }; 52constexpr int32_t POINT_INDEX2 { 2 }; 53constexpr int32_t POINT_INDEX3 { 3 }; 54constexpr int32_t POINT_INDEX4 { 4 }; 55constexpr int32_t PAINT_STROKE_WIDTH { 10 }; 56constexpr int32_t PAINT_PATH_RADIUS { 10 }; 57constexpr int64_t DOUBLE_CLICK_INTERVAL_TIME_SLOW { 450000 }; 58[[ maybe_unused ]] constexpr int64_t WAIT_DOUBLE_CLICK_INTERVAL_TIME { 100000 }; 59constexpr float DOUBLE_CLICK_DISTANCE_LONG_CONFIG { 96.0f }; 60[[ maybe_unused ]] constexpr float VPR_CONFIG { 3.25f }; 61constexpr int32_t POW_SQUARE { 2 }; 62constexpr int32_t ROTATION_ANGLE_0 { 0 }; 63constexpr int32_t ROTATION_ANGLE_90 { 90 }; 64constexpr int32_t ROTATION_ANGLE_180 { 180 }; 65constexpr int32_t ROTATION_ANGLE_270 { 270 }; 66constexpr uint64_t FOLD_SCREEN_MAIN_ID { 5 }; 67const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0); 68const std::string FOLDABLE = system::GetParameter("const.window.foldabledevice.rotate_policy", ""); 69constexpr int32_t WINDOW_ROTATE { 0 }; 70constexpr int32_t SCREEN_ROTATE { 1 }; 71constexpr int32_t FOLDABLE_DEVICE { 2 }; 72constexpr char FOLDABLE_ROTATE { '0' }; 73constexpr int32_t SUBSCRIPT_TWO { 2 }; 74constexpr int32_t SUBSCRIPT_ZERO { 0 }; 75constexpr std::string_view SCREEN_READING { "accessibility_screenreader_enabled" }; 76constexpr std::string_view SCREEN_READ_ENABLE { "1" }; 77constexpr int32_t POINTER_NUMBER_TO_DRAW { 10 }; 78#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 79constexpr int64_t PARTICLE_LIFE_TIME { 700 }; 80constexpr int32_t PARTICLE_COUNT { -1 }; 81constexpr int32_t DEFAULT_EMIT_RATE { 0 }; 82constexpr int32_t EMIT_RATE { 400 }; 83constexpr int32_t PATH_SIZE_EIGHT { 8 }; 84constexpr int32_t MAX_PATH_SIZE { 50 }; 85constexpr int32_t MAX_PATH_LENGTH { 500 }; 86constexpr float PARTICLE_RADIUS { 5.0f }; 87constexpr float DEFAULT_PARTICLE_POSITION_X { 0.0f }; 88constexpr float DEFAULT_PARTICLE_POSITION_Y { 0.0f }; 89constexpr float DEFAULT_EMIT_SIZE_RANGE_BEGIN { 0.0f }; 90constexpr float DEFAULT_EMIT_SIZE_RANGE_END { 0.0f }; 91constexpr float EMIT_SIZE_RANGE_BEGIN { 80.0f }; 92constexpr float EMIT_SIZE_RANGE_END { 80.0f }; 93constexpr float EMIT_VELOCITY_VALUE_RANGE_BEGIN { 50.0f }; 94constexpr float EMIT_VELOCITY_VALUE_RANGE_END { 100.0f }; 95constexpr float EMIT_VELOCITY_ANGLE_RANGE_BEGIN { -180.0f }; 96constexpr float EMIT_VELOCITY_ANGLE_RANGE_END { 180.0f }; 97constexpr float EMIT_OPACITY_RANGE_BEGIN { 0.3f }; 98constexpr float EMIT_OPACITY_RANGE_END { 1.0f }; 99constexpr float EMIT_SCALE_RANGE_BEGIN { 0.3f }; 100constexpr float EMIT_SCALE_RANGE_END { 1.0f }; 101constexpr float EMIT_SCALE_CHANGE_RANGE_BEGIN { 1.0f }; 102constexpr float EMIT_SCALE_CHANGE_RANGE_END { 0.0f }; 103constexpr float SCALE_CHANGE_VELOCITY_RANGE_BEGIN { -1.0f }; 104constexpr float SCALE_CHANGE_VELOCITY_RANGE_END { -1.0f }; 105constexpr int32_t SCALE_CHANGE_START_MILLIS { 0 }; 106constexpr int32_t SCALE_CHANGE_END_MILLIS { 700 }; 107constexpr float ALPHA_RANGE_BEGIN { 1.0f }; 108constexpr float ALPHA_RANGE_END { 0.0f }; 109constexpr float EMIT_RADIUS { 40.0f }; 110constexpr float TRACK_FILTER_SCALAR { 20.0f }; 111constexpr int32_t TRACK_PATH_LENGTH_400 { 400 }; 112constexpr int32_t TRACK_PATH_LENGTH_500 { 500 }; 113constexpr int32_t TRACK_PATH_LENGTH_900 { 900 }; 114constexpr int32_t TRACK_PATH_LENGTH_1000 { 1000 }; 115constexpr int32_t TRACK_PATH_LENGTH_1400 { 1400 }; 116constexpr int32_t TRACK_PATH_LENGTH_1500 { 1500 }; 117constexpr int32_t TRACK_PATH_LENGTH_1900 { 1900 }; 118constexpr int32_t TRACK_PATH_LENGTH_2000 { 2000 }; 119constexpr uint32_t TRACK_COLOR_BLUE { 0xFF1ED0EE }; 120constexpr uint32_t TRACK_COLOR_BLUE_R { 0x1E }; 121constexpr uint32_t TRACK_COLOR_BLUE_G { 0xD0 }; 122constexpr uint32_t TRACK_COLOR_BLUE_B { 0xEE }; 123constexpr uint32_t TRACK_COLOR_PINK { 0xFFFF42D2 }; 124constexpr uint32_t TRACK_COLOR_PINK_R { 0xFF }; 125constexpr uint32_t TRACK_COLOR_PINK_G { 0x42 }; 126constexpr uint32_t TRACK_COLOR_PINK_B { 0xD2 }; 127constexpr uint32_t TRACK_COLOR_ORANGE_RED { 0xFFFF7B47 }; 128constexpr uint32_t TRACK_COLOR_ORANGE_RED_R { 0xFF }; 129constexpr uint32_t TRACK_COLOR_ORANGE_RED_G { 0x7B }; 130constexpr uint32_t TRACK_COLOR_ORANGE_RED_B { 0x47 }; 131constexpr uint32_t TRACK_COLOR_YELLOW { 0xFFFFC628 }; 132constexpr uint32_t TRACK_COLOR_YELLOW_R { 0xFF }; 133constexpr uint32_t TRACK_COLOR_YELLOW_G { 0xC6 }; 134constexpr uint32_t TRACK_COLOR_YELLOW_B { 0x28 }; 135constexpr uint32_t ALPHA_ZERO { 0xFF }; 136constexpr float TRACK_WIDTH_TEN { 10.0f }; 137constexpr float TRACK_WIDTH_THIRTY { 30.0f }; 138constexpr float COLOR_TRANSITIONS_LENGTH { 400.0f }; 139constexpr int32_t PROTOCOL_DURATION { 200 }; 140#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 141} // namespace 142 143KnuckleDrawingManager::KnuckleDrawingManager() 144{ 145#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 146 paint_.SetColor(Rosen::Drawing::Color::COLOR_WHITE); 147#else 148 paint_.SetColor(Rosen::Drawing::Color::COLOR_CYAN); 149#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 150 paint_.SetAntiAlias(true); 151 float outerCircleTransparency = 1.0f; 152 paint_.SetAlphaF(outerCircleTransparency); 153 paint_.SetWidth(PAINT_STROKE_WIDTH); 154 paint_.SetStyle(Rosen::Drawing::Paint::PaintStyle::PAINT_STROKE); 155 paint_.SetJoinStyle(Rosen::Drawing::Pen::JoinStyle::ROUND_JOIN); 156 paint_.SetCapStyle(Rosen::Drawing::Pen::CapStyle::ROUND_CAP); 157 paint_.SetPathEffect(Rosen::Drawing::PathEffect::CreateCornerPathEffect(PAINT_PATH_RADIUS)); 158 displayInfo_.x = 0; 159 displayInfo_.y = 0; 160 displayInfo_.id = 0; 161 displayInfo_.dpi = 0; 162 displayInfo_.width = 0; 163 displayInfo_.height = 0; 164 displayInfo_.direction = Direction::DIRECTION0; 165 displayInfo_.displayDirection = Direction::DIRECTION0; 166} 167 168void KnuckleDrawingManager::KnuckleDrawHandler(std::shared_ptr<PointerEvent> touchEvent) 169{ 170 CALL_DEBUG_ENTER; 171 CHKPV(touchEvent); 172 if (!IsSingleKnuckle(touchEvent)) { 173 return; 174 } 175 CreateObserver(); 176 int32_t touchAction = touchEvent->GetPointerAction(); 177 if (IsValidAction(touchAction) && IsSingleKnuckleDoubleClick(touchEvent)) { 178 int32_t displayId = touchEvent->GetTargetDisplayId(); 179 CreateTouchWindow(displayId); 180 StartTouchDraw(touchEvent); 181 } 182} 183 184bool KnuckleDrawingManager::IsSingleKnuckle(std::shared_ptr<PointerEvent> touchEvent) 185{ 186 CALL_DEBUG_ENTER; 187 CHKPF(touchEvent); 188 int32_t id = touchEvent->GetPointerId(); 189 PointerEvent::PointerItem item; 190 touchEvent->GetPointerItem(id, item); 191 if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE || 192 touchEvent->GetPointerIds().size() != 1 || isRotate_) { 193 MMI_HILOGD("Touch tool type is:%{public}d", item.GetToolType()); 194 if (!pointerInfos_.empty()) { 195 DestoryWindow(); 196 } else if (isRotate_) { 197 isRotate_ = false; 198 if (item.GetToolType() == PointerEvent::TOOL_TYPE_KNUCKLE) { 199 return true; 200 } 201 } 202 return false; 203 } 204 MMI_HILOGD("Touch tool type is single knuckle"); 205 return true; 206} 207 208bool KnuckleDrawingManager::IsSingleKnuckleDoubleClick(std::shared_ptr<PointerEvent> touchEvent) 209{ 210 CALL_DEBUG_ENTER; 211 CHKPF(touchEvent); 212 int32_t touchAction = touchEvent->GetPointerAction(); 213 if (touchAction == PointerEvent::POINTER_ACTION_DOWN) { 214 pointerNum_ = 0; 215 firstDownTime_ = touchEvent->GetActionTime(); 216 int64_t intervalTime = touchEvent->GetActionTime() - lastUpTime_; 217 bool isTimeIntervalReady = intervalTime > 0 && intervalTime <= DOUBLE_CLICK_INTERVAL_TIME_SLOW; 218 int32_t id = touchEvent->GetPointerId(); 219 PointerEvent::PointerItem pointerItem; 220 touchEvent->GetPointerItem(id, pointerItem); 221 auto displayXY = TOUCH_DRAWING_MGR->CalcDrawCoordinate(displayInfo_, pointerItem); 222 float downToPrevDownDistance = static_cast<float>(sqrt(pow(lastDownPointer_.x - displayXY.first, POW_SQUARE) + 223 pow(lastDownPointer_.y - displayXY.second, POW_SQUARE))); 224 bool isDistanceReady = downToPrevDownDistance < DOUBLE_CLICK_DISTANCE_LONG_CONFIG * POW_SQUARE; 225 if (isTimeIntervalReady && isDistanceReady) { 226 return false; 227 } 228 lastDownPointer_.x = displayXY.first; 229 lastDownPointer_.y = displayXY.second; 230 } else if (touchAction == PointerEvent::POINTER_ACTION_UP) { 231 lastUpTime_ = touchEvent->GetActionTime(); 232 } 233 return true; 234} 235 236bool KnuckleDrawingManager::IsValidAction(const int32_t action) 237{ 238 CALL_DEBUG_ENTER; 239 if (screenReadState_.state == SCREEN_READ_ENABLE) { 240 DestoryWindow(); 241 } 242 if (action == PointerEvent::POINTER_ACTION_DOWN || action == PointerEvent::POINTER_ACTION_PULL_DOWN || 243 (action == PointerEvent::POINTER_ACTION_MOVE && (!pointerInfos_.empty())) || 244 (action == PointerEvent::POINTER_ACTION_PULL_MOVE && (!pointerInfos_.empty())) || 245 action == PointerEvent::POINTER_ACTION_UP || action == PointerEvent::POINTER_ACTION_PULL_UP) { 246 return true; 247 } 248 MMI_HILOGE("Action is not down or move or up, action:%{public}d", action); 249 return false; 250} 251 252void KnuckleDrawingManager::UpdateDisplayInfo(const DisplayInfo& displayInfo) 253{ 254 CALL_DEBUG_ENTER; 255 if (displayInfo_.direction != displayInfo.direction) { 256 MMI_HILOGD("DisplayInfo direction change"); 257 isRotate_ = true; 258 } 259 scaleW_ = displayInfo.width > displayInfo.height ? displayInfo.width : displayInfo.height; 260 scaleH_ = displayInfo.width > displayInfo.height ? displayInfo.width : displayInfo.height; 261 displayInfo_ = displayInfo; 262} 263 264void KnuckleDrawingManager::StartTouchDraw(std::shared_ptr<PointerEvent> touchEvent) 265{ 266 CALL_DEBUG_ENTER; 267 CHKPV(touchEvent); 268 int32_t ret = DrawGraphic(touchEvent); 269 if (ret != RET_OK) { 270 MMI_HILOGD("Can't get enough pointers to draw"); 271 return; 272 } 273 Rosen::RSTransaction::FlushImplicitTransaction(); 274} 275 276void KnuckleDrawingManager::RotationCanvasNode( 277 std::shared_ptr<Rosen::RSCanvasNode> canvasNode, const DisplayInfo& displayInfo) 278{ 279 CALL_DEBUG_ENTER; 280 CHKPV(canvasNode); 281 if (displayInfo.direction == Direction::DIRECTION90) { 282 canvasNode->SetRotation(ROTATION_ANGLE_270); 283 canvasNode->SetTranslateX(0); 284 } else if (displayInfo.direction == Direction::DIRECTION270) { 285 canvasNode->SetRotation(ROTATION_ANGLE_90); 286 canvasNode->SetTranslateX(-std::fabs(displayInfo.width - displayInfo.height)); 287 } else if (displayInfo.direction == Direction::DIRECTION180) { 288 canvasNode->SetRotation(ROTATION_ANGLE_180); 289 canvasNode->SetTranslateX(-std::fabs(displayInfo.width - displayInfo.height)); 290 } else { 291 canvasNode->SetRotation(ROTATION_ANGLE_0); 292 canvasNode->SetTranslateX(0); 293 } 294 canvasNode->SetTranslateY(0); 295} 296 297bool KnuckleDrawingManager::CheckRotatePolicy(const DisplayInfo& displayInfo) 298{ 299 CALL_DEBUG_ENTER; 300 bool isNeedRotate = false; 301 switch (ROTATE_POLICY) { 302 case WINDOW_ROTATE: 303 isNeedRotate = true; 304 break; 305 case SCREEN_ROTATE: 306 break; 307 case FOLDABLE_DEVICE: { 308 MMI_HILOGI("FOLDABLE:%{public}s", FOLDABLE.c_str()); 309 if ((displayInfo.displayMode == DisplayMode::MAIN && FOLDABLE[SUBSCRIPT_ZERO] == FOLDABLE_ROTATE) || 310 (displayInfo.displayMode == DisplayMode::FULL && FOLDABLE[SUBSCRIPT_TWO] == FOLDABLE_ROTATE)) { 311 isNeedRotate = true; 312 } 313 break; 314 } 315 default: 316 MMI_HILOGW("Unknown ROTATE_POLICY:%{public}d", ROTATE_POLICY); 317 break; 318 } 319 return isNeedRotate; 320} 321 322#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 323void KnuckleDrawingManager::InitParticleEmitter() 324{ 325 CALL_DEBUG_ENTER; 326 Rosen::Vector2f position = {DEFAULT_PARTICLE_POSITION_X, DEFAULT_PARTICLE_POSITION_Y}; 327 Rosen::Vector2f emitSize = {DEFAULT_EMIT_SIZE_RANGE_BEGIN, DEFAULT_EMIT_SIZE_RANGE_END}; 328 Rosen::Range<int64_t> lifeTime = {PARTICLE_LIFE_TIME, PARTICLE_LIFE_TIME}; 329 std::shared_ptr<Rosen::RSImage> image = std::make_shared<Rosen::RSImage>(); 330 Rosen::EmitterConfig emitterConfig( 331 DEFAULT_EMIT_RATE, Rosen::ShapeType::CIRCLE, position, emitSize, PARTICLE_COUNT, lifeTime, 332 Rosen::ParticleType::POINTS, PARTICLE_RADIUS, image, Rosen::Vector2f()); 333 334 Rosen::Range<float> velocityValue = {EMIT_VELOCITY_VALUE_RANGE_BEGIN, EMIT_VELOCITY_VALUE_RANGE_END}; 335 Rosen::Range<float> velocityAngle = {EMIT_VELOCITY_ANGLE_RANGE_BEGIN, EMIT_VELOCITY_ANGLE_RANGE_END}; 336 Rosen::ParticleVelocity velocity(velocityValue, velocityAngle); 337 338 std::vector<Rosen::Change<Rosen::RSColor>> valColorChangeOverLife; 339 Rosen::RSColor rsColorRangeBegin(Rosen::Drawing::Color::COLOR_WHITE); 340 Rosen::RSColor rsColorRangeEnd(Rosen::Drawing::Color::COLOR_WHITE); 341 Rosen::Range<Rosen::RSColor> colorVal = {rsColorRangeBegin, rsColorRangeEnd}; 342 Rosen::ParticleColorParaType color( 343 colorVal, Rosen::DistributionType::UNIFORM, Rosen::ParticleUpdator::NONE, Rosen::Range<float>(), 344 Rosen::Range<float>(), Rosen::Range<float>(), Rosen::Range<float>(), valColorChangeOverLife); 345 346 std::vector<Rosen::Change<float>> opacityChangeOverLifes; 347 Rosen::Range<float> opacityVal = {EMIT_OPACITY_RANGE_BEGIN, EMIT_OPACITY_RANGE_END}; 348 Rosen::ParticleParaType<float> opacity( 349 opacityVal, Rosen::ParticleUpdator::NONE, Rosen::Range<float>(), opacityChangeOverLifes); 350 351 Rosen::RSAnimationTimingCurve rSAnimationTimingCurve(Rosen::RSAnimationTimingCurve::LINEAR); 352 Rosen::Change<float> scaleChange 353 (EMIT_SCALE_CHANGE_RANGE_BEGIN, EMIT_SCALE_CHANGE_RANGE_END, SCALE_CHANGE_START_MILLIS, SCALE_CHANGE_END_MILLIS, 354 rSAnimationTimingCurve); 355 std::vector<Rosen::Change<float>> scaleChangeOverLifes; 356 scaleChangeOverLifes.emplace_back(scaleChange); 357 Rosen::Range<float> scaleVal = {EMIT_SCALE_RANGE_BEGIN, EMIT_SCALE_RANGE_END}; 358 Rosen::Range<float> scaleChangeVelocity = {SCALE_CHANGE_VELOCITY_RANGE_BEGIN, SCALE_CHANGE_VELOCITY_RANGE_END}; 359 Rosen::ParticleParaType<float> scale( 360 scaleVal, Rosen::ParticleUpdator::CURVE, scaleChangeVelocity, scaleChangeOverLifes); 361 362 Rosen::ParticleAcceleration acceleration; 363 Rosen::ParticleParaType<float> spin; 364 365 Rosen::ParticleParams params(emitterConfig, velocity, acceleration, color, opacity, scale, spin); 366 std::vector<Rosen::ParticleParams> particleParams; 367 particleParams.push_back(params); 368 brushCanvasNode_->SetParticleParams(particleParams); 369} 370 371void KnuckleDrawingManager::CreateTouchWindow(const int32_t displayId) 372{ 373 CALL_DEBUG_ENTER; 374 if (surfaceNode_ != nullptr) { 375 MMI_HILOGD("surfaceNode_ is already exist"); 376 return; 377 } 378 Rosen::RSSurfaceNodeConfig surfaceNodeConfig; 379 surfaceNodeConfig.SurfaceNodeName = "knuckle window"; 380 Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE; 381 surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType); 382 383 CHKPV(surfaceNode_); 384 surfaceNode_->SetSkipLayer(true); 385 surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL); 386 surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z); 387 surfaceNode_->SetBounds(0, 0, scaleW_, scaleH_); 388 surfaceNode_->SetFrame(0, 0, scaleW_, scaleH_); 389 390#ifndef USE_ROSEN_DRAWING 391 surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT); 392#else 393 surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT); 394#endif // USE_ROSEN_DRAWING 395 396 screenId_ = static_cast<uint64_t>(displayId); 397 surfaceNode_->SetRotation(0); 398 CreateBrushWorkCanvasNode(); 399 CreateTrackCanvasNode(); 400 surfaceNode_->AddChild(trackCanvasNode_, DEFAULT_VALUE); 401 surfaceNode_->AddChild(brushCanvasNode_, DEFAULT_VALUE); 402 if (displayInfo_.displayMode == DisplayMode::MAIN) { 403 screenId_ = FOLD_SCREEN_MAIN_ID; 404 } 405 MMI_HILOGI("screenId_: %{public}" PRIu64, screenId_); 406 surfaceNode_->AttachToDisplay(screenId_); 407 if (CheckRotatePolicy(displayInfo_)) { 408 RotationCanvasNode(brushCanvasNode_, displayInfo_); 409 RotationCanvasNode(trackCanvasNode_, displayInfo_); 410 } 411 brushCanvasNode_->ResetSurface(scaleW_, scaleH_); 412 trackCanvasNode_->ResetSurface(scaleW_, scaleH_); 413 InitParticleEmitter(); 414 Rosen::RSTransaction::FlushImplicitTransaction(); 415} 416#else 417void KnuckleDrawingManager::CreateTouchWindow(const int32_t displayId) 418{ 419 CALL_DEBUG_ENTER; 420 if (surfaceNode_ != nullptr) { 421 MMI_HILOGD("surfaceNode_ is already exist"); 422 return; 423 } 424 Rosen::RSSurfaceNodeConfig surfaceNodeConfig; 425 surfaceNodeConfig.SurfaceNodeName = "knuckle window"; 426 Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE; 427 surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType); 428 429 CHKPV(surfaceNode_); 430 surfaceNode_->SetSkipLayer(true); 431 surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL); 432 surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z); 433 surfaceNode_->SetBounds(0, 0, scaleW_, scaleH_); 434 surfaceNode_->SetFrame(0, 0, scaleW_, scaleH_); 435 436#ifndef USE_ROSEN_DRAWING 437 surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT); 438#else 439 surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT); 440#endif // USE_ROSEN_DRAWING 441 442 screenId_ = static_cast<uint64_t>(displayId); 443 surfaceNode_->SetRotation(0); 444 CreateCanvasNode(); 445 surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE); 446 if (displayInfo_.displayMode == DisplayMode::MAIN) { 447 screenId_ = FOLD_SCREEN_MAIN_ID; 448 } 449 MMI_HILOGI("screenId_: %{public}" PRIu64, screenId_); 450 surfaceNode_->AttachToDisplay(screenId_); 451 if (CheckRotatePolicy(displayInfo_)) { 452 RotationCanvasNode(canvasNode_, displayInfo_); 453 } 454 canvasNode_->ResetSurface(scaleW_, scaleH_); 455 Rosen::RSTransaction::FlushImplicitTransaction(); 456} 457#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 458 459#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 460void KnuckleDrawingManager::CreateBrushWorkCanvasNode() 461{ 462 brushCanvasNode_ = Rosen::RSCanvasDrawingNode::Create(); 463 CHKPV(brushCanvasNode_); 464 brushCanvasNode_->SetBounds(0, 0, scaleW_, scaleH_); 465 brushCanvasNode_->SetFrame(0, 0, scaleW_, scaleH_); 466 467#ifndef USE_ROSEN_DRAWING 468 brushCanvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT); 469#else 470 brushCanvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT); 471#endif // USE_ROSEN_DRAWING 472 brushCanvasNode_->SetCornerRadius(1); 473 brushCanvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z); 474 brushCanvasNode_->SetRotation(0); 475 brushCanvasNode_->SetAlpha(ALPHA_RANGE_BEGIN); 476} 477 478void KnuckleDrawingManager::CreateTrackCanvasNode() 479{ 480 trackCanvasNode_ = Rosen::RSCanvasDrawingNode::Create(); 481 CHKPV(trackCanvasNode_); 482 trackCanvasNode_->SetBounds(0, 0, scaleW_, scaleH_); 483 trackCanvasNode_->SetFrame(0, 0, scaleW_, scaleH_); 484 485#ifndef USE_ROSEN_DRAWING 486 trackCanvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT); 487#else 488 trackCanvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT); 489#endif // USE_ROSEN_DRAWING 490 trackCanvasNode_->SetCornerRadius(1); 491 trackCanvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z); 492 trackCanvasNode_->SetRotation(0); 493 trackCanvasNode_->SetAlpha(ALPHA_RANGE_BEGIN); 494} 495#else 496void KnuckleDrawingManager::CreateCanvasNode() 497{ 498 canvasNode_ = Rosen::RSCanvasDrawingNode::Create(); 499 CHKPV(canvasNode_); 500 canvasNode_->SetBounds(0, 0, scaleW_, scaleH_); 501 canvasNode_->SetFrame(0, 0, scaleW_, scaleH_); 502 503#ifndef USE_ROSEN_DRAWING 504 canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT); 505#else 506 canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT); 507#endif // USE_ROSEN_DRAWING 508 canvasNode_->SetCornerRadius(1); 509 canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z); 510 canvasNode_->SetRotation(0); 511} 512#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 513 514int32_t KnuckleDrawingManager::GetPointerPos(std::shared_ptr<PointerEvent> touchEvent) 515{ 516 CHKPR(touchEvent, RET_ERR); 517 if (touchEvent->GetPointerAction() == PointerEvent::POINTER_ACTION_UP) { 518 isActionUp_ = true; 519 return RET_OK; 520 } 521 PointerInfo pointerInfo; 522 int32_t pointerId = touchEvent->GetPointerId(); 523 PointerEvent::PointerItem pointerItem; 524 if (!touchEvent->GetPointerItem(pointerId, pointerItem)) { 525 MMI_HILOGE("Can't find pointer item, pointer:%{public}d", pointerId); 526 return RET_ERR; 527 } 528 auto displayXY = TOUCH_DRAWING_MGR->CalcDrawCoordinate(displayInfo_, pointerItem); 529 pointerInfo.x = displayXY.first; 530 pointerInfo.y = displayXY.second; 531 pointerInfos_.push_back(pointerInfo); 532 pointerNum_++; 533 534 if (pointerInfos_.size() == MAX_POINTER_NUM) { 535 pointerInfos_[POINT_INDEX3].x = (pointerInfos_[POINT_INDEX2].x + pointerInfos_[POINT_INDEX4].x) / MID_POINT; 536 pointerInfos_[POINT_INDEX3].y = (pointerInfos_[POINT_INDEX2].y + pointerInfos_[POINT_INDEX4].y) / MID_POINT; 537 } else { 538 MMI_HILOGD("Can't get enough pointers to draw"); 539 return RET_ERR; 540 } 541 return RET_OK; 542} 543 544#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 545void KnuckleDrawingManager::UpdateEmitter() 546{ 547 CALL_DEBUG_ENTER; 548 CHKPV(brushCanvasNode_); 549 std::optional<Rosen::Vector2f> position = std::nullopt; 550 position = {pointerInfos_[POINT_INDEX1].x - EMIT_RADIUS, pointerInfos_[POINT_INDEX1].y - EMIT_RADIUS}; 551 std::optional<Rosen::Vector2f> emitSize = std::nullopt; 552 emitSize = {EMIT_SIZE_RANGE_BEGIN, EMIT_SIZE_RANGE_END}; 553 std::optional<int32_t> emitRate = std::nullopt; 554 emitRate = EMIT_RATE; 555 auto updater = std::make_shared<Rosen::EmitterUpdater>( 556 0, position, emitSize, emitRate); 557 std::vector<std::shared_ptr<Rosen::EmitterUpdater>> paras; 558 paras.push_back(updater); 559 brushCanvasNode_->SetEmitterUpdater(paras); 560} 561 562uint32_t KnuckleDrawingManager::GetDeltaColor(uint32_t deltaSource, uint32_t deltaTarget) 563{ 564 CALL_DEBUG_ENTER; 565 if (deltaTarget > deltaSource) { 566 MMI_HILOGE("Invalid deltaSource or deltaTarget"); 567 return 0; 568 } else { 569 return deltaSource - deltaTarget; 570 } 571} 572 573uint32_t KnuckleDrawingManager::DrawTrackColorBlue(int32_t pathValue) 574{ 575 CALL_DEBUG_ENTER; 576 if (((static_cast<int32_t>(pathLength_) / TRACK_PATH_LENGTH_2000) != 0) && 577 (pathValue < TRACK_PATH_LENGTH_400)) { 578 uint32_t deltaR = GetDeltaColor(TRACK_COLOR_YELLOW_R, TRACK_COLOR_BLUE_R); 579 uint32_t deltaG = GetDeltaColor(TRACK_COLOR_BLUE_G, TRACK_COLOR_YELLOW_G); 580 uint32_t deltaB = GetDeltaColor(TRACK_COLOR_BLUE_B, TRACK_COLOR_YELLOW_B); 581 float pathLength = path_.GetLength(false); 582 trackColorR_ -= deltaR * pathLength / COLOR_TRANSITIONS_LENGTH; 583 trackColorG_ += deltaG * pathLength / COLOR_TRANSITIONS_LENGTH; 584 trackColorB_ += deltaB * pathLength / COLOR_TRANSITIONS_LENGTH; 585 uint32_t colorQuad = Rosen::Drawing::Color::ColorQuadSetARGB( 586 ALPHA_ZERO, trackColorR_, trackColorG_, trackColorB_); 587 return colorQuad; 588 } else { 589 trackColorR_ = TRACK_COLOR_BLUE_R; 590 trackColorG_ = TRACK_COLOR_BLUE_G; 591 trackColorB_ = TRACK_COLOR_BLUE_B; 592 return TRACK_COLOR_BLUE; 593 } 594} 595 596uint32_t KnuckleDrawingManager::DrawTrackColorPink(int32_t pathValue) 597{ 598 CALL_DEBUG_ENTER; 599 if (pathValue < TRACK_PATH_LENGTH_900) { 600 uint32_t deltaR = GetDeltaColor(TRACK_COLOR_PINK_R, TRACK_COLOR_BLUE_R); 601 uint32_t deltaG = GetDeltaColor(TRACK_COLOR_BLUE_G, TRACK_COLOR_PINK_G); 602 uint32_t deltaB = GetDeltaColor(TRACK_COLOR_BLUE_B, TRACK_COLOR_PINK_B); 603 float pathLength = path_.GetLength(false); 604 trackColorR_ += deltaR * pathLength / COLOR_TRANSITIONS_LENGTH; 605 trackColorG_ -= deltaG * pathLength / COLOR_TRANSITIONS_LENGTH; 606 trackColorB_ -= deltaB * pathLength / COLOR_TRANSITIONS_LENGTH; 607 uint32_t colorQuad = Rosen::Drawing::Color::ColorQuadSetARGB( 608 ALPHA_ZERO, trackColorR_, trackColorG_, trackColorB_); 609 return colorQuad; 610 } else { 611 trackColorR_ = TRACK_COLOR_PINK_R; 612 trackColorG_ = TRACK_COLOR_PINK_G; 613 trackColorB_ = TRACK_COLOR_PINK_B; 614 return TRACK_COLOR_PINK; 615 } 616} 617 618uint32_t KnuckleDrawingManager::DrawTrackColorOrangeRed(int32_t pathValue) 619{ 620 CALL_DEBUG_ENTER; 621 if (pathValue < TRACK_PATH_LENGTH_1400) { 622 uint32_t deltaR = GetDeltaColor(TRACK_COLOR_ORANGE_RED_R, TRACK_COLOR_PINK_R); 623 uint32_t deltaG = GetDeltaColor(TRACK_COLOR_ORANGE_RED_G, TRACK_COLOR_PINK_G); 624 uint32_t deltaB = GetDeltaColor(TRACK_COLOR_PINK_B, TRACK_COLOR_ORANGE_RED_B); 625 float pathLength = path_.GetLength(false); 626 trackColorR_ += deltaR * pathLength / COLOR_TRANSITIONS_LENGTH; 627 trackColorG_ += deltaG * pathLength / COLOR_TRANSITIONS_LENGTH; 628 trackColorB_ -= deltaB * pathLength / COLOR_TRANSITIONS_LENGTH; 629 uint32_t colorQuad = Rosen::Drawing::Color::ColorQuadSetARGB( 630 ALPHA_ZERO, trackColorR_, trackColorG_, trackColorB_); 631 return colorQuad; 632 } else { 633 trackColorR_ = TRACK_COLOR_ORANGE_RED_R; 634 trackColorG_ = TRACK_COLOR_ORANGE_RED_G; 635 trackColorB_ = TRACK_COLOR_ORANGE_RED_B; 636 return TRACK_COLOR_ORANGE_RED; 637 } 638} 639 640uint32_t KnuckleDrawingManager::DrawTrackColorYellow(int32_t pathValue) 641{ 642 CALL_DEBUG_ENTER; 643 if (pathValue < TRACK_PATH_LENGTH_1900) { 644 uint32_t deltaR = GetDeltaColor(TRACK_COLOR_YELLOW_R, TRACK_COLOR_ORANGE_RED_R); 645 uint32_t deltaG = GetDeltaColor(TRACK_COLOR_YELLOW_G, TRACK_COLOR_ORANGE_RED_G); 646 uint32_t deltaB = GetDeltaColor(TRACK_COLOR_ORANGE_RED_B, TRACK_COLOR_YELLOW_B); 647 float pathLength = path_.GetLength(false); 648 trackColorR_ += deltaR * pathLength / COLOR_TRANSITIONS_LENGTH; 649 trackColorG_ += deltaG * pathLength / COLOR_TRANSITIONS_LENGTH; 650 trackColorB_ -= deltaB * pathLength / COLOR_TRANSITIONS_LENGTH; 651 uint32_t colorQuad = Rosen::Drawing::Color::ColorQuadSetARGB( 652 ALPHA_ZERO, trackColorR_, trackColorG_, trackColorB_); 653 return colorQuad; 654 } else { 655 trackColorR_ = TRACK_COLOR_YELLOW_R; 656 trackColorG_ = TRACK_COLOR_YELLOW_G; 657 trackColorB_ = TRACK_COLOR_YELLOW_B; 658 return TRACK_COLOR_YELLOW; 659 } 660} 661 662void KnuckleDrawingManager::DrawTrackCanvas() 663{ 664 CALL_DEBUG_ENTER; 665 CHKPV(trackCanvasNode_); 666#ifndef USE_ROSEN_DRAWING 667 auto trackCanvas = static_cast<Rosen::RSRecordingCanvas *>(trackCanvasNode_-> 668 BeginRecording(scaleW_, scaleH_)); 669#else 670 auto trackCanvas = static_cast<Rosen::Drawing::RecordingCanvas *>(trackCanvasNode_-> 671 BeginRecording(scaleW_, scaleH_)); 672#endif // USE_ROSEN_DRAWING 673 CHKPV(trackCanvas); 674 pathLength_ += path_.GetLength(false); 675 int32_t pathValue = static_cast<int32_t>(pathLength_) % TRACK_PATH_LENGTH_2000; 676 Rosen::Drawing::Pen pen; 677 678 if (pathValue < TRACK_PATH_LENGTH_500) { 679 pen.SetColor(DrawTrackColorBlue(pathValue)); 680 } else if (pathValue < TRACK_PATH_LENGTH_1000) { 681 pen.SetColor(DrawTrackColorPink(pathValue)); 682 } else if (pathValue < TRACK_PATH_LENGTH_1500) { 683 pen.SetColor(DrawTrackColorOrangeRed(pathValue)); 684 } else { 685 pen.SetColor(DrawTrackColorYellow(pathValue)); 686 } 687 pen.SetWidth(PAINT_STROKE_WIDTH); 688 Rosen::Drawing::Filter filter; 689 filter.SetMaskFilter( 690 Rosen::Drawing::MaskFilter::CreateBlurMaskFilter(Rosen::Drawing::BlurType::OUTER, TRACK_FILTER_SCALAR)); 691 pen.SetFilter(filter); 692 trackCanvas->AttachPen(pen); 693 trackCanvas->DrawPath(path_); 694 trackCanvas->DetachPen(); 695 696 trackCanvas->AttachPaint(paint_); 697 trackCanvas->DrawPath(path_); 698 trackCanvas->DetachPaint(); 699 trackCanvasNode_->FinishRecording(); 700} 701 702void KnuckleDrawingManager::DrawBrushCanvas() 703{ 704 if (pathInfos_.size() >= PATH_SIZE_EIGHT) { 705 brushPathLength_ += path_.GetLength(false); 706 float pathLength = pathInfos_[0].GetLength(false); 707 if (((brushPathLength_ - pathLength) > MAX_PATH_LENGTH) || (pathInfos_.size() >= MAX_PATH_SIZE)) { 708 pathInfos_.erase(pathInfos_.begin()); 709 brushPathLength_ -= pathLength; 710 } 711 pathInfos_.emplace_back(path_); 712 CHKPV(brushCanvasNode_); 713 brushCanvasNode_->ResetSurface(scaleW_, scaleH_); 714 715#ifndef USE_ROSEN_DRAWING 716 auto canvas = static_cast<Rosen::RSRecordingCanvas *>(brushCanvasNode_-> 717 BeginRecording(scaleW_, scaleH_)); 718#else 719 auto canvas = static_cast<Rosen::Drawing::RecordingCanvas *>(brushCanvasNode_-> 720 BeginRecording(scaleW_, scaleH_)); 721#endif // USE_ROSEN_DRAWING 722 CHKPV(canvas); 723 for (size_t i = 0; (i < pathInfos_.size()) && (pathInfos_.size() != 1); ++i) { 724 Rosen::Drawing::Paint paint; 725 paint.SetAntiAlias(true); 726 paint.SetStyle(Rosen::Drawing::Paint::PaintStyle::PAINT_STROKE); 727 paint.SetJoinStyle(Rosen::Drawing::Pen::JoinStyle::ROUND_JOIN); 728 paint.SetCapStyle(Rosen::Drawing::Pen::CapStyle::ROUND_CAP); 729 730 paint.SetWidth(TRACK_WIDTH_THIRTY / (pathInfos_.size() - 1) * i + TRACK_WIDTH_TEN); 731 paint.SetColor(Rosen::Drawing::Color::COLOR_WHITE); 732 canvas->AttachPaint(paint); 733 canvas->DrawPath(pathInfos_[i]); 734 canvas->DetachPaint(); 735 } 736 brushCanvasNode_->FinishRecording(); 737 } else { 738 pathInfos_.emplace_back(path_); 739 brushPathLength_ += path_.GetLength(false); 740 } 741} 742 743void KnuckleDrawingManager::ActionUpAnimation() 744{ 745 CALL_DEBUG_ENTER; 746 CHKPV(trackCanvasNode_); 747 Rosen::RSAnimationTimingProtocol protocol; 748 protocol.SetDuration(PROTOCOL_DURATION); 749 protocol.SetRepeatCount(1); 750 auto animate = Rosen::RSNode::Animate( 751 protocol, 752 Rosen::RSAnimationTimingCurve::LINEAR, 753 [this]() { 754 trackCanvasNode_->SetAlpha(ALPHA_RANGE_END); 755 }); 756 Rosen::RSTransaction::FlushImplicitTransaction(); 757} 758 759int32_t KnuckleDrawingManager::DrawGraphic(std::shared_ptr<PointerEvent> touchEvent) 760{ 761 CALL_DEBUG_ENTER; 762 CHKPR(touchEvent, RET_ERR); 763 if (GetPointerPos(touchEvent) != RET_OK) { 764 MMI_HILOGD("GetPointerPos failed"); 765 return RET_ERR; 766 } 767 if (!isActionUp_) { 768 UpdateEmitter(); 769 path_.MoveTo(pointerInfos_[POINT_INDEX0].x, pointerInfos_[POINT_INDEX0].y); 770 path_.CubicTo(pointerInfos_[POINT_INDEX1].x, pointerInfos_[POINT_INDEX1].y, 771 pointerInfos_[POINT_INDEX2].x, pointerInfos_[POINT_INDEX2].y, 772 pointerInfos_[POINT_INDEX3].x, pointerInfos_[POINT_INDEX3].y); 773 pointerInfos_.erase(pointerInfos_.begin(), pointerInfos_.begin() + POINT_INDEX3); 774 if (pointerNum_ < POINTER_NUMBER_TO_DRAW) { 775 MMI_HILOGE("Pointer number not enough to draw"); 776 return RET_ERR; 777 } 778 DrawTrackCanvas(); 779 DrawBrushCanvas(); 780 } else { 781 MMI_HILOGE("The isActionUp_ is true"); 782 isActionUp_ = false; 783 pathInfos_.clear(); 784 pathLength_ = 0.0f; 785 brushPathLength_ = 0.0f; 786 trackColorR_ = 0x00; 787 trackColorG_ = 0x00; 788 trackColorB_ = 0x00; 789 if (ClearBrushCanvas() != RET_OK) { 790 MMI_HILOGE("ClearBrushCanvas failed"); 791 return RET_ERR; 792 } 793 ActionUpAnimation(); 794 int32_t repeatTime = 1; 795 int32_t timerId = TimerMgr->AddTimer(PROTOCOL_DURATION, repeatTime, [this]() { 796 DestoryWindow(); 797 }); 798 if (timerId < 0) { 799 MMI_HILOGE("Add timer failed, timerId:%{public}d", timerId); 800 DestoryWindow(); 801 } 802 return RET_OK; 803 } 804 path_.Reset(); 805 return RET_OK; 806} 807#else 808int32_t KnuckleDrawingManager::DrawGraphic(std::shared_ptr<PointerEvent> touchEvent) 809{ 810 CALL_DEBUG_ENTER; 811 CHKPR(touchEvent, RET_ERR); 812 CHKPR(canvasNode_, RET_ERR); 813 if (GetPointerPos(touchEvent) != RET_OK) { 814 MMI_HILOGD("GetPointerPos failed"); 815 return RET_ERR; 816 } 817 if (!isActionUp_) { 818 path_.MoveTo(pointerInfos_[POINT_INDEX0].x, pointerInfos_[POINT_INDEX0].y); 819 path_.CubicTo(pointerInfos_[POINT_INDEX1].x, pointerInfos_[POINT_INDEX1].y, 820 pointerInfos_[POINT_INDEX2].x, pointerInfos_[POINT_INDEX2].y, 821 pointerInfos_[POINT_INDEX3].x, pointerInfos_[POINT_INDEX3].y); 822 pointerInfos_.erase(pointerInfos_.begin(), pointerInfos_.begin() + POINT_INDEX3); 823 if (pointerNum_ < POINTER_NUMBER_TO_DRAW) { 824 return RET_ERR; 825 } 826#ifndef USE_ROSEN_DRAWING 827 auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_-> 828 BeginRecording(scaleW_, scaleH_)); 829#else 830 auto canvas = static_cast<Rosen::Drawing::RecordingCanvas *>(canvasNode_-> 831 BeginRecording(scaleW_, scaleH_)); 832#endif // USE_ROSEN_DRAWING 833 CHKPR(canvas, RET_ERR); 834 canvas->AttachPaint(paint_); 835 canvas->DrawPath(path_); 836 canvas->DetachPaint(); 837 } else { 838 MMI_HILOGD("isActionUp_ is true"); 839 isActionUp_ = false; 840 return DestoryWindow(); 841 } 842 path_.Reset(); 843 canvasNode_->FinishRecording(); 844 return RET_OK; 845} 846#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 847 848#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 849int32_t KnuckleDrawingManager::ClearTrackCanvas() 850{ 851 CALL_DEBUG_ENTER; 852 CHKPR(trackCanvasNode_, RET_ERR); 853#ifndef USE_ROSEN_DRAWING 854 auto trackCanvas = static_cast<Rosen::RSRecordingCanvas *>(trackCanvasNode_-> 855 BeginRecording(scaleW_, scaleH_)); 856#else 857 auto trackCanvas = static_cast<Rosen::Drawing::RecordingCanvas *>(trackCanvasNode_-> 858 BeginRecording(scaleW_, scaleH_)); 859#endif // USE_ROSEN_DRAWING 860 CHKPR(trackCanvas, RET_ERR); 861 trackCanvas->Clear(); 862 trackCanvasNode_->FinishRecording(); 863 CHKPR(surfaceNode_, RET_ERR); 864 surfaceNode_->RemoveChild(trackCanvasNode_); 865 trackCanvasNode_->ResetSurface(scaleW_, scaleH_); 866 trackCanvasNode_.reset(); 867 return RET_OK; 868} 869 870int32_t KnuckleDrawingManager::ClearBrushCanvas() 871{ 872 CALL_DEBUG_ENTER; 873 CHKPR(brushCanvasNode_, RET_ERR); 874#ifndef USE_ROSEN_DRAWING 875 auto brushCanvas = static_cast<Rosen::RSRecordingCanvas *>(brushCanvasNode_-> 876 BeginRecording(scaleW_, scaleH_)); 877#else 878 auto brushCanvas = static_cast<Rosen::Drawing::RecordingCanvas *>(brushCanvasNode_-> 879 BeginRecording(scaleW_, scaleH_)); 880#endif // USE_ROSEN_DRAWING 881 CHKPR(brushCanvas, RET_ERR); 882 brushCanvas->Clear(); 883 brushCanvasNode_->FinishRecording(); 884 CHKPR(surfaceNode_, RET_ERR); 885 surfaceNode_->RemoveChild(brushCanvasNode_); 886 brushCanvasNode_->ResetSurface(scaleW_, scaleH_); 887 brushCanvasNode_.reset(); 888 return RET_OK; 889} 890#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 891 892#ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 893int32_t KnuckleDrawingManager::DestoryWindow() 894{ 895 CALL_DEBUG_ENTER; 896 pointerInfos_.clear(); 897 path_.Reset(); 898 ClearBrushCanvas(); 899 if (ClearTrackCanvas() != RET_OK) { 900 MMI_HILOGE("ClearTrackCanvas failed"); 901 return RET_ERR; 902 } 903 CHKPR(surfaceNode_, RET_ERR); 904 surfaceNode_->DetachToDisplay(screenId_); 905 surfaceNode_.reset(); 906 Rosen::RSTransaction::FlushImplicitTransaction(); 907 return RET_OK; 908} 909#else 910int32_t KnuckleDrawingManager::DestoryWindow() 911{ 912 CALL_DEBUG_ENTER; 913 pointerInfos_.clear(); 914 path_.Reset(); 915 CHKPR(canvasNode_, RET_ERR); 916#ifndef USE_ROSEN_DRAWING 917 auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_-> 918 BeginRecording(scaleW_, scaleH_)); 919#else 920 auto canvas = static_cast<Rosen::Drawing::RecordingCanvas *>(canvasNode_-> 921 BeginRecording(scaleW_, scaleH_)); 922#endif // USE_ROSEN_DRAWING 923 CHKPR(canvas, RET_ERR); 924 canvas->Clear(); 925 canvasNode_->FinishRecording(); 926 CHKPR(surfaceNode_, RET_ERR); 927 surfaceNode_->DetachToDisplay(screenId_); 928 surfaceNode_->RemoveChild(canvasNode_); 929 canvasNode_->ResetSurface(scaleW_, scaleH_); 930 canvasNode_.reset(); 931 surfaceNode_.reset(); 932 Rosen::RSTransaction::FlushImplicitTransaction(); 933 return RET_OK; 934} 935#endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC 936 937void KnuckleDrawingManager::CreateObserver() 938{ 939 CALL_DEBUG_ENTER; 940 if (!hasScreenReadObserver_) { 941 screenReadState_.switchName = SCREEN_READING; 942 CreateScreenReadObserver(screenReadState_); 943 } 944 MMI_HILOGD("screenReadState_.state: %{public}s", screenReadState_.state.c_str()); 945} 946 947template <class T> 948void KnuckleDrawingManager::CreateScreenReadObserver(T &item) 949{ 950 CALL_DEBUG_ENTER; 951 SettingObserver::UpdateFunc updateFunc = [&item](const std::string& key) { 952 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID) 953 .GetStringValue(key, item.state); 954 if (ret != RET_OK) { 955 MMI_HILOGE("Get value from setting date fail"); 956 return; 957 } 958 MMI_HILOGI("key: %{public}s, state: %{public}s", key.c_str(), item.state.c_str()); 959 }; 960 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID) 961 .CreateObserver(item.switchName, updateFunc); 962 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID). 963 RegisterObserver(statusObserver); 964 if (ret != ERR_OK) { 965 MMI_HILOGE("Register setting observer failed, ret=%{public}d", ret); 966 statusObserver = nullptr; 967 return; 968 } 969 hasScreenReadObserver_ = true; 970} 971 972std::string KnuckleDrawingManager::GetScreenReadState() 973{ 974 return screenReadState_.state; 975} 976} // namespace MMI 977} // namespace OHOS