• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 <event_handler.h>
17 #include <iostream>
18 #include <surface.h>
19 
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkColor.h"
22 #include "window.h"
23 
24 #include "accesstoken_kit.h"
25 #ifdef SUPPORT_ACCESS_TOKEN
26 #include "nativetoken_kit.h"
27 #include "token_setproc.h"
28 #endif
29 #include "modifier/rs_extended_modifier.h"
30 #include "modifier/rs_property_modifier.h"
31 #include "render/rs_border.h"
32 #include "transaction/rs_transaction.h"
33 #include "ui/rs_display_node.h"
34 #include "ui/rs_root_node.h"
35 #include "ui/rs_surface_extractor.h"
36 #include "ui/rs_surface_node.h"
37 #include "ui/rs_ui_director.h"
38 
39 using namespace OHOS;
40 using namespace OHOS::Rosen;
41 using namespace std;
42 
43 std::shared_ptr<RSNode> rootNode;
44 std::vector<std::shared_ptr<RSCanvasNode>> nodes;
45 
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)46 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
47 {
48     std::cout << "rs app demo Init Rosen Backend!" << std::endl;
49 
50     rootNode = RSRootNode::Create();
51     rootNode->SetBounds(0, 0, width, height);
52     rootNode->SetFrame(0, 0, width, height);
53     rootNode->SetBackgroundColor(SK_ColorYELLOW);
54 
55     nodes.emplace_back(RSCanvasNode::Create());
56     nodes[0]->SetBounds(10, 10, 100, 100);
57     nodes[0]->SetFrame(10, 10, 100, 100);
58     nodes[0]->SetBackgroundColor(SK_ColorBLUE);
59 
60     rootNode->AddChild(nodes[0], -1);
61 
62     rootNode->AddChild(nodes[0], -1);
63     rsUiDirector->SetRoot(rootNode->GetId());
64 }
65 
66 class NodeModifier : public RSNodeModifier {
67 public:
68     NodeModifier() = default;
69     virtual ~NodeModifier() = default;
70 
Modify(RSNode & target) const71     void Modify(RSNode& target) const override
72     {
73         target.SetTranslate(translate_->Get());
74     }
75 
SetTranslate(Vector2f translate)76     void SetTranslate(Vector2f translate)
77     {
78         if (translate_ == nullptr) {
79             translate_ = std::make_shared<RSAnimatableProperty<Vector2f>>(translate);
80             AttachProperty(translate_);
81         } else {
82             translate_->Set(translate);
83         }
84     }
85 
GetTranslate() const86     Vector2f GetTranslate() const
87     {
88         return currentTranslateValue_;
89     }
90 
SetTranslateCallBack()91     bool SetTranslateCallBack()
92     {
93         if (!translate_) {
94             return false;
95         }
96 
97         // add callback for each frame
98         translate_->SetUpdateCallback([&](Vector2f vec) { currentTranslateValue_ = vec; });
99         return true;
100     }
101 
102     Vector2f currentTranslateValue_ = Vector2f(0.0f, 0.0f);
103 
104 private:
105     std::shared_ptr<RSAnimatableProperty<Vector2f>> translate_;
106 };
107 
InitNativeTokenInfo()108 void InitNativeTokenInfo()
109 {
110 #ifdef SUPPORT_ACCESS_TOKEN
111     uint64_t tokenId;
112     const char *perms[1];
113     perms[0] = "ohos.permission.SYSTEM_FLOAT_WINDOW";
114     NativeTokenInfoParams infoInstance = {
115         .dcapsNum = 0,
116         .permsNum = 1,
117         .aclsNum = 0,
118         .dcaps = NULL,
119         .perms = perms,
120         .acls = NULL,
121         .processName = "render_service_client_gesture_interrupt_animation_demo",
122         .aplStr = "system_basic",
123     };
124     tokenId = GetAccessTokenId(&infoInstance);
125     SetSelfTokenID(tokenId);
126     Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
127     std::cout << "init native token for float window" << std::endl;
128 #endif
129 }
130 
main()131 int main()
132 {
133 #ifdef SUPPORT_ACCESS_TOKEN
134     int cnt = 0;
135     InitNativeTokenInfo();
136     // Init demo env
137     std::cout << "rs app demo start!" << std::endl;
138     sptr<WindowOption> option = new WindowOption();
139     option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
140     option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
141     option->SetWindowRect({ 0, 0, 720, 1280 });
142     auto window = Window::Create("app_demo", option);
143     window->Show();
144     sleep(1);
145     auto rect = window->GetRect();
146     while (rect.width_ == 0 && rect.height_ == 0) {
147         std::cout << "rs app demo create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
148         window->Hide();
149         window->Destroy();
150         window = Window::Create("app_demo", option);
151         window->Show();
152         sleep(1);
153         rect = window->GetRect();
154     }
155     std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
156     auto surfaceNode = window->GetSurfaceNode();
157 
158     // Build rosen renderThread & create nodes
159     std::cout << "rs app demo stage " << cnt++ << std::endl;
160     auto rsUiDirector = RSUIDirector::Create();
161     rsUiDirector->Init();
162     auto runner = OHOS::AppExecFwk::EventRunner::Create(true);
163     auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
164     rsUiDirector->SetUITaskRunner(
165         [handler](const std::function<void()>& task, uint32_t delay) { handler->PostTask(task); });
166     runner->Run();
167     RSTransaction::FlushImplicitTransaction();
168     rsUiDirector->SetRSSurfaceNode(surfaceNode);
169     Init(rsUiDirector, rect.width_, rect.height_);
170 
171     std::cout << "rs app demo stage " << cnt++ << std::endl;
172 
173     // simulate sliding trajecity
174     int pointsNum = 30;
175     vector<Vector2f> handPoint(pointsNum);
176     for (int i = 0; i < handPoint.size(); i++) {
177         handPoint[i].data_[0] = 0.0f;
178         handPoint[i].data_[1] = 0.5f * i * i;
179     }
180 
181     // simulate sliding stage
182     for (auto vec : handPoint) {
183         nodes[0]->SetTranslate(vec);
184         rsUiDirector->SendMessages();
185         usleep(30000);
186     }
187 
188     // calculate sliding velocity
189     auto velocity = (handPoint[pointsNum - 1] - handPoint[pointsNum - 2]) * (1.0f / (30000.0f * 1e-6));
190 
191     // calculate final points
192     Vector2f finalTrans = handPoint[pointsNum - 1] + velocity * 0.5;
193 
194     std::cout << "rs app demo stage " << cnt++ << std::endl;
195 
196     auto nodeModifier = std::make_shared<NodeModifier>();
197     nodes[0]->AddModifier(nodeModifier);
198 
199     // init property
200     nodes[0]->SetTranslate(handPoint[pointsNum - 1]);
201 
202     RSAnimationTimingProtocol protocol;
203     // duration is not effective when the curve is interpolatingSpring
204     protocol.SetDuration(3000);
205 
206     auto timingCurve = RSAnimationTimingCurve::CreateInterpolatingSpring(1.0f, 225.0f, 30.0f, 2.0f);
207 
208     // create property animation
209     RSNode::Animate(
210         protocol, timingCurve,
211         [&]() {
212             std::cout << "the end tranlate of sliding animation is " << finalTrans.data_[0] << ", "
213                       << finalTrans.data_[1] << std::endl;
214             nodeModifier->SetTranslate(finalTrans);
215         },
216         []() { std::cout << "sliding animation finish callback" << std::endl; });
217 
218     int64_t startNum = 80825861106;
219     int64_t interruptNum = 80825861106 * 15;
220 
221     bool hasRunningAnimation = true;
222     bool stopSignal = true;
223 
224     while (hasRunningAnimation) {
225         hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
226         rsUiDirector->FlushModifier();
227         rsUiDirector->SendMessages();
228         std::cout << "the current translate is " << nodeModifier->GetTranslate().data_[0] << ", "
229                   << nodeModifier->GetTranslate().data_[1] << endl;
230 
231         // simulate to stop animation by gesture
232         if ((startNum >= interruptNum) && stopSignal) {
233             std::cout << "stop sliding animation in current translate " << nodeModifier->GetTranslate().data_[0] << ", "
234                       << nodeModifier->GetTranslate().data_[1] << endl;
235 
236             // set duration to 0
237             protocol.SetDuration(0);
238 
239             // create interrupt animation
240             RSNode::Animate(
241                 protocol, RSAnimationTimingCurve::EASE_IN_OUT,
242                 [&]() { nodeModifier->SetTranslate(nodeModifier->GetTranslate()); },
243                 [&]() {
244                     std::cout << "interrupt animation finish callback, the end translate is "
245                               << nodeModifier->GetTranslate().data_[0] << ", " << nodeModifier->GetTranslate().data_[1]
246                               << std::endl;
247                 });
248 
249             stopSignal = false;
250         }
251         startNum += 100000000;
252         usleep(100000);
253     }
254 
255     // dump property via modifiers
256     std::cout << "rs app demo stage " << cnt++ << std::endl;
257     std::cout << nodes[0]->GetStagingProperties().Dump() << std::endl;
258     std::cout << "rs app demo end!" << std::endl;
259     sleep(3);
260 
261     window->Hide();
262     window->Destroy();
263 #endif
264     return 0;
265 }