• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "animation_module.h"
17 
18 #include <cerrno>
19 
20 #include <gslogger.h>
21 #include <scoped_bytrace.h>
22 #include <securec.h>
23 
24 namespace OHOS {
25 namespace {
26 DEFINE_HILOG_LABEL("AnimationModule");
27 } // namespace
28 
Init()29 GSError AnimationModule::Init()
30 {
31     handler = AppExecFwk::EventHandler::Current();
32     vhelper = VsyncHelper::Current();
33     auto wm = WindowManager::GetInstance();
34     auto option = WindowOption::Get();
35     option->SetWindowType(WINDOW_TYPE_ANIMATION);
36     auto wret = wm->CreateWindow(window, option);
37     if (wret != GSERROR_OK || window == nullptr) {
38         GSLOG2HI(ERROR) << "WindowManager::CreateWindow failed: " << GSErrorStr(wret);
39         return wret;
40     }
41 
42     window->Hide();
43     auto producer = window->GetProducer();
44     return GSERROR_OK;
45 }
46 
StartRotationAnimation(int32_t did,int32_t degree)47 GSError AnimationModule::StartRotationAnimation(int32_t did, int32_t degree)
48 {
49     if (isAnimationRunning == false) {
50         struct Animation animation {
51             .degree = degree,
52             .retval = new Promise<GSError>(),
53         };
54         handler->PostTask(std::bind(&AnimationModule::StartAnimation, this, std::ref(animation)));
55         return animation.retval->Await();
56     }
57     return GSERROR_ANIMATION_RUNNING;
58 }
59 
OnScreenShot(const struct WMImageInfo & info)60 void AnimationModule::OnScreenShot(const struct WMImageInfo &info)
61 {
62     int32_t length = info.size;
63     struct AnimationScreenshotInfo ainfo = {
64         .wmimage = info,
65         .ptr = nullptr,
66     };
67     if (info.wret != GSERROR_OK) {
68         screenshotPromise->Resolve(ainfo);
69         return;
70     }
71 
72     ainfo.ptr = std::make_shared<struct Array>();
73     ainfo.ptr->ptr = std::make_unique<uint8_t[]>(length);
74     ainfo.wmimage.data = ainfo.ptr.get();
75     if (memcpy_s(ainfo.ptr->ptr.get(), length, info.data, info.size) != EOK) {
76         GSLOG2HI(ERROR) << "memcpy_s failed: " << strerror(errno);
77         ainfo.wmimage.wret = static_cast<enum GSError>(GSERROR_INTERNAL);
78         screenshotPromise->Resolve(ainfo);
79         return;
80     }
81 
82     screenshotPromise->Resolve(ainfo);
83 }
84 
StartAnimation(struct Animation & animation)85 void AnimationModule::StartAnimation(struct Animation &animation)
86 {
87     if (isAnimationRunning) {
88         animation.retval->Resolve(GSERROR_ANIMATION_RUNNING);
89         return;
90     }
91 
92     ScopedBytrace trace(__func__);
93     isAnimationRunning = true;
94     GSLOG2HI(INFO) << "Animation Start";
95     window->Hide();
96     auto wm = WindowManager::GetInstance();
97     screenshotPromise = new Promise<struct AnimationScreenshotInfo>();
98     wm->ListenNextScreenShot(0, this);
99     auto asinfo = screenshotPromise->Await();
100     if (asinfo.wmimage.wret) {
101         GSLOG2HI(ERROR) << "OnScreenShot failed: " << GSErrorStr(asinfo.wmimage.wret);
102         animation.retval->Resolve(static_cast<enum GSError>(asinfo.wmimage.wret));
103         isAnimationRunning = false;
104         return;
105     }
106 
107     window->Show();
108 
109     auto sret = eglSurface->InitContext();
110     if (sret != GSERROR_OK) {
111         GSLOG2HI(ERROR) << "EGLSurface InitContext failed: " << sret;
112         animation.retval->Resolve(static_cast<enum GSError>(sret));
113         isAnimationRunning = false;
114         return;
115     }
116 
117     ranimation = std::make_unique<RotationAnimation>();
118     constexpr int32_t rotationAnimationDuration = 500;
119     auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
120         std::chrono::steady_clock::now().time_since_epoch()).count();
121     struct RotationAnimationParam param = {
122         .data = asinfo.ptr,
123         .width = window->GetWidth(),
124         .height = window->GetHeight(),
125         .startTime = now,
126         .duration = rotationAnimationDuration,
127         .degree = animation.degree,
128     };
129     auto gret = ranimation->Init(param);
130     if (gret != GSERROR_OK) {
131         GSLOG2HI(ERROR) << "RotationAnimation Init failed: " << GSErrorStr(gret);
132         animation.retval->Resolve(gret);
133         isAnimationRunning = false;
134         return;
135     }
136 
137     struct FrameCallback cb = { .callback_ = std::bind(&AnimationModule::AnimationSync, this, SYNC_FUNC_ARG) };
138     animation.retval->Resolve(static_cast<enum GSError>(vhelper->RequestFrameCallback(cb)));
139 }
140 
AnimationSync(int64_t time,void * data)141 void AnimationModule::AnimationSync(int64_t time, void *data)
142 {
143     ScopedBytrace trace(__func__);
144     if (ranimation->Draw()) {
145         eglSurface->SwapBuffers();
146         struct FrameCallback cb = { .callback_ = std::bind(&AnimationModule::AnimationSync, this, SYNC_FUNC_ARG) };
147         vhelper->RequestFrameCallback(cb);
148         trace.End();
149     } else {
150         trace.End();
151         GSLOG2HI(INFO) << "Animation End";
152         window->Hide();
153         isAnimationRunning = false;
154     }
155 }
156 } // namespace OHOS
157