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