Index: chrome/browser/ui/webui/chromeos/drive_internals_ui.cc |
diff --git a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc |
index 09ad4d008fb6cb864b68843b89d2cbd6c582e120..343c0a6885dadee23f7d76d034874006f806c158 100644 |
--- a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc |
+++ b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc |
@@ -6,10 +6,14 @@ |
#include "base/bind.h" |
#include "base/file_util.h" |
+#include "base/format_macros.h" |
+#include "base/stringprintf.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_cache.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_util.h" |
#include "chrome/browser/profiles/profile.h" |
@@ -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 DriveInternalsWebUIHandler : public content::WebUIMessageHandler { |
public: |
@@ -89,56 +149,122 @@ class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { |
private: |
// WebUIMessageHandler override. |
- virtual void RegisterMessages() OVERRIDE { |
- web_ui()->RegisterMessageCallback( |
- "pageLoaded", |
- base::Bind(&DriveInternalsWebUIHandler::OnPageLoaded, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
+ virtual void RegisterMessages() OVERRIDE; |
+ |
+ // Returns a GDataSystemService. |
+ gdata::GDataSystemService* GetSystemService(); |
// Called when the page is first loaded. |
- 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))); |
- } |
+ void OnPageLoaded(const base::ListValue* args); |
// Called when GetGCacheContents() is complete. |
- void OnGetGCacheContents(base::ListValue* gcache_contents) { |
- DCHECK(gcache_contents); |
- web_ui()->CallJavascriptFunction("updateGCacheContents", *gcache_contents); |
- } |
+ void OnGetGCacheContents(base::ListValue* 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_; |
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 |
DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui) |