1 /*
2 * Copyright (c) 2024 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 "boot_animation_operation.h"
17
18 #include "boot_picture_player.h"
19 #include "boot_sound_player.h"
20 #include "boot_video_player.h"
21 #include "log.h"
22 #include <parameters.h>
23 #include "platform/common/rs_system_properties.h"
24 #include "transaction/rs_transaction.h"
25 #include "transaction/rs_interfaces.h"
26
27 using namespace OHOS;
28 static const int DELAY_TIME_MS = 1000;
29
~BootAnimationOperation()30 BootAnimationOperation::~BootAnimationOperation()
31 {
32 if (rsSurfaceNode_) {
33 rsSurfaceNode_->DetachToDisplay(currentScreenId_);
34 }
35 if (rsDisplayNode_) {
36 rsDisplayNode_->RemoveFromTree();
37 }
38 OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
39 }
40
Init(const BootAnimationConfig & config,int32_t width,int32_t height,int32_t duration)41 void BootAnimationOperation::Init(const BootAnimationConfig& config, int32_t width, int32_t height, int32_t duration)
42 {
43 LOGI("Init enter, width: %{public}d, height: %{public}d, screenId : " BPUBU64 "", width, height, config.screenId);
44 currentScreenId_ = config.screenId;
45 windowWidth_ = width;
46 windowHeight_ = height;
47 duration_ = duration * DELAY_TIME_MS;
48
49 eventThread_ = std::thread([this, &config] { this->StartEventHandler(config); });
50 }
51
StartEventHandler(const BootAnimationConfig & config)52 void BootAnimationOperation::StartEventHandler(const BootAnimationConfig& config)
53 {
54 LOGI("StartEventHandler");
55 runner_ = AppExecFwk::EventRunner::Create(false);
56 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
57 mainHandler_->PostTask([this] { this->InitRsDisplayNode(); });
58 mainHandler_->PostTask([this, &config] { this->InitRsSurfaceNode(config.rotateDegree); });
59 mainHandler_->PostTask([this] { this->StopBootAnimation(); }, duration_);
60 #ifdef PLAYER_FRAMEWORK_ENABLE
61 if (IsBootVideoEnabled(config)) {
62 mainHandler_->PostTask([this, &config] { this->PlayVideo(config.videoDefaultPath); });
63 runner_->Run();
64 LOGI("runner run has ended.");
65 return;
66 } else {
67 mainHandler_->PostTask([this, &config] { this->PlaySound(config.soundPath); });
68 }
69 #else
70 LOGI("player framework is disabled");
71 #endif
72 mainHandler_->PostTask([this, &config] { this->PlayPicture(config.picZipPath); });
73 runner_->Run();
74 LOGI("runner run has ended.");
75 }
76
SetSoundEnable(bool isEnabled)77 void BootAnimationOperation::SetSoundEnable(bool isEnabled)
78 {
79 isSoundEnabled_ = isEnabled;
80 }
81
GetThread()82 std::thread& BootAnimationOperation::GetThread()
83 {
84 return eventThread_;
85 }
86
InitRsDisplayNode()87 bool BootAnimationOperation::InitRsDisplayNode()
88 {
89 LOGI("InitRsDisplayNode start");
90 OHOS::Rosen::RSDisplayNodeConfig config = {currentScreenId_, false, 0};
91
92 rsDisplayNode_ = OHOS::Rosen::RSDisplayNode::Create(config);
93 if (rsDisplayNode_ == nullptr) {
94 LOGE("init display node failed");
95 return false;
96 }
97 rsDisplayNode_->SetDisplayOffset(0, 0);
98 rsDisplayNode_->SetFrame(0, 0, windowWidth_, windowHeight_);
99 rsDisplayNode_->SetBounds(0, 0, windowWidth_, windowHeight_);
100 rsDisplayNode_->SetBootAnimation(true);
101 // flush transaction
102 auto transactionProxy = OHOS::Rosen::RSTransactionProxy::GetInstance();
103 if (transactionProxy == nullptr) {
104 LOGE("transactionProxy is nullptr");
105 return false;
106 }
107 transactionProxy->FlushImplicitTransaction();
108 return true;
109 }
110
InitRsSurfaceNode(int32_t degree)111 bool BootAnimationOperation::InitRsSurfaceNode(int32_t degree)
112 {
113 LOGI("InitRsSurfaceNode start");
114 struct Rosen::RSSurfaceNodeConfig rsSurfaceNodeConfig;
115 rsSurfaceNodeConfig.SurfaceNodeName =
116 currentScreenId_ == 0 ? "BootAnimationNode" : "BootAnimationNodeExtra";
117 rsSurfaceNodeConfig.isSync = true;
118 Rosen::RSSurfaceNodeType rsSurfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
119 rsSurfaceNode_ = Rosen::RSSurfaceNode::Create(rsSurfaceNodeConfig, rsSurfaceNodeType);
120 if (!rsSurfaceNode_) {
121 LOGE("create rsSurfaceNode failed");
122 return false;
123 }
124 LOGI("rotation degree: %{public}d", degree);
125 rsSurfaceNode_->SetRotation(degree);
126 rsSurfaceNode_->SetPositionZ(MAX_ZORDER);
127 rsSurfaceNode_->SetBounds({0, 0, windowWidth_, windowHeight_});
128 rsSurfaceNode_->SetBackgroundColor(0xFF000000);
129 rsSurfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT);
130 rsSurfaceNode_->SetBootAnimation(true);
131 OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
132 rsSurfaceNode_->AttachToDisplay(currentScreenId_);
133 OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
134 if (!system::GetBoolParameter(BOOT_ANIMATION_READY, false)) {
135 system::SetParameter(BOOT_ANIMATION_READY, "true");
136 LOGI("set boot animation ready true");
137 }
138 return true;
139 }
140
PlayVideo(const std::string & path)141 void BootAnimationOperation::PlayVideo(const std::string& path)
142 {
143 LOGI("boot animation play video");
144 PlayerParams params;
145 #ifdef PLAYER_FRAMEWORK_ENABLE
146 params.surface = rsSurfaceNode_ ? rsSurfaceNode_->GetSurface() : nullptr;
147 #endif
148 params.resPath = path;
149 callback_ = {
150 .userData = this,
151 .callback = [this](void*) { this->StopBootAnimation(); },
152 };
153 params.callback = &callback_;
154 params.screenId = currentScreenId_;
155 params.soundEnabled = isSoundEnabled_;
156 videoPlayer_ = std::make_shared<BootVideoPlayer>(params);
157 videoPlayer_->Play();
158 }
159
PlayPicture(const std::string & path)160 void BootAnimationOperation::PlayPicture(const std::string& path)
161 {
162 LOGI("boot animation play sequence frames");
163 if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
164 system::SetParameter(BOOT_ANIMATION_STARTED, "true");
165 LOGI("set boot animation started true");
166 }
167
168 InitRsSurface();
169 PlayerParams params;
170 params.screenId = currentScreenId_;
171 params.rsSurface = rsSurface_;
172 params.resPath = path;
173 picPlayer_ = std::make_shared<BootPicturePlayer>(params);
174 picPlayer_->Play();
175 }
176
PlaySound(const std::string & path)177 void BootAnimationOperation::PlaySound(const std::string& path)
178 {
179 LOGI("boot animation play sound");
180 PlayerParams params;
181 params.resPath = path;
182 params.screenId = currentScreenId_;
183 params.soundEnabled = isSoundEnabled_;
184 soundPlayer_ = std::make_shared<BootSoundPlayer>(params);
185 soundPlayer_->Play();
186 }
187
InitRsSurface()188 bool BootAnimationOperation::InitRsSurface()
189 {
190 LOGI("InitRsSurface start");
191 #ifdef NEW_RENDER_CONTEXT
192 std::shared_ptr<OHOS::Rosen::RenderContextBase> renderContext =
193 Rosen::RenderContextBaseFactory::CreateRenderContext();
194 if (renderContext == nullptr) {
195 LOGE("create render context failed");
196 return false;
197 }
198 renderContext->Init();
199 std::shared_ptr<Rosen::DrawingContext> drawingContext = std::make_shared<Rosen::DrawingContext>(
200 renderContext->GetRenderType());
201 sptr<Surface> surface = rsSurfaceNode_->GetSurface();
202 drawingContext->SetUpDrawingContext();
203 rsSurface_ = Rosen::RSSurfaceFactory::CreateRSSurface(Rosen::PlatformName::OHOS, surface, drawingContext);
204 rsSurface_->SetRenderContext(renderContext);
205 #else
206 rsSurface_ = OHOS::Rosen::RSSurfaceExtractor::ExtractRSSurface(rsSurfaceNode_);
207 if (rsSurface_ == nullptr) {
208 LOGE("rsSurface is nullptr");
209 return false;
210 }
211 #ifdef ACE_ENABLE_GL
212 LOGI("init egl context start");
213 if (Rosen::RSSystemProperties::GetGpuApiType() == OHOS::Rosen::GpuApiType::OPENGL) {
214 OHOS::Rosen::RenderContext* rc = OHOS::Rosen::RenderContextFactory::GetInstance().CreateEngine();
215 if (rc == nullptr) {
216 LOGE("init egl context failed");
217 return false;
218 } else {
219 LOGI("init egl context success");
220 rc->InitializeEglContext();
221 rsSurface_->SetRenderContext(rc);
222 }
223 }
224 #endif // ACE_ENABLE_GL
225 #endif // NEW_RENDER_CONTEXT
226 return true;
227 }
228
IsBootVideoEnabled(const BootAnimationConfig & config)229 bool BootAnimationOperation::IsBootVideoEnabled(const BootAnimationConfig& config)
230 {
231 if (config.videoDefaultPath.empty() && !config.picZipPath.empty()) {
232 LOGI("video path is empty and picture path is not empty");
233 return false;
234 }
235
236 if (!IsFileExisted(config.videoDefaultPath)) {
237 LOGE("video file not found");
238 }
239 return true;
240 }
241
StopBootAnimation()242 void BootAnimationOperation::StopBootAnimation()
243 {
244 LOGI("StopBootAnimation");
245 if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
246 system::SetParameter(BOOT_ANIMATION_STARTED, "true");
247 LOGI("set boot animation started true");
248 }
249 runner_->Stop();
250 LOGI("runner has called stop.");
251 mainHandler_ = nullptr;
252 }
253