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
44 namespace OHOS {
45 namespace MMI {
46 namespace {
47 constexpr int32_t DEFAULT_VALUE { -1 };
48 constexpr int32_t MAX_POINTER_NUM { 5 };
49 constexpr int32_t MID_POINT { 2 };
50 constexpr int32_t POINT_INDEX0 { 0 };
51 constexpr int32_t POINT_INDEX1 { 1 };
52 constexpr int32_t POINT_INDEX2 { 2 };
53 constexpr int32_t POINT_INDEX3 { 3 };
54 constexpr int32_t POINT_INDEX4 { 4 };
55 constexpr int32_t PAINT_STROKE_WIDTH { 10 };
56 constexpr int32_t PAINT_PATH_RADIUS { 10 };
57 constexpr int64_t DOUBLE_CLICK_INTERVAL_TIME_SLOW { 450000 };
58 constexpr int64_t WAIT_DOUBLE_CLICK_INTERVAL_TIME { 100000 };
59 constexpr float DOUBLE_CLICK_DISTANCE_LONG_CONFIG { 96.0f };
60 constexpr float VPR_CONFIG { 3.25f };
61 constexpr int32_t POW_SQUARE { 2 };
62 constexpr int32_t ROTATION_ANGLE_0 { 0 };
63 constexpr int32_t ROTATION_ANGLE_90 { 90 };
64 constexpr int32_t ROTATION_ANGLE_180 { 180 };
65 constexpr int32_t ROTATION_ANGLE_270 { 270 };
66 constexpr uint64_t FOLD_SCREEN_MAIN_ID { 5 };
67 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
68 const std::string FOLDABLE = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
69 constexpr int32_t WINDOW_ROTATE { 0 };
70 constexpr int32_t SCREEN_ROTATE { 1 };
71 constexpr int32_t FOLDABLE_DEVICE { 2 };
72 constexpr char FOLDABLE_ROTATE { '0' };
73 constexpr int32_t SUBSCRIPT_TWO { 2 };
74 constexpr int32_t SUBSCRIPT_ZERO { 0 };
75 constexpr std::string_view SCREEN_READING { "accessibility_screenreader_enabled" };
76 constexpr std::string_view SCREEN_READ_ENABLE { "1" };
77 constexpr int32_t POINTER_NUMBER_TO_DRAW { 10 };
78 #ifdef OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC
79 constexpr int64_t PARTICLE_LIFE_TIME { 700 };
80 constexpr int32_t PARTICLE_COUNT { -1 };
81 constexpr int32_t DEFAULT_EMIT_RATE { 0 };
82 constexpr int32_t EMIT_RATE { 400 };
83 constexpr int32_t PATH_SIZE_EIGHT { 8 };
84 constexpr int32_t MAX_PATH_SIZE { 50 };
85 constexpr int32_t MAX_PATH_LENGTH { 500 };
86 constexpr float PARTICLE_RADIUS { 5.0f };
87 constexpr float DEFAULT_PARTICLE_POSITION_X { 0.0f };
88 constexpr float DEFAULT_PARTICLE_POSITION_Y { 0.0f };
89 constexpr float DEFAULT_EMIT_SIZE_RANGE_BEGIN { 0.0f };
90 constexpr float DEFAULT_EMIT_SIZE_RANGE_END { 0.0f };
91 constexpr float EMIT_SIZE_RANGE_BEGIN { 80.0f };
92 constexpr float EMIT_SIZE_RANGE_END { 80.0f };
93 constexpr float EMIT_VELOCITY_VALUE_RANGE_BEGIN { 50.0f };
94 constexpr float EMIT_VELOCITY_VALUE_RANGE_END { 100.0f };
95 constexpr float EMIT_VELOCITY_ANGLE_RANGE_BEGIN { -180.0f };
96 constexpr float EMIT_VELOCITY_ANGLE_RANGE_END { 180.0f };
97 constexpr float EMIT_OPACITY_RANGE_BEGIN { 0.3f };
98 constexpr float EMIT_OPACITY_RANGE_END { 1.0f };
99 constexpr float EMIT_SCALE_RANGE_BEGIN { 0.3f };
100 constexpr float EMIT_SCALE_RANGE_END { 1.0f };
101 constexpr float EMIT_SCALE_CHANGE_RANGE_BEGIN { 1.0f };
102 constexpr float EMIT_SCALE_CHANGE_RANGE_END { 0.0f };
103 constexpr float SCALE_CHANGE_VELOCITY_RANGE_BEGIN { -1.0f };
104 constexpr float SCALE_CHANGE_VELOCITY_RANGE_END { -1.0f };
105 constexpr int32_t SCALE_CHANGE_START_MILLIS { 0 };
106 constexpr int32_t SCALE_CHANGE_END_MILLIS { 700 };
107 constexpr float ALPHA_RANGE_BEGIN { 1.0f };
108 constexpr float ALPHA_RANGE_END { 0.0f };
109 constexpr float EMIT_RADIUS { 40.0f };
110 constexpr float TRACK_FILTER_SCALAR { 20.0f };
111 constexpr int32_t TRACK_PATH_LENGTH_400 { 400 };
112 constexpr int32_t TRACK_PATH_LENGTH_500 { 500 };
113 constexpr int32_t TRACK_PATH_LENGTH_900 { 900 };
114 constexpr int32_t TRACK_PATH_LENGTH_1000 { 1000 };
115 constexpr int32_t TRACK_PATH_LENGTH_1400 { 1400 };
116 constexpr int32_t TRACK_PATH_LENGTH_1500 { 1500 };
117 constexpr int32_t TRACK_PATH_LENGTH_1900 { 1900 };
118 constexpr int32_t TRACK_PATH_LENGTH_2000 { 2000 };
119 constexpr uint32_t TRACK_COLOR_BLUE { 0xFF1ED0EE };
120 constexpr uint32_t TRACK_COLOR_BLUE_R { 0x1E };
121 constexpr uint32_t TRACK_COLOR_BLUE_G { 0xD0 };
122 constexpr uint32_t TRACK_COLOR_BLUE_B { 0xEE };
123 constexpr uint32_t TRACK_COLOR_PINK { 0xFFFF42D2 };
124 constexpr uint32_t TRACK_COLOR_PINK_R { 0xFF };
125 constexpr uint32_t TRACK_COLOR_PINK_G { 0x42 };
126 constexpr uint32_t TRACK_COLOR_PINK_B { 0xD2 };
127 constexpr uint32_t TRACK_COLOR_ORANGE_RED { 0xFFFF7B47 };
128 constexpr uint32_t TRACK_COLOR_ORANGE_RED_R { 0xFF };
129 constexpr uint32_t TRACK_COLOR_ORANGE_RED_G { 0x7B };
130 constexpr uint32_t TRACK_COLOR_ORANGE_RED_B { 0x47 };
131 constexpr uint32_t TRACK_COLOR_YELLOW { 0xFFFFC628 };
132 constexpr uint32_t TRACK_COLOR_YELLOW_R { 0xFF };
133 constexpr uint32_t TRACK_COLOR_YELLOW_G { 0xC6 };
134 constexpr uint32_t TRACK_COLOR_YELLOW_B { 0x28 };
135 constexpr uint32_t ALPHA_ZERO { 0xFF };
136 constexpr float TRACK_WIDTH_TEN { 10.0f };
137 constexpr float TRACK_WIDTH_THIRTY { 30.0f };
138 constexpr float COLOR_TRANSITIONS_LENGTH { 400.0f };
139 constexpr int32_t PROTOCOL_DURATION { 200 };
140 #endif // OHOS_BUILD_ENABLE_NEW_KNUCKLE_DYNAMIC
141 } // namespace
142
KnuckleDrawingManager()143 KnuckleDrawingManager::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
KnuckleDrawHandler(std::shared_ptr<PointerEvent> touchEvent)168 void 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
IsSingleKnuckle(std::shared_ptr<PointerEvent> touchEvent)184 bool 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
IsSingleKnuckleDoubleClick(std::shared_ptr<PointerEvent> touchEvent)208 bool 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
IsValidAction(const int32_t action)236 bool 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
UpdateDisplayInfo(const DisplayInfo & displayInfo)252 void 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
StartTouchDraw(std::shared_ptr<PointerEvent> touchEvent)264 void 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
RotationCanvasNode(std::shared_ptr<Rosen::RSCanvasNode> canvasNode,const DisplayInfo & displayInfo)276 void 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
CheckRotatePolicy(const DisplayInfo & displayInfo)297 bool 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
InitParticleEmitter()323 void 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
CreateTouchWindow(const int32_t displayId)371 void 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
CreateTouchWindow(const int32_t displayId)417 void 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
CreateBrushWorkCanvasNode()460 void 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
CreateTrackCanvasNode()478 void 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
CreateCanvasNode()496 void 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
GetPointerPos(std::shared_ptr<PointerEvent> touchEvent)514 int32_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
UpdateEmitter()545 void 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
GetDeltaColor(uint32_t deltaSource,uint32_t deltaTarget)562 uint32_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
DrawTrackColorBlue(int32_t pathValue)573 uint32_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
DrawTrackColorPink(int32_t pathValue)596 uint32_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
DrawTrackColorOrangeRed(int32_t pathValue)618 uint32_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
DrawTrackColorYellow(int32_t pathValue)640 uint32_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
DrawTrackCanvas()662 void 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
DrawBrushCanvas()702 void 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
ActionUpAnimation()743 void 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
DrawGraphic(std::shared_ptr<PointerEvent> touchEvent)759 int32_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("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
DrawGraphic(std::shared_ptr<PointerEvent> touchEvent)808 int32_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
ClearTrackCanvas()849 int32_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
ClearBrushCanvas()870 int32_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
DestoryWindow()893 int32_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
DestoryWindow()910 int32_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
CreateObserver()937 void 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
947 template <class T>
CreateScreenReadObserver(T & item)948 void 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
GetScreenReadState()972 std::string KnuckleDrawingManager::GetScreenReadState()
973 {
974 return screenReadState_.state;
975 }
976 } // namespace MMI
977 } // namespace OHOS