summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/DEPS1
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.cc51
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.h25
-rw-r--r--content/browser/indexed_db/indexed_db_internals_ui.cc193
-rw-r--r--content/browser/indexed_db/indexed_db_internals_ui.h22
-rw-r--r--content/browser/resources/indexed_db/indexeddb_internals.html10
-rw-r--r--content/browser/resources/indexed_db/indexeddb_internals.js42
-rw-r--r--content/content_browser.gypi1
8 files changed, 302 insertions, 43 deletions
diff --git a/content/DEPS b/content/DEPS
index fae46cf..141bb04 100644
--- a/content/DEPS
+++ b/content/DEPS
@@ -62,6 +62,7 @@ include_rules = [
"+third_party/tcmalloc",
"+third_party/khronos",
"+third_party/webrtc",
+ "+third_party/zlib/google",
"+third_party/WebKit/Source/Platform/chromium",
"+third_party/WebKit/Source/WebKit/chromium",
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 3c72a9e..b95be28 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -128,13 +128,12 @@ std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() {
std::vector<IndexedDBInfo> result;
for (std::vector<GURL>::const_iterator iter = origins.begin();
iter != origins.end(); ++iter) {
- const GURL& origin = *iter;
+ const GURL& origin_url = *iter;
- string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin);
- base::FilePath idb_directory = GetIndexedDBFilePath(origin_id);
- result.push_back(IndexedDBInfo(origin,
- GetOriginDiskUsage(origin),
- GetOriginLastModified(origin),
+ base::FilePath idb_directory = GetFilePath(origin_url);
+ result.push_back(IndexedDBInfo(origin_url,
+ GetOriginDiskUsage(origin_url),
+ GetOriginLastModified(origin_url),
idb_directory));
}
return result;
@@ -150,8 +149,7 @@ int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
base::Time IndexedDBContextImpl::GetOriginLastModified(const GURL& origin_url) {
if (data_path_.empty() || !IsInOriginSet(origin_url))
return base::Time();
- string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
- base::FilePath idb_directory = GetIndexedDBFilePath(origin_id);
+ base::FilePath idb_directory = GetFilePath(origin_url);
base::PlatformFileInfo file_info;
if (!file_util::GetFileInfo(idb_directory, &file_info))
return base::Time();
@@ -160,6 +158,25 @@ base::Time IndexedDBContextImpl::GetOriginLastModified(const GURL& origin_url) {
void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
+ ForceClose(origin_url);
+ if (data_path_.empty() || !IsInOriginSet(origin_url))
+ return;
+
+ base::FilePath idb_directory = GetFilePath(origin_url);
+ EnsureDiskUsageCacheInitialized(origin_url);
+ const bool recursive = true;
+ bool deleted = file_util::Delete(idb_directory, recursive);
+
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ if (deleted) {
+ RemoveFromOriginSet(origin_url);
+ origin_size_map_.erase(origin_url);
+ space_available_map_.erase(origin_url);
+ }
+}
+
+void IndexedDBContextImpl::ForceClose(const GURL& origin_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
if (data_path_.empty() || !IsInOriginSet(origin_url))
return;
@@ -172,22 +189,14 @@ void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) {
connections.erase(it++);
db->forceClose();
}
- DCHECK(connections_[origin_url].size() == 0);
+ DCHECK_EQ(connections_[origin_url].size(), 0UL);
connections_.erase(origin_url);
}
+}
+base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) {
string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
- base::FilePath idb_directory = GetIndexedDBFilePath(origin_id);
- EnsureDiskUsageCacheInitialized(origin_url);
- const bool recursive = true;
- bool deleted = file_util::Delete(idb_directory, recursive);
-
- QueryDiskAndUpdateQuotaUsage(origin_url);
- if (deleted) {
- RemoveFromOriginSet(origin_url);
- origin_size_map_.erase(origin_url);
- space_available_map_.erase(origin_url);
- }
+ return GetIndexedDBFilePath(origin_id);
}
base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
@@ -197,7 +206,7 @@ base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url,
WebIDBDatabase* connection) {
- DCHECK(connections_[origin_url].count(connection) == 0);
+ DCHECK_EQ(connections_[origin_url].count(connection), 0UL);
if (quota_manager_proxy()) {
quota_manager_proxy()->NotifyStorageAccessed(
quota::QuotaClient::kIndexedDatabase, origin_url,
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 52aa57b..e40e6ae 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -54,9 +54,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
static const base::FilePath::CharType kIndexedDBExtension[];
// Disables the exit-time deletion of session-only data.
- void SetForceKeepSessionState() {
- force_keep_session_state_ = true;
- }
+ void SetForceKeepSessionState() { force_keep_session_state_ = true; }
// IndexedDBContext implementation:
virtual std::vector<GURL> GetAllOrigins() OVERRIDE;
@@ -64,8 +62,8 @@ class CONTENT_EXPORT IndexedDBContextImpl
virtual int64 GetOriginDiskUsage(const GURL& origin_url) OVERRIDE;
virtual base::Time GetOriginLastModified(const GURL& origin_url) OVERRIDE;
virtual void DeleteForOrigin(const GURL& origin_url) OVERRIDE;
- virtual base::FilePath GetFilePathForTesting(
- const string16& origin_id) const OVERRIDE;
+ virtual base::FilePath GetFilePathForTesting(const string16& origin_id) const
+ OVERRIDE;
// Methods called by IndexedDBDispatcherHost for quota support.
void ConnectionOpened(const GURL& origin_url, WebKit::WebIDBDatabase*);
@@ -76,7 +74,13 @@ class CONTENT_EXPORT IndexedDBContextImpl
quota::QuotaManagerProxy* quota_manager_proxy();
+ void ForceClose(const GURL& origin_url);
+ base::FilePath GetFilePath(const GURL& origin_url);
base::FilePath data_path() const { return data_path_; }
+ bool IsInOriginSet(const GURL& origin_url) {
+ std::set<GURL>* set = GetOriginSet();
+ return set->find(origin_url) != set->end();
+ }
// For unit tests allow to override the |data_path_|.
void set_data_path_for_testing(const base::FilePath& data_path) {
@@ -100,8 +104,10 @@ class CONTENT_EXPORT IndexedDBContextImpl
int64 ReadUsageFromDisk(const GURL& origin_url) const;
void EnsureDiskUsageCacheInitialized(const GURL& origin_url);
void QueryDiskAndUpdateQuotaUsage(const GURL& origin_url);
- void GotUsageAndQuota(const GURL& origin_url, quota::QuotaStatusCode,
- int64 usage, int64 quota);
+ void GotUsageAndQuota(const GURL& origin_url,
+ quota::QuotaStatusCode,
+ int64 usage,
+ int64 quota);
void GotUpdatedQuota(const GURL& origin_url, int64 usage, int64 quota);
void QueryAvailableQuota(const GURL& origin_url);
@@ -112,11 +118,6 @@ class CONTENT_EXPORT IndexedDBContextImpl
void RemoveFromOriginSet(const GURL& origin_url) {
GetOriginSet()->erase(origin_url);
}
- bool IsInOriginSet(const GURL& origin_url) {
- std::set<GURL>* set = GetOriginSet();
- return set->find(origin_url) != set->end();
- }
-
// Only for testing.
void ResetCaches();
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
index 1869091..4d6f04b 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -5,19 +5,30 @@
#include "content/browser/indexed_db/indexed_db_internals_ui.h"
#include <algorithm>
+#include <string>
#include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_vector.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager.h"
+#include "content/public/browser/download_url_parameters.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/url_constants.h"
#include "grit/content_resources.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
+#include "third_party/zlib/google/zip.h"
+#include "webkit/base/file_path_string_conversions.h"
+#include "webkit/database/database_util.h"
+
+using webkit_database::DatabaseUtil;
namespace content {
@@ -27,6 +38,11 @@ IndexedDBInternalsUI::IndexedDBInternalsUI(WebUI* web_ui)
"getAllOrigins",
base::Bind(&IndexedDBInternalsUI::GetAllOrigins, base::Unretained(this)));
+ web_ui->RegisterMessageCallback(
+ "downloadOriginData",
+ base::Bind(&IndexedDBInternalsUI::DownloadOriginData,
+ base::Unretained(this)));
+
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIIndexedDBInternalsHost);
source->SetUseJsonJSFormatV2();
@@ -80,8 +96,8 @@ bool HostNameComparator(const IndexedDBInfo& i, const IndexedDBInfo& j) {
}
void IndexedDBInternalsUI::GetAllOriginsOnWebkitThread(
- scoped_ptr<ContextList> contexts,
- scoped_ptr<std::vector<base::FilePath> > context_paths) {
+ const scoped_ptr<ContextList> contexts,
+ const scoped_ptr<std::vector<base::FilePath> > context_paths) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
DCHECK_EQ(contexts->size(), context_paths->size());
@@ -124,4 +140,177 @@ void IndexedDBInternalsUI::OnOriginsReady(
"indexeddb.onOriginsReady", urls, base::StringValue(path.value()));
}
+static void FindContext(const base::FilePath& partition_path,
+ StoragePartition** result_partition,
+ scoped_refptr<IndexedDBContextImpl>* result_context,
+ StoragePartition* storage_partition) {
+ if (storage_partition->GetPath() == partition_path) {
+ *result_partition = storage_partition;
+ *result_context = static_cast<IndexedDBContextImpl*>(
+ storage_partition->GetIndexedDBContext());
+ }
+}
+
+void IndexedDBInternalsUI::DownloadOriginData(const base::ListValue* args) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ base::FilePath::StringType path_string;
+ if (!args->GetString(0, &path_string))
+ return;
+ const base::FilePath partition_path(path_string);
+
+ std::string url_string;
+ if (!args->GetString(1, &url_string))
+ return;
+ const GURL origin_url(url_string);
+
+ // search the origins to find the right context
+
+ BrowserContext* browser_context =
+ web_ui()->GetWebContents()->GetBrowserContext();
+
+ scoped_refptr<IndexedDBContextImpl> result_context;
+ StoragePartition* result_partition;
+ scoped_ptr<ContextList> contexts(new ContextList);
+ BrowserContext::StoragePartitionCallback cb = base::Bind(
+ &FindContext, partition_path, &result_partition, &result_context);
+ BrowserContext::ForEachStoragePartition(browser_context, cb);
+ DCHECK(result_partition);
+ DCHECK(result_context);
+
+ BrowserThread::PostTask(
+ BrowserThread::WEBKIT_DEPRECATED,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread,
+ base::Unretained(this),
+ result_partition->GetPath(),
+ result_context,
+ origin_url));
+}
+
+void IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread(
+ const base::FilePath& partition_path,
+ const scoped_refptr<IndexedDBContextImpl> context,
+ const GURL& origin_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
+
+ if (!context->IsInOriginSet(origin_url))
+ return;
+
+ context->ForceClose(origin_url);
+
+ base::ScopedTempDir temp_dir;
+ if (!temp_dir.CreateUniqueTempDir())
+ return;
+
+ // This will get cleaned up on the File thread after the download
+ // has completed.
+ base::FilePath temp_path = temp_dir.Take();
+
+ base::string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ base::FilePath::StringType zip_name =
+ webkit_base::WebStringToFilePathString(origin_id);
+ base::FilePath zip_path =
+ temp_path.Append(zip_name).AddExtension(FILE_PATH_LITERAL("zip"));
+
+ // This happens on the "webkit" thread (which is really just the IndexedDB
+ // thread) as a simple way to avoid another script reopening the origin
+ // while we are zipping.
+ zip::Zip(context->GetFilePath(origin_url), zip_path, true);
+
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&IndexedDBInternalsUI::OnDownloadDataReady,
+ base::Unretained(this),
+ partition_path,
+ origin_url,
+ temp_path,
+ zip_path));
+}
+
+void IndexedDBInternalsUI::OnDownloadDataReady(
+ const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath temp_path,
+ const base::FilePath zip_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const GURL url = GURL(FILE_PATH_LITERAL("file://") + zip_path.value());
+ BrowserContext* browser_context =
+ web_ui()->GetWebContents()->GetBrowserContext();
+ scoped_ptr<DownloadUrlParameters> dl_params(
+ DownloadUrlParameters::FromWebContents(web_ui()->GetWebContents(), url));
+ DownloadManager* dlm = BrowserContext::GetDownloadManager(browser_context);
+
+ const GURL referrer(web_ui()->GetWebContents()->GetURL());
+ dl_params->set_referrer(
+ content::Referrer(referrer, WebKit::WebReferrerPolicyDefault));
+
+ // This is how to watch for the download to finish: first wait for it
+ // to start, then attach a DownloadItem::Observer to observe the
+ // state change to the finished state.
+ dl_params->set_callback(base::Bind(&IndexedDBInternalsUI::OnDownloadStarted,
+ base::Unretained(this),
+ partition_path,
+ origin_url,
+ temp_path));
+ dlm->DownloadUrl(dl_params.Pass());
+}
+
+// The entire purpose of this class is to delete the temp file after
+// the download is complete.
+class FileDeleter : public DownloadItem::Observer {
+ public:
+ explicit FileDeleter(const base::FilePath& temp_dir) : temp_dir_(temp_dir) {}
+ virtual ~FileDeleter();
+
+ virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE;
+ virtual void OnDownloadOpened(DownloadItem* item) OVERRIDE {}
+ virtual void OnDownloadRemoved(DownloadItem* item) OVERRIDE {}
+ virtual void OnDownloadDestroyed(DownloadItem* item) OVERRIDE {}
+
+ private:
+ const base::FilePath temp_dir_;
+};
+
+void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
+ switch (item->GetState()) {
+ case DownloadItem::IN_PROGRESS:
+ break;
+ case DownloadItem::COMPLETE:
+ case DownloadItem::CANCELLED:
+ case DownloadItem::INTERRUPTED: {
+ item->RemoveObserver(this);
+ BrowserThread::DeleteOnFileThread::Destruct(this);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+FileDeleter::~FileDeleter() {
+ base::ScopedTempDir path;
+ bool will_delete ALLOW_UNUSED = path.Set(temp_dir_);
+ DCHECK(will_delete);
+}
+
+void IndexedDBInternalsUI::OnDownloadStarted(
+ const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath& temp_path,
+ DownloadItem* item,
+ net::Error error) {
+
+ if (error != net::OK) {
+ LOG(ERROR) << "Error downloading database dump: "
+ << net::ErrorToString(error);
+ return;
+ }
+
+ item->AddObserver(new FileDeleter(temp_path));
+ web_ui()->CallJavascriptFunction("indexeddb.onOriginDownloadReady",
+ base::StringValue(partition_path.value()),
+ base::StringValue(origin_url.spec()));
+}
+
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.h b/content/browser/indexed_db/indexed_db_internals_ui.h
index 174db19..bc9a5da 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.h
+++ b/content/browser/indexed_db/indexed_db_internals_ui.h
@@ -11,11 +11,14 @@
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/indexed_db_context.h"
#include "content/public/browser/web_ui_controller.h"
+#include "net/base/net_errors.h"
namespace base { class ListValue; }
namespace content {
+class DownloadItem;
+class IndexedDBContextImpl;
class StoragePartition;
// The implementation for the chrome://indexeddb-internals page.
@@ -28,8 +31,8 @@ class IndexedDBInternalsUI : public WebUIController {
typedef std::vector<scoped_refptr<IndexedDBContext> > ContextList;
void GetAllOrigins(const base::ListValue* args);
void GetAllOriginsOnWebkitThread(
- scoped_ptr<ContextList> contexts,
- scoped_ptr<std::vector<base::FilePath> > context_paths);
+ const scoped_ptr<ContextList> contexts,
+ const scoped_ptr<std::vector<base::FilePath> > context_paths);
void OnOriginsReady(scoped_ptr<std::vector<IndexedDBInfo> > origins,
const base::FilePath& path);
@@ -37,6 +40,21 @@ class IndexedDBInternalsUI : public WebUIController {
std::vector<base::FilePath>* paths,
StoragePartition* partition);
+ void DownloadOriginData(const base::ListValue* args);
+ void DownloadOriginDataOnWebkitThread(
+ const base::FilePath& partition_path,
+ const scoped_refptr<IndexedDBContextImpl> context,
+ const GURL& origin_url);
+ void OnDownloadDataReady(const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath temp_path,
+ const base::FilePath zip_path);
+ void OnDownloadStarted(const base::FilePath& partition_path,
+ const GURL& origin_url,
+ const base::FilePath& temp_path,
+ content::DownloadItem* item,
+ net::Error error);
+
DISALLOW_COPY_AND_ASSIGN(IndexedDBInternalsUI);
};
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.html b/content/browser/resources/indexed_db/indexeddb_internals.html
index 5db358d..87337ec 100644
--- a/content/browser/resources/indexed_db/indexeddb_internals.html
+++ b/content/browser/resources/indexed_db/indexeddb_internals.html
@@ -10,10 +10,11 @@
<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
<!-- templates -->
<div style="display:none">
- <div id="indexeddb-list-template">
+ <div id="indexeddb-list-template"
+ jsvalues="$partition_path:$this.partition_path">
<div class="indexeddb-summary">
<span>Instances in: </span>
- <span jscontent="$this.path"></span>
+ <span jscontent="$this.partition_path"></span>
<span jscontent="'(' + $this.idbs.length + ')'"></span>
</div>
<div class="indexeddb-item" jsselect="$this.idbs">
@@ -31,6 +32,11 @@
<span>Path:</span>
<span jscontent="path"></span>
</div>
+ <div class="controls">
+ <a href="#" class="download"
+ jsvalues=".idb_origin_url:url;.idb_partition_path:$partition_path">Download</a>
+ <span class="download-status" style="display: none">Loading...</span>
+ </div>
</div>
</div>
</div>
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.js b/content/browser/resources/indexed_db/indexeddb_internals.js
index 9bc3b0b..378b9ad 100644
--- a/content/browser/resources/indexed_db/indexeddb_internals.js
+++ b/content/browser/resources/indexed_db/indexeddb_internals.js
@@ -9,16 +9,50 @@ cr.define('indexeddb', function() {
chrome.send('getAllOrigins');
}
- function onOriginsReady(origins, path) {
+ function progressNodeFor(link) {
+ return link.parentNode.querySelector('.download-status');
+ }
+
+ function downloadOriginData(event) {
+ var link = event.target;
+ progressNodeFor(link).style.display = 'inline';
+ chrome.send('downloadOriginData', [link.idb_partition_path,
+ link.idb_origin_url]);
+ return false;
+ }
+
+ // Fired from the backend after the data has been zipped up, and the
+ // download manager has begun downloading the file.
+ function onOriginDownloadReady(partition_path, origin_url) {
+ var downloadLinks = document.querySelectorAll('a.download');
+ for (var i = 0; i < downloadLinks.length; ++i) {
+ var link = downloadLinks[i];
+ if (partition_path == link.idb_partition_path &&
+ origin_url == link.idb_origin_url) {
+ progressNodeFor(link).style.display = 'none';
+ }
+ }
+ }
+
+ // Fired from the backend with a single partition's worth of
+ // IndexedDB metadata.
+ function onOriginsReady(origins, partition_path) {
var template = jstGetTemplate('indexeddb-list-template');
var container = $('indexeddb-list');
container.appendChild(template);
- jstProcess(new JsEvalContext({ idbs: origins, path: path}), template);
+ jstProcess(new JsEvalContext({ idbs: origins,
+ partition_path: partition_path}), template);
+
+ var downloadLinks = container.querySelectorAll('a.download');
+ for (var i = 0; i < downloadLinks.length; ++i) {
+ downloadLinks[i].addEventListener('click', downloadOriginData, false);
+ }
}
return {
- initialize: initialize,
- onOriginsReady: onOriginsReady,
+ initialize: initialize,
+ onOriginDownloadReady: onOriginDownloadReady,
+ onOriginsReady: onOriginsReady,
};
});
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index b00f0e8..8fcfbc3 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -12,6 +12,7 @@
'../skia/skia.gyp:skia',
'../sql/sql.gyp:sql',
'../third_party/re2/re2.gyp:re2',
+ '../third_party/zlib/zlib.gyp:zip',
'../third_party/zlib/zlib.gyp:zlib',
'../ui/snapshot/snapshot.gyp:snapshot',
'../ui/ui.gyp:ui',