1 //
2 // Copyright 2011 The Android Open Source Project
3 //
4 // Implementation file for CrunchCache
5 // This file defines functions laid out and documented in
6 // CrunchCache.h
7 
8 #include <utils/Compat.h>
9 #include <utils/Vector.h>
10 #include <utils/String8.h>
11 
12 #include "DirectoryWalker.h"
13 #include "FileFinder.h"
14 #include "CacheUpdater.h"
15 #include "CrunchCache.h"
16 
17 using namespace android;
18 
CrunchCache(String8 sourcePath,String8 destPath,FileFinder * ff)19 CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)
20     : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)
21 {
22     // We initialize the default value to return to 0 so if a file doesn't exist
23     // then all files are automatically "newer" than it.
24 
25     // Set file extensions to look for. Right now just pngs.
26     mExtensions.push(String8(".png"));
27 
28     // Load files into our data members
29     loadFiles();
30 }
31 
crunch(CacheUpdater * cu,bool forceOverwrite)32 size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)
33 {
34     size_t numFilesUpdated = 0;
35 
36     // Iterate through the source files and compare to cache.
37     // After processing a file, remove it from the source files and
38     // from the dest files.
39     // We're done when we're out of files in source.
40     String8 relativePath;
41     while (mSourceFiles.size() > 0) {
42         // Get the full path to the source file, then convert to a c-string
43         // and offset our beginning pointer to the length of the sourcePath
44         // This efficiently strips the source directory prefix from our path.
45         // Also, String8 doesn't have a substring method so this is what we've
46         // got to work with.
47         const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
48         // Strip leading slash if present
49         int offset = 0;
50         if (rPathPtr[0] == OS_PATH_SEPARATOR)
51             offset = 1;
52         relativePath = String8(rPathPtr + offset);
53 
54         if (forceOverwrite || needsUpdating(relativePath)) {
55             cu->processImage(mSourcePath.appendPathCopy(relativePath),
56                              mDestPath.appendPathCopy(relativePath));
57             numFilesUpdated++;
58             // crunchFile(relativePath);
59         }
60         // Delete this file from the source files and (if it exists) from the
61         // dest files.
62         mSourceFiles.removeItemsAt(0);
63         mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));
64     }
65 
66     // Iterate through what's left of destFiles and delete leftovers
67     while (mDestFiles.size() > 0) {
68         cu->deleteFile(mDestFiles.keyAt(0));
69         mDestFiles.removeItemsAt(0);
70     }
71 
72     // Update our knowledge of the files cache
73     // both source and dest should be empty by now.
74     loadFiles();
75 
76     return numFilesUpdated;
77 }
78 
loadFiles()79 void CrunchCache::loadFiles()
80 {
81     // Clear out our data structures to avoid putting in duplicates
82     mSourceFiles.clear();
83     mDestFiles.clear();
84 
85     // Make a directory walker that points to the system.
86     DirectoryWalker* dw = new SystemDirectoryWalker();
87 
88     // Load files in the source directory
89     mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);
90 
91     // Load files in the destination directory
92     mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);
93 
94     delete dw;
95 }
96 
needsUpdating(const String8 & relativePath) const97 bool CrunchCache::needsUpdating(const String8& relativePath) const
98 {
99     // Retrieve modification dates for this file entry under the source and
100     // cache directory trees. The vectors will return a modification date of 0
101     // if the file doesn't exist.
102     time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
103     time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
104     return sourceDate > destDate;
105 }
106