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