blob: a1b56d95a07861ed10e1837d4926f525250e435b [file] [log] [blame]
[email protected]698601e2009-10-21 22:43:371// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/dom_ui/filebrowse_ui.h"
6
7#include "app/l10n_util.h"
8#include "app/resource_bundle.h"
[email protected]2041cf342010-02-19 03:15:599#include "base/callback.h"
[email protected]698601e2009-10-21 22:43:3710#include "base/logging.h"
11#include "base/message_loop.h"
[email protected]07046ab2010-01-20 21:42:4412#include "base/path_service.h"
[email protected]5c4c7402009-10-30 19:58:0613#include "base/singleton.h"
[email protected]698601e2009-10-21 22:43:3714#include "base/string_piece.h"
15#include "base/string_util.h"
16#include "base/thread.h"
17#include "base/time.h"
18#include "base/values.h"
[email protected]9d6b9aff2009-12-11 17:39:1819#include "base/weak_ptr.h"
[email protected]698601e2009-10-21 22:43:3720#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]dcd23fe2009-11-12 20:21:1821#include "chrome/browser/browser.h"
[email protected]1717246f2010-02-10 17:08:1522#include "chrome/browser/browser_list.h"
[email protected]dcd23fe2009-11-12 20:21:1823#include "chrome/browser/browser_window.h"
[email protected]fae20792009-10-28 20:31:5824#include "chrome/browser/chrome_thread.h"
[email protected]698601e2009-10-21 22:43:3725#include "chrome/browser/dom_ui/dom_ui_favicon_source.h"
[email protected]274e42b2010-01-29 22:03:5726#include "chrome/browser/download/download_manager.h"
27#include "chrome/browser/download/download_util.h"
[email protected]1717246f2010-02-10 17:08:1528#include "chrome/browser/history/history_types.h"
[email protected]698601e2009-10-21 22:43:3729#include "chrome/browser/metrics/user_metrics.h"
[email protected]9d6b9aff2009-12-11 17:39:1830#include "chrome/browser/net/url_fetcher.h"
[email protected]698601e2009-10-21 22:43:3731#include "chrome/browser/profile.h"
[email protected]1717246f2010-02-10 17:08:1532#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]07046ab2010-01-20 21:42:4433#include "chrome/common/chrome_paths.h"
[email protected]698601e2009-10-21 22:43:3734#include "chrome/common/jstemplate_builder.h"
35#include "chrome/common/time_format.h"
36#include "chrome/common/url_constants.h"
37#include "net/base/escape.h"
38
39#include "grit/browser_resources.h"
40#include "grit/chromium_strings.h"
41#include "grit/generated_resources.h"
42#include "grit/locale_settings.h"
43
[email protected]07046ab2010-01-20 21:42:4444#if defined(OS_CHROMEOS)
[email protected]268b02f2010-02-04 21:07:1545#include "chrome/browser/chromeos/cros/mount_library.h"
[email protected]07046ab2010-01-20 21:42:4446#endif
47
[email protected]698601e2009-10-21 22:43:3748// Maximum number of search results to return in a given search. We should
49// eventually remove this.
50static const int kMaxSearchResults = 100;
51static const std::wstring kPropertyPath = L"path";
52static const std::wstring kPropertyTitle = L"title";
53static const std::wstring kPropertyDirectory = L"isDirectory";
[email protected]9d6b9aff2009-12-11 17:39:1854static const std::string kPicasawebUserPrefix =
55 "http://picasaweb.google.com/data/feed/api/user/";
56static const std::string kPicasawebDefault = "/albumid/default";
57static const std::string kPicasawebDropBox = "/DropBox";
58static const std::string kPicasawebBaseUrl = "http://picasaweb.google.com/";
[email protected]698601e2009-10-21 22:43:3759
[email protected]f5bf8ccf2010-02-05 18:19:2560static const char* kFilebrowseURLHash = "chrome://filebrowse#";
61static const int kPopupLeft = 0;
62static const int kPopupTop = 0;
63static const int kPopupWidth = 250;
64static const int kPopupHeight = 300;
65
[email protected]698601e2009-10-21 22:43:3766class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource {
67 public:
68 FileBrowseUIHTMLSource();
69
70 // Called when the network layer has requested a resource underneath
71 // the path we registered.
[email protected]f09d93792009-11-17 00:10:3672 virtual void StartDataRequest(const std::string& path,
73 bool is_off_the_record,
74 int request_id);
[email protected]698601e2009-10-21 22:43:3775 virtual std::string GetMimeType(const std::string&) const {
76 return "text/html";
77 }
78
79 private:
[email protected]8de85a62009-11-06 08:32:1780 ~FileBrowseUIHTMLSource() {}
81
[email protected]698601e2009-10-21 22:43:3782 DISALLOW_COPY_AND_ASSIGN(FileBrowseUIHTMLSource);
83};
84
[email protected]9d6b9aff2009-12-11 17:39:1885class TaskProxy;
86
[email protected]698601e2009-10-21 22:43:3787// The handler for Javascript messages related to the "filebrowse" view.
[email protected]dcd23fe2009-11-12 20:21:1888class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
[email protected]9d6b9aff2009-12-11 17:39:1889 public DOMMessageHandler,
[email protected]07046ab2010-01-20 21:42:4490#if defined(OS_CHROMEOS)
91 public chromeos::MountLibrary::Observer,
92#endif
[email protected]9d6b9aff2009-12-11 17:39:1893 public base::SupportsWeakPtr<FilebrowseHandler>,
[email protected]274e42b2010-01-29 22:03:5794 public URLFetcher::Delegate,
95 public DownloadManager::Observer,
96 public DownloadItem::Observer {
[email protected]698601e2009-10-21 22:43:3797 public:
[email protected]dcd23fe2009-11-12 20:21:1898 FilebrowseHandler();
99 virtual ~FilebrowseHandler();
[email protected]698601e2009-10-21 22:43:37100
[email protected]274e42b2010-01-29 22:03:57101 // Init work after Attach.
102 void Init();
103
[email protected]698601e2009-10-21 22:43:37104 // DirectoryLister::DirectoryListerDelegate methods:
105 virtual void OnListFile(const file_util::FileEnumerator::FindInfo& data);
106 virtual void OnListDone(int error);
107
108 // DOMMessageHandler implementation.
109 virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
110 virtual void RegisterMessages();
111
[email protected]07046ab2010-01-20 21:42:44112#if defined(OS_CHROMEOS)
113 void MountChanged(chromeos::MountLibrary* obj,
114 chromeos::MountEventType evt,
115 const std::string& path);
116#endif
117
[email protected]274e42b2010-01-29 22:03:57118 // DownloadItem::Observer interface
119 virtual void OnDownloadUpdated(DownloadItem* download);
120 virtual void OnDownloadFileCompleted(DownloadItem* download) { }
121 virtual void OnDownloadOpened(DownloadItem* download) { }
122
123 // DownloadManager::Observer interface
124 virtual void ModelChanged();
125 virtual void SetDownloads(std::vector<DownloadItem*>& downloads);
126
[email protected]698601e2009-10-21 22:43:37127 // Callback for the "getRoots" message.
128 void HandleGetRoots(const Value* value);
129
[email protected]a67fa08e2010-02-12 20:43:55130 void GetChildrenForPath(FilePath& path, bool is_refresh);
131
[email protected]9d6b9aff2009-12-11 17:39:18132 void OnURLFetchComplete(const URLFetcher* source,
133 const GURL& url,
134 const URLRequestStatus& status,
135 int response_code,
136 const ResponseCookies& cookies,
137 const std::string& data);
138
[email protected]698601e2009-10-21 22:43:37139 // Callback for the "getChildren" message.
140 void HandleGetChildren(const Value* value);
[email protected]c4a530b2010-03-08 17:33:03141 // Callback for the "refreshDirectory" message.
142 void HandleRefreshDirectory(const Value* value);
[email protected]698601e2009-10-21 22:43:37143
144 // Callback for the "getMetadata" message.
145 void HandleGetMetadata(const Value* value);
146
[email protected]9d6b9aff2009-12-11 17:39:18147 // Callback for the "openNewWindow" message.
[email protected]dcd23fe2009-11-12 20:21:18148 void OpenNewFullWindow(const Value* value);
149 void OpenNewPopupWindow(const Value* value);
150
[email protected]9d6b9aff2009-12-11 17:39:18151 // Callback for the "uploadToPicasaweb" message.
152 void UploadToPicasaweb(const Value* value);
153
[email protected]274e42b2010-01-29 22:03:57154 // Callback for the "getDownloads" message.
155 void HandleGetDownloads(const Value* value);
156
157 void HandleCreateNewFolder(const Value* value);
158
[email protected]a67fa08e2010-02-12 20:43:55159 void HandleDeleteFile(const Value* value);
160 void DeleteFile(const FilePath& path);
161 void FireDeleteComplete(const FilePath& path);
162
163 void HandlePauseToggleDownload(const Value* value);
164
[email protected]c4a530b2010-03-08 17:33:03165 void HandleCancelDownload(const Value* value);
166 void HandleAllowDownload(const Value* value);
167
[email protected]9d6b9aff2009-12-11 17:39:18168 void ReadInFile();
169 void FireUploadComplete();
170
[email protected]698601e2009-10-21 22:43:37171 private:
[email protected]dcd23fe2009-11-12 20:21:18172
173 void OpenNewWindow(const Value* value, bool popup);
174
[email protected]274e42b2010-01-29 22:03:57175 // Clear all download items and their observers.
176 void ClearDownloadItems();
177
178 // Send the current list of downloads to the page.
179 void SendCurrentDownloads();
180
[email protected]698601e2009-10-21 22:43:37181 scoped_ptr<ListValue> filelist_value_;
182 FilePath currentpath_;
[email protected]dcd23fe2009-11-12 20:21:18183 Profile* profile_;
[email protected]9d6b9aff2009-12-11 17:39:18184 std::string current_file_contents_;
185 std::string current_file_uploaded_;
186 int upload_response_code_;
187 TaskProxy* CurrentTask_;
[email protected]698601e2009-10-21 22:43:37188 scoped_refptr<net::DirectoryLister> lister_;
[email protected]a67fa08e2010-02-12 20:43:55189 bool is_refresh_;
[email protected]698601e2009-10-21 22:43:37190
[email protected]274e42b2010-01-29 22:03:57191 DownloadManager* download_manager_;
192 typedef std::vector<DownloadItem*> DownloadList;
193 DownloadList download_items_;
194
[email protected]dcd23fe2009-11-12 20:21:18195 DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler);
[email protected]698601e2009-10-21 22:43:37196};
197
[email protected]9d6b9aff2009-12-11 17:39:18198class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
199 public:
[email protected]a67fa08e2010-02-12 20:43:55200 explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler, FilePath& path)
201 : handler_(handler),
202 path_(path) {}
[email protected]9d6b9aff2009-12-11 17:39:18203 void ReadInFileProxy() {
204 if (handler_) {
205 handler_->ReadInFile();
206 }
207 }
208
209 void FireUploadCompleteProxy() {
210 if (handler_) {
211 handler_->FireUploadComplete();
212 }
213 }
[email protected]a67fa08e2010-02-12 20:43:55214
215 void DeleteFileProxy() {
216 if (handler_) {
217 handler_->DeleteFile(path_);
218 }
219 }
220
221 void FireDeleteCompleteProxy() {
222 if (handler_) {
223 handler_->FireDeleteComplete(path_);
224 }
225 }
[email protected]9d6b9aff2009-12-11 17:39:18226 private:
227 base::WeakPtr<FilebrowseHandler> handler_;
[email protected]a67fa08e2010-02-12 20:43:55228 FilePath path_;
[email protected]9d6b9aff2009-12-11 17:39:18229 friend class base::RefCountedThreadSafe<TaskProxy>;
230};
231
232
[email protected]698601e2009-10-21 22:43:37233////////////////////////////////////////////////////////////////////////////////
234//
235// FileBrowseHTMLSource
236//
237////////////////////////////////////////////////////////////////////////////////
238
239FileBrowseUIHTMLSource::FileBrowseUIHTMLSource()
240 : DataSource(chrome::kChromeUIFileBrowseHost, MessageLoop::current()) {
241}
242
243void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path,
[email protected]f09d93792009-11-17 00:10:36244 bool is_off_the_record, int request_id) {
[email protected]698601e2009-10-21 22:43:37245 DictionaryValue localized_strings;
[email protected]11f4857282009-11-13 19:56:17246 // TODO(dhg): Add stirings to localized strings, also add more strings
[email protected]dcd23fe2009-11-12 20:21:18247 // that are currently hardcoded.
[email protected]f95f0752010-03-09 16:47:10248 localized_strings.SetString(L"title",
249 l10n_util::GetString(IDS_FILEBROWSER_TITLE));
250 localized_strings.SetString(L"pause",
251 l10n_util::GetString(IDS_FILEBROWSER_PAUSE));
252 localized_strings.SetString(L"resume",
253 l10n_util::GetString(IDS_FILEBROWSER_RESUME));
254 localized_strings.SetString(L"scanning",
255 l10n_util::GetString(IDS_FILEBROWSER_SCANNING));
256 localized_strings.SetString(L"confirmdelete",
257 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_DELETE));
258 localized_strings.SetString(L"confirmyes",
259 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_YES));
260 localized_strings.SetString(L"confirmcancel",
261 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_CANCEL));
262 localized_strings.SetString(L"allowdownload",
263 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_DOWNLOAD));
264 localized_strings.SetString(L"filenameprompt",
265 l10n_util::GetString(IDS_FILEBROWSER_PROMPT_FILENAME));
266 localized_strings.SetString(L"save",
267 l10n_util::GetString(IDS_FILEBROWSER_SAVE));
268 localized_strings.SetString(L"newfolder",
269 l10n_util::GetString(IDS_FILEBROWSER_NEW_FOLDER));
270 localized_strings.SetString(L"open",
271 l10n_util::GetString(IDS_FILEBROWSER_OPEN));
272 localized_strings.SetString(L"picasaweb",
273 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_PICASAWEB));
274 localized_strings.SetString(L"flikr",
275 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_FLIKR));
276 localized_strings.SetString(L"email",
277 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_EMAIL));
278 localized_strings.SetString(L"delete",
279 l10n_util::GetString(IDS_FILEBROWSER_DELETE));
[email protected]698601e2009-10-21 22:43:37280
281 SetFontAndTextDirection(&localized_strings);
282
283 static const base::StringPiece filebrowse_html(
284 ResourceBundle::GetSharedInstance().GetRawDataResource(
285 IDR_FILEBROWSE_HTML));
286 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
287 filebrowse_html, &localized_strings);
288
289 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
290 html_bytes->data.resize(full_html.size());
291 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
292
293 SendResponse(request_id, html_bytes);
294}
295
296////////////////////////////////////////////////////////////////////////////////
297//
[email protected]dcd23fe2009-11-12 20:21:18298// FilebrowseHandler
[email protected]698601e2009-10-21 22:43:37299//
300////////////////////////////////////////////////////////////////////////////////
[email protected]dcd23fe2009-11-12 20:21:18301FilebrowseHandler::FilebrowseHandler()
[email protected]274e42b2010-01-29 22:03:57302 : profile_(NULL),
[email protected]a67fa08e2010-02-12 20:43:55303 is_refresh_(false),
[email protected]274e42b2010-01-29 22:03:57304 download_manager_(NULL) {
[email protected]a67fa08e2010-02-12 20:43:55305 lister_ = NULL;
[email protected]07046ab2010-01-20 21:42:44306#if defined(OS_CHROMEOS)
307 chromeos::MountLibrary* lib = chromeos::MountLibrary::Get();
308 lib->AddObserver(this);
309#endif
[email protected]698601e2009-10-21 22:43:37310}
311
[email protected]dcd23fe2009-11-12 20:21:18312FilebrowseHandler::~FilebrowseHandler() {
[email protected]07046ab2010-01-20 21:42:44313#if defined(OS_CHROMEOS)
314 chromeos::MountLibrary* lib = chromeos::MountLibrary::Get();
315 lib->RemoveObserver(this);
316#endif
[email protected]698601e2009-10-21 22:43:37317 if (lister_.get()) {
318 lister_->Cancel();
319 lister_->set_delegate(NULL);
320 }
[email protected]274e42b2010-01-29 22:03:57321
322 ClearDownloadItems();
323 download_manager_->RemoveObserver(this);
[email protected]698601e2009-10-21 22:43:37324}
325
[email protected]dcd23fe2009-11-12 20:21:18326DOMMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) {
[email protected]698601e2009-10-21 22:43:37327 // Create our favicon data source.
[email protected]fae20792009-10-28 20:31:58328 ChromeThread::PostTask(
329 ChromeThread::IO, FROM_HERE,
330 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:09331 Singleton<ChromeURLDataManager>::get(),
[email protected]fae20792009-10-28 20:31:58332 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:23333 make_scoped_refptr(new DOMUIFavIconSource(dom_ui->GetProfile()))));
[email protected]dcd23fe2009-11-12 20:21:18334 profile_ = dom_ui->GetProfile();
[email protected]274e42b2010-01-29 22:03:57335
[email protected]698601e2009-10-21 22:43:37336 return DOMMessageHandler::Attach(dom_ui);
337}
338
[email protected]274e42b2010-01-29 22:03:57339void FilebrowseHandler::Init() {
340 download_manager_ = profile_->GetOriginalProfile()->GetDownloadManager();
341 download_manager_->AddObserver(this);
342}
343
[email protected]dcd23fe2009-11-12 20:21:18344void FilebrowseHandler::RegisterMessages() {
[email protected]698601e2009-10-21 22:43:37345 dom_ui_->RegisterMessageCallback("getRoots",
[email protected]dcd23fe2009-11-12 20:21:18346 NewCallback(this, &FilebrowseHandler::HandleGetRoots));
[email protected]698601e2009-10-21 22:43:37347 dom_ui_->RegisterMessageCallback("getChildren",
[email protected]dcd23fe2009-11-12 20:21:18348 NewCallback(this, &FilebrowseHandler::HandleGetChildren));
[email protected]698601e2009-10-21 22:43:37349 dom_ui_->RegisterMessageCallback("getMetadata",
[email protected]dcd23fe2009-11-12 20:21:18350 NewCallback(this, &FilebrowseHandler::HandleGetMetadata));
351 dom_ui_->RegisterMessageCallback("openNewPopupWindow",
352 NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow));
353 dom_ui_->RegisterMessageCallback("openNewFullWindow",
354 NewCallback(this, &FilebrowseHandler::OpenNewFullWindow));
[email protected]9d6b9aff2009-12-11 17:39:18355 dom_ui_->RegisterMessageCallback("uploadToPicasaweb",
356 NewCallback(this, &FilebrowseHandler::UploadToPicasaweb));
[email protected]274e42b2010-01-29 22:03:57357 dom_ui_->RegisterMessageCallback("getDownloads",
358 NewCallback(this, &FilebrowseHandler::HandleGetDownloads));
359 dom_ui_->RegisterMessageCallback("createNewFolder",
360 NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder));
[email protected]a67fa08e2010-02-12 20:43:55361 dom_ui_->RegisterMessageCallback("pauseToggleDownload",
362 NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
363 dom_ui_->RegisterMessageCallback("deleteFile",
364 NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
[email protected]c4a530b2010-03-08 17:33:03365 dom_ui_->RegisterMessageCallback("cancelDownload",
366 NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
367 dom_ui_->RegisterMessageCallback("allowDownload",
368 NewCallback(this, &FilebrowseHandler::HandleAllowDownload));
369 dom_ui_->RegisterMessageCallback("refreshDirectory",
370 NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
[email protected]9d6b9aff2009-12-11 17:39:18371}
372
[email protected]a67fa08e2010-02-12 20:43:55373
374void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
375 // We notify the UI by telling it to refresh its contents.
376 FilePath dir_path = path.DirName();
377 GetChildrenForPath(dir_path, true);
378};
379
[email protected]9d6b9aff2009-12-11 17:39:18380void FilebrowseHandler::FireUploadComplete() {
381 DictionaryValue info_value;
382 info_value.SetString(L"path", current_file_uploaded_);
383
384 std::string username;
385 username = getenv("CHROMEOS_USER");
386
387 if (username.empty()) {
388 LOG(ERROR) << "Unable to get username";
389 return;
390 }
391 int location = username.find_first_of('@',0);
392 if (location <= 0) {
393 LOG(ERROR) << "Username not formatted correctly";
394 return;
395 }
396 username = username.erase(username.find_first_of('@',0));
397 std::string picture_url;
398 picture_url = kPicasawebBaseUrl;
399 picture_url += username;
400 picture_url += kPicasawebDropBox;
401 info_value.SetString(L"url", picture_url);
402 info_value.SetInteger(L"status_code", upload_response_code_);
403 dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value);
404}
405
[email protected]07046ab2010-01-20 21:42:44406#if defined(OS_CHROMEOS)
407void FilebrowseHandler::MountChanged(chromeos::MountLibrary* obj,
408 chromeos::MountEventType evt,
409 const std::string& path) {
410 if (evt == chromeos::DISK_REMOVED ||
411 evt == chromeos::DISK_CHANGED) {
412 dom_ui_->CallJavascriptFunction(L"rootsChanged");
413 }
414}
415#endif
416
[email protected]9d6b9aff2009-12-11 17:39:18417void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source,
418 const GURL& url,
419 const URLRequestStatus& status,
420 int response_code,
421 const ResponseCookies& cookies,
422 const std::string& data) {
423 upload_response_code_ = response_code;
424
425 ChromeThread::PostTask(
426 ChromeThread::UI, FROM_HERE,
427 NewRunnableMethod(CurrentTask_, &TaskProxy::FireUploadCompleteProxy));
[email protected]698601e2009-10-21 22:43:37428}
429
[email protected]dcd23fe2009-11-12 20:21:18430void FilebrowseHandler::HandleGetRoots(const Value* value) {
[email protected]698601e2009-10-21 22:43:37431 ListValue results_value;
432 DictionaryValue info_value;
[email protected]698601e2009-10-21 22:43:37433 // TODO(dhg): add other entries, make this more general
[email protected]07046ab2010-01-20 21:42:44434#if defined(OS_CHROMEOS)
435 chromeos::MountLibrary* lib = chromeos::MountLibrary::Get();
436 const chromeos::MountLibrary::DiskVector& disks = lib->disks();
437
438 for (size_t i = 0; i < disks.size(); ++i) {
439 if (!disks[i].mount_path.empty()) {
440 DictionaryValue* page_value = new DictionaryValue();
441 page_value->SetString(kPropertyPath, disks[i].mount_path);
442 FilePath currentpath;
443 currentpath = FilePath(disks[i].mount_path);
444 std::string filename;
445 filename = currentpath.BaseName().value();
446 page_value->SetString(kPropertyTitle, filename);
447 page_value->SetBoolean(kPropertyDirectory, true);
448 results_value.Append(page_value);
449 }
450 }
451#else
452 DictionaryValue* page_value = new DictionaryValue();
453 page_value->SetString(kPropertyPath, "/media");
454 page_value->SetString(kPropertyTitle, "Removeable");
[email protected]698601e2009-10-21 22:43:37455 page_value->SetBoolean(kPropertyDirectory, true);
456
457 results_value.Append(page_value);
[email protected]07046ab2010-01-20 21:42:44458#endif
459 FilePath default_download_path;
460 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
461 &default_download_path)) {
462 NOTREACHED();
463 }
464
465 DictionaryValue* download_value = new DictionaryValue();
466 download_value->SetString(kPropertyPath, default_download_path.value());
467 download_value->SetString(kPropertyTitle, "File Shelf");
468 download_value->SetBoolean(kPropertyDirectory, true);
469
470 results_value.Append(download_value);
[email protected]698601e2009-10-21 22:43:37471
[email protected]9d6b9aff2009-12-11 17:39:18472 info_value.SetString(L"functionCall", "getRoots");
[email protected]07046ab2010-01-20 21:42:44473 info_value.SetString(kPropertyPath, "");
[email protected]9d6b9aff2009-12-11 17:39:18474 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37475 info_value, results_value);
476}
477
[email protected]274e42b2010-01-29 22:03:57478void FilebrowseHandler::HandleCreateNewFolder(const Value* value) {
479#if defined(OS_CHROMEOS)
480 if (value && value->GetType() == Value::TYPE_LIST) {
481 const ListValue* list_value = static_cast<const ListValue*>(value);
482 std::string path;
483
484 // Get path string.
485 if (list_value->GetString(0, &path)) {
486
487 FilePath currentpath;
488 currentpath = FilePath(path);
489
490 if (!file_util::CreateDirectory(currentpath)) {
491 LOG(ERROR) << "unable to create directory";
492 }
493 } else {
494 LOG(ERROR) << "Unable to get string";
495 return;
496 }
497 }
498#endif
499}
500
[email protected]c4a530b2010-03-08 17:33:03501void FilebrowseHandler::HandleRefreshDirectory(const Value* value) {
502 if (value && value->GetType() == Value::TYPE_LIST) {
503 const ListValue* list_value = static_cast<const ListValue*>(value);
504 std::string path;
505
506 // Get path string.
507 if (list_value->GetString(0, &path)) {
508 FilePath currentpath;
509#if defined(OS_WIN)
510 currentpath = FilePath(ASCIIToWide(path));
511#else
512 currentpath = FilePath(path);
513#endif
514 GetChildrenForPath(currentpath, true);
515 } else {
516 LOG(ERROR) << "Unable to get string";
517 return;
518 }
519 }
520}
521
[email protected]a67fa08e2010-02-12 20:43:55522void FilebrowseHandler::HandlePauseToggleDownload(const Value* value) {
523#if defined(OS_CHROMEOS)
524 if (value && value->GetType() == Value::TYPE_LIST) {
525 const ListValue* list_value = static_cast<const ListValue*>(value);
526 int id;
527 std::string str_id;
528
529 if (list_value->GetString(0, &str_id)) {
530 id = atoi(str_id.c_str());
531 DownloadItem* item = download_items_[id];
532 item->TogglePause();
533 } else {
534 LOG(ERROR) << "Unable to get id for download to pause";
535 return;
536 }
537 }
538#endif
539}
540
[email protected]c4a530b2010-03-08 17:33:03541void FilebrowseHandler::HandleAllowDownload(const Value* value) {
542#if defined(OS_CHROMEOS)
543 if (value && value->GetType() == Value::TYPE_LIST) {
544 const ListValue* list_value = static_cast<const ListValue*>(value);
545 int id;
546 std::string str_id;
547
548 if (list_value->GetString(0, &str_id)) {
549 id = atoi(str_id.c_str());
550 DownloadItem* item = download_items_[id];
551 download_manager_->DangerousDownloadValidated(item);
552 } else {
553 LOG(ERROR) << "Unable to get id for download to pause";
554 return;
555 }
556 }
557#endif
558}
559
560void FilebrowseHandler::HandleCancelDownload(const Value* value) {
561#if defined(OS_CHROMEOS)
562 if (value && value->GetType() == Value::TYPE_LIST) {
563 const ListValue* list_value = static_cast<const ListValue*>(value);
564 int id;
565 std::string str_id;
566
567 if (list_value->GetString(0, &str_id)) {
568 id = atoi(str_id.c_str());
569 DownloadItem* item = download_items_[id];
570 item->Cancel(true);
571 FilePath path = item->full_path();
572 FilePath dir_path = path.DirName();
573 item->Remove(true);
574 GetChildrenForPath(dir_path, true);
575 } else {
576 LOG(ERROR) << "Unable to get id for download to pause";
577 return;
578 }
579 }
580#endif
581}
582
[email protected]dcd23fe2009-11-12 20:21:18583void FilebrowseHandler::OpenNewFullWindow(const Value* value) {
584 OpenNewWindow(value, false);
585}
[email protected]698601e2009-10-21 22:43:37586
[email protected]dcd23fe2009-11-12 20:21:18587void FilebrowseHandler::OpenNewPopupWindow(const Value* value) {
588 OpenNewWindow(value, true);
589}
590
591void FilebrowseHandler::OpenNewWindow(const Value* value, bool popup) {
592 if (value && value->GetType() == Value::TYPE_LIST) {
593 const ListValue* list_value = static_cast<const ListValue*>(value);
594 Value* list_member;
595 std::string path;
596
597 // Get path string.
598 if (list_value->Get(0, &list_member) &&
599 list_member->GetType() == Value::TYPE_STRING) {
600 const StringValue* string_value =
601 static_cast<const StringValue*>(list_member);
602 string_value->GetAsString(&path);
603 } else {
604 LOG(ERROR) << "Unable to get string";
605 return;
606 }
607 Browser* browser;
608 if (popup) {
609 browser = Browser::CreateForPopup(profile_);
610 } else {
611 browser = Browser::Create(profile_);
612 }
613 browser->AddTabWithURL(
614 GURL(path), GURL(), PageTransition::LINK,
615 true, -1, false, NULL);
616 if (popup) {
617 // TODO(dhg): Remove these from being hardcoded. Allow javascript
618 // to specify.
[email protected]078a10a2010-03-02 17:41:44619 browser->window()->SetBounds(gfx::Rect(0, 0, 400, 300),
620 BrowserWindow::WINDOW_BOUNDS);
[email protected]dcd23fe2009-11-12 20:21:18621 } else {
[email protected]078a10a2010-03-02 17:41:44622 browser->window()->SetBounds(gfx::Rect(0, 0, 800, 600),
623 BrowserWindow::WINDOW_BOUNDS);
[email protected]dcd23fe2009-11-12 20:21:18624 }
625 browser->window()->Show();
626 } else {
627 LOG(ERROR) << "Wasn't able to get the List if requested files.";
628 return;
629 }
630}
631
[email protected]9d6b9aff2009-12-11 17:39:18632void FilebrowseHandler::ReadInFile() {
633#if defined(OS_CHROMEOS)
634 // Get the users username
635 std::string username;
636 username = getenv("CHROMEOS_USER");
637
638 if (username.empty()) {
639 LOG(ERROR) << "Unable to get username";
640 return;
641 }
642 int location = username.find_first_of('@',0);
643 if (location <= 0) {
644 LOG(ERROR) << "Username not formatted correctly";
645 return;
646 }
647 username = username.erase(username.find_first_of('@',0));
648 std::string url = kPicasawebUserPrefix;
649 url += username;
650 url += kPicasawebDefault;
651
652 FilePath currentpath;
653 currentpath = FilePath(current_file_uploaded_);
654 // Get the filename
655 std::string filename;
656 filename = currentpath.BaseName().value();
657 std::string filecontents;
658 if (!file_util::ReadFileToString(currentpath, &filecontents)) {
659 LOG(ERROR) << "Unable to read this file:" << currentpath.value();
660 return;
661 }
662
663 URLFetcher* fetcher = URLFetcher::Create(0,
664 GURL(url),
665 URLFetcher::POST,
666 this);
667 fetcher->set_upload_data("image/jpeg", filecontents);
668
669 // Set the filename on the server
670 std::string slug = "Slug: ";
671 slug += filename;
672 fetcher->set_extra_request_headers(slug);
673 fetcher->set_request_context(Profile::GetDefaultRequestContext());
674 fetcher->Start();
675#endif
676}
677
678// This is just a prototype for allowing generic uploads to various sites
679// TODO(dhg): Remove this and implement general upload.
680void FilebrowseHandler::UploadToPicasaweb(const Value* value) {
681 std::string path;
682#if defined(OS_CHROMEOS)
683 if (value && value->GetType() == Value::TYPE_LIST) {
684 const ListValue* list_value = static_cast<const ListValue*>(value);
685 Value* list_member;
686
687 // Get search string.
688 if (list_value->Get(0, &list_member) &&
689 list_member->GetType() == Value::TYPE_STRING) {
690 const StringValue* string_value =
691 static_cast<const StringValue*>(list_member);
692 string_value->GetAsString(&path);
693 }
694
695 } else {
696 LOG(ERROR) << "Wasn't able to get the List if requested files.";
697 return;
698 }
699 current_file_uploaded_ = path;
700 // ReadInFile();
[email protected]a67fa08e2010-02-12 20:43:55701 FilePath current_path(path);
702 TaskProxy* task = new TaskProxy(AsWeakPtr(), current_path);
[email protected]9d6b9aff2009-12-11 17:39:18703 task->AddRef();
704 CurrentTask_ = task;
705 ChromeThread::PostTask(
706 ChromeThread::FILE, FROM_HERE,
707 NewRunnableMethod(
708 task, &TaskProxy::ReadInFileProxy));
709#endif
710}
711
[email protected]a67fa08e2010-02-12 20:43:55712void FilebrowseHandler::GetChildrenForPath(FilePath& path, bool is_refresh) {
713 filelist_value_.reset(new ListValue());
714 currentpath_ = FilePath(path);
715
716 if (lister_.get()) {
717 lister_->Cancel();
718 lister_->set_delegate(NULL);
719 lister_ = NULL;
720 }
721
722 is_refresh_ = is_refresh;
723 lister_ = new net::DirectoryLister(currentpath_, this);
724 lister_->Start();
725}
726
[email protected]dcd23fe2009-11-12 20:21:18727void FilebrowseHandler::HandleGetChildren(const Value* value) {
728 std::string path;
[email protected]698601e2009-10-21 22:43:37729 if (value && value->GetType() == Value::TYPE_LIST) {
730 const ListValue* list_value = static_cast<const ListValue*>(value);
731 Value* list_member;
732
733 // Get search string.
734 if (list_value->Get(0, &list_member) &&
735 list_member->GetType() == Value::TYPE_STRING) {
736 const StringValue* string_value =
737 static_cast<const StringValue*>(list_member);
738 string_value->GetAsString(&path);
739 }
740
741 } else {
[email protected]dcd23fe2009-11-12 20:21:18742 LOG(ERROR) << "Wasn't able to get the List if requested files.";
[email protected]698601e2009-10-21 22:43:37743 return;
744 }
745 filelist_value_.reset(new ListValue());
[email protected]a67fa08e2010-02-12 20:43:55746 FilePath currentpath;
[email protected]698601e2009-10-21 22:43:37747#if defined(OS_WIN)
[email protected]a67fa08e2010-02-12 20:43:55748 currentpath = FilePath(ASCIIToWide(path));
[email protected]698601e2009-10-21 22:43:37749#else
[email protected]a67fa08e2010-02-12 20:43:55750 currentpath = FilePath(path);
[email protected]698601e2009-10-21 22:43:37751#endif
752
[email protected]a67fa08e2010-02-12 20:43:55753 GetChildrenForPath(currentpath, false);
[email protected]698601e2009-10-21 22:43:37754}
755
[email protected]dcd23fe2009-11-12 20:21:18756void FilebrowseHandler::OnListFile(
[email protected]698601e2009-10-21 22:43:37757 const file_util::FileEnumerator::FindInfo& data) {
[email protected]07046ab2010-01-20 21:42:44758#if defined(OS_WIN)
759 if (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
760 return;
761 }
762#elif defined(OS_POSIX)
763 if (data.filename[0] == '.') {
764 return;
765 }
766#endif
767
[email protected]698601e2009-10-21 22:43:37768 DictionaryValue* file_value = new DictionaryValue();
769
770#if defined(OS_WIN)
771 int64 size = (static_cast<int64>(data.nFileSizeHigh) << 32) |
772 data.nFileSizeLow;
773 file_value->SetString(kPropertyTitle, data.cFileName);
774 file_value->SetString(kPropertyPath,
775 currentpath_.Append(data.cFileName).value());
776 file_value->SetBoolean(kPropertyDirectory,
777 (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
778
779#elif defined(OS_POSIX)
780 file_value->SetString(kPropertyTitle, data.filename);
781 file_value->SetString(kPropertyPath,
782 currentpath_.Append(data.filename).value());
783 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.stat.st_mode));
784#endif
785 filelist_value_->Append(file_value);
786}
787
[email protected]dcd23fe2009-11-12 20:21:18788void FilebrowseHandler::OnListDone(int error) {
[email protected]698601e2009-10-21 22:43:37789 DictionaryValue info_value;
[email protected]a67fa08e2010-02-12 20:43:55790 if (is_refresh_) {
791 info_value.SetString(L"functionCall", "refresh");
792 } else {
793 info_value.SetString(L"functionCall", "getChildren");
794 }
[email protected]698601e2009-10-21 22:43:37795 info_value.SetString(kPropertyPath, currentpath_.value());
[email protected]9d6b9aff2009-12-11 17:39:18796 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37797 info_value, *(filelist_value_.get()));
[email protected]a67fa08e2010-02-12 20:43:55798 SendCurrentDownloads();
[email protected]698601e2009-10-21 22:43:37799}
800
[email protected]dcd23fe2009-11-12 20:21:18801void FilebrowseHandler::HandleGetMetadata(const Value* value) {
[email protected]698601e2009-10-21 22:43:37802}
803
[email protected]274e42b2010-01-29 22:03:57804void FilebrowseHandler::HandleGetDownloads(const Value* value) {
805 ModelChanged();
806}
807
808void FilebrowseHandler::ModelChanged() {
809 ClearDownloadItems();
[email protected]c4a530b2010-03-08 17:33:03810 download_manager_->GetCurrentDownloads(this, FilePath());
[email protected]274e42b2010-01-29 22:03:57811}
812
813void FilebrowseHandler::SetDownloads(std::vector<DownloadItem*>& downloads) {
814 ClearDownloadItems();
[email protected]274e42b2010-01-29 22:03:57815 // Scan for any in progress downloads and add ourself to them as an observer.
816 for (DownloadList::iterator it = downloads.begin();
817 it != downloads.end(); ++it) {
818 DownloadItem* download = *it;
819 // We want to know what happens as the download progresses and be notified
820 // when the user validates the dangerous download.
821 if (download->state() == DownloadItem::IN_PROGRESS ||
822 download->safety_state() == DownloadItem::DANGEROUS) {
823 download->AddObserver(this);
824 download_items_.push_back(download);
825 }
826 }
827
828 SendCurrentDownloads();
829}
830
[email protected]a67fa08e2010-02-12 20:43:55831void FilebrowseHandler::DeleteFile(const FilePath& path) {
832 if (!file_util::Delete(path, true)) {
833 LOG(ERROR) << "unable to delete directory";
834 }
835 ChromeThread::PostTask(
836 ChromeThread::UI, FROM_HERE,
837 NewRunnableMethod(CurrentTask_, &TaskProxy::FireDeleteCompleteProxy));
838}
839
840void FilebrowseHandler::HandleDeleteFile(const Value* value) {
841 #if defined(OS_CHROMEOS)
842 if (value && value->GetType() == Value::TYPE_LIST) {
843 const ListValue* list_value = static_cast<const ListValue*>(value);
844 std::string path;
845
846 // Get path string.
847 if (list_value->GetString(0, &path)) {
848
849 FilePath currentpath;
850 currentpath = FilePath(path);
[email protected]c4a530b2010-03-08 17:33:03851 for (unsigned int x = 0; x < download_items_.size(); x++) {
852 FilePath item = download_items_[x]->full_path();
853 if (item == currentpath) {
854 download_items_[x]->Cancel(true);
855 download_items_[x]->Remove(true);
856 FilePath dir_path = item.DirName();
857 GetChildrenForPath(dir_path, true);
858 return;
859 }
860 }
[email protected]a67fa08e2010-02-12 20:43:55861 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath);
862 task->AddRef();
863 CurrentTask_ = task;
864 ChromeThread::PostTask(
865 ChromeThread::FILE, FROM_HERE,
866 NewRunnableMethod(
867 task, &TaskProxy::DeleteFileProxy));
868 } else {
869 LOG(ERROR) << "Unable to get string";
870 return;
871 }
872 }
873#endif
874}
875
[email protected]274e42b2010-01-29 22:03:57876void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
877 DownloadList::iterator it = find(download_items_.begin(),
878 download_items_.end(),
879 download);
880 if (it == download_items_.end())
881 return;
882 const int id = static_cast<int>(it - download_items_.begin());
883
884 ListValue results_value;
885 results_value.Append(download_util::CreateDownloadItemValue(download, id));
886 dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value);
887}
888
889void FilebrowseHandler::ClearDownloadItems() {
890 for (DownloadList::iterator it = download_items_.begin();
891 it != download_items_.end(); ++it) {
892 (*it)->RemoveObserver(this);
893 }
894 download_items_.clear();
895}
896
897void FilebrowseHandler::SendCurrentDownloads() {
898 ListValue results_value;
899 for (DownloadList::iterator it = download_items_.begin();
900 it != download_items_.end(); ++it) {
901 int index = static_cast<int>(it - download_items_.begin());
902 results_value.Append(download_util::CreateDownloadItemValue(*it, index));
903 }
904
905 dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
906}
907
[email protected]698601e2009-10-21 22:43:37908////////////////////////////////////////////////////////////////////////////////
909//
[email protected]f5bf8ccf2010-02-05 18:19:25910// FileBrowseUI
[email protected]698601e2009-10-21 22:43:37911//
912////////////////////////////////////////////////////////////////////////////////
913
[email protected]274e42b2010-01-29 22:03:57914FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) {
[email protected]9d6b9aff2009-12-11 17:39:18915 FilebrowseHandler* handler = new FilebrowseHandler();
916 AddMessageHandler((handler)->Attach(this));
[email protected]274e42b2010-01-29 22:03:57917 handler->Init();
[email protected]698601e2009-10-21 22:43:37918 FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource();
919
920 // Set up the chrome://filebrowse/ source.
[email protected]fae20792009-10-28 20:31:58921 ChromeThread::PostTask(
922 ChromeThread::IO, FROM_HERE,
923 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:09924 Singleton<ChromeURLDataManager>::get(),
[email protected]698601e2009-10-21 22:43:37925 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:23926 make_scoped_refptr(html_source)));
[email protected]698601e2009-10-21 22:43:37927}
[email protected]f5bf8ccf2010-02-05 18:19:25928
929// static
[email protected]1717246f2010-02-10 17:08:15930Browser* FileBrowseUI::OpenPopup(Profile* profile,
931 const std::string& hashArgument) {
932 // Get existing pop up for given hashArgument.
933 Browser* browser = GetPopupForPath(hashArgument);
[email protected]f5bf8ccf2010-02-05 18:19:25934
[email protected]1717246f2010-02-10 17:08:15935 // Create new browser if no matching pop up found.
936 if (browser == NULL) {
937 browser = Browser::CreateForPopup(profile);
[email protected]f5bf8ccf2010-02-05 18:19:25938
[email protected]1717246f2010-02-10 17:08:15939 std::string url(kFilebrowseURLHash);
940 url.append(hashArgument);
[email protected]f5bf8ccf2010-02-05 18:19:25941
[email protected]1717246f2010-02-10 17:08:15942 browser->AddTabWithURL(
943 GURL(url), GURL(), PageTransition::LINK,
944 true, -1, false, NULL);
945 browser->window()->SetBounds(gfx::Rect(kPopupLeft,
946 kPopupTop,
947 kPopupWidth,
[email protected]078a10a2010-03-02 17:41:44948 kPopupHeight),
949 BrowserWindow::WINDOW_BOUNDS);
[email protected]1717246f2010-02-10 17:08:15950
951 browser->window()->Show();
952 }
[email protected]f5bf8ccf2010-02-05 18:19:25953
954 return browser;
955}
[email protected]1717246f2010-02-10 17:08:15956
957Browser* FileBrowseUI::GetPopupForPath(const std::string& path) {
958 for (BrowserList::const_iterator it = BrowserList::begin();
959 it != BrowserList::end(); ++it) {
960 if ((*it)->type() == Browser::TYPE_POPUP) {
961 const GURL& url =
962 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
963
964 if (url.SchemeIs(chrome::kChromeUIScheme) &&
965 url.host() == chrome::kChromeUIFileBrowseHost &&
966 url.ref() == path) {
967 return (*it);
968 }
969 }
970 }
971
972 return NULL;
973}