• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <iostream>
17 #include <vector>
18 
19 #include "include/core/SkBitmap.h"
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkColor.h"
22 #include "include/core/SkImage.h"
23 #include "include/core/SkImageInfo.h"
24 #include "include/core/SkPaint.h"
25 #include "include/core/SkRect.h"
26 #include "wm/window.h"
27 
28 #include "accesstoken_kit.h"
29 #ifdef SUPPORT_ACCESS_TOKEN
30 #include "nativetoken_kit.h"
31 #include "token_setproc.h"
32 #endif
33 #include "animation/rs_transition.h"
34 #include "animation/rs_transition_effect.h"
35 #include "transaction/rs_transaction.h"
36 #include "ui/rs_display_node.h"
37 #include "ui/rs_root_node.h"
38 #include "ui/rs_surface_node.h"
39 #include "ui/rs_ui_director.h"
40 
41 using namespace std;
42 using namespace OHOS;
43 using namespace OHOS::Rosen;
44 
45 constexpr int64_t START_NUMBER = 181154000809;
46 constexpr int64_t INCREASE_NUMBER = 10000000;
47 constexpr int64_t SLEEP_TIME = 10000;
48 constexpr int NUMBER_HALF = 2;
49 constexpr int NUMBER_TWO = 2;
50 constexpr int CLIP_NUMBER = 10;
51 constexpr int COLOR_VALUE_MAX = 255;
52 constexpr int WINDOW_WIDTH = 720;
53 constexpr int WINDOW_HEIGHT = 1280;
54 constexpr int ANIMATION_DURATION = 2000;
55 constexpr int ANIMATION_DELAY_TIME = 500;
56 std::shared_ptr<RSNode> rootNode;
57 std::vector<std::shared_ptr<RSCanvasNode>> nodes;
58 std::shared_ptr<RSUIDirector> rsUiDirector;
59 
60 class TransitionModifier1 : public RSTransitionModifier {
61 public:
Draw(RSDrawingContext & context) const62     void Draw(RSDrawingContext& context) const override
63     {
64         if (!radius_ || !backgroundColor_ || !alpha_) {
65             SkRect rect = SkRect::MakeXYWH(0, 0, 0, 0);
66             SkPaint p;
67             context.canvas->drawRect(rect, p);
68             return;
69         }
70         context.canvas->save();
71         SkPath path;
72         path.addCircle(context.width / NUMBER_HALF, context.height / NUMBER_HALF,
73             radius_->Get() * sqrt(pow(context.width / NUMBER_HALF, NUMBER_TWO) +
74             pow(context.height / NUMBER_HALF, NUMBER_TWO)));
75         context.canvas->clipPath(path);
76         SkRect rect = SkRect::MakeXYWH(0, 0, context.width, context.height);
77         SkPaint p;
78         p.setColor(backgroundColor_->Get().AsArgbInt());
79         p.setAlphaf(alpha_->Get());
80         context.canvas->drawRect(rect, p);
81         context.canvas->restore();
82     }
83 
SetRadius(float radius)84     void SetRadius(float radius)
85     {
86         if (radius_ == nullptr) {
87             radius_ = std::make_shared<RSAnimatableProperty<float>>(radius);
88             AttachProperty(radius_);
89         } else {
90             radius_->Set(radius);
91         }
92     }
93 
SetBackgroundColor(Color backgroundColor)94     void SetBackgroundColor(Color backgroundColor)
95     {
96         if (backgroundColor_ == nullptr) {
97             backgroundColor_ = std::make_shared<RSAnimatableProperty<Color>>(backgroundColor);
98             AttachProperty(backgroundColor_);
99         } else {
100             backgroundColor_->Set(backgroundColor);
101         }
102     }
103 
SetAlpha(float alpha)104     void SetAlpha(float alpha)
105     {
106         if (alpha_ == nullptr) {
107             alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
108             AttachProperty(alpha_);
109         } else {
110             alpha_->Set(alpha);
111         }
112     }
113 
Active()114     void Active() override
115     {
116         // should set property of before transition-in
117         SetRadius(0);
118         SetBackgroundColor(Color(COLOR_VALUE_MAX, 0, 0));
119         SetAlpha(0);
120     }
121 
Identity()122     void Identity() override
123     {
124         // should set property of after transition-in
125         SetRadius(1);
126         SetBackgroundColor(Color(0, 0, COLOR_VALUE_MAX));
127         SetAlpha(1);
128     }
129 
130 private:
131     std::shared_ptr<RSAnimatableProperty<float>> radius_;
132     std::shared_ptr<RSAnimatableProperty<Color>> backgroundColor_;
133     std::shared_ptr<RSAnimatableProperty<float>> alpha_;
134 };
135 
136 class TransitionModifier2 : public RSTransitionModifier {
137 public:
Draw(RSDrawingContext & context) const138     void Draw(RSDrawingContext& context) const override
139     {
140         float radius = 0;
141         if (radius_) {
142             radius = radius_->Get();
143         }
144         context.canvas->save();
145         SkPath path;
146         path.addCircle(0, 0, radius * sqrt(pow(context.width, NUMBER_TWO) + pow(context.height, NUMBER_TWO)));
147         context.canvas->clipPath(path);
148         SkRect rect = SkRect::MakeXYWH(0, 0, context.width, context.height);
149         SkPaint p;
150         p.setColor(backgroundColor_.AsArgbInt());
151         context.canvas->drawRect(rect, p);
152         context.canvas->restore();
153     }
154 
SetRadius(float radius)155     void SetRadius(float radius)
156     {
157         if (radius_ == nullptr) {
158             radius_ = std::make_shared<RSAnimatableProperty<float>>(radius);
159             AttachProperty(radius_);
160         } else {
161             radius_->Set(radius);
162         }
163     }
164 
SetBackgroundColor(Color backgroundColor)165     void SetBackgroundColor(Color backgroundColor)
166     {
167         backgroundColor_ = backgroundColor;
168     }
169 
Active()170     void Active() override
171     {
172         // should set property of before transition-in
173         SetRadius(0);
174     }
175 
Identity()176     void Identity() override
177     {
178         // should set property of after transition-in
179         SetRadius(1);
180     }
181 
182 private:
183     std::shared_ptr<RSAnimatableProperty<float>> radius_;
184     Color backgroundColor_ = Color(COLOR_VALUE_MAX, 0, 0);
185 };
186 
187 class TransitionModifier3 : public RSTransitionModifier {
188 public:
Draw(RSDrawingContext & context) const189     void Draw(RSDrawingContext& context) const override
190     {
191         float clipWidth = 0;
192         if (clipWidth_) {
193             clipWidth = clipWidth_->Get();
194         }
195         for (int i = 0; i < clipPieces_; i++) {
196             context.canvas->save();
197             SkRect clipRect = SkRect::MakeXYWH(context.width / clipPieces_ * i, 0,
198                 clipWidth * context.width / clipPieces_, context.height);
199             context.canvas->clipRect(clipRect);
200             SkRect rect = SkRect::MakeXYWH(0, 0, context.width, context.height);
201             SkPaint p;
202             p.setColor(backgroundColor_.AsArgbInt());
203             context.canvas->drawRect(rect, p);
204             context.canvas->restore();
205         }
206     }
207 
SetClipWidth(float clipWidth)208     void SetClipWidth(float clipWidth)
209     {
210         if (clipWidth_ == nullptr) {
211             clipWidth_ = std::make_shared<RSAnimatableProperty<float>>(clipWidth);
212             AttachProperty(clipWidth_);
213         } else {
214             clipWidth_->Set(clipWidth);
215         }
216     }
217 
SetBackgroundColor(Color backgroundColor)218     void SetBackgroundColor(Color backgroundColor)
219     {
220         backgroundColor_ = backgroundColor;
221     }
222 
Active()223     void Active() override
224     {
225         // should set property of before transition-in
226         SetClipWidth(0);
227     }
228 
Identity()229     void Identity() override
230     {
231         // should set property of after transition-in
232         SetClipWidth(1);
233     }
234 
235 private:
236     std::shared_ptr<RSAnimatableProperty<float>> clipWidth_;
237     Color backgroundColor_ = Color(COLOR_VALUE_MAX, 0, 0);
238     int clipPieces_ = CLIP_NUMBER;
239 };
240 
241 class TransitionModifier4 : public RSTransitionModifier {
242 public:
Draw(RSDrawingContext & context) const243     void Draw(RSDrawingContext& context) const override
244     {
245         float clipWidth = 0;
246         if (clipWidth_) {
247             clipWidth = clipWidth_->Get();
248         }
249         for (int i = 0; i < clipPieces_; i++) {
250             context.canvas->save();
251             SkRect clipRect = SkRect::MakeXYWH(
252                 context.width / clipPieces_ * (i + 1) - clipWidth * context.width / clipPieces_, 0,
253                 clipWidth * context.width / clipPieces_, context.height);
254             context.canvas->clipRect(clipRect);
255             SkRect rect = SkRect::MakeXYWH(0, 0, context.width, context.height);
256             SkPaint p;
257             p.setColor(backgroundColor_.AsArgbInt());
258             context.canvas->drawRect(rect, p);
259             context.canvas->restore();
260         }
261     }
262 
SetClipWidth(float clipWidth)263     void SetClipWidth(float clipWidth)
264     {
265         if (clipWidth_ == nullptr) {
266             clipWidth_ = std::make_shared<RSAnimatableProperty<float>>(clipWidth);
267             AttachProperty(clipWidth_);
268         } else {
269             clipWidth_->Set(clipWidth);
270         }
271     }
272 
SetBackgroundColor(Color backgroundColor)273     void SetBackgroundColor(Color backgroundColor)
274     {
275         backgroundColor_ = backgroundColor;
276     }
277 
Active()278     void Active() override
279     {
280         // should set property of before transition-in
281         SetClipWidth(0);
282     }
283 
Identity()284     void Identity() override
285     {
286         // should set property of after transition-in
287         SetClipWidth(1);
288     }
289 
290 private:
291     std::shared_ptr<RSAnimatableProperty<float>> clipWidth_;
292     Color backgroundColor_ = Color(COLOR_VALUE_MAX, 0, 0);
293     int clipPieces_ = CLIP_NUMBER;
294 };
295 
296 class TransitionModifier5 : public RSTransitionModifier {
297 public:
Draw(RSDrawingContext & context) const298     void Draw(RSDrawingContext& context) const override
299     {
300         float clipHeight = 0;
301         if (clipHeight_) {
302             clipHeight = clipHeight_->Get();
303         }
304         for (int i = 0; i < clipPieces_; i++) {
305             context.canvas->save();
306             SkRect clipRect = SkRect::MakeXYWH(0, context.height / clipPieces_ * i,
307                 context.width, clipHeight * context.height / clipPieces_);
308             context.canvas->clipRect(clipRect);
309             SkRect rect = SkRect::MakeXYWH(0, 0, context.width, context.height);
310             SkPaint p;
311             p.setColor(backgroundColor_.AsArgbInt());
312             context.canvas->drawRect(rect, p);
313             context.canvas->restore();
314         }
315     }
316 
SetClipHeight(float clipHeight)317     void SetClipHeight(float clipHeight)
318     {
319         if (clipHeight_ == nullptr) {
320             clipHeight_ = std::make_shared<RSAnimatableProperty<float>>(clipHeight);
321             AttachProperty(clipHeight_);
322         } else {
323             clipHeight_->Set(clipHeight);
324         }
325     }
326 
SetBackgroundColor(Color backgroundColor)327     void SetBackgroundColor(Color backgroundColor)
328     {
329         backgroundColor_ = backgroundColor;
330     }
331 
Active()332     void Active() override
333     {
334         // should set property of before transition-in
335         SetClipHeight(0);
336     }
337 
Identity()338     void Identity() override
339     {
340         // should set property of after transition-in
341         SetClipHeight(1);
342     }
343 
344 private:
345     std::shared_ptr<RSAnimatableProperty<float>> clipHeight_;
346     Color backgroundColor_ = Color(COLOR_VALUE_MAX, 0, 0);
347     int clipPieces_ = CLIP_NUMBER;
348 };
349 
Transition1()350 void Transition1()
351 {
352     nodes.emplace_back(RSCanvasNode::Create());
353     nodes[0]->SetBounds({ 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
354     // define custom modifier for transition
355     auto transitionModifier1 = std::make_shared<TransitionModifier1>();
356     auto transitionModifier2 = std::make_shared<TransitionModifier2>();
357     transitionModifier2->SetBackgroundColor(Color(0, 0, COLOR_VALUE_MAX));
358     // add the modifier to node
359     nodes[0]->AddModifier(transitionModifier1);
360     nodes[0]->AddModifier(transitionModifier2);
361     // create transition effect
362     auto transitionInEffect = RSTransitionEffect::Create()->Custom(transitionModifier1);
363     auto transitionOutEffect = RSTransitionEffect::Create()->Custom(transitionModifier2);
364     nodes[0]->SetTransitionEffect(RSTransitionEffect::Asymmetric(transitionInEffect, transitionOutEffect));
365     // define animation protocol
366     RSAnimationTimingProtocol protocol;
367     // set duration as 2000 millisecond
368     protocol.SetDuration(ANIMATION_DURATION);
369     // create transition-in animation
370     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
371         rootNode->AddChild(nodes[0]);
372     }, []() {
373         std::cout << "nodes0 appears" << std::endl;
374     });
375     uint64_t timeStamp = START_NUMBER;
376     bool hasRunningAnimation = true;
377     while (hasRunningAnimation) {
378         hasRunningAnimation = rsUiDirector->FlushAnimation(timeStamp);
379         rsUiDirector->FlushModifier();
380         rsUiDirector->SendMessages();
381         timeStamp += INCREASE_NUMBER;
382         usleep(SLEEP_TIME);
383     }
384     nodes[0]->RemoveModifier(transitionModifier1);
385 }
386 
Transition2()387 void Transition2()
388 {
389     nodes.emplace_back(RSCanvasNode::Create());
390     nodes[1]->SetBounds({ 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
391     // define custom modifier for transition
392     auto transitionModifier2 = std::make_shared<TransitionModifier2>();
393     auto transitionModifier3 = std::make_shared<TransitionModifier3>();
394     transitionModifier2->SetBackgroundColor(Color(0, COLOR_VALUE_MAX, 0));
395     transitionModifier3->SetBackgroundColor(Color(0, COLOR_VALUE_MAX, 0));
396     // add the modifier to node
397     nodes[1]->AddModifier(transitionModifier2);
398     nodes[1]->AddModifier(transitionModifier3);
399     // create transition effect
400     auto transitionInEffect = RSTransitionEffect::Create()->Custom(transitionModifier2);
401     auto transitionOutEffect = RSTransitionEffect::Create()->Custom(transitionModifier3);
402     nodes[1]->SetTransitionEffect(RSTransitionEffect::Asymmetric(transitionInEffect, transitionOutEffect));
403     // define animation protocol
404     RSAnimationTimingProtocol protocol;
405     // set duration as 2000 millisecond
406     protocol.SetDuration(ANIMATION_DURATION);
407     // create transition-out animation
408     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
409         rootNode->RemoveChild(nodes[0]);
410     }, []() {
411         std::cout << "nodes0 disappears" << std::endl;
412     });
413     protocol.SetStartDelay(ANIMATION_DELAY_TIME);
414     // create transition-in animation
415     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
416         rootNode->AddChild(nodes[1]);
417     }, []() {
418         std::cout << "nodes1 appears" << std::endl;
419     });
420     uint64_t timeStamp = START_NUMBER;
421     bool hasRunningAnimation = true;
422     while (hasRunningAnimation) {
423         hasRunningAnimation = rsUiDirector->FlushAnimation(timeStamp);
424         rsUiDirector->FlushModifier();
425         rsUiDirector->SendMessages();
426         timeStamp += INCREASE_NUMBER;
427         usleep(SLEEP_TIME);
428     }
429     nodes[1]->RemoveModifier(transitionModifier2);
430 }
431 
Transition3()432 void Transition3()
433 {
434     nodes.emplace_back(RSCanvasNode::Create());
435     nodes[NUMBER_TWO]->SetBounds({ 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
436     // define custom modifier for transition
437     auto transitionModifier4 = std::make_shared<TransitionModifier4>();
438     auto transitionModifier5 = std::make_shared<TransitionModifier5>();
439     transitionModifier4->SetBackgroundColor(Color(0, COLOR_VALUE_MAX, COLOR_VALUE_MAX));
440     transitionModifier5->SetBackgroundColor(Color(0, COLOR_VALUE_MAX, COLOR_VALUE_MAX));
441     // add the modifier to node
442     nodes[NUMBER_TWO]->AddModifier(transitionModifier4);
443     nodes[NUMBER_TWO]->AddModifier(transitionModifier5);
444     // create transition effect
445     auto transitionInEffect = RSTransitionEffect::Create()->Custom(transitionModifier4);
446     auto transitionOutEffect = RSTransitionEffect::Create()->Custom(transitionModifier5);
447     nodes[NUMBER_TWO]->SetTransitionEffect(RSTransitionEffect::Asymmetric(transitionInEffect, transitionOutEffect));
448     // define animation protocol
449     RSAnimationTimingProtocol protocol;
450     // set duration as 2000 millisecond
451     protocol.SetDuration(ANIMATION_DURATION);
452     // create transition-out animation
453     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
454         rootNode->RemoveChild(nodes[1]);
455     }, []() {
456         std::cout << "nodes1 disappears" << std::endl;
457     });
458     // create transition-in animation
459     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
460         rootNode->AddChild(nodes[NUMBER_TWO]);
461     }, []() {
462         std::cout << "nodes2 appears" << std::endl;
463     });
464     uint64_t timeStamp = START_NUMBER;
465     bool hasRunningAnimation = true;
466     while (hasRunningAnimation) {
467         hasRunningAnimation = rsUiDirector->FlushAnimation(timeStamp);
468         rsUiDirector->FlushModifier();
469         rsUiDirector->SendMessages();
470         timeStamp += INCREASE_NUMBER;
471         usleep(SLEEP_TIME);
472     }
473     nodes[NUMBER_TWO]->RemoveModifier(transitionModifier4);
474 }
475 
Transition4()476 void Transition4()
477 {
478     // define animation protocol
479     RSAnimationTimingProtocol protocol;
480     // set duration as 2000 millisecond
481     protocol.SetDuration(ANIMATION_DURATION);
482     // create transition-out animation
483     RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
484         rootNode->RemoveChild(nodes[NUMBER_TWO]);
485     }, []() {
486         std::cout << "nodes2 disappears" << std::endl;
487     });
488     uint64_t timeStamp = START_NUMBER;
489     bool hasRunningAnimation = true;
490     while (hasRunningAnimation) {
491         hasRunningAnimation = rsUiDirector->FlushAnimation(timeStamp);
492         rsUiDirector->FlushModifier();
493         rsUiDirector->SendMessages();
494         timeStamp += INCREASE_NUMBER;
495         usleep(SLEEP_TIME);
496     }
497 }
498 
InitNativeTokenInfo()499 void InitNativeTokenInfo()
500 {
501 #ifdef SUPPORT_ACCESS_TOKEN
502     uint64_t tokenId;
503     const char *perms[1];
504     perms[0] = "ohos.permission.SYSTEM_FLOAT_WINDOW";
505     NativeTokenInfoParams infoInstance = {
506         .dcapsNum = 0,
507         .permsNum = 1,
508         .aclsNum = 0,
509         .dcaps = NULL,
510         .perms = perms,
511         .acls = NULL,
512         .processName = "render_service_client_transition_demo",
513         .aplStr = "system_basic",
514     };
515     tokenId = GetAccessTokenId(&infoInstance);
516     SetSelfTokenID(tokenId);
517     Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
518     std::cout << "init native token for float window" << std::endl;
519 #endif
520 }
521 
main()522 int main()
523 {
524 #ifdef SUPPORT_ACCESS_TOKEN
525     std::cout << "transition demo start!" << std::endl;
526     InitNativeTokenInfo();
527     // create window
528     sptr<WindowOption> option = new WindowOption();
529     option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
530     option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
531     option->SetWindowRect({ 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT });
532     auto window = Window::Create("transition", option);
533     window->Show();
534     sleep(1);
535     auto rect = window->GetRect();
536     while (rect.width_ == 0 && rect.height_ == 0) {
537         std::cout << "create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
538         window->Hide();
539         window->Destroy();
540         window = Window::Create("transition_demo", option);
541         window->Show();
542         sleep(1);
543         rect = window->GetRect();
544     }
545     std::cout << "create window " << rect.width_ << " " << rect.height_ << std::endl;
546     auto surfaceNode = window->GetSurfaceNode();
547 
548     std::cout << "init rosen backend!" << std::endl;
549 
550     // init rosen backend
551     rsUiDirector = RSUIDirector::Create();
552     rsUiDirector->Init();
553     RSTransaction::FlushImplicitTransaction();
554     rsUiDirector->SetRSSurfaceNode(surfaceNode);
555 
556     rootNode = RSRootNode::Create();
557     rootNode->SetBounds(0, 0, rect.width_, rect.height_);
558     rootNode->SetFrame(0, 0, rect.width_, rect.height_);
559     rootNode->SetBackgroundColor(SK_ColorWHITE);
560     rsUiDirector->SetRSRootNode(rootNode->ReinterpretCastTo<RSRootNode>());
561 
562     std::cout << "nodes[0] appearing." << std::endl;
563     Transition1();
564     sleep(NUMBER_TWO);
565     std::cout << "nodes[0] disappearing and nodes[1] appearing." << std::endl;
566     Transition2();
567     sleep(NUMBER_TWO);
568     std::cout << "nodes[1] disappearing and nodes[2] appearing." << std::endl;
569     Transition3();
570     sleep(NUMBER_TWO);
571     std::cout << "nodes[2] disappearing." << std::endl;
572     Transition4();
573     sleep(NUMBER_TWO);
574 
575     std::cout << "transition demo end!" << std::endl;
576     window->Hide();
577     window->Destroy();
578 #endif
579     return 0;
580 }
581