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