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

gdata: Add File System Contents section to chrome:drive-internals

This section is used to show metadata of the file system as pre-formatted
text. We could make it prettier, but pre-formatted text should be sufficient
for developers.

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

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148759 0039d316-1c4b-4281-b951-d872f2087c98
parent ff48ff7a
...@@ -6,3 +6,7 @@ ...@@ -6,3 +6,7 @@
#gcache-contents { #gcache-contents {
font-size: small; font-size: small;
} }
#file-system-contents {
font-size: small;
}
...@@ -18,5 +18,7 @@ ...@@ -18,5 +18,7 @@
<table> <table>
<tbody id='gcache-contents'></tbody> <tbody id='gcache-contents'></tbody>
</table> </table>
<h2>File System Contents</h2>
<div id='file-system-contents'></div>
</body> </body>
</html> </html>
...@@ -43,6 +43,17 @@ function updateGCacheContents(gcacheContents) { ...@@ -43,6 +43,17 @@ function updateGCacheContents(gcacheContents) {
} }
} }
/**
* Updates the File System Contents section. The function is called from the
* C++ side repeatedly with contents of a directory.
* @param {string} directoryContentsAsText Pre-formatted string representation
* of contents a directory in the file system.
*/
function updateFileSystemContents(directoryContentsAsText) {
var div = $('file-system-contents');
div.appendChild(createElementFromText('pre', directoryContentsAsText));
}
/** /**
* Creates an element named |elementName| containing the content |text|. * Creates an element named |elementName| containing the content |text|.
* @param {string} elementName Name of the new element to be created. * @param {string} elementName Name of the new element to be created.
......
...@@ -6,10 +6,14 @@ ...@@ -6,10 +6,14 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/file_util.h" #include "base/file_util.h"
#include "base/format_macros.h"
#include "base/stringprintf.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/gdata/gdata.pb.h"
#include "chrome/browser/chromeos/gdata/gdata_auth_service.h" #include "chrome/browser/chromeos/gdata/gdata_auth_service.h"
#include "chrome/browser/chromeos/gdata/gdata_cache.h" #include "chrome/browser/chromeos/gdata/gdata_cache.h"
#include "chrome/browser/chromeos/gdata/gdata_documents_service.h" #include "chrome/browser/chromeos/gdata/gdata_documents_service.h"
#include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h"
#include "chrome/browser/chromeos/gdata/gdata_system_service.h" #include "chrome/browser/chromeos/gdata/gdata_system_service.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h" #include "chrome/browser/chromeos/gdata/gdata_util.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -77,6 +81,62 @@ void GetGCacheContents(const FilePath& root_path, ...@@ -77,6 +81,62 @@ void GetGCacheContents(const FilePath& root_path,
} }
} }
// Formats |entry| into text.
std::string FormatEntry(const FilePath& path,
const gdata::GDataEntryProto& entry) {
using base::StringAppendF;
using gdata::util::FormatTimeAsString;
std::string out;
StringAppendF(&out, "%s\n", path.AsUTF8Unsafe().c_str());
StringAppendF(&out, " title: %s\n", entry.title().c_str());
StringAppendF(&out, " resource_id: %s\n", entry.resource_id().c_str());
StringAppendF(&out, " edit_url: %s\n", entry.edit_url().c_str());
StringAppendF(&out, " content_url: %s\n", entry.content_url().c_str());
StringAppendF(&out, " parent_resource_id: %s\n",
entry.parent_resource_id().c_str());
StringAppendF(&out, " upload_url: %s\n", entry.upload_url().c_str());
const gdata::PlatformFileInfoProto& file_info = entry.file_info();
StringAppendF(&out, " file_info\n");
StringAppendF(&out, " size: %"PRId64"\n", file_info.size());
StringAppendF(&out, " is_directory: %d\n", file_info.is_directory());
StringAppendF(&out, " is_symbolic_link: %d\n",
file_info.is_symbolic_link());
const base::Time last_modified = base::Time::FromInternalValue(
file_info.last_modified());
const base::Time last_accessed = base::Time::FromInternalValue(
file_info.last_accessed());
const base::Time creation_time = base::Time::FromInternalValue(
file_info.creation_time());
StringAppendF(&out, " last_modified: %s\n",
FormatTimeAsString(last_modified).c_str());
StringAppendF(&out, " last_accessed: %s\n",
FormatTimeAsString(last_accessed).c_str());
StringAppendF(&out, " creation_time: %s\n",
FormatTimeAsString(creation_time).c_str());
if (entry.has_file_specific_info()) {
const gdata::GDataFileSpecificInfo& file_specific_info =
entry.file_specific_info();
StringAppendF(&out, " thumbnail_url: %s\n",
file_specific_info.thumbnail_url().c_str());
StringAppendF(&out, " alternate_url: %s\n",
file_specific_info.alternate_url().c_str());
StringAppendF(&out, " content_mime_type: %s\n",
file_specific_info.content_mime_type().c_str());
StringAppendF(&out, " file_md5: %s\n",
file_specific_info.file_md5().c_str());
StringAppendF(&out, " document_extension: %s\n",
file_specific_info.document_extension().c_str());
StringAppendF(&out, " is_hosted_document: %d\n",
file_specific_info.is_hosted_document());
}
return out;
}
// Class to handle messages from chrome://drive-internals. // Class to handle messages from chrome://drive-internals.
class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { class DriveInternalsWebUIHandler : public content::WebUIMessageHandler {
public: public:
...@@ -89,56 +149,122 @@ class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { ...@@ -89,56 +149,122 @@ class DriveInternalsWebUIHandler : public content::WebUIMessageHandler {
private: private:
// WebUIMessageHandler override. // WebUIMessageHandler override.
virtual void RegisterMessages() OVERRIDE { virtual void RegisterMessages() OVERRIDE;
web_ui()->RegisterMessageCallback(
"pageLoaded", // Returns a GDataSystemService.
base::Bind(&DriveInternalsWebUIHandler::OnPageLoaded, gdata::GDataSystemService* GetSystemService();
weak_ptr_factory_.GetWeakPtr()));
}
// Called when the page is first loaded. // Called when the page is first loaded.
void OnPageLoaded(const base::ListValue* args) { void OnPageLoaded(const base::ListValue* args);
Profile* profile = Profile::FromWebUI(web_ui());
gdata::GDataSystemService* system_service =
gdata::GDataSystemServiceFactory::GetForProfile(profile);
// |system_service| may be NULL in the guest/incognito mode.
if (!system_service)
return;
gdata::DocumentsServiceInterface* documents_service =
system_service->docs_service();
DCHECK(documents_service);
// Update the auth status section.
base::DictionaryValue auth_status;
auth_status.SetBoolean("has-refresh-token",
documents_service->HasRefreshToken());
auth_status.SetBoolean("has-access-token",
documents_service->HasAccessToken());
web_ui()->CallJavascriptFunction("updateAuthStatus", auth_status);
// Start updating the GCache contents section.
const FilePath root_path =
gdata::GDataCache::GetCacheRootPath(profile);
base::ListValue* gcache_contents = new ListValue;
content::BrowserThread::PostBlockingPoolTaskAndReply(
FROM_HERE,
base::Bind(&GetGCacheContents, root_path, gcache_contents),
base::Bind(&DriveInternalsWebUIHandler::OnGetGCacheContents,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(gcache_contents)));
}
// Called when GetGCacheContents() is complete. // Called when GetGCacheContents() is complete.
void OnGetGCacheContents(base::ListValue* gcache_contents) { void OnGetGCacheContents(base::ListValue* gcache_contents);
DCHECK(gcache_contents);
web_ui()->CallJavascriptFunction("updateGCacheContents", *gcache_contents); // Called when ReadDirectoryByPath() is complete.
} void OnReadDirectoryByPath(const FilePath& parent_path,
gdata::GDataFileError error,
bool hide_hosted_documents,
scoped_ptr<gdata::GDataEntryProtoVector> entries);
base::WeakPtrFactory<DriveInternalsWebUIHandler> weak_ptr_factory_; base::WeakPtrFactory<DriveInternalsWebUIHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler); DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler);
}; };
void DriveInternalsWebUIHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"pageLoaded",
base::Bind(&DriveInternalsWebUIHandler::OnPageLoaded,
weak_ptr_factory_.GetWeakPtr()));
}
gdata::GDataSystemService* DriveInternalsWebUIHandler::GetSystemService() {
Profile* profile = Profile::FromWebUI(web_ui());
return gdata::GDataSystemServiceFactory::GetForProfile(profile);
}
void DriveInternalsWebUIHandler::OnPageLoaded(const base::ListValue* args) {
gdata::GDataSystemService* system_service = GetSystemService();
// |system_service| may be NULL in the guest/incognito mode.
if (!system_service)
return;
gdata::DocumentsServiceInterface* documents_service =
system_service->docs_service();
DCHECK(documents_service);
// Update the auth status section.
base::DictionaryValue auth_status;
auth_status.SetBoolean("has-refresh-token",
documents_service->HasRefreshToken());
auth_status.SetBoolean("has-access-token",
documents_service->HasAccessToken());
web_ui()->CallJavascriptFunction("updateAuthStatus", auth_status);
// Start updating the GCache contents section.
Profile* profile = Profile::FromWebUI(web_ui());
const FilePath root_path =
gdata::GDataCache::GetCacheRootPath(profile);
base::ListValue* gcache_contents = new ListValue;
content::BrowserThread::PostBlockingPoolTaskAndReply(
FROM_HERE,
base::Bind(&GetGCacheContents, root_path, gcache_contents),
base::Bind(&DriveInternalsWebUIHandler::OnGetGCacheContents,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(gcache_contents)));
}
void DriveInternalsWebUIHandler::OnGetGCacheContents(
base::ListValue* gcache_contents) {
DCHECK(gcache_contents);
web_ui()->CallJavascriptFunction("updateGCacheContents", *gcache_contents);
// Start updating the file system tree section, if we have access token.
gdata::GDataSystemService* system_service = GetSystemService();
if (!system_service->docs_service()->HasAccessToken())
return;
// Start rendering the file system tree as text.
const FilePath root_path = FilePath(gdata::kGDataRootDirectory);
system_service->file_system()->ReadDirectoryByPath(
root_path,
base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath,
weak_ptr_factory_.GetWeakPtr(),
root_path));
}
void DriveInternalsWebUIHandler::OnReadDirectoryByPath(
const FilePath& parent_path,
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));
}
}
// 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);
}
} // namespace } // namespace
DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui) DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui)
......
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