OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/chromeos/drive_internals_ui.h" | 5 #include "chrome/browser/ui/webui/chromeos/drive_internals_ui.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/format_macros.h" |
| 10 #include "base/stringprintf.h" |
9 #include "base/memory/weak_ptr.h" | 11 #include "base/memory/weak_ptr.h" |
| 12 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
10 #include "chrome/browser/chromeos/gdata/gdata_auth_service.h" | 13 #include "chrome/browser/chromeos/gdata/gdata_auth_service.h" |
11 #include "chrome/browser/chromeos/gdata/gdata_cache.h" | 14 #include "chrome/browser/chromeos/gdata/gdata_cache.h" |
12 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" | 15 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" |
| 16 #include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h" |
13 #include "chrome/browser/chromeos/gdata/gdata_system_service.h" | 17 #include "chrome/browser/chromeos/gdata/gdata_system_service.h" |
14 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 18 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
15 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" | 20 #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" |
17 #include "chrome/common/url_constants.h" | 21 #include "chrome/common/url_constants.h" |
18 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/web_ui.h" | 23 #include "content/public/browser/web_ui.h" |
20 #include "content/public/browser/web_ui_message_handler.h" | 24 #include "content/public/browser/web_ui_message_handler.h" |
21 #include "grit/browser_resources.h" | 25 #include "grit/browser_resources.h" |
22 | 26 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 files[current] = entry; | 74 files[current] = entry; |
71 } | 75 } |
72 | 76 |
73 // Convert |files| into |gcache_contents|. | 77 // Convert |files| into |gcache_contents|. |
74 for (std::map<FilePath, DictionaryValue*>::const_iterator | 78 for (std::map<FilePath, DictionaryValue*>::const_iterator |
75 iter = files.begin(); iter != files.end(); ++iter) { | 79 iter = files.begin(); iter != files.end(); ++iter) { |
76 gcache_contents->Append(iter->second); | 80 gcache_contents->Append(iter->second); |
77 } | 81 } |
78 } | 82 } |
79 | 83 |
| 84 // Formats |entry| into text. |
| 85 std::string FormatEntry(const FilePath& path, |
| 86 const gdata::GDataEntryProto& entry) { |
| 87 using base::StringAppendF; |
| 88 using gdata::util::FormatTimeAsString; |
| 89 |
| 90 std::string out; |
| 91 StringAppendF(&out, "%s\n", path.AsUTF8Unsafe().c_str()); |
| 92 StringAppendF(&out, " title: %s\n", entry.title().c_str()); |
| 93 StringAppendF(&out, " resource_id: %s\n", entry.resource_id().c_str()); |
| 94 StringAppendF(&out, " edit_url: %s\n", entry.edit_url().c_str()); |
| 95 StringAppendF(&out, " content_url: %s\n", entry.content_url().c_str()); |
| 96 StringAppendF(&out, " parent_resource_id: %s\n", |
| 97 entry.parent_resource_id().c_str()); |
| 98 StringAppendF(&out, " upload_url: %s\n", entry.upload_url().c_str()); |
| 99 |
| 100 const gdata::PlatformFileInfoProto& file_info = entry.file_info(); |
| 101 StringAppendF(&out, " file_info\n"); |
| 102 StringAppendF(&out, " size: %"PRId64"\n", file_info.size()); |
| 103 StringAppendF(&out, " is_directory: %d\n", file_info.is_directory()); |
| 104 StringAppendF(&out, " is_symbolic_link: %d\n", |
| 105 file_info.is_symbolic_link()); |
| 106 |
| 107 const base::Time last_modified = base::Time::FromInternalValue( |
| 108 file_info.last_modified()); |
| 109 const base::Time last_accessed = base::Time::FromInternalValue( |
| 110 file_info.last_accessed()); |
| 111 const base::Time creation_time = base::Time::FromInternalValue( |
| 112 file_info.creation_time()); |
| 113 StringAppendF(&out, " last_modified: %s\n", |
| 114 FormatTimeAsString(last_modified).c_str()); |
| 115 StringAppendF(&out, " last_accessed: %s\n", |
| 116 FormatTimeAsString(last_accessed).c_str()); |
| 117 StringAppendF(&out, " creation_time: %s\n", |
| 118 FormatTimeAsString(creation_time).c_str()); |
| 119 |
| 120 if (entry.has_file_specific_info()) { |
| 121 const gdata::GDataFileSpecificInfo& file_specific_info = |
| 122 entry.file_specific_info(); |
| 123 StringAppendF(&out, " thumbnail_url: %s\n", |
| 124 file_specific_info.thumbnail_url().c_str()); |
| 125 StringAppendF(&out, " alternate_url: %s\n", |
| 126 file_specific_info.alternate_url().c_str()); |
| 127 StringAppendF(&out, " content_mime_type: %s\n", |
| 128 file_specific_info.content_mime_type().c_str()); |
| 129 StringAppendF(&out, " file_md5: %s\n", |
| 130 file_specific_info.file_md5().c_str()); |
| 131 StringAppendF(&out, " document_extension: %s\n", |
| 132 file_specific_info.document_extension().c_str()); |
| 133 StringAppendF(&out, " is_hosted_document: %d\n", |
| 134 file_specific_info.is_hosted_document()); |
| 135 } |
| 136 |
| 137 return out; |
| 138 } |
| 139 |
80 // Class to handle messages from chrome://drive-internals. | 140 // Class to handle messages from chrome://drive-internals. |
81 class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { | 141 class DriveInternalsWebUIHandler : public content::WebUIMessageHandler { |
82 public: | 142 public: |
83 DriveInternalsWebUIHandler() | 143 DriveInternalsWebUIHandler() |
84 : weak_ptr_factory_(this) { | 144 : weak_ptr_factory_(this) { |
85 } | 145 } |
86 | 146 |
87 virtual ~DriveInternalsWebUIHandler() { | 147 virtual ~DriveInternalsWebUIHandler() { |
88 } | 148 } |
89 | 149 |
90 private: | 150 private: |
91 // WebUIMessageHandler override. | 151 // WebUIMessageHandler override. |
92 virtual void RegisterMessages() OVERRIDE { | 152 virtual void RegisterMessages() OVERRIDE; |
93 web_ui()->RegisterMessageCallback( | 153 |
94 "pageLoaded", | 154 // Returns a GDataSystemService. |
95 base::Bind(&DriveInternalsWebUIHandler::OnPageLoaded, | 155 gdata::GDataSystemService* GetSystemService(); |
96 weak_ptr_factory_.GetWeakPtr())); | |
97 } | |
98 | 156 |
99 // Called when the page is first loaded. | 157 // Called when the page is first loaded. |
100 void OnPageLoaded(const base::ListValue* args) { | 158 void OnPageLoaded(const base::ListValue* args); |
101 Profile* profile = Profile::FromWebUI(web_ui()); | |
102 gdata::GDataSystemService* system_service = | |
103 gdata::GDataSystemServiceFactory::GetForProfile(profile); | |
104 // |system_service| may be NULL in the guest/incognito mode. | |
105 if (!system_service) | |
106 return; | |
107 | |
108 gdata::DocumentsServiceInterface* documents_service = | |
109 system_service->docs_service(); | |
110 DCHECK(documents_service); | |
111 | |
112 // Update the auth status section. | |
113 base::DictionaryValue auth_status; | |
114 auth_status.SetBoolean("has-refresh-token", | |
115 documents_service->HasRefreshToken()); | |
116 auth_status.SetBoolean("has-access-token", | |
117 documents_service->HasAccessToken()); | |
118 web_ui()->CallJavascriptFunction("updateAuthStatus", auth_status); | |
119 | |
120 // Start updating the GCache contents section. | |
121 const FilePath root_path = | |
122 gdata::GDataCache::GetCacheRootPath(profile); | |
123 base::ListValue* gcache_contents = new ListValue; | |
124 content::BrowserThread::PostBlockingPoolTaskAndReply( | |
125 FROM_HERE, | |
126 base::Bind(&GetGCacheContents, root_path, gcache_contents), | |
127 base::Bind(&DriveInternalsWebUIHandler::OnGetGCacheContents, | |
128 weak_ptr_factory_.GetWeakPtr(), | |
129 base::Owned(gcache_contents))); | |
130 } | |
131 | 159 |
132 // Called when GetGCacheContents() is complete. | 160 // Called when GetGCacheContents() is complete. |
133 void OnGetGCacheContents(base::ListValue* gcache_contents) { | 161 void OnGetGCacheContents(base::ListValue* gcache_contents); |
134 DCHECK(gcache_contents); | 162 |
135 web_ui()->CallJavascriptFunction("updateGCacheContents", *gcache_contents); | 163 // Called when ReadDirectoryByPath() is complete. |
136 } | 164 void OnReadDirectoryByPath(const FilePath& parent_path, |
| 165 gdata::GDataFileError error, |
| 166 bool hide_hosted_documents, |
| 167 scoped_ptr<gdata::GDataEntryProtoVector> entries); |
137 | 168 |
138 base::WeakPtrFactory<DriveInternalsWebUIHandler> weak_ptr_factory_; | 169 base::WeakPtrFactory<DriveInternalsWebUIHandler> weak_ptr_factory_; |
139 DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler); | 170 DISALLOW_COPY_AND_ASSIGN(DriveInternalsWebUIHandler); |
140 }; | 171 }; |
141 | 172 |
| 173 void DriveInternalsWebUIHandler::RegisterMessages() { |
| 174 web_ui()->RegisterMessageCallback( |
| 175 "pageLoaded", |
| 176 base::Bind(&DriveInternalsWebUIHandler::OnPageLoaded, |
| 177 weak_ptr_factory_.GetWeakPtr())); |
| 178 } |
| 179 |
| 180 gdata::GDataSystemService* DriveInternalsWebUIHandler::GetSystemService() { |
| 181 Profile* profile = Profile::FromWebUI(web_ui()); |
| 182 return gdata::GDataSystemServiceFactory::GetForProfile(profile); |
| 183 } |
| 184 |
| 185 void DriveInternalsWebUIHandler::OnPageLoaded(const base::ListValue* args) { |
| 186 gdata::GDataSystemService* system_service = GetSystemService(); |
| 187 // |system_service| may be NULL in the guest/incognito mode. |
| 188 if (!system_service) |
| 189 return; |
| 190 |
| 191 gdata::DocumentsServiceInterface* documents_service = |
| 192 system_service->docs_service(); |
| 193 DCHECK(documents_service); |
| 194 |
| 195 // Update the auth status section. |
| 196 base::DictionaryValue auth_status; |
| 197 auth_status.SetBoolean("has-refresh-token", |
| 198 documents_service->HasRefreshToken()); |
| 199 auth_status.SetBoolean("has-access-token", |
| 200 documents_service->HasAccessToken()); |
| 201 web_ui()->CallJavascriptFunction("updateAuthStatus", auth_status); |
| 202 |
| 203 // Start updating the GCache contents section. |
| 204 Profile* profile = Profile::FromWebUI(web_ui()); |
| 205 const FilePath root_path = |
| 206 gdata::GDataCache::GetCacheRootPath(profile); |
| 207 base::ListValue* gcache_contents = new ListValue; |
| 208 content::BrowserThread::PostBlockingPoolTaskAndReply( |
| 209 FROM_HERE, |
| 210 base::Bind(&GetGCacheContents, root_path, gcache_contents), |
| 211 base::Bind(&DriveInternalsWebUIHandler::OnGetGCacheContents, |
| 212 weak_ptr_factory_.GetWeakPtr(), |
| 213 base::Owned(gcache_contents))); |
| 214 } |
| 215 |
| 216 void DriveInternalsWebUIHandler::OnGetGCacheContents( |
| 217 base::ListValue* gcache_contents) { |
| 218 DCHECK(gcache_contents); |
| 219 web_ui()->CallJavascriptFunction("updateGCacheContents", *gcache_contents); |
| 220 |
| 221 // Start updating the file system tree section, if we have access token. |
| 222 gdata::GDataSystemService* system_service = GetSystemService(); |
| 223 if (!system_service->docs_service()->HasAccessToken()) |
| 224 return; |
| 225 |
| 226 // Start rendering the file system tree as text. |
| 227 const FilePath root_path = FilePath(gdata::kGDataRootDirectory); |
| 228 system_service->file_system()->ReadDirectoryByPath( |
| 229 root_path, |
| 230 base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath, |
| 231 weak_ptr_factory_.GetWeakPtr(), |
| 232 root_path)); |
| 233 } |
| 234 |
| 235 void DriveInternalsWebUIHandler::OnReadDirectoryByPath( |
| 236 const FilePath& parent_path, |
| 237 gdata::GDataFileError error, |
| 238 bool hide_hosted_documents, |
| 239 scoped_ptr<gdata::GDataEntryProtoVector> entries) { |
| 240 if (error != gdata::GDATA_FILE_OK) |
| 241 return; |
| 242 DCHECK(entries.get()); |
| 243 |
| 244 std::string file_system_as_text; |
| 245 for (size_t i = 0; i < entries->size(); ++i) { |
| 246 const gdata::GDataEntryProto& entry = (*entries)[i]; |
| 247 const FilePath current_path = parent_path.Append( |
| 248 FilePath::FromUTF8Unsafe(entry.base_name())); |
| 249 |
| 250 file_system_as_text.append(FormatEntry(current_path, entry) + "\n"); |
| 251 |
| 252 if (entry.file_info().is_directory()) { |
| 253 GetSystemService()->file_system()->ReadDirectoryByPath( |
| 254 current_path, |
| 255 base::Bind(&DriveInternalsWebUIHandler::OnReadDirectoryByPath, |
| 256 weak_ptr_factory_.GetWeakPtr(), |
| 257 current_path)); |
| 258 } |
| 259 } |
| 260 |
| 261 // There may be pending ReadDirectoryByPath() calls, but we can update |
| 262 // the page with what we have now. This results in progressive |
| 263 // updates, which is good for a large file system. |
| 264 const base::StringValue value(file_system_as_text); |
| 265 web_ui()->CallJavascriptFunction("updateFileSystemContents", value); |
| 266 } |
| 267 |
142 } // namespace | 268 } // namespace |
143 | 269 |
144 DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui) | 270 DriveInternalsUI::DriveInternalsUI(content::WebUI* web_ui) |
145 : WebUIController(web_ui) { | 271 : WebUIController(web_ui) { |
146 web_ui->AddMessageHandler(new DriveInternalsWebUIHandler()); | 272 web_ui->AddMessageHandler(new DriveInternalsWebUIHandler()); |
147 | 273 |
148 ChromeWebUIDataSource* source = | 274 ChromeWebUIDataSource* source = |
149 new ChromeWebUIDataSource(chrome::kChromeUIDriveInternalsHost); | 275 new ChromeWebUIDataSource(chrome::kChromeUIDriveInternalsHost); |
150 source->add_resource_path("drive_internals.css", IDR_DRIVE_INTERNALS_CSS); | 276 source->add_resource_path("drive_internals.css", IDR_DRIVE_INTERNALS_CSS); |
151 source->add_resource_path("drive_internals.js", IDR_DRIVE_INTERNALS_JS); | 277 source->add_resource_path("drive_internals.js", IDR_DRIVE_INTERNALS_JS); |
152 source->set_default_resource(IDR_DRIVE_INTERNALS_HTML); | 278 source->set_default_resource(IDR_DRIVE_INTERNALS_HTML); |
153 | 279 |
154 Profile* profile = Profile::FromWebUI(web_ui); | 280 Profile* profile = Profile::FromWebUI(web_ui); |
155 ChromeURLDataManager::AddDataSource(profile, source); | 281 ChromeURLDataManager::AddDataSource(profile, source); |
156 } | 282 } |
157 | 283 |
158 } // namespace chromeos | 284 } // namespace chromeos |
OLD | NEW |