Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bc12a0b authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android Code Review
Browse files

Merge "Added Caching for PreProcessed PNGs"

parents 1e24ccbd 8a39da80
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
	AaptAssets.cpp \
	Command.cpp \
	CrunchCache.cpp \
	FileFinder.cpp \
	Main.cpp \
	Package.cpp \
	StringPool.cpp \
+10 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ typedef enum Command {
    kCommandAdd,
    kCommandRemove,
    kCommandPackage,
    kCommandCrunch,
} Command;

/*
@@ -42,13 +43,14 @@ public:
          mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
          mIsOverlayPackage(false),
          mAutoAddOverlay(false), mGenDependencies(false),
          mAssetSourceDir(NULL), mProguardFile(NULL),
          mAssetSourceDir(NULL), 
          mCrunchedOutputDir(NULL), mProguardFile(NULL),
          mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
          mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
          mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
          mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
          mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
          mArgc(0), mArgv(NULL)
          mUseCrunchCache(false), mArgc(0), mArgv(NULL)
        {}
    ~Bundle(void) {}

@@ -106,6 +108,8 @@ public:
     */
    const char* getAssetSourceDir() const { return mAssetSourceDir; }
    void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; }
    const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }
    void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }
    const char* getProguardFile() const { return mProguardFile; }
    void setProguardFile(const char* file) { mProguardFile = file; }
    const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; }
@@ -151,6 +155,8 @@ public:
    void setNonConstantId(bool val) { mNonConstantId = val; }
    const char* getProduct() const { return mProduct; }
    void setProduct(const char * val) { mProduct = val; }
    void setUseCrunchCache(bool val) { mUseCrunchCache = val; }
    bool getUseCrunchCache() { return mUseCrunchCache; }

    /*
     * Set and get the file specification.
@@ -231,6 +237,7 @@ private:
    bool        mAutoAddOverlay;
    bool        mGenDependencies;
    const char* mAssetSourceDir;
    const char* mCrunchedOutputDir;
    const char* mProguardFile;
    const char* mAndroidManifestFile;
    const char* mPublicOutputFile;
@@ -254,6 +261,7 @@ private:
    bool        mDebugMode;
    bool        mNonConstantId;
    const char* mProduct;
    bool        mUseCrunchCache;

    /* file specification */
    int         mArgc;
+107 −0
Original line number Diff line number Diff line
//
// Copyright 2011 The Android Open Source Project
//
// Abstraction of calls to system to make directories and delete files and
// wrapper to image processing.

#ifndef CACHE_UPDATER_H
#define CACHE_UPDATER_H

#include <utils/String8.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include "Images.h"

using namespace android;

/** CacheUpdater
 *  This is a pure virtual class that declares abstractions of functions useful
 *  for managing a cache files. This manager is set up to be used in a
 *  mirror cache where the source tree is duplicated and filled with processed
 *  images. This class is abstracted to allow for dependency injection during
 *  unit testing.
 *  Usage:
 *      To update/add a file to the cache, call processImage
 *      To remove a file from the cache, call deleteFile
 */
class CacheUpdater {
public:
    // Make sure all the directories along this path exist
    virtual void ensureDirectoriesExist(String8 path) = 0;

    // Delete a file
    virtual void deleteFile(String8 path) = 0;

    // Process an image from source out to dest
    virtual void processImage(String8 source, String8 dest) = 0;
private:
};

/** SystemCacheUpdater
 * This is an implementation of the above virtual cache updater specification.
 * This implementations hits the filesystem to manage a cache and calls out to
 * the PNG crunching in images.h to process images out to its cache components.
 */
class SystemCacheUpdater : public CacheUpdater {
public:
    // Constructor to set bundle to pass to preProcessImage
    SystemCacheUpdater (Bundle* b)
        : bundle(b) { };

    // Make sure all the directories along this path exist
    virtual void ensureDirectoriesExist(String8 path)
    {
        // Check to see if we're dealing with a fully qualified path
        String8 existsPath;
        String8 toCreate;
        String8 remains;
        struct stat s;

        // Check optomistically to see if all directories exist.
        // If something in the path doesn't exist, then walk the path backwards
        // and find the place to start creating directories forward.
        if (stat(path.string(),&s) == -1) {
            // Walk backwards to find place to start creating directories
            existsPath = path;
            do {
                // As we remove the end of existsPath add it to
                // the string of paths to create.
                toCreate = existsPath.getPathLeaf().appendPath(toCreate);
                existsPath = existsPath.getPathDir();
            } while (stat(existsPath.string(),&s) == -1);

            // Walk forwards and build directories as we go
            do {
                // Advance to the next segment of the path
                existsPath.appendPath(toCreate.walkPath(&remains));
                toCreate = remains;
#ifdef HAVE_MS_C_RUNTIME
                _mkdir(existsPath.string());
#else
                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
#endif
            } while (remains.length() > 0);
        } //if
    };

