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:
~CacheUpdater()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
SystemCacheUpdater(Bundle * b)54     explicit SystemCacheUpdater (Bundle* b)
55         : bundle(b) { };
56 
57     // Make sure all the directories along this path exist
ensureDirectoriesExist(String8 path)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
deleteFile(String8 path)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
processImage(String8 source,String8 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