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