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