xref: /aosp_15_r20/frameworks/base/cmds/bootanimation/BootAnimation.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2007 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #ifndef ANDROID_BOOTANIMATION_H
18*d57664e9SAndroid Build Coastguard Worker #define ANDROID_BOOTANIMATION_H
19*d57664e9SAndroid Build Coastguard Worker 
20*d57664e9SAndroid Build Coastguard Worker #include <vector>
21*d57664e9SAndroid Build Coastguard Worker #include <queue>
22*d57664e9SAndroid Build Coastguard Worker #include <climits>
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker #include <stdint.h>
25*d57664e9SAndroid Build Coastguard Worker #include <sys/types.h>
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker #include <androidfw/AssetManager.h>
28*d57664e9SAndroid Build Coastguard Worker #include <gui/DisplayEventReceiver.h>
29*d57664e9SAndroid Build Coastguard Worker #include <utils/Looper.h>
30*d57664e9SAndroid Build Coastguard Worker #include <utils/Thread.h>
31*d57664e9SAndroid Build Coastguard Worker #include <binder/IBinder.h>
32*d57664e9SAndroid Build Coastguard Worker 
33*d57664e9SAndroid Build Coastguard Worker #include <ui/Rotation.h>
34*d57664e9SAndroid Build Coastguard Worker #include <ui/LayerStack.h>
35*d57664e9SAndroid Build Coastguard Worker 
36*d57664e9SAndroid Build Coastguard Worker #include <EGL/egl.h>
37*d57664e9SAndroid Build Coastguard Worker #include <GLES2/gl2.h>
38*d57664e9SAndroid Build Coastguard Worker 
39*d57664e9SAndroid Build Coastguard Worker namespace android {
40*d57664e9SAndroid Build Coastguard Worker 
41*d57664e9SAndroid Build Coastguard Worker class Surface;
42*d57664e9SAndroid Build Coastguard Worker class SurfaceComposerClient;
43*d57664e9SAndroid Build Coastguard Worker class SurfaceControl;
44*d57664e9SAndroid Build Coastguard Worker 
45*d57664e9SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
46*d57664e9SAndroid Build Coastguard Worker 
47*d57664e9SAndroid Build Coastguard Worker class BootAnimation : public Thread, public IBinder::DeathRecipient
48*d57664e9SAndroid Build Coastguard Worker {
49*d57664e9SAndroid Build Coastguard Worker public:
50*d57664e9SAndroid Build Coastguard Worker     static constexpr int MAX_FADED_FRAMES_COUNT = std::numeric_limits<int>::max();
51*d57664e9SAndroid Build Coastguard Worker 
52*d57664e9SAndroid Build Coastguard Worker     struct Texture {
53*d57664e9SAndroid Build Coastguard Worker         GLint   w;
54*d57664e9SAndroid Build Coastguard Worker         GLint   h;
55*d57664e9SAndroid Build Coastguard Worker         GLuint  name;
56*d57664e9SAndroid Build Coastguard Worker     };
57*d57664e9SAndroid Build Coastguard Worker 
58*d57664e9SAndroid Build Coastguard Worker     struct Font {
59*d57664e9SAndroid Build Coastguard Worker         FileMap* map = nullptr;
60*d57664e9SAndroid Build Coastguard Worker         Texture texture;
61*d57664e9SAndroid Build Coastguard Worker         int char_width;
62*d57664e9SAndroid Build Coastguard Worker         int char_height;
63*d57664e9SAndroid Build Coastguard Worker     };
64*d57664e9SAndroid Build Coastguard Worker 
65*d57664e9SAndroid Build Coastguard Worker     struct Animation {
66*d57664e9SAndroid Build Coastguard Worker         struct Frame {
67*d57664e9SAndroid Build Coastguard Worker             String8 name;
68*d57664e9SAndroid Build Coastguard Worker             FileMap* map = nullptr;
69*d57664e9SAndroid Build Coastguard Worker             int trimX;
70*d57664e9SAndroid Build Coastguard Worker             int trimY;
71*d57664e9SAndroid Build Coastguard Worker             int trimWidth;
72*d57664e9SAndroid Build Coastguard Worker             int trimHeight;
73*d57664e9SAndroid Build Coastguard Worker             mutable GLuint tid;
74*d57664e9SAndroid Build Coastguard Worker             bool operator < (const Frame& rhs) const {
75*d57664e9SAndroid Build Coastguard Worker                 return name < rhs.name;
76*d57664e9SAndroid Build Coastguard Worker             }
77*d57664e9SAndroid Build Coastguard Worker         };
78*d57664e9SAndroid Build Coastguard Worker         struct Part {
79*d57664e9SAndroid Build Coastguard Worker             int count;  // The number of times this part should repeat, 0 for infinite
80*d57664e9SAndroid Build Coastguard Worker             int pause;  // The number of frames to pause for at the end of this part
81*d57664e9SAndroid Build Coastguard Worker             int clockPosX;  // The x position of the clock, in pixels. Positive values offset from
82*d57664e9SAndroid Build Coastguard Worker                             // the left of the screen, negative values offset from the right.
83*d57664e9SAndroid Build Coastguard Worker             int clockPosY;  // The y position of the clock, in pixels. Positive values offset from
84*d57664e9SAndroid Build Coastguard Worker                             // the bottom of the screen, negative values offset from the top.
85*d57664e9SAndroid Build Coastguard Worker                             // If either of the above are INT_MIN the clock is disabled, if INT_MAX
86*d57664e9SAndroid Build Coastguard Worker                             // the clock is centred on that axis.
87*d57664e9SAndroid Build Coastguard Worker             String8 path;
88*d57664e9SAndroid Build Coastguard Worker             String8 trimData;
89*d57664e9SAndroid Build Coastguard Worker             SortedVector<Frame> frames;
90*d57664e9SAndroid Build Coastguard Worker             bool playUntilComplete;
91*d57664e9SAndroid Build Coastguard Worker             int framesToFadeCount;
92*d57664e9SAndroid Build Coastguard Worker             float backgroundColor[3];
93*d57664e9SAndroid Build Coastguard Worker             uint8_t* audioData;
94*d57664e9SAndroid Build Coastguard Worker             int audioLength;
95*d57664e9SAndroid Build Coastguard Worker             Animation* animation;
96*d57664e9SAndroid Build Coastguard Worker             // Controls if dynamic coloring is enabled for this part.
97*d57664e9SAndroid Build Coastguard Worker             bool useDynamicColoring = false;
98*d57664e9SAndroid Build Coastguard Worker             // Defines if this part is played after the dynamic coloring part.
99*d57664e9SAndroid Build Coastguard Worker             bool postDynamicColoring = false;
100*d57664e9SAndroid Build Coastguard Worker 
hasFadingPhaseAnimation::Part101*d57664e9SAndroid Build Coastguard Worker             bool hasFadingPhase() const {
102*d57664e9SAndroid Build Coastguard Worker                 return !playUntilComplete && framesToFadeCount > 0;
103*d57664e9SAndroid Build Coastguard Worker             }
104*d57664e9SAndroid Build Coastguard Worker         };
105*d57664e9SAndroid Build Coastguard Worker         int fps;
106*d57664e9SAndroid Build Coastguard Worker         int width;
107*d57664e9SAndroid Build Coastguard Worker         int height;
108*d57664e9SAndroid Build Coastguard Worker         bool progressEnabled;
109*d57664e9SAndroid Build Coastguard Worker         Vector<Part> parts;
110*d57664e9SAndroid Build Coastguard Worker         String8 audioConf;
111*d57664e9SAndroid Build Coastguard Worker         String8 fileName;
112*d57664e9SAndroid Build Coastguard Worker         ZipFileRO* zip;
113*d57664e9SAndroid Build Coastguard Worker         Font clockFont;
114*d57664e9SAndroid Build Coastguard Worker         Font progressFont;
115*d57664e9SAndroid Build Coastguard Worker          // Controls if dynamic coloring is enabled for the whole animation.
116*d57664e9SAndroid Build Coastguard Worker         bool dynamicColoringEnabled = false;
117*d57664e9SAndroid Build Coastguard Worker         int colorTransitionStart = 0; // Start frame of dynamic color transition.
118*d57664e9SAndroid Build Coastguard Worker         int colorTransitionEnd = 0; // End frame of dynamic color transition.
119*d57664e9SAndroid Build Coastguard Worker         float startColors[4][3]; // Start colors of dynamic color transition.
120*d57664e9SAndroid Build Coastguard Worker         float endColors[4][3];   // End colors of dynamic color transition.
121*d57664e9SAndroid Build Coastguard Worker     };
122*d57664e9SAndroid Build Coastguard Worker 
123*d57664e9SAndroid Build Coastguard Worker     // Collects all attributes that must be tracked per physical display.
124*d57664e9SAndroid Build Coastguard Worker     struct Display {
125*d57664e9SAndroid Build Coastguard Worker         int width;
126*d57664e9SAndroid Build Coastguard Worker         int height;
127*d57664e9SAndroid Build Coastguard Worker         int initWidth;
128*d57664e9SAndroid Build Coastguard Worker         int initHeight;
129*d57664e9SAndroid Build Coastguard Worker         EGLDisplay  eglSurface;
130*d57664e9SAndroid Build Coastguard Worker         sp<IBinder> displayToken;
131*d57664e9SAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl;
132*d57664e9SAndroid Build Coastguard Worker         sp<Surface> surface;
133*d57664e9SAndroid Build Coastguard Worker     };
134*d57664e9SAndroid Build Coastguard Worker 
135*d57664e9SAndroid Build Coastguard Worker     // All callbacks will be called from this class's internal thread.
136*d57664e9SAndroid Build Coastguard Worker     class Callbacks : public RefBase {
137*d57664e9SAndroid Build Coastguard Worker     public:
138*d57664e9SAndroid Build Coastguard Worker         // Will be called during initialization after we have loaded
139*d57664e9SAndroid Build Coastguard Worker         // the animation and be provided with all parts in animation.
init(const Vector<Animation::Part> &)140*d57664e9SAndroid Build Coastguard Worker         virtual void init(const Vector<Animation::Part>& /*parts*/) {}
141*d57664e9SAndroid Build Coastguard Worker 
142*d57664e9SAndroid Build Coastguard Worker         // Will be called while animation is playing before each part is
143*d57664e9SAndroid Build Coastguard Worker         // played. It will be provided with the part and play count for it.
144*d57664e9SAndroid Build Coastguard Worker         // It will be provided with the partNumber for the part about to be played,
145*d57664e9SAndroid Build Coastguard Worker         // as well as a reference to the part itself. It will also be provided with
146*d57664e9SAndroid Build Coastguard Worker         // which play of that part is about to start, some parts are repeated
147*d57664e9SAndroid Build Coastguard Worker         // multiple times.
playPart(int,const Animation::Part &,int)148*d57664e9SAndroid Build Coastguard Worker         virtual void playPart(int /*partNumber*/, const Animation::Part& /*part*/,
149*d57664e9SAndroid Build Coastguard Worker                               int /*playNumber*/) {}
150*d57664e9SAndroid Build Coastguard Worker 
151*d57664e9SAndroid Build Coastguard Worker         // Will be called when animation is done and thread is shutting down.
shutdown()152*d57664e9SAndroid Build Coastguard Worker         virtual void shutdown() {}
153*d57664e9SAndroid Build Coastguard Worker     };
154*d57664e9SAndroid Build Coastguard Worker 
155*d57664e9SAndroid Build Coastguard Worker     explicit BootAnimation(sp<Callbacks> callbacks);
156*d57664e9SAndroid Build Coastguard Worker     virtual ~BootAnimation();
157*d57664e9SAndroid Build Coastguard Worker 
158*d57664e9SAndroid Build Coastguard Worker     sp<SurfaceComposerClient> session() const;
159*d57664e9SAndroid Build Coastguard Worker 
160*d57664e9SAndroid Build Coastguard Worker private:
161*d57664e9SAndroid Build Coastguard Worker     virtual bool        threadLoop();
162*d57664e9SAndroid Build Coastguard Worker     virtual status_t    readyToRun();
163*d57664e9SAndroid Build Coastguard Worker     virtual void        onFirstRef();
164*d57664e9SAndroid Build Coastguard Worker     virtual void        binderDied(const wp<IBinder>& who);
165*d57664e9SAndroid Build Coastguard Worker 
166*d57664e9SAndroid Build Coastguard Worker     bool                updateIsTimeAccurate();
167*d57664e9SAndroid Build Coastguard Worker 
168*d57664e9SAndroid Build Coastguard Worker     class TimeCheckThread : public Thread {
169*d57664e9SAndroid Build Coastguard Worker     public:
170*d57664e9SAndroid Build Coastguard Worker         explicit TimeCheckThread(BootAnimation* bootAnimation);
171*d57664e9SAndroid Build Coastguard Worker         virtual ~TimeCheckThread();
172*d57664e9SAndroid Build Coastguard Worker     private:
173*d57664e9SAndroid Build Coastguard Worker         virtual status_t    readyToRun();
174*d57664e9SAndroid Build Coastguard Worker         virtual bool        threadLoop();
175*d57664e9SAndroid Build Coastguard Worker         bool                doThreadLoop();
176*d57664e9SAndroid Build Coastguard Worker         void                addTimeDirWatch();
177*d57664e9SAndroid Build Coastguard Worker 
178*d57664e9SAndroid Build Coastguard Worker         int mInotifyFd;
179*d57664e9SAndroid Build Coastguard Worker         int mBootAnimWd;
180*d57664e9SAndroid Build Coastguard Worker         int mTimeWd;
181*d57664e9SAndroid Build Coastguard Worker         BootAnimation* mBootAnimation;
182*d57664e9SAndroid Build Coastguard Worker     };
183*d57664e9SAndroid Build Coastguard Worker 
184*d57664e9SAndroid Build Coastguard Worker     // Display event handling
185*d57664e9SAndroid Build Coastguard Worker     class DisplayEventCallback;
186*d57664e9SAndroid Build Coastguard Worker     std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver;
187*d57664e9SAndroid Build Coastguard Worker     sp<Looper> mLooper;
188*d57664e9SAndroid Build Coastguard Worker     int displayEventCallback(int fd, int events, void* data);
189*d57664e9SAndroid Build Coastguard Worker     void processDisplayEvents();
190*d57664e9SAndroid Build Coastguard Worker 
191*d57664e9SAndroid Build Coastguard Worker     status_t initTexture(Texture* texture, AssetManager& asset, const char* name,
192*d57664e9SAndroid Build Coastguard Worker         bool premultiplyAlpha = true);
193*d57664e9SAndroid Build Coastguard Worker     status_t initTexture(FileMap* map, int* width, int* height,
194*d57664e9SAndroid Build Coastguard Worker         bool premultiplyAlpha = true);
195*d57664e9SAndroid Build Coastguard Worker     status_t initFont(Font* font, const char* fallback);
196*d57664e9SAndroid Build Coastguard Worker     void initShaders();
197*d57664e9SAndroid Build Coastguard Worker     bool android(const Display& display);
198*d57664e9SAndroid Build Coastguard Worker     status_t initDisplaysAndSurfaces();
199*d57664e9SAndroid Build Coastguard Worker     bool movie();
200*d57664e9SAndroid Build Coastguard Worker     void drawText(const char* str, const Font& font, bool bold,
201*d57664e9SAndroid Build Coastguard Worker                   int* x, int* y, const Display& display);
202*d57664e9SAndroid Build Coastguard Worker     void drawClock(const Font& font, const int xPos, const int yPos, const Display& display);
203*d57664e9SAndroid Build Coastguard Worker     void drawProgress(int percent, const Font& font,
204*d57664e9SAndroid Build Coastguard Worker                       const int xPos, const int yPos, const Display& display);
205*d57664e9SAndroid Build Coastguard Worker     void fadeFrame(int frameLeft, int frameBottom, int frameWidth, int frameHeight,
206*d57664e9SAndroid Build Coastguard Worker                    const Animation::Part& part, int fadedFramesCount);
207*d57664e9SAndroid Build Coastguard Worker     void drawTexturedQuad(float xStart, float yStart,
208*d57664e9SAndroid Build Coastguard Worker                           float width, float height, const Display& display);
209*d57664e9SAndroid Build Coastguard Worker     bool validClock(const Animation::Part& part);
210*d57664e9SAndroid Build Coastguard Worker     Animation* loadAnimation(const String8&);
211*d57664e9SAndroid Build Coastguard Worker     bool playAnimation(const Animation&);
212*d57664e9SAndroid Build Coastguard Worker     void releaseAnimation(Animation*) const;
213*d57664e9SAndroid Build Coastguard Worker     bool parseAnimationDesc(Animation&);
214*d57664e9SAndroid Build Coastguard Worker     bool preloadZip(Animation &animation);
215*d57664e9SAndroid Build Coastguard Worker     void findBootAnimationFile();
216*d57664e9SAndroid Build Coastguard Worker     bool findBootAnimationFileInternal(const std::vector<std::string>& files);
217*d57664e9SAndroid Build Coastguard Worker     bool preloadAnimation();
218*d57664e9SAndroid Build Coastguard Worker     EGLConfig getEglConfig(const EGLDisplay&);
219*d57664e9SAndroid Build Coastguard Worker     ui::Size limitSurfaceSize(int width, int height) const;
220*d57664e9SAndroid Build Coastguard Worker     void resizeSurface(int newWidth, int newHeight, Display& display);
221*d57664e9SAndroid Build Coastguard Worker     void projectSceneToWindow(const Display& display);
222*d57664e9SAndroid Build Coastguard Worker     void rotateAwayFromNaturalOrientationIfNeeded(Display& display);
223*d57664e9SAndroid Build Coastguard Worker     ui::Rotation parseOrientationProperty();
224*d57664e9SAndroid Build Coastguard Worker     void configureDisplayAndLayerStack(const Display& display, ui::LayerStack layerStack);
225*d57664e9SAndroid Build Coastguard Worker 
226*d57664e9SAndroid Build Coastguard Worker     bool shouldStopPlayingPart(const Animation::Part& part, int fadedFramesCount,
227*d57664e9SAndroid Build Coastguard Worker                                int lastDisplayedProgress);
228*d57664e9SAndroid Build Coastguard Worker     void checkExit();
229*d57664e9SAndroid Build Coastguard Worker 
230*d57664e9SAndroid Build Coastguard Worker     void handleViewport(nsecs_t timestep, const Display& display);
231*d57664e9SAndroid Build Coastguard Worker     void initDynamicColors();
232*d57664e9SAndroid Build Coastguard Worker 
233*d57664e9SAndroid Build Coastguard Worker     sp<SurfaceComposerClient>       mSession;
234*d57664e9SAndroid Build Coastguard Worker     AssetManager mAssets;
235*d57664e9SAndroid Build Coastguard Worker     Texture     mAndroid[2];
236*d57664e9SAndroid Build Coastguard Worker     int         mMaxWidth = 0;
237*d57664e9SAndroid Build Coastguard Worker     int         mMaxHeight = 0;
238*d57664e9SAndroid Build Coastguard Worker     int         mCurrentInset;
239*d57664e9SAndroid Build Coastguard Worker     int         mTargetInset;
240*d57664e9SAndroid Build Coastguard Worker     bool        mUseNpotTextures = false;
241*d57664e9SAndroid Build Coastguard Worker     EGLDisplay  mEgl;
242*d57664e9SAndroid Build Coastguard Worker     EGLDisplay  mEglContext;
243*d57664e9SAndroid Build Coastguard Worker     // Per-Display Attributes (to support multi-display)
244*d57664e9SAndroid Build Coastguard Worker     std::vector<Display> mDisplays;
245*d57664e9SAndroid Build Coastguard Worker     bool        mClockEnabled;
246*d57664e9SAndroid Build Coastguard Worker     bool        mTimeIsAccurate;
247*d57664e9SAndroid Build Coastguard Worker     bool        mTimeFormat12Hour;
248*d57664e9SAndroid Build Coastguard Worker     bool        mShuttingDown;
249*d57664e9SAndroid Build Coastguard Worker     bool        mDynamicColorsApplied = false;
250*d57664e9SAndroid Build Coastguard Worker     String8     mZipFileName;
251*d57664e9SAndroid Build Coastguard Worker     SortedVector<String8> mLoadedFiles;
252*d57664e9SAndroid Build Coastguard Worker     sp<TimeCheckThread> mTimeCheckThread = nullptr;
253*d57664e9SAndroid Build Coastguard Worker     sp<Callbacks> mCallbacks;
254*d57664e9SAndroid Build Coastguard Worker     Animation* mAnimation = nullptr;
255*d57664e9SAndroid Build Coastguard Worker     GLuint mImageShader;
256*d57664e9SAndroid Build Coastguard Worker     GLuint mTextShader;
257*d57664e9SAndroid Build Coastguard Worker     GLuint mImageFadeLocation;
258*d57664e9SAndroid Build Coastguard Worker     GLuint mImageTextureLocation;
259*d57664e9SAndroid Build Coastguard Worker     GLuint mTextCropAreaLocation;
260*d57664e9SAndroid Build Coastguard Worker     GLuint mTextTextureLocation;
261*d57664e9SAndroid Build Coastguard Worker     GLuint mImageColorProgressLocation;
262*d57664e9SAndroid Build Coastguard Worker };
263*d57664e9SAndroid Build Coastguard Worker 
264*d57664e9SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
265*d57664e9SAndroid Build Coastguard Worker 
266*d57664e9SAndroid Build Coastguard Worker }; // namespace android
267*d57664e9SAndroid Build Coastguard Worker 
268*d57664e9SAndroid Build Coastguard Worker #endif // ANDROID_BOOTANIMATION_H
269