diff options
| author | 2014-10-22 09:00:49 -0700 | |
|---|---|---|
| committer | 2014-10-22 09:00:49 -0700 | |
| commit | 5a71f83227f0340a265f34b226d8fe01d4dd9773 (patch) | |
| tree | 9e74435ad8e21fe6ace6a1c49ca2f596c60ced34 /cmds/bootanimation/BootAnimation.cpp | |
| parent | 52656916e35b08013bf776b3603d6cecba287a1e (diff) | |
| parent | a0d07d49b8b0aae71beb48ec31b43f6923530d00 (diff) | |
Merge lmp-dev-plus-aosp-without-vendor into stage-aosp-master
Change-Id: I7063b7b52e9c09a57eb6bf3b4ffa3716d58ebf43
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 f3e3affe3793..167014e7c7a2 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> @@ -31,28 +32,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" @@ -96,6 +97,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, @@ -105,7 +109,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; @@ -124,20 +128,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; @@ -163,7 +167,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; } @@ -187,8 +191,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); @@ -200,7 +204,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); @@ -286,6 +290,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; @@ -388,29 +395,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 @@ -421,20 +475,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); } @@ -469,11 +532,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); + } } } } @@ -520,6 +588,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(); |