diff options
Diffstat (limited to 'cmds/bootanimation/BootAnimation.cpp')
-rw-r--r-- | cmds/bootanimation/BootAnimation.cpp | 145 |
1 files changed, 112 insertions, 33 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 7f7ae2c..b2474f2 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#define LOG_NDEBUG 0 #define LOG_TAG "BootAnimation" #include <stdint.h> @@ -30,28 +31,28 @@ #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Log.h> -#include <utils/threads.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <ui/Region.h> #include <ui/DisplayInfo.h> -#include <ui/FramebufferNativeWindow.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> -#include <core/SkBitmap.h> -#include <core/SkStream.h> -#include <core/SkImageDecoder.h> +#include <SkBitmap.h> +#include <SkStream.h> +#include <SkImageDecoder.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <EGL/eglext.h> #include "BootAnimation.h" +#include "AudioPlayer.h" +#define OEM_BOOTANIMATION_FILE "/oem/media/bootanimation.zip" #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip" #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip" #define EXIT_PROP_NAME "service.bootanim.exit" @@ -99,6 +100,9 @@ void BootAnimation::binderDied(const wp<IBinder>&) // might be blocked on a condition variable that will never be updated. kill( getpid(), SIGKILL ); requestExit(); + if (mAudioPlayer != NULL) { + mAudioPlayer->requestExit(); + } } status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, @@ -108,7 +112,7 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, return NO_INIT; SkBitmap bitmap; SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(), - &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode); + &bitmap, kUnknown_SkColorType, SkImageDecoder::kDecodePixels_Mode); asset->close(); delete asset; @@ -127,20 +131,20 @@ status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, glGenTextures(1, &texture->name); glBindTexture(GL_TEXTURE_2D, texture->name); - switch (bitmap.getConfig()) { - case SkBitmap::kA8_Config: + switch (bitmap.colorType()) { + case kAlpha_8_SkColorType: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, p); break; - case SkBitmap::kARGB_4444_Config: + case kARGB_4444_SkColorType: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p); break; - case SkBitmap::kARGB_8888_Config: + case kN32_SkColorType: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, p); break; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p); break; @@ -166,7 +170,7 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame) if (codec) { codec->setDitherImage(false); codec->decode(&stream, &bitmap, - SkBitmap::kARGB_8888_Config, + kN32_SkColorType, SkImageDecoder::kDecodePixels_Mode); delete codec; } @@ -190,8 +194,8 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame) if (tw < w) tw <<= 1; if (th < h) th <<= 1; - switch (bitmap.getConfig()) { - case SkBitmap::kARGB_8888_Config: + switch (bitmap.colorType()) { + case kN32_SkColorType: if (tw != w || th != h) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); @@ -203,7 +207,7 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame) } break; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: if (tw != w || th != h) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); @@ -289,6 +293,9 @@ status_t BootAnimation::readyToRun() { (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) || + ((access(OEM_BOOTANIMATION_FILE, R_OK) == 0) && + ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) || + ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) { mZip = zipFile; @@ -391,29 +398,76 @@ void BootAnimation::checkExit() { int exitnow = atoi(value); if (exitnow) { requestExit(); + if (mAudioPlayer != NULL) { + mAudioPlayer->requestExit(); + } } } -bool BootAnimation::movie() +// Parse a color represented as an HTML-style 'RRGGBB' string: each pair of +// characters in str is a hex number in [0, 255], which are converted to +// floating point values in the range [0.0, 1.0] and placed in the +// corresponding elements of color. +// +// If the input string isn't valid, parseColor returns false and color is +// left unchanged. +static bool parseColor(const char str[7], float color[3]) { + float tmpColor[3]; + for (int i = 0; i < 3; i++) { + int val = 0; + for (int j = 0; j < 2; j++) { + val *= 16; + char c = str[2*i + j]; + if (c >= '0' && c <= '9') val += c - '0'; + else if (c >= 'A' && c <= 'F') val += (c - 'A') + 10; + else if (c >= 'a' && c <= 'f') val += (c - 'a') + 10; + else return false; + } + tmpColor[i] = static_cast<float>(val) / 255.0f; + } + memcpy(color, tmpColor, sizeof(tmpColor)); + return true; +} + +bool BootAnimation::readFile(const char* name, String8& outString) { - ZipEntryRO desc = mZip->findEntryByName("desc.txt"); - ALOGE_IF(!desc, "couldn't find desc.txt"); - if (!desc) { + ZipEntryRO entry = mZip->findEntryByName(name); + ALOGE_IF(!entry, "couldn't find %s", name); + if (!entry) { return false; } - FileMap* descMap = mZip->createEntryFileMap(desc); - mZip->releaseEntry(desc); - ALOGE_IF(!descMap, "descMap is null"); - if (!descMap) { + FileMap* entryMap = mZip->createEntryFileMap(entry); + mZip->releaseEntry(entry); + ALOGE_IF(!entryMap, "entryMap is null"); + if (!entryMap) { return false; } - String8 desString((char const*)descMap->getDataPtr(), - descMap->getDataLength()); - descMap->release(); + outString.setTo((char const*)entryMap->getDataPtr(), entryMap->getDataLength()); + entryMap->release(); + return true; +} + +bool BootAnimation::movie() +{ + String8 desString; + + if (!readFile("desc.txt", desString)) { + return false; + } char const* s = desString.string(); + // Create and initialize an AudioPlayer if we have an audio_conf.txt file + String8 audioConf; + if (readFile("audio_conf.txt", audioConf)) { + mAudioPlayer = new AudioPlayer; + if (!mAudioPlayer->init(audioConf.string())) { + ALOGE("mAudioPlayer.init failed"); + mAudioPlayer = NULL; + } + } + Animation animation; // Parse the description file @@ -424,20 +478,29 @@ bool BootAnimation::movie() const char* l = line.string(); int fps, width, height, count, pause; char path[ANIM_ENTRY_NAME_MAX]; + char color[7] = "000000"; // default to black if unspecified + char pathType; if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { - //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); + // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps); animation.width = width; animation.height = height; animation.fps = fps; } - else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) { - //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path); + else if (sscanf(l, " %c %d %d %s #%6s", &pathType, &count, &pause, path, color) >= 4) { + // ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s", pathType, count, pause, path, color); Animation::Part part; part.playUntilComplete = pathType == 'c'; part.count = count; part.pause = pause; part.path = path; + part.audioFile = NULL; + if (!parseColor(color, part.backgroundColor)) { + ALOGE("> invalid color '#%s'", color); + part.backgroundColor[0] = 0.0f; + part.backgroundColor[1] = 0.0f; + part.backgroundColor[2] = 0.0f; + } animation.parts.add(part); } @@ -472,11 +535,16 @@ bool BootAnimation::movie() if (method == ZipFileRO::kCompressStored) { FileMap* map = mZip->createEntryFileMap(entry); if (map) { - Animation::Frame frame; - frame.name = leaf; - frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); - part.frames.add(frame); + if (leaf == "audio.wav") { + // a part may have at most one audio file + part.audioFile = map; + } else { + Animation::Frame frame; + frame.name = leaf; + frame.map = map; + part.frames.add(frame); + } } } } @@ -523,6 +591,17 @@ bool BootAnimation::movie() if(exitPending() && !part.playUntilComplete) break; + // only play audio file the first time we animate the part + if (r == 0 && mAudioPlayer != NULL && part.audioFile) { + mAudioPlayer->playFile(part.audioFile); + } + + glClearColor( + part.backgroundColor[0], + part.backgroundColor[1], + part.backgroundColor[2], + 1.0f); + for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) { const Animation::Frame& frame(part.frames[j]); nsecs_t lastFrame = systemTime(); |