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

Commit ea9e6d24 authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android Git Automerger
Browse files

am b582af31: am 0bc12a0b: Merge "Added Caching for PreProcessed PNGs"

* commit 'b582af31':
  Added Caching for PreProcessed PNGs
parents 2c311be7 b582af31
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