Permalink
Browse files

Exit boot animation cleanly.

The desc.txt file can now mark parts as 'must finish cleanly' by using
'c' as the part line prefix rather than 'p'.  If so indicated, if the
bootanimation is asked to quit it will do so only after waiting to
finish that part.

I considered either making init.c service killing smarter or promoting
bootanim to be a bindable service with a requestExit method.  However,
these changes are probably too big/risky given our ship date.  So
I used a property as a mailbox between SurfaceFlinger and bootanim.

Bug: 6679877
Change-Id: I1f8dd9e7da1ea80a483b31fa14c4a5645922d774
  • Loading branch information...
Kevin Hester authored and pixelflinger committed Apr 26, 2012
1 parent fe54cb6 commit d3782b26b2026e60a8e0d4b967a156369f2a46f8
Showing with 38 additions and 5 deletions.
  1. +35 −5 cmds/bootanimation/BootAnimation.cpp
  2. +3 −0 cmds/bootanimation/BootAnimation.h
@@ -54,6 +54,7 @@
#define USER_BOOTANIMATION_FILE "/data/local/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"

extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
const struct timespec *request,
@@ -297,6 +298,9 @@ bool BootAnimation::threadLoop()
r = movie();
}

// No need to force exit anymore
property_set(EXIT_PROP_NAME, "0");

eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
@@ -363,6 +367,8 @@ bool BootAnimation::android()
const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
if (sleepTime > 0)
usleep(sleepTime);

checkExit();
} while (!exitPending());

glDeleteTextures(1, &mAndroid[0].name);
@@ -371,6 +377,16 @@ bool BootAnimation::android()
}


void BootAnimation::checkExit() {
// Allow surface flinger to gracefully request shutdown
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
}
}

bool BootAnimation::movie()
{
ZipFileRO& zip(mZip);
@@ -397,20 +413,23 @@ bool BootAnimation::movie()
const char* l = line.string();
int fps, width, height, count, pause;
char path[256];
char pathType;
if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
//ALOGD("> w=%d, h=%d, fps=%d", fps, width, height);
//LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
animation.width = width;
animation.height = height;
animation.fps = fps;
}
if (sscanf(l, "p %d %d %s", &count, &pause, path) == 3) {
//ALOGD("> count=%d, pause=%d, path=%s", count, pause, path);
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);
Animation::Part part;
part.playUntilComplete = pathType == 'c';
part.count = count;
part.pause = pause;
part.path = path;
animation.parts.add(part);
}

s = ++endl;
}

@@ -472,13 +491,17 @@ bool BootAnimation::movie()
Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height));

for (int i=0 ; i<pcount && !exitPending() ; i++) {
for (int i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
glBindTexture(GL_TEXTURE_2D, 0);

for (int r=0 ; !part.count || r<part.count ; r++) {
for (int j=0 ; j<fcount && !exitPending(); j++) {
// Exit any non playuntil complete parts immediately
if(exitPending() && !part.playUntilComplete)
break;

for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime();

@@ -525,8 +548,15 @@ bool BootAnimation::movie()
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
}

checkExit();
}

usleep(part.pause * ns2us(frameDuration));

// For infinite parts, we've now played them at least once, so perhaps exit
if(exitPending() && !part.count)
break;
}

// free the textures for this part
@@ -70,6 +70,7 @@ class BootAnimation : public Thread, public IBinder::DeathRecipient
int pause;
String8 path;
SortedVector<Frame> frames;
bool playUntilComplete;
};
int fps;
int width;
@@ -82,6 +83,8 @@ class BootAnimation : public Thread, public IBinder::DeathRecipient
bool android();
bool movie();

void checkExit();

sp<SurfaceComposerClient> mSession;
AssetManager mAssets;
Texture mAndroid[2];

0 comments on commit d3782b2

Please sign in to comment.