• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "ui/rs_ui_context.h"
27 
28 using namespace OHOS;
29 static const int DELAY_TIME_MS = 1000;
30 
~BootAnimationOperation()31 BootAnimationOperation::~BootAnimationOperation()
32 {
33     if (rsSurfaceNode_) {
34         rsSurfaceNode_->DetachToDisplay(currentScreenId_);
35     }
36     if (rsDisplayNode_) {
37         rsDisplayNode_->RemoveFromTree();
38     }
39     OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
40     LOGI("Release RsNode");
41 }
42 
Init(const BootAnimationConfig & config,int32_t width,int32_t height,int32_t duration)43 void BootAnimationOperation::Init(const BootAnimationConfig& config, int32_t width, int32_t height, int32_t duration)
44 {
45     LOGI("Init enter, width: %{public}d, height: %{public}d, screenId : " BPUBU64 "", width, height, config.screenId);
46     currentScreenId_ = config.screenId;
47     windowWidth_ = width;
48     windowHeight_ = height;
49     duration_ = duration * DELAY_TIME_MS;
50 
51     eventThread_ = std::thread([this, &config] { this->StartEventHandler(config); });
52 }
53 
StartEventHandler(const BootAnimationConfig & config)54 void BootAnimationOperation::StartEventHandler(const BootAnimationConfig& config)
55 {
56     LOGI("StartEventHandler");
57     runner_ = AppExecFwk::EventRunner::Create(false);
58     mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
59     mainHandler_->PostTask([this] { this->InitRsDisplayNode(); });
60     mainHandler_->PostTask([this, &config] { this->InitRsSurfaceNode(config.rotateDegree); });
61     mainHandler_->PostTask([this] { this->StopBootAnimation(); }, duration_);
62 #ifdef PLAYER_FRAMEWORK_ENABLE
63     if (IsBootVideoEnabled(config)) {
64         mainHandler_->PostTask([this, &config] { this->PlayVideo(config.videoDefaultPath); });
65         runner_->Run();
66         LOGI("runner run has ended.");
67         return;
68     } else {
69         mainHandler_->PostTask([this, &config] { this->PlaySound(config.soundPath); });
70     }
71 #else
72     LOGI("player framework is disabled");
73 #endif
74     mainHandler_->PostTask([this, &config] { this->PlayPicture(config.picZipPath); });
75     runner_->Run();
76     LOGI("runner run has ended.");
77 }
78 
SetSoundEnable(bool isEnabled)79 void BootAnimationOperation::SetSoundEnable(bool isEnabled)
80 {
81     isSoundEnabled_ = isEnabled;
82 }
83 
GetThread()84 std::thread& BootAnimationOperation::GetThread()
85 {
86     return eventThread_;
87 }
88 
InitRsDisplayNode()89 bool BootAnimationOperation::InitRsDisplayNode()
90 {
91     LOGI("InitRsDisplayNode start");
92     OHOS::Rosen::RSDisplayNodeConfig config = {currentScreenId_, false, 0};
93     rsUIDirector_ = OHOS::Rosen::RSUIDirector::Create();
94     rsUIDirector_->Init(false, false);
95     auto rsUIContext = rsUIDirector_->GetRSUIContext();
96     rsDisplayNode_ = OHOS::Rosen::RSDisplayNode::Create(config, rsUIContext);
97     if (rsDisplayNode_ == nullptr) {
98         LOGE("init display node failed");
99         return false;
100     }
101     rsDisplayNode_->SetDisplayOffset(0, 0);
102     rsDisplayNode_->SetFrame(0, 0, windowWidth_, windowHeight_);
103     rsDisplayNode_->SetBounds(0, 0, windowWidth_, windowHeight_);
104     rsDisplayNode_->SetBootAnimation(true);
105     if (rsUIContext != nullptr) {
106         auto transaction = rsUIContext->GetRSTransaction();
107         if (transaction == nullptr) {
108             LOGE("transaction is nullptr");
109             return false;
110         }
111         transaction->FlushImplicitTransaction();
112     } else {
113         auto transactionProxy = OHOS::Rosen::RSTransactionProxy::GetInstance();
114         if (transactionProxy == nullptr) {
115             LOGE("transactionProxy is nullptr");
116             return false;
117         }
118         transactionProxy->FlushImplicitTransaction();
119     }
120     return true;
121 }
122 
InitRsSurfaceNode(int32_t degree)123 bool BootAnimationOperation::InitRsSurfaceNode(int32_t degree)
124 {
125     LOGI("InitRsSurfaceNode start");
126     struct Rosen::RSSurfaceNodeConfig rsSurfaceNodeConfig;
127     rsSurfaceNodeConfig.SurfaceNodeName =
128         currentScreenId_ == 0 ? "BootAnimationNode" : "BootAnimationNodeExtra";
129     rsSurfaceNodeConfig.isSync = false;
130     Rosen::RSSurfaceNodeType rsSurfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
131     auto rsUIContext = rsUIDirector_->GetRSUIContext();
132     rsSurfaceNode_ = Rosen::RSSurfaceNode::Create(rsSurfaceNodeConfig, rsSurfaceNodeType, true, false, rsUIContext);
133     if (!rsSurfaceNode_) {
134         LOGE("create rsSurfaceNode failed");
135         return false;
136     }
137     LOGI("rotation degree: %{public}d", degree);
138     rsSurfaceNode_->SetRotation(degree);
139     rsSurfaceNode_->SetPositionZ(MAX_ZORDER);
140     rsSurfaceNode_->SetBounds({0, 0, windowWidth_, windowHeight_});
141     rsSurfaceNode_->SetBackgroundColor(0xFF000000);
142     rsSurfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT);
143     rsSurfaceNode_->SetBootAnimation(true);
144     OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
145     rsSurfaceNode_->AttachToDisplay(currentScreenId_);
146     OHOS::Rosen::RSTransaction::FlushImplicitTransaction();
147     if (!system::GetBoolParameter(BOOT_ANIMATION_READY, false)) {
148         system::SetParameter(BOOT_ANIMATION_READY, "true");
149         LOGI("set boot animation ready true");
150     }
151     return true;
152 }
153 
PlayVideo(const std::string & path)154 void BootAnimationOperation::PlayVideo(const std::string& path)
155 {
156     LOGI("boot animation play video");
157     PlayerParams params;
158 #ifdef PLAYER_FRAMEWORK_ENABLE
159     params.surface = rsSurfaceNode_ ? rsSurfaceNode_->GetSurface() : nullptr;
160 #endif
161     params.resPath = path;
162     callback_ = {
163         .userData = this,
164         .callback = [this](void*) { this->StopBootAnimation(); },
165     };
166     params.callback = &callback_;
167     params.screenId = currentScreenId_;
168     params.soundEnabled = isSoundEnabled_;
169     videoPlayer_ = std::make_shared<BootVideoPlayer>(params);
170     videoPlayer_->Play();
171 }
172 
PlayPicture(const std::string & path)173 void BootAnimationOperation::PlayPicture(const std::string& path)
174 {
175     LOGI("boot animation play sequence frames");
176     if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
177         system::SetParameter(BOOT_ANIMATION_STARTED, "true");
178         LOGI("set boot animation started true");
179     }
180 
181     if (!InitRsSurface()) {
182         runner_->Stop();
183         return;
184     }
185     PlayerParams params;
186     params.screenId = currentScreenId_;
187     params.rsSurface = rsSurface_;
188     params.resPath = path;
189     picPlayer_ = std::make_shared<BootPicturePlayer>(params);
190     picPlayer_->Play();
191 }
192 
PlaySound(const std::string & path)193 void BootAnimationOperation::PlaySound(const std::string& path)
194 {
195     LOGI("boot animation play sound");
196     PlayerParams params;
197     params.resPath = path;
198     params.screenId = currentScreenId_;
199     params.soundEnabled = isSoundEnabled_;
200     soundPlayer_ = std::make_shared<BootSoundPlayer>(params);
201     soundPlayer_->Play();
202 }
203 
InitRsSurface()204 bool BootAnimationOperation::InitRsSurface()
205 {
206     LOGI("InitRsSurface start");
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     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     return true;
236 }
237 
StopBootAnimation()238 void BootAnimationOperation::StopBootAnimation()
239 {
240     LOGI("StopBootAnimation");
241     if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
242         system::SetParameter(BOOT_ANIMATION_STARTED, "true");
243         LOGI("set boot animation started true");
244     }
245     runner_->Stop();
246     LOGI("runner has called stop.");
247     mainHandler_ = nullptr;
248 }
249