Commit b4306f90 authored by satorux@chromium.org's avatar satorux@chromium.org

gdata: Add Cache Contents section to chrome:drive-internals

This section is used to show states of cached files.

BUG=135328
TEST=the new section is shown in chrome:drive-internals properly

Review URL: https://chromiumcodereview.appspot.com/10825062

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148823 0039d316-1c4b-4281-b951-d872f2087c98
parent b48f7f75
......@@ -10,3 +10,7 @@
#file-system-contents {
font-size: small;
}
#cache-contents {
font-size: small;
}
......@@ -9,16 +9,42 @@
</head>
<body>
<h1>Drive Internals</h1>
<h2>Authentication Status</h2>
<div>
<a href="#auth-status-section">Authentication Status</a> |
<a href="#gcache-contents-section">GCache Contents</a> |
<a href="#file-system-contents-section">File System Contents</a> |
<a href="#cache-contents-section">Cache Contents</a>
</div>
<h2 id='auth-status-contents-section'>Authentication Status</h2>
<ul>
<li>Has refresh token: <span id='has-refresh-token'></span></li>
<li>Has access token: <span id='has-access-token'></span></li>
</ul>
<h2>GCache Contents</h2>
<h2 id='gcache-contents-section'>GCache Contents</h2>
<table>
<tbody id='gcache-contents'></tbody>
<tbody id='gcache-contents'>
<tr><th>Path</th><th>Size</th><th>Last Modified</th></tr>
</tbody>
</table>
<h2>File System Contents</h2>
<h2 id='file-system-contents-section'>File System Contents</h2>
<div id='file-system-contents'></div>
<h2 id='cache-contents-section'>Cache Contents</h2>
<table>
<tbody id='cache-contents'>
<tr>
<th>Resource ID</th>
<th>MD5</th>
<th>Present</th>
<th>Pinned</th>
<th>Dirty</th>
<th>Mounted</th>
<th>Persistent</th>
</tr>
</tbody>
</table>
</body>
</html>
......@@ -18,13 +18,6 @@ function updateAuthStatus(authStatus) {
*/
function updateGCacheContents(gcacheContents) {
var tbody = $('gcache-contents');
// Add a header row.
var tr = document.createElement('tr');
tr.appendChild(createElementFromText('th', 'Path'));
tr.appendChild(createElementFromText('th', 'Size'));
tr.appendChild(createElementFromText('th', 'Last Modified'));
tbody.appendChild(tr);
for (var i = 0; i < gcacheContents.length; i++) {
var entry = gcacheContents[i];
var tr = document.createElement('tr');
......@@ -54,6 +47,24 @@ function updateFileSystemContents(directoryContentsAsText) {
div.appendChild(createElementFromText('pre', directoryContentsAsText));
}
/**
* Updates the Cache Contents section.
* @param {Object} cacheEntry Dictionary describing a cache entry.
* The function is called from the C++ side repeatedly.
*/
function updateCacheContents(cacheEntry) {
var tr = document.createElement('tr');
tr.appendChild(createElementFromText('td', cacheEntry.resource_id));
tr.appendChild(createElementFromText('td', cacheEntry.md5));
tr.appendChild(createElementFromText('td', cacheEntry.is_present));
tr.appendChild(createElementFromText('td', cacheEntry.is_pinned));
tr.appendChild(createElementFromText('td', cacheEntry.is_dirty));
tr.appendChild(createElementFromText('td', cacheEntry.is_mounted));
tr.appendChild(createElementFromText('td', cacheEntry.is_persistent));
$('cache-contents').appendChild(tr);
}
/**
* Creates an element named |elementName| containing the content |text|.
* @param {string} elementName Name of the new element to be created.
......
......@@ -141,7 +141,8 @@ std::string FormatEntry(const FilePath& path,
class DriveInternalsWebUIHandler : public content::WebUIMessageHandler {
public:
DriveInternalsWebUIHandler()
: weak_ptr_factory_(this) {
: num_pending_reads_(0),
weak_ptr_factory_(this) {
}
virtual ~DriveInternalsWebUIHandler() {
......@@ -166,6 +167,17 @@ class DriveInternalsWebUIHandler : public content::WebUIMessageHandler {
bool hide_hosted_documents,
scoped_ptr<gdata::GDataEntryProtoVector> entries);
// Called when GetResourceIdsOfAllFilesOnUIThread() is complete.
void OnGetResourceIdsOfAllFiles(
const std::vector<std::string>& resource_ids);
// Called when GetCacheEntryOnUIThread() is complete.
void OnGetCacheEntry(const std::string& resource_id,
bool success,
const gdata::GDataCacheEntry& cache_entry);
// The number of pending ReadDirectoryByPath() calls.
int num_pending_reads_;
base::WeakPtrFactory<DriveInternalsWebUIHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler);
};
......@@ -225,6 +237,7 @@ void DriveInternalsWebUIHandler::OnGetGCacheContents(
// Start rendering the file system tree as text.
const FilePath root_path = FilePath(gdata::kGDataRootDirectory);
++num_pending_reads_;
system_service->file_system()->ReadDirectoryByPath(
root_path,
base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath,
......@@ -237,32 +250,77 @@ void DriveInternalsWebUIHandler::OnReadDirectoryByPath(
gdata::GDataFileError error,
bool hide_hosted_documents,
scoped_ptr<gdata::GDataEntryProtoVector> entries) {
if (error != gdata::GDATA_FILE_OK)
return;
DCHECK(entries.get());
std::string file_system_as_text;
for (size_t i = 0; i < entries->size(); ++i) {
const gdata::GDataEntryProto& entry = (*entries)[i];
const FilePath current_path = parent_path.Append(
FilePath::FromUTF8Unsafe(entry.base_name()));
file_system_as_text.append(FormatEntry(current_path, entry) + "\n");
if (entry.file_info().is_directory()) {
GetSystemService()->file_system()->ReadDirectoryByPath(
current_path,
base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath,
weak_ptr_factory_.GetWeakPtr(),
current_path));
--num_pending_reads_;
if (error == gdata::GDATA_FILE_OK) {
DCHECK(entries.get());
std::string file_system_as_text;
for (size_t i = 0; i < entries->size(); ++i) {
const gdata::GDataEntryProto& entry = (*entries)[i];
const FilePath current_path = parent_path.Append(
FilePath::FromUTF8Unsafe(entry.base_name()));
file_system_as_text.append(FormatEntry(current_path, entry) + "\n");
if (entry.file_info().is_directory()) {
++num_pending_reads_;
GetSystemService()->file_system()->ReadDirectoryByPath(
current_path,
base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath,
weak_ptr_factory_.GetWeakPtr(),
current_path));
}
}
// There may be pending ReadDirectoryByPath() calls, but we can update
// the page with what we have now. This results in progressive
// updates, which is good for a large file system.
const base::StringValue value(file_system_as_text);
web_ui()->CallJavascriptFunction("updateFileSystemContents", value);
}
// Start updating the cache contents section once all directories are
// processed.
if (num_pending_reads_ == 0) {
GetSystemService()->cache()->GetResourceIdsOfAllFilesOnUIThread(
base::Bind(&DriveInternalsWebUIHandler::OnGetResourceIdsOfAllFiles,
weak_ptr_factory_.GetWeakPtr()));
}
}
void DriveInternalsWebUIHandler::OnGetResourceIdsOfAllFiles(
const std::vector<std::string>& resource_ids) {
for (size_t i = 0; i < resource_ids.size(); ++i) {
const std::string& resource_id = resource_ids[i];
GetSystemService()->cache()->GetCacheEntryOnUIThread(
resource_id,
"", // Don't check MD5.
base::Bind(&DriveInternalsWebUIHandler::OnGetCacheEntry,
weak_ptr_factory_.GetWeakPtr(),
resource_id));
}
}
void DriveInternalsWebUIHandler::OnGetCacheEntry(
const std::string& resource_id,
bool success,
const gdata::GDataCacheEntry& cache_entry) {
if (!success) {
LOG(ERROR) << "Failed to get cache entry: " << resource_id;
return;
}
// There may be pending ReadDirectoryByPath() calls, but we can update
// the page with what we have now. This results in progressive
// updates, which is good for a large file system.
const base::StringValue value(file_system_as_text);
web_ui()->CallJavascriptFunction("updateFileSystemContents", value);
// Convert |cache_entry| into a dictionary.
base::DictionaryValue value;
value.SetString("resource_id", resource_id);
value.SetString("md5", cache_entry.md5());
value.SetBoolean("is_present", cache_entry.is_present());
value.SetBoolean("is_pinned", cache_entry.is_pinned());
value.SetBoolean("is_dirty", cache_entry.is_dirty());
value.SetBoolean("is_mounted", cache_entry.is_mounted());
value.SetBoolean("is_persistent", cache_entry.is_persistent());
web_ui()->CallJavascriptFunction("updateCacheContents", value);
}
} // namespace
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment