1// 2// Copyright 2011 The Android Open Source Project 3// 4// Abstraction of calls to system to make directories and delete files and 5// wrapper to image processing. 6 7#ifndef CACHE_UPDATER_H 8#define CACHE_UPDATER_H 9 10#include <utils/String8.h> 11#include <sys/types.h> 12#include <sys/stat.h> 13#include <stdio.h> 14#include "Images.h" 15#ifdef HAVE_MS_C_RUNTIME 16#include <direct.h> 17#endif 18 19using namespace android; 20 21/** CacheUpdater 22 * This is a pure virtual class that declares abstractions of functions useful 23 * for managing a cache files. This manager is set up to be used in a 24 * mirror cache where the source tree is duplicated and filled with processed 25 * images. This class is abstracted to allow for dependency injection during 26 * unit testing. 27 * Usage: 28 * To update/add a file to the cache, call processImage 29 * To remove a file from the cache, call deleteFile 30 */ 31class CacheUpdater { 32public: 33 // Make sure all the directories along this path exist 34 virtual void ensureDirectoriesExist(String8 path) = 0; 35 36 // Delete a file 37 virtual void deleteFile(String8 path) = 0; 38 39 // Process an image from source out to dest 40 virtual void processImage(String8 source, String8 dest) = 0; 41private: 42}; 43 44/** SystemCacheUpdater 45 * This is an implementation of the above virtual cache updater specification. 46 * This implementations hits the filesystem to manage a cache and calls out to 47 * the PNG crunching in images.h to process images out to its cache components. 48 */ 49class SystemCacheUpdater : public CacheUpdater { 50public: 51 // Constructor to set bundle to pass to preProcessImage 52 SystemCacheUpdater (Bundle* b) 53 : bundle(b) { }; 54 55 // Make sure all the directories along this path exist 56 virtual void ensureDirectoriesExist(String8 path) 57 { 58 // Check to see if we're dealing with a fully qualified path 59 String8 existsPath; 60 String8 toCreate; 61 String8 remains; 62 struct stat s; 63 64 // Check optomistically to see if all directories exist. 65 // If something in the path doesn't exist, then walk the path backwards 66 // and find the place to start creating directories forward. 67 if (stat(path.string(),&s) == -1) { 68 // Walk backwards to find place to start creating directories 69 existsPath = path; 70 do { 71 // As we remove the end of existsPath add it to 72 // the string of paths to create. 73 toCreate = existsPath.getPathLeaf().appendPath(toCreate); 74 existsPath = existsPath.getPathDir(); 75 } while (stat(existsPath.string(),&s) == -1); 76 77 // Walk forwards and build directories as we go 78 do { 79 // Advance to the next segment of the path 80 existsPath.appendPath(toCreate.walkPath(&remains)); 81 toCreate = remains; 82#ifdef HAVE_MS_C_RUNTIME 83 _mkdir(existsPath.string()); 84#else 85 mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); 86#endif 87 } while (remains.length() > 0); 88 } //if 89 }; 90 91 // Delete a file 92 virtual void deleteFile(String8 path) 93 { 94 if (remove(path.string()) != 0) 95 fprintf(stderr,"ERROR DELETING %s\n",path.string()); 96 }; 97 98 // Process an image from source out to dest 99 virtual void processImage(String8 source, String8 dest) 100 { 101 // Make sure we're trying to write to a directory that is extant 102 ensureDirectoriesExist(dest.getPathDir()); 103 104 preProcessImageToCache(bundle, source, dest); 105 }; 106private: 107 Bundle* bundle; 108}; 109 110#endif // CACHE_UPDATER_H