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