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