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