summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'cmds')
-rw-r--r--cmds/bootanimation/Android.mk3
-rw-r--r--cmds/bootanimation/BootAnimation.cpp283
-rw-r--r--cmds/bootanimation/BootAnimation.h9
3 files changed, 287 insertions, 8 deletions
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 <utils/misc.h>
#include <signal.h>
#include <time.h>
+#include <pthread.h>
+#include <sys/select.h>
#include <cutils/properties.h>
@@ -54,6 +57,10 @@
#include <GLES/glext.h>
#include <EGL/eglext.h>
+#include <media/AudioSystem.h>
+#include <media/mediaplayer.h>
+#include <media/IMediaHTTPService.h>
+
#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<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
glBindTexture(GL_TEXTURE_2D, 0);
+ /*calculate if we need to runtime save memory
+ * condition: runtime free memory is less than the textures that will used.
+ * needSaveMem default to be false
+ */
+ GLint mMaxTextureSize;
+ bool needSaveMem = false;
+ GLuint mTextureid;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ //ALOGD("freemem:%ld, %d", getFreeMemory(), mMaxTextureSize);
+ if(getFreeMemory() < mMaxTextureSize * mMaxTextureSize * fcount / 1024) {
+ ALOGD("Use save memory method, maybe small fps in actual.");
+ needSaveMem = true;
+ glGenTextures(1, &mTextureid);
+ glBindTexture(GL_TEXTURE_2D, mTextureid);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ }
+
for (int r=0 ; !part.count || r<part.count ; r++) {
// Exit any non playuntil complete parts immediately
if(exitPending() && !part.playUntilComplete)
@@ -614,10 +746,10 @@ bool BootAnimation::movie()
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime();
- if (r > 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<fcount ; j++) {
const Animation::Frame& frame(part.frames[j]);
glDeleteTextures(1, &frame.tid);
}
}
+
+ if (needSaveMem) {
+ glDeleteTextures(1, &mTextureid);
+ }
+
+ }
+
+ ALOGD("waiting for media player to complete.");
+ struct timespec timeout;
+ clock_gettime(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += 5; //timeout after 5s.
+
+ pthread_mutex_lock(&mp_lock);
+ while (!isMPlayerCompleted) {
+ int err = pthread_cond_timedwait(&mp_cond, &mp_lock, &timeout);
+ if (err == ETIMEDOUT) {
+ break;
+ }
}
+ pthread_mutex_unlock(&mp_lock);
+ ALOGD("media player is completed.");
+
+ pthread_cond_destroy(&mp_cond);
+ pthread_mutex_destroy(&mp_lock);
return false;
}
+char *BootAnimation::getAnimationFileName(ImageID image)
+{
+ char *fileName[2][3] = { { OEM_BOOTANIMATION_FILE,
+ SYSTEM_BOOTANIMATION_FILE,
+ SYSTEM_ENCRYPTED_BOOTANIMATION_FILE }, {
+ OEM_SHUTDOWN_ANIMATION_FILE,
+ SYSTEM_SHUTDOWN_ANIMATION_FILE,
+ SYSTEM_ENCRYPTED_SHUTDOWN_ANIMATION_FILE} };
+ int state;
+
+ state = checkBootState() ? 0 : 1;
+
+ return fileName[state][image];
+}
+
+char *BootAnimation::getBootRingtoneFileName(ImageID image)
+{
+ if (image == IMG_ENC) {
+ return NULL;
+ }
+
+ char *fileName[2][2] = { { OEM_BOOT_MUSIC_FILE,
+ SYSTEM_BOOT_MUSIC_FILE }, {
+ OEM_SHUTDOWN_MUSIC_FILE,
+ SYSTEM_SHUTDOWN_MUSIC_FILE } };
+ int state;
+
+ state = checkBootState() ? 0 : 1;
+
+ return fileName[state][image];
+}
+
+
+void BootAnimation::playBackgroundMusic(void)
+{
+ //Shutdown music is playing in ShutdownThread.java
+ if (!checkBootState()) {
+ return;
+ }
+
+ /* Make sure sound cards are populated */
+ FILE* fp = NULL;
+ if ((fp = fopen("/proc/asound/cards", "r")) == NULL) {
+ ALOGW("Cannot open /proc/asound/cards file to get sound card info.");
+ }
+
+ char value[PROPERTY_VALUE_MAX];
+ property_get("qcom.audio.init", value, "null");
+ if (strncmp(value, "complete", 8) != 0) {
+ ALOGW("Audio service is not initiated.");
+ }
+
+ fclose(fp);
+
+ char *fileName;
+ if (((fileName = getBootRingtoneFileName(IMG_DATA)) != NULL && access(fileName, R_OK) == 0) ||
+ ((fileName = getBootRingtoneFileName(IMG_SYS)) != NULL
+ && access(fileName, R_OK) == 0)) {
+ pthread_t tid;
+ pthread_create(&tid, NULL, playMusic, (void *)fileName);
+ pthread_join(tid, NULL);
+ }
+}
+bool BootAnimation::checkBootState(void)
+{
+ char value[PROPERTY_VALUE_MAX];
+ bool ret = true;
+
+ property_get("sys.shutdown.requested", value, "null");
+ if (strncmp(value, "null", 4) != 0) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+void* playMusic(void* arg)
+{
+ int index = 0;
+ char *fileName = (char *)arg;
+ sp<MediaPlayer> mp = new MediaPlayer();
+ sp<MPlayerListener> 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<SurfaceComposerClient> mSession;
sp<AudioPlayer> 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