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