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