1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_LOCAL_EXTENSION_CACHE_H_
6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_LOCAL_EXTENSION_CACHE_H_
11 #include "base/callback_forward.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/time/time.h"
17 namespace extensions
{
19 // Cache .crx files in some local dir for future use. Cache keeps only latest
20 // version of the extensions. Only one instance of LocalExtensionCache can work
21 // with the same directory. But LocalExtensionCache instance can be shared
22 // between multiple clients. Public interface can be used only from UI thread.
23 class LocalExtensionCache
{
25 // |cache_dir| - directory that will be used for caching CRX files.
26 // |max_cache_size| - maximum disk space that cache can use, 0 means no limit.
27 // |max_cache_age| - maximum age that unused item can be kept in cache, 0 age
28 // means that all unused cache items will be removed on Shutdown.
29 // All file I/O is done via the |backend_task_runner|.
30 LocalExtensionCache(const base::FilePath
& cache_dir
,
31 size_t max_cache_size
,
32 const base::TimeDelta
& max_cache_age
,
33 const scoped_refptr
<base::SequencedTaskRunner
>&
35 ~LocalExtensionCache();
37 // Name of flag file that indicates that cache is ready (import finished).
38 static const char kCacheReadyFlagFileName
[];
40 // Initialize cache. If |wait_for_cache_initialization| is |true|, the cache
41 // contents will not be read until a flag file appears in the cache directory,
42 // signaling that the cache is ready. The |callback| is called when cache is
43 // ready and cache dir content was already checked.
44 void Init(bool wait_for_cache_initialization
,
45 const base::Closure
& callback
);
47 // Shut down the cache. The |callback| will be invoked when the cache has shut
48 // down completely and there are no more pending file I/O operations.
49 void Shutdown(const base::Closure
& callback
);
51 // If extension with |id| exists in the cache, returns |true|, |file_path| and
52 // |version| for the extension. Extension will be marked as used with current
54 bool GetExtension(const std::string
& id
,
55 base::FilePath
* file_path
,
56 std::string
* version
);
58 // Put extension with |id| and |version| into local cache. Older version in
59 // the cache will be on next run so it can be safely used. Extension will be
60 // marked as used with current timestamp. The file will be available via
61 // GetExtension when |callback| is called. Original |file_path| won't be
62 // deleted from the disk. There is no guarantee that |callback| will be
64 void PutExtension(const std::string
& id
,
65 const base::FilePath
& file_path
,
66 const std::string
& version
,
67 const base::Closure
& callback
);
69 // Remove extension with |id| from local cache, corresponding crx file will be
70 // removed from disk too.
71 bool RemoveExtension(const std::string
& id
);
73 bool is_ready() const { return state_
== kReady
; }
74 bool is_uninitialized() const { return state_
== kUninitialized
; }
75 bool is_shutdown() const { return state_
== kShutdown
; }
78 void SetCacheStatusPollingDelayForTests(const base::TimeDelta
& delay
);
81 struct CacheItemInfo
{
85 base::FilePath file_path
;
87 CacheItemInfo(const std::string
& version
,
88 const base::Time
& last_used
,
90 const base::FilePath
& file_path
);
92 typedef std::map
<std::string
, CacheItemInfo
> CacheMap
;
101 // Sends BackendCheckCacheStatus task on backend thread.
102 void CheckCacheStatus(const base::Closure
& callback
);
104 // Checks whether a flag file exists in the |cache_dir|, indicating that the
105 // cache is ready. This method is invoked via the |backend_task_runner_| and
106 // posts its result back to the |local_cache| on the UI thread.
107 static void BackendCheckCacheStatus(
108 base::WeakPtr
<LocalExtensionCache
> local_cache
,
109 const base::FilePath
& cache_dir
,
110 const base::Closure
& callback
);
112 // Invoked on the UI thread after checking whether the cache is ready. If the
113 // cache is not ready yet, posts a delayed task that will repeat the check,
114 // thus polling for cache readiness.
115 void OnCacheStatusChecked(bool ready
, const base::Closure
& callback
);
117 // Checks the cache contents. This is a helper that invokes the actual check
118 // by posting to the |backend_task_runner_|.
119 void CheckCacheContents(const base::Closure
& callback
);
121 // Checks the cache contents. This method is invoked via the
122 // |backend_task_runner_| and posts back a list of cache entries to the
123 // |local_cache| on the UI thread.
124 static void BackendCheckCacheContents(
125 base::WeakPtr
<LocalExtensionCache
> local_cache
,
126 const base::FilePath
& cache_dir
,
127 const base::Closure
& callback
);
129 // Helper for BackendCheckCacheContents() that updates |cache_content|.
130 static void BackendCheckCacheContentsInternal(
131 const base::FilePath
& cache_dir
,
132 CacheMap
* cache_content
);
134 // Invoked when the cache content on disk has been checked. |cache_content|
135 // contains all the currently valid crx files in the cache.
136 void OnCacheContentsChecked(scoped_ptr
<CacheMap
> cache_content
,
137 const base::Closure
& callback
);
139 // Update timestamp for the file to mark it as "used". This method is invoked
140 // via the |backend_task_runner_|.
141 static void BackendMarkFileUsed(const base::FilePath
& file_path
,
142 const base::Time
& time
);
144 // Installs the downloaded crx file at |path| in the |cache_dir|. This method
145 // is invoked via the |backend_task_runner_|.
146 static void BackendInstallCacheEntry(
147 base::WeakPtr
<LocalExtensionCache
> local_cache
,
148 const base::FilePath
& cache_dir
,
149 const std::string
& id
,
150 const base::FilePath
& file_path
,
151 const std::string
& version
,
152 const base::Closure
& callback
);
154 // Invoked on the UI thread when a new entry has been installed in the cache.
155 void OnCacheEntryInstalled(const std::string
& id
,
156 const CacheItemInfo
& info
,
157 const base::Closure
& callback
);
159 // Remove crx file at |file_path| in the cache. This method is invoked via
160 // the |backend_task_runner_|.
161 static void BackendRemoveCacheEntry(const base::FilePath
& file_path
);
163 // Compare two cache items returns true if first item is older.
164 static bool CompareCacheItemsAge(const CacheMap::iterator
& lhs
,
165 const CacheMap::iterator
& rhs
);
167 // Calculate which files need to be deleted and schedule files deletion.
170 // Path to the directory where the extension cache is stored.
171 base::FilePath cache_dir_
;
173 // Maximum size of cache dir on disk.
174 size_t max_cache_size_
;
176 // Minimal age of unused item in cache, items prior to this age will be
177 // deleted on shutdown.
178 base::Time min_cache_age_
;
180 // Task runner for executing file I/O tasks.
181 scoped_refptr
<base::SequencedTaskRunner
> backend_task_runner_
;
183 // Track state of the instance.
186 // This contains info about all cached extensions.
187 CacheMap cached_extensions_
;
189 // Weak factory for callbacks from the backend and delayed tasks.
190 base::WeakPtrFactory
<LocalExtensionCache
> weak_ptr_factory_
;
192 // Delay between polling cache status.
193 base::TimeDelta cache_status_polling_delay_
;
195 DISALLOW_COPY_AND_ASSIGN(LocalExtensionCache
);
198 } // namespace extensions
200 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_LOCAL_EXTENSION_CACHE_H_