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