From afd31e08299008fdc5c2813f21b2573f29dc53df Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Tue, 3 Dec 2013 13:16:03 +0000 Subject: Reimplement ZipFileRO in terms of libziparchive. This lets us share zip archive processing code with both the runtime (Art, dalvik) and critical java code (StrictJarFile). This change also moves several utility methods to ZipUtils and dedups code across several zip inflation methods. One of the side effects of this change is that several processing loops are now O(n) instead of O(n^2). bug: 10193060 Change-Id: I3c7188496837a47246c4f342e45485a70fef3169 --- cmds/bootanimation/BootAnimation.cpp | 98 ++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 39 deletions(-) (limited to 'cmds/bootanimation/BootAnimation.cpp') diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 0f610e975b64..7b4e6eed6094 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -63,14 +63,19 @@ extern "C" int clock_nanosleep(clockid_t clock_id, int flags, namespace android { +static const int ANIM_ENTRY_NAME_MAX = 256; + // --------------------------------------------------------------------------- -BootAnimation::BootAnimation() : Thread(false) +BootAnimation::BootAnimation() : Thread(false), mZip(NULL) { mSession = new SurfaceComposerClient(); } BootAnimation::~BootAnimation() { + if (mZip != NULL) { + delete mZip; + } } void BootAnimation::onFirstRef() { @@ -86,7 +91,7 @@ sp BootAnimation::session() const { } -void BootAnimation::binderDied(const wp& who) +void BootAnimation::binderDied(const wp&) { // woah, surfaceflinger died! ALOGD("SurfaceFlinger died, exiting..."); @@ -268,8 +273,6 @@ status_t BootAnimation::readyToRun() { mFlingerSurfaceControl = control; mFlingerSurface = s; - mAndroidAnimation = true; - // If the device has encryption turned on or is in process // of being encrypted we show the encrypted boot animation. char decrypt[PROPERTY_VALUE_MAX]; @@ -277,16 +280,17 @@ status_t BootAnimation::readyToRun() { bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt); + ZipFileRO* zipFile = NULL; if ((encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && - (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) || + ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) || ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) && - (mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) || + ((zipFile = ZipFileRO::open(USER_BOOTANIMATION_FILE)) != NULL)) || ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && - (mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) { - mAndroidAnimation = false; + ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) { + mZip = zipFile; } return NO_ERROR; @@ -295,7 +299,9 @@ status_t BootAnimation::readyToRun() { bool BootAnimation::threadLoop() { bool r; - if (mAndroidAnimation) { + // We have no bootanimation file, so we use the stock android logo + // animation. + if (mZip == NULL) { r = android(); } else { r = movie(); @@ -392,11 +398,14 @@ void BootAnimation::checkExit() { bool BootAnimation::movie() { - ZipFileRO& zip(mZip); + ZipEntryRO desc = mZip->findEntryByName("desc.txt"); + ALOGE_IF(!desc, "couldn't find desc.txt"); + if (!desc) { + return false; + } - size_t numEntries = zip.getNumEntries(); - ZipEntryRO desc = zip.findEntryByName("desc.txt"); - FileMap* descMap = zip.createEntryFileMap(desc); + FileMap* descMap = mZip->createEntryFileMap(desc); + mZip->releaseEntry(desc); ALOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; @@ -415,7 +424,7 @@ bool BootAnimation::movie() String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause; - char path[256]; + char path[ANIM_ENTRY_NAME_MAX]; char pathType; if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); @@ -438,28 +447,37 @@ bool BootAnimation::movie() // read all the data structures const size_t pcount = animation.parts.size(); - for (size_t i=0 ; i 0) { - for (int j=0 ; jstartIteration(&cookie)) { + return false; + } + + ZipEntryRO entry; + char name[ANIM_ENTRY_NAME_MAX]; + while ((entry = mZip->nextEntry(cookie)) != NULL) { + const int foundEntryName = mZip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX); + if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) { + ALOGE("Error fetching entry file name"); + continue; + } + + const String8 entryName(name); + const String8 path(entryName.getPathDir()); + const String8 leaf(entryName.getPathLeaf()); + if (leaf.size() > 0) { + for (size_t j=0 ; jgetEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) { + 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); } } } @@ -468,6 +486,8 @@ bool BootAnimation::movie() } } + mZip->endIteration(cookie); + // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); @@ -494,7 +514,7 @@ bool BootAnimation::movie() Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); - for (int i=0 ; i