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