18a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin//
28a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Copyright 2011 The Android Open Source Project
38a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin//
48a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// Abstraction of calls to system to make directories and delete files and
58a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin// wrapper to image processing.
68a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
78a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifndef CACHE_UPDATER_H
88a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#define CACHE_UPDATER_H
98a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
108a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <utils/String8.h>
118a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <sys/types.h>
128a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <sys/stat.h>
138a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include <stdio.h>
148a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#include "Images.h"
158a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
168a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinusing namespace android;
178a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
188a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin/** CacheUpdater
198a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  This is a pure virtual class that declares abstractions of functions useful
208a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  for managing a cache files. This manager is set up to be used in a
218a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  mirror cache where the source tree is duplicated and filled with processed
228a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  images. This class is abstracted to allow for dependency injection during
238a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  unit testing.
248a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *  Usage:
258a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *      To update/add a file to the cache, call processImage
268a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin *      To remove a file from the cache, call deleteFile
278a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */
288a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinclass CacheUpdater {
298a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinpublic:
308a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Make sure all the directories along this path exist
318a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void ensureDirectoriesExist(String8 path) = 0;
328a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
338a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Delete a file
348a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void deleteFile(String8 path) = 0;
358a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
368a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Process an image from source out to dest
378a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void processImage(String8 source, String8 dest) = 0;
388a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinprivate:
398a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin};
408a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
418a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin/** SystemCacheUpdater
428a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * This is an implementation of the above virtual cache updater specification.
438a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * This implementations hits the filesystem to manage a cache and calls out to
448a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin * the PNG crunching in images.h to process images out to its cache components.
458a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin */
468a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinclass SystemCacheUpdater : public CacheUpdater {
478a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinpublic:
488a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Constructor to set bundle to pass to preProcessImage
498a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    SystemCacheUpdater (Bundle* b)
508a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        : bundle(b) { };
518a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
528a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Make sure all the directories along this path exist
538a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void ensureDirectoriesExist(String8 path)
548a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    {
558a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        // Check to see if we're dealing with a fully qualified path
568a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        String8 existsPath;
578a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        String8 toCreate;
588a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        String8 remains;
598a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        struct stat s;
608a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
618a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        // Check optomistically to see if all directories exist.
628a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        // If something in the path doesn't exist, then walk the path backwards
638a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        // and find the place to start creating directories forward.
648a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        if (stat(path.string(),&s) == -1) {
658a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            // Walk backwards to find place to start creating directories
668a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            existsPath = path;
678a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            do {
688a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                // As we remove the end of existsPath add it to
698a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                // the string of paths to create.
708a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                toCreate = existsPath.getPathLeaf().appendPath(toCreate);
718a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                existsPath = existsPath.getPathDir();
728a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            } while (stat(existsPath.string(),&s) == -1);
738a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
748a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            // Walk forwards and build directories as we go
758a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            do {
768a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                // Advance to the next segment of the path
778a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                existsPath.appendPath(toCreate.walkPath(&remains));
788a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                toCreate = remains;
798a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#ifdef HAVE_MS_C_RUNTIME
808a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                _mkdir(existsPath.string());
818a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#else
828a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
838a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif
848a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            } while (remains.length() > 0);
858a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        } //if
868a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    };
878a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
888a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Delete a file
898a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void deleteFile(String8 path)
908a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    {
918a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        if (remove(path.string()) != 0)
928a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin            fprintf(stderr,"ERROR DELETING %s\n",path.string());
938a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    };
948a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
958a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    // Process an image from source out to dest
968a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    virtual void processImage(String8 source, String8 dest)
978a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    {
988a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        // Make sure we're trying to write to a directory that is extant
998a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        ensureDirectoriesExist(dest.getPathDir());
1008a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
1018a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin        preProcessImageToCache(bundle, source, dest);
1028a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    };
1038a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskinprivate:
1048a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin    Bundle* bundle;
1058a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin};
1068a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin
1078a39da80b33691b0c82458c3b7727e13ff71277eJosiah Gaskin#endif // CACHE_UPDATER_H