From d168891d421662aa2ed561a6657daf762a20fe53 Mon Sep 17 00:00:00 2001 From: Chiou-Hao Hsu Date: Mon, 13 Oct 2014 17:55:42 -0700 Subject: BootAnimation: Play boot/shutdown animation and music Add support to show customized boot and shut down animation, as well as music. Change-Id: I69c87640175a96a18833a763a34afd362bbfb487 Conflicts: cmds/bootanimation/Android.mk cmds/bootanimation/BootAnimation.cpp Bootanimation: Fix the low memory device oom when run boot animation Low memory device is easily to be oom when run boot animation. Here we do optimize the boot animation GL Texture only one frame needed. That is free timely and re-init it again. When in boot animation, the fps=15, so it is ok to do the delete and re-init. CRs-Fixed: 572325 Change-Id: I1e81c3d0f3600ac895f9bd7bd00a284f3d4b7d4c bootanimtion: fix no boot sound due to error file descriptor -wrong file descriptor passed to setDataSource(fd, offset, length) API and causes no sound -use the default setDataSource(httpService,url,header) to parse the file of boot sound CRs-Fixed: 731547 Change-Id: I437e7d797cd13b7f8f8e0fbf81d5de99c55c27d1 --- cmds/bootanimation/Android.mk | 3 +- cmds/bootanimation/BootAnimation.cpp | 283 ++++++++++++++++++++++++++++++++++- cmds/bootanimation/BootAnimation.h | 9 +- 3 files changed, 287 insertions(+), 8 deletions(-) (limited to 'cmds') diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk index cc3b6f8..a2d5675 100644 --- a/cmds/bootanimation/Android.mk +++ b/cmds/bootanimation/Android.mk @@ -23,7 +23,8 @@ LOCAL_SHARED_LIBRARIES := \ libEGL \ libGLESv1_CM \ libgui \ - libtinyalsa + libtinyalsa \ + libmedia ifeq ($(TARGET_CONTINUOUS_SPLASH_ENABLED),true) LOCAL_CFLAGS += -DCONTINUOUS_SPLASH diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 5b9ecd0..f7a75d3 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 The Android Open Source Project + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,8 @@ #include #include #include +#include +#include #include @@ -54,6 +57,10 @@ #include #include +#include +#include +#include + #include "BootAnimation.h" #include "AudioPlayer.h" @@ -62,6 +69,16 @@ #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip" #define THEME_BOOTANIMATION_FILE "/data/system/theme/bootanimation.zip" +#define OEM_SHUTDOWN_ANIMATION_FILE "/oem/media/shutdownanimation.zip" +#define SYSTEM_SHUTDOWN_ANIMATION_FILE "/system/media/shutdownanimation.zip" +#define SYSTEM_ENCRYPTED_SHUTDOWN_ANIMATION_FILE "/system/media/shutdownanimation-encrypted.zip" + +#define OEM_BOOT_MUSIC_FILE "/oem/media/boot.wav" +#define SYSTEM_BOOT_MUSIC_FILE "/system/media/boot.wav" + +#define OEM_SHUTDOWN_MUSIC_FILE "/oem/media/shutdown.wav" +#define SYSTEM_SHUTDOWN_MUSIC_FILE "/system/media/shutdown.wav" + #define EXIT_PROP_NAME "service.bootanim.exit" namespace android { @@ -70,6 +87,87 @@ static const int ANIM_ENTRY_NAME_MAX = 256; // --------------------------------------------------------------------------- +static pthread_mutex_t mp_lock; +static pthread_cond_t mp_cond; +static bool isMPlayerPrepared = false; +static bool isMPlayerCompleted = false; + +class MPlayerListener : public MediaPlayerListener +{ + void notify(int msg, int ext1, int ext2, const Parcel *obj) + { + switch (msg) { + case MEDIA_NOP: // interface test message + break; + case MEDIA_PREPARED: + pthread_mutex_lock(&mp_lock); + isMPlayerPrepared = true; + pthread_cond_signal(&mp_cond); + pthread_mutex_unlock(&mp_lock); + break; + case MEDIA_PLAYBACK_COMPLETE: + pthread_mutex_lock(&mp_lock); + isMPlayerCompleted = true; + pthread_cond_signal(&mp_cond); + pthread_mutex_unlock(&mp_lock); + break; + default: + break; + } + } +}; + +static long getFreeMemory(void) +{ + int fd = open("/proc/meminfo", O_RDONLY); + const char* const sums[] = { "MemFree:", "Cached:", NULL }; + const int sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 }; + int num = 2; + + if (fd < 0) { + ALOGW("Unable to open /proc/meminfo"); + return -1; + } + + char buffer[256]; + const int len = read(fd, buffer, sizeof(buffer)-1); + close(fd); + + if (len < 0) { + ALOGW("Unable to read /proc/meminfo"); + return -1; + } + buffer[len] = 0; + + size_t numFound = 0; + long mem = 0; + + char* p = buffer; + while (*p && numFound < num) { + int i = 0; + while (sums[i]) { + if (strncmp(p, sums[i], sumsLen[i]) == 0) { + p += sumsLen[i]; + while (*p == ' ') p++; + char* num = p; + while (*p >= '0' && *p <= '9') p++; + if (*p != 0) { + *p = 0; + p++; + if (*p == 0) p--; + } + mem += atoll(num); + numFound++; + break; + } + i++; + } + p++; + } + + return numFound > 0 ? mem : -1; +} + BootAnimation::BootAnimation() : Thread(false), mZip(NULL) { mSession = new SurfaceComposerClient(); @@ -289,12 +387,14 @@ status_t BootAnimation::readyToRun() { char decrypt[PROPERTY_VALUE_MAX]; property_get("vold.decrypt", decrypt, ""); + // Use customized resources for boot and showdown animation + // instead of system predefined boot animation files. bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt); ZipFileRO* zipFile = NULL; if ((encryptedAnimation && - (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && - ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) || + (access(getAnimationFileName(IMG_ENC), R_OK) == 0) && + ((zipFile = ZipFileRO::open(getAnimationFileName(IMG_ENC))) != NULL)) || ((access(THEME_BOOTANIMATION_FILE, R_OK) == 0) && ((zipFile = ZipFileRO::open(THEME_BOOTANIMATION_FILE)) != NULL)) || @@ -303,8 +403,13 @@ status_t BootAnimation::readyToRun() { ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) || ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && - ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) { + ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL)) || + ((access(getAnimationFileName(IMG_DATA), R_OK) == 0) && + ((zipFile = ZipFileRO::open(getAnimationFileName(IMG_DATA))) != NULL)) || + + ((access(getAnimationFileName(IMG_SYS), R_OK) == 0) && + ((zipFile = ZipFileRO::open(getAnimationFileName(IMG_SYS))) != NULL))) { mZip = zipFile; } @@ -458,6 +563,7 @@ bool BootAnimation::readFile(const char* name, String8& outString) bool BootAnimation::movie() { + char value[PROPERTY_VALUE_MAX]; String8 desString; if (!readFile("desc.txt", desString)) { @@ -589,11 +695,37 @@ bool BootAnimation::movie() Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); + pthread_mutex_init(&mp_lock, NULL); + pthread_cond_init(&mp_cond, NULL); + + property_get("persist.sys.silent", value, "null"); + if (strncmp(value, "1", 1) != 0) { + playBackgroundMusic(); + } for (size_t i=0 ; i 0) { + if (r > 0 && !needSaveMem) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { - if (part.count != 1) { + if (!needSaveMem && part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -670,17 +802,156 @@ bool BootAnimation::movie() } // free the textures for this part - if (part.count != 1) { + if (!needSaveMem && part.count != 1) { for (size_t j=0 ; j mp = new MediaPlayer(); + sp mListener = new MPlayerListener(); + if (mp != NULL) { + ALOGD("starting to play %s", fileName); + mp->setListener(mListener); + + if (mp->setDataSource(NULL, fileName, NULL) == NO_ERROR) { + mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); + mp->prepare(); + } else { + ALOGE("failed to setDataSource for %s", fileName); + return NULL; + } + + //waiting for media player is prepared. + pthread_mutex_lock(&mp_lock); + while (!isMPlayerPrepared) { + pthread_cond_wait(&mp_cond, &mp_lock); + } + pthread_mutex_unlock(&mp_lock); + + audio_devices_t device = AudioSystem::getDevicesForStream(AUDIO_STREAM_ENFORCED_AUDIBLE); + AudioSystem::initStreamVolume(AUDIO_STREAM_ENFORCED_AUDIBLE,0,7); + AudioSystem::setStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, 7, device); + + AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index, device); + if (index != 0) { + ALOGD("playing %s", fileName); + mp->seekTo(0); + mp->start(); + } else { + ALOGW("current volume is zero."); + } + } + return NULL; +} // --------------------------------------------------------------------------- } diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index f968b25..758f7f7 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -87,12 +87,18 @@ private: bool readFile(const char* name, String8& outString); bool movie(); + enum ImageID { IMG_DATA = 0, IMG_SYS = 1, IMG_ENC = 2 }; + char *getAnimationFileName(ImageID image); + char *getBootRingtoneFileName(ImageID image); + void playBackgroundMusic(); + bool checkBootState(); void checkExit(); + void checkShowAndroid(); sp mSession; sp mAudioPlayer; AssetManager mAssets; - Texture mAndroid[2]; + Texture mAndroid[3]; int mWidth; int mHeight; EGLDisplay mDisplay; @@ -103,6 +109,7 @@ private: ZipFileRO *mZip; }; +static void* playMusic(void* arg); // --------------------------------------------------------------------------- }; // namespace android -- cgit v1.1