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_server.h"
17
18 #include <multimodal_event_handler.h>
19 #include <securec.h>
20
21 #include <cpudraw.h>
22 #include <scoped_bytrace.h>
23 #include <gslogger.h>
24
25 namespace OHOS {
26 namespace {
27 DEFINE_HILOG_LABEL("AnimationServer");
28 } // namespace
29
Init()30 GSError AnimationServer::Init()
31 {
32 handler = AppExecFwk::EventHandler::Current();
33 auto wm = WindowManager::GetInstance();
34 auto wret = wm->Init();
35 if (wret != GSERROR_OK) {
36 GSLOG2HI(ERROR) << "WindowManager::Init failed: " << GSErrorStr(wret);
37 return static_cast<enum GSError>(wret);
38 }
39
40 WindowManagerServiceClient::GetInstance()->Init();
41 animationModule.Init();
42
43 auto splitOption = WindowOption::Get();
44 splitOption->SetWindowType(WINDOW_TYPE_SPLIT_LINE);
45 wret = wm->CreateWindow(splitWindow, splitOption);
46 if (wret != GSERROR_OK || splitWindow == nullptr) {
47 GSLOG2HI(ERROR) << "WindowManager::CreateWindow failed: " << GSErrorStr(wret);
48 return static_cast<enum GSError>(wret);
49 }
50 splitWindow->Hide();
51 auto func = std::bind(&AnimationServer::OnSplitStatusChange, this, std::placeholders::_1);
52 splitWindow->OnSplitStatusChange(func);
53
54 auto launchPageOption = WindowOption::Get();
55 launchPageOption->SetWindowType(WINDOW_TYPE_LAUNCH_PAGE);
56 wret = wm->CreateWindow(launchPageWindow, launchPageOption);
57 if (wret != WM_OK || launchPageWindow == nullptr) {
58 GSLOG2HI(ERROR) << "WindowManager::CreateWindow failed: " << WMErrorStr(wret);
59 return static_cast<enum GSError>(wret);
60 }
61 launchPageWindow->Hide();
62 return GSERROR_OK;
63 }
64
StartRotationAnimation(int32_t did,int32_t degree)65 GSError AnimationServer::StartRotationAnimation(int32_t did, int32_t degree)
66 {
67 return animationModule.StartRotationAnimation(did, degree);
68 }
69
SplitModeCreateBackground()70 GSError AnimationServer::SplitModeCreateBackground()
71 {
72 ScopedBytrace trace(__func__);
73 GSLOG2HI(DEBUG);
74 splitWindow->Show();
75 splitWindow->SwitchTop();
76 return GSERROR_OK;
77 }
78
SplitModeCreateMiddleLine()79 GSError AnimationServer::SplitModeCreateMiddleLine()
80 {
81 ScopedBytrace trace(__func__);
82 GSLOG2HI(DEBUG);
83 midlineY = splitWindow->GetHeight() / 0x2 + splitWindow->GetY();
84 haveMiddleLine = true;
85 handler->PostTask(std::bind(&AnimationServer::SplitWindowUpdate, this));
86 return GSERROR_OK;
87 }
88
CreateLaunchPage(const std::string & filename)89 GSError AnimationServer::CreateLaunchPage(const std::string &filename)
90 {
91 GSLOG2HI(DEBUG);
92 auto ret = resource.Parse(filename);
93 if (ret) {
94 return GSERROR_INVALID_ARGUMENTS;
95 }
96
97 int32_t width = launchPageWindow->GetDestWidth();
98 int32_t height = launchPageWindow->GetDestHeight();
99
100 launchPageWindow->SwitchTop();
101 launchPageWindow->Show();
102 launchPageWindow->Resize(resource.GetWidth(), resource.GetHeight());
103 launchPageWindow->ScaleTo(width, height);
104
105 handler->PostTask(std::bind(&AnimationServer::LaunchPageWindowUpdate, this));
106 return GSERROR_OK;
107 }
108
CancelLaunchPage()109 GSError AnimationServer::CancelLaunchPage()
110 {
111 GSLOG2HI(DEBUG);
112 launchPageWindow->Hide();
113 return GSERROR_OK;
114 }
115
SplitWindowUpdate()116 void AnimationServer::SplitWindowUpdate()
117 {
118 ScopedBytrace trace(__func__);
119 sptr<SurfaceBuffer> buffer;
120 auto surf = splitWindow->GetSurface();
121 BufferRequestConfig rconfig = {
122 .width = surf->GetDefaultWidth(),
123 .height = surf->GetDefaultHeight(),
124 .strideAlignment = 0x8,
125 .format = PIXEL_FMT_RGBA_8888,
126 .usage = surf->GetDefaultUsage(),
127 .timeout = 0,
128 };
129
130 int releaseFence = -1;
131 GSError ret = surf->RequestBuffer(buffer, releaseFence, rconfig);
132 if (ret == GSERROR_NO_BUFFER) {
133 return;
134 } else if (ret != GSERROR_OK || buffer == nullptr) {
135 return;
136 }
137
138 auto addr = buffer->GetVirAddr();
139 if (addr == nullptr) {
140 surf->CancelBuffer(buffer);
141 return;
142 }
143
144 static int32_t count = 0;
145 SplitWindowDraw(reinterpret_cast<uint32_t *>(buffer->GetVirAddr()), rconfig.width, rconfig.height, count);
146 count++;
147
148 BufferFlushConfig fconfig = {
149 .damage = {
150 .w = rconfig.width,
151 .h = rconfig.height,
152 },
153 };
154 surf->FlushBuffer(buffer, -1, fconfig);
155 }
156
SplitWindowDraw(uint32_t * vaddr,uint32_t width,uint32_t height,uint32_t count)157 void AnimationServer::SplitWindowDraw(uint32_t *vaddr, uint32_t width, uint32_t height, uint32_t count)
158 {
159 ScopedBytrace trace(__func__);
160 GSLOG2HI(DEBUG) << "midlineY: " << midlineY << ", midlineDown: " << midlineDown;
161 Cpudraw draw(vaddr, width, height);
162
163 draw.SetColor(0xff000000);
164 draw.DrawRect(0, 0, width, height);
165 if (haveMiddleLine == false) {
166 draw.SetColor(0xff333333);
167 constexpr double left = 0.1;
168 constexpr double w = 0.8;
169 constexpr double top1 = 0.025;
170 constexpr double top2 = 0.575;
171 constexpr double h = 0.4;
172
173 draw.DrawRect(left * width, top1 * height, w * width, h * height);
174 draw.DrawRect(left * width, top2 * height, w * width, h * height);
175 } else {
176 auto midlineYlocal = midlineY - splitWindow->GetY();
177 draw.SetColor(midlineDown ? 0xffffffff : 0xffcccccc);
178 constexpr double lineHeight = 0.1;
179 draw.DrawRect(0, midlineYlocal - (int32_t)(height * lineHeight / 0x2), width, height * lineHeight);
180 }
181 }
182
OnSplitStatusChange(SplitStatus status)183 void AnimationServer::OnSplitStatusChange(SplitStatus status)
184 {
185 ScopedBytrace trace(__func__);
186 if (status == SPLIT_STATUS_DESTROY) {
187 splitWindow->Hide();
188 haveMiddleLine = false;
189 }
190 }
191
LaunchPageWindowUpdate()192 void AnimationServer::LaunchPageWindowUpdate()
193 {
194 auto surf = launchPageWindow->GetSurface();
195 sptr<SurfaceBuffer> buffer;
196 BufferRequestConfig rconfig = {
197 .width = launchPageWindow->GetWidth(),
198 .height = launchPageWindow->GetHeight(),
199 .strideAlignment = 0x8,
200 .format = PIXEL_FMT_RGBA_8888,
201 .usage = surf->GetDefaultUsage(),
202 .timeout = 0,
203 };
204
205 int releaseFence = -1;
206 SurfaceError ret = surf->RequestBuffer(buffer, releaseFence, rconfig);
207 if (ret == SURFACE_ERROR_NO_BUFFER) {
208 return;
209 } else if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
210 return;
211 }
212
213 auto addr = buffer->GetVirAddr();
214 if (addr == nullptr) {
215 surf->CancelBuffer(buffer);
216 return;
217 }
218
219 resource.GetNextData(reinterpret_cast<uint32_t *>(addr));
220 BufferFlushConfig fconfig = {
221 .damage = {
222 .w = rconfig.width,
223 .h = rconfig.height,
224 },
225 };
226 surf->FlushBuffer(buffer, -1, fconfig);
227 }
228 } // namespace OHOS
229