    // Delete a file
    virtual void deleteFile(String8 path)
    {
        if (remove(path.string()) != 0)
            fprintf(stderr,"ERROR DELETING %s\n",path.string());
    };

    // Process an image from source out to dest
    virtual void processImage(String8 source, String8 dest)
    {
        // Make sure we're trying to write to a directory that is extant
        ensureDirectoriesExist(dest.getPathDir());

        preProcessImageToCache(bundle, source, dest);
    };
private:
    Bundle* bundle;
};

#endif // CACHE_UPDATER_H
 No newline at end of file
+22 −0
Original line number Diff line number Diff line
@@ -1504,3 +1504,25 @@ bail:
    }
    return retVal;
}

/*
 * Do PNG Crunching
 * PRECONDITIONS
 *  -S flag points to a source directory containing drawable* folders
 *  -C flag points to destination directory. The folder structure in the
 *     source directory will be mirrored to the destination (cache) directory
 *
 * POSTCONDITIONS
 *  Destination directory will be updated to match the PNG files in
 *  the source directory. 
 */
int doCrunch(Bundle* bundle)
{
    fprintf(stdout, "Crunching PNG Files in ");
    fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]);
    fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir());

    updatePreProcessedCache(bundle);

    return NO_ERROR;
}
+104 −0
Original line number Diff line number Diff line
//
// Copyright 2011 The Android Open Source Project
//
// Implementation file for CrunchCache
// This file defines functions laid out and documented in
// CrunchCache.h

#include <utils/Vector.h>
#include <utils/String8.h>

#include "DirectoryWalker.h"
#include "FileFinder.h"
#include "CacheUpdater.h"
#include "CrunchCache.h"

using namespace android;

CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)
    : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)
{
    // We initialize the default value to return to 0 so if a file doesn't exist
    // then all files are automatically "newer" than it.

    // Set file extensions to look for. Right now just pngs.
    mExtensions.push(String8(".png"));

    // Load files into our data members
    loadFiles();
}

size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)
{
    size_t numFilesUpdated = 0;

    // Iterate through the source files and compare to cache.
    // After processing a file, remove it from the source files and
    // from the dest files.
    // We're done when we're out of files in source.
    String8 relativePath;
    while (mSourceFiles.size() > 0) {
        // Get the full path to the source file, then convert to a c-string
        // and offset our beginning pointer to the length of the sourcePath
        // This efficiently strips the source directory prefix from our path.
        // Also, String8 doesn't have a substring method so this is what we've
        // got to work with.
        const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
        // Strip leading slash if present
        int offset = 0;
        if (rPathPtr[0] == OS_PATH_SEPARATOR)
            offset = 1;
        relativePath = String8(rPathPtr + offset);

        if (forceOverwrite || needsUpdating(relativePath)) {
            cu->processImage(mSourcePath.appendPathCopy(relativePath),
                             mDestPath.appendPathCopy(relativePath));
            numFilesUpdated++;
            // crunchFile(relativePath);
        }
        // Delete this file from the source files and (if it exists) from the
        // dest files.
        mSourceFiles.removeItemsAt(0);
        mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));
    }

    // Iterate through what's left of destFiles and delete leftovers
    while (mDestFiles.size() > 0) {
        cu->deleteFile(mDestFiles.keyAt(0));
        mDestFiles.removeItemsAt(0);
    }

    // Update our knowledge of the files cache
    // both source and dest should be empty by now.
    loadFiles();

    return numFilesUpdated;
}

void CrunchCache::loadFiles()
{
    // Clear out our data structures to avoid putting in duplicates
    mSourceFiles.clear();
    mDestFiles.clear();

    // Make a directory walker that points to the system.
    DirectoryWalker* dw = new SystemDirectoryWalker();

    // Load files in the source directory
    mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);

    // Load files in the destination directory
    mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);

    delete dw;
}

bool CrunchCache::needsUpdating(String8 relativePath) const
{
    // Retrieve modification dates for this file entry under the source and
    // cache directory trees. The vectors will return a modification date of 0
    // if the file doesn't exist.
    time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
    time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
    return sourceDate > destDate;
}
 No newline at end of file
Loading