blob: 81dddb2ae30285cfc5f5e060634b2cab29b1f7df [file] [log] [blame]
[email protected]f90bf0d92011-01-13 02:12:441// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]698601e2009-10-21 22:43:372// 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
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]ba8164242010-11-16 21:31:008#include "base/command_line.h"
[email protected]23ebd2302010-11-04 16:23:209#include "base/file_util.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"
[email protected]34b99632011-01-01 01:01:0616#include "base/threading/thread.h"
[email protected]698601e2009-10-21 22:43:3717#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2218#include "base/utf_string_conversions.h"
[email protected]698601e2009-10-21 22:43:3719#include "base/values.h"
[email protected]9d6b9aff2009-12-11 17:39:1820#include "base/weak_ptr.h"
[email protected]698601e2009-10-21 22:43:3721#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]facac1532010-10-11 22:59:5022#include "chrome/browser/browser_thread.h"
[email protected]c848d3d92010-09-16 21:57:4523#include "chrome/browser/dom_ui/mediaplayer_ui.h"
[email protected]e0813a392011-02-01 22:57:2524#include "chrome/browser/dom_ui/web_ui_favicon_source.h"
[email protected]75986612010-07-16 22:23:5725#include "chrome/browser/download/download_item.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]8ecad5e2010-12-02 21:18:3330#include "chrome/browser/profiles/profile.h"
[email protected]1717246f2010-02-10 17:08:1531#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]c848d3d92010-09-16 21:57:4532#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]2ad4a902010-11-17 06:05:1333#include "chrome/browser/ui/browser.h"
34#include "chrome/browser/ui/browser_list.h"
[email protected]339d6dd2010-11-12 00:41:5835#include "chrome/browser/ui/browser_navigator.h"
[email protected]2ad4a902010-11-17 06:05:1336#include "chrome/browser/ui/browser_window.h"
[email protected]07046ab2010-01-20 21:42:4437#include "chrome/common/chrome_paths.h"
[email protected]ba8164242010-11-16 21:31:0038#include "chrome/common/chrome_switches.h"
[email protected]698601e2009-10-21 22:43:3739#include "chrome/common/jstemplate_builder.h"
[email protected]68d2a05f2010-05-07 21:39:5540#include "chrome/common/net/url_fetcher.h"
[email protected]698601e2009-10-21 22:43:3741#include "chrome/common/time_format.h"
42#include "chrome/common/url_constants.h"
[email protected]698601e2009-10-21 22:43:3743#include "grit/browser_resources.h"
44#include "grit/chromium_strings.h"
45#include "grit/generated_resources.h"
46#include "grit/locale_settings.h"
[email protected]c848d3d92010-09-16 21:57:4547#include "net/base/escape.h"
[email protected]df53d2d2010-11-19 08:56:1248#include "net/url_request/url_request_file_job.h"
[email protected]c051a1b2011-01-21 23:30:1749#include "ui/base/l10n/l10n_util.h"
[email protected]42ce29d2011-01-20 23:19:4650#include "ui/base/resource/resource_bundle.h"
[email protected]698601e2009-10-21 22:43:3751
[email protected]07046ab2010-01-20 21:42:4452#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:2453#include "chrome/browser/chromeos/cros/cros_library.h"
[email protected]268b02f2010-02-04 21:07:1554#include "chrome/browser/chromeos/cros/mount_library.h"
[email protected]d52bb8a2010-05-10 21:05:3555#include "chrome/browser/chromeos/login/user_manager.h"
[email protected]07046ab2010-01-20 21:42:4456#endif
57
[email protected]698601e2009-10-21 22:43:3758// Maximum number of search results to return in a given search. We should
59// eventually remove this.
60static const int kMaxSearchResults = 100;
[email protected]e4fbe8e2010-08-07 07:00:4661static const char kPropertyPath[] = "path";
62static const char kPropertyTitle[] = "title";
63static const char kPropertyDirectory[] = "isDirectory";
64static const char kPicasawebUserPrefix[] =
[email protected]9d6b9aff2009-12-11 17:39:1865 "http://picasaweb.google.com/data/feed/api/user/";
[email protected]e4fbe8e2010-08-07 07:00:4666static const char kPicasawebDefault[] = "/albumid/default";
67static const char kPicasawebDropBox[] = "/home";
68static const char kPicasawebBaseUrl[] = "http://picasaweb.google.com/";
69static const char kMediaPath[] = "/media";
70static const char kFilebrowseURLHash[] = "chrome://filebrowse#";
[email protected]f5bf8ccf2010-02-05 18:19:2571static const int kPopupLeft = 0;
72static const int kPopupTop = 0;
[email protected]f5bf8ccf2010-02-05 18:19:2573
[email protected]698601e2009-10-21 22:43:3774class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource {
75 public:
76 FileBrowseUIHTMLSource();
77
78 // Called when the network layer has requested a resource underneath
79 // the path we registered.
[email protected]f09d93792009-11-17 00:10:3680 virtual void StartDataRequest(const std::string& path,
81 bool is_off_the_record,
82 int request_id);
[email protected]698601e2009-10-21 22:43:3783 virtual std::string GetMimeType(const std::string&) const {
84 return "text/html";
85 }
86
87 private:
[email protected]8de85a62009-11-06 08:32:1788 ~FileBrowseUIHTMLSource() {}
89
[email protected]698601e2009-10-21 22:43:3790 DISALLOW_COPY_AND_ASSIGN(FileBrowseUIHTMLSource);
91};
92
[email protected]9d6b9aff2009-12-11 17:39:1893class TaskProxy;
94
[email protected]698601e2009-10-21 22:43:3795// The handler for Javascript messages related to the "filebrowse" view.
[email protected]dcd23fe2009-11-12 20:21:1896class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
[email protected]36e12172011-02-08 23:46:0297 public WebUIMessageHandler,
[email protected]07046ab2010-01-20 21:42:4498#if defined(OS_CHROMEOS)
99 public chromeos::MountLibrary::Observer,
100#endif
[email protected]9d6b9aff2009-12-11 17:39:18101 public base::SupportsWeakPtr<FilebrowseHandler>,
[email protected]274e42b2010-01-29 22:03:57102 public URLFetcher::Delegate,
103 public DownloadManager::Observer,
104 public DownloadItem::Observer {
[email protected]698601e2009-10-21 22:43:37105 public:
[email protected]dcd23fe2009-11-12 20:21:18106 FilebrowseHandler();
107 virtual ~FilebrowseHandler();
[email protected]698601e2009-10-21 22:43:37108
[email protected]274e42b2010-01-29 22:03:57109 // Init work after Attach.
110 void Init();
111
[email protected]698601e2009-10-21 22:43:37112 // DirectoryLister::DirectoryListerDelegate methods:
[email protected]9ee2c8d2010-08-21 23:25:22113 virtual void OnListFile(
114 const net::DirectoryLister::DirectoryListerData& data);
[email protected]698601e2009-10-21 22:43:37115 virtual void OnListDone(int error);
116
[email protected]36e12172011-02-08 23:46:02117 // WebUIMessageHandler implementation.
118 virtual WebUIMessageHandler* Attach(DOMUI* dom_ui);
[email protected]698601e2009-10-21 22:43:37119 virtual void RegisterMessages();
120
[email protected]07046ab2010-01-20 21:42:44121#if defined(OS_CHROMEOS)
122 void MountChanged(chromeos::MountLibrary* obj,
123 chromeos::MountEventType evt,
124 const std::string& path);
125#endif
126
[email protected]274e42b2010-01-29 22:03:57127 // DownloadItem::Observer interface
128 virtual void OnDownloadUpdated(DownloadItem* download);
[email protected]ebdd2012011-01-19 11:06:57129 virtual void OnDownloadFileCompleted(DownloadItem* download);
[email protected]274e42b2010-01-29 22:03:57130 virtual void OnDownloadOpened(DownloadItem* download) { }
131
132 // DownloadManager::Observer interface
133 virtual void ModelChanged();
[email protected]82f37b02010-07-29 22:04:57134
[email protected]698601e2009-10-21 22:43:37135 // Callback for the "getRoots" message.
[email protected]88942a22010-08-19 20:34:43136 void HandleGetRoots(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37137
[email protected]a67fa08e2010-02-12 20:43:55138 void GetChildrenForPath(FilePath& path, bool is_refresh);
139
[email protected]9d6b9aff2009-12-11 17:39:18140 void OnURLFetchComplete(const URLFetcher* source,
141 const GURL& url,
[email protected]f90bf0d92011-01-13 02:12:44142 const net::URLRequestStatus& status,
[email protected]9d6b9aff2009-12-11 17:39:18143 int response_code,
144 const ResponseCookies& cookies,
145 const std::string& data);
146
[email protected]698601e2009-10-21 22:43:37147 // Callback for the "getChildren" message.
[email protected]88942a22010-08-19 20:34:43148 void HandleGetChildren(const ListValue* args);
[email protected]c4a530b2010-03-08 17:33:03149 // Callback for the "refreshDirectory" message.
[email protected]88942a22010-08-19 20:34:43150 void HandleRefreshDirectory(const ListValue* args);
151 void HandleIsAdvancedEnabled(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37152
153 // Callback for the "getMetadata" message.
[email protected]88942a22010-08-19 20:34:43154 void HandleGetMetadata(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37155
[email protected]9d6b9aff2009-12-11 17:39:18156 // Callback for the "openNewWindow" message.
[email protected]88942a22010-08-19 20:34:43157 void OpenNewFullWindow(const ListValue* args);
158 void OpenNewPopupWindow(const ListValue* args);
[email protected]dcd23fe2009-11-12 20:21:18159
[email protected]9d6b9aff2009-12-11 17:39:18160 // Callback for the "uploadToPicasaweb" message.
[email protected]88942a22010-08-19 20:34:43161 void UploadToPicasaweb(const ListValue* args);
[email protected]9d6b9aff2009-12-11 17:39:18162
[email protected]274e42b2010-01-29 22:03:57163 // Callback for the "getDownloads" message.
[email protected]88942a22010-08-19 20:34:43164 void HandleGetDownloads(const ListValue* args);
[email protected]274e42b2010-01-29 22:03:57165
[email protected]88942a22010-08-19 20:34:43166 void HandleCreateNewFolder(const ListValue* args);
[email protected]274e42b2010-01-29 22:03:57167
[email protected]88942a22010-08-19 20:34:43168 void PlayMediaFile(const ListValue* args);
169 void EnqueueMediaFile(const ListValue* args);
[email protected]17496bb2010-03-10 19:48:23170
[email protected]88942a22010-08-19 20:34:43171 void HandleDeleteFile(const ListValue* args);
[email protected]d3d9b4fb2010-09-24 16:24:27172 void HandleCopyFile(const ListValue* value);
173 void CopyFile(const FilePath& src, const FilePath& dest);
[email protected]a67fa08e2010-02-12 20:43:55174 void DeleteFile(const FilePath& path);
175 void FireDeleteComplete(const FilePath& path);
[email protected]d3d9b4fb2010-09-24 16:24:27176 void FireCopyComplete(const FilePath& src, const FilePath& dest);
[email protected]a67fa08e2010-02-12 20:43:55177
[email protected]88942a22010-08-19 20:34:43178 void HandlePauseToggleDownload(const ListValue* args);
[email protected]a67fa08e2010-02-12 20:43:55179
[email protected]88942a22010-08-19 20:34:43180 void HandleCancelDownload(const ListValue* args);
181 void HandleAllowDownload(const ListValue* args);
[email protected]c4a530b2010-03-08 17:33:03182
[email protected]9d6b9aff2009-12-11 17:39:18183 void ReadInFile();
184 void FireUploadComplete();
185
[email protected]d52bb8a2010-05-10 21:05:35186 void SendPicasawebRequest();
[email protected]23ebd2302010-11-04 16:23:20187
188 // Callback for the "validateSavePath" message.
189 void HandleValidateSavePath(const ListValue* args);
190
191 // Validate a save path on file thread.
192 void ValidateSavePathOnFileThread(const FilePath& save_path);
193
194 // Fire save path validation result to JS onValidatedSavePath.
195 void FireOnValidatedSavePathOnUIThread(bool valid, const FilePath& save_path);
196
[email protected]698601e2009-10-21 22:43:37197 private:
[email protected]dcd23fe2009-11-12 20:21:18198
[email protected]ebdd2012011-01-19 11:06:57199 // Retrieves downloads from the DownloadManager and updates the page.
200 void UpdateDownloadList();
201
[email protected]88942a22010-08-19 20:34:43202 void OpenNewWindow(const ListValue* args, bool popup);
[email protected]dcd23fe2009-11-12 20:21:18203
[email protected]274e42b2010-01-29 22:03:57204 // Clear all download items and their observers.
205 void ClearDownloadItems();
206
207 // Send the current list of downloads to the page.
208 void SendCurrentDownloads();
209
[email protected]377b4cc2010-05-18 17:25:19210 void SendNewDownload(DownloadItem* download);
211
[email protected]698601e2009-10-21 22:43:37212 scoped_ptr<ListValue> filelist_value_;
213 FilePath currentpath_;
[email protected]dcd23fe2009-11-12 20:21:18214 Profile* profile_;
[email protected]93a58bf72010-06-04 23:01:20215 TabContents* tab_contents_;
[email protected]9d6b9aff2009-12-11 17:39:18216 std::string current_file_contents_;
217 std::string current_file_uploaded_;
218 int upload_response_code_;
[email protected]d52bb8a2010-05-10 21:05:35219 TaskProxy* current_task_;
[email protected]698601e2009-10-21 22:43:37220 scoped_refptr<net::DirectoryLister> lister_;
[email protected]a67fa08e2010-02-12 20:43:55221 bool is_refresh_;
[email protected]d52bb8a2010-05-10 21:05:35222 scoped_ptr<URLFetcher> fetch_;
[email protected]698601e2009-10-21 22:43:37223
[email protected]274e42b2010-01-29 22:03:57224 DownloadManager* download_manager_;
225 typedef std::vector<DownloadItem*> DownloadList;
[email protected]377b4cc2010-05-18 17:25:19226 DownloadList active_download_items_;
[email protected]274e42b2010-01-29 22:03:57227 DownloadList download_items_;
[email protected]377b4cc2010-05-18 17:25:19228 bool got_first_download_list_;
[email protected]dcd23fe2009-11-12 20:21:18229 DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler);
[email protected]698601e2009-10-21 22:43:37230};
231
[email protected]9d6b9aff2009-12-11 17:39:18232class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
233 public:
[email protected]d3d9b4fb2010-09-24 16:24:27234 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
235 const FilePath& path, const FilePath& dest)
[email protected]a67fa08e2010-02-12 20:43:55236 : handler_(handler),
[email protected]d3d9b4fb2010-09-24 16:24:27237 src_(path),
238 dest_(dest) {}
239 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
240 const FilePath& path)
241 : handler_(handler),
242 src_(path) {}
[email protected]9d6b9aff2009-12-11 17:39:18243 void ReadInFileProxy() {
244 if (handler_) {
245 handler_->ReadInFile();
246 }
247 }
[email protected]068a71f2010-05-11 22:35:48248 void DeleteFetcher(URLFetcher* fetch) {
249 delete fetch;
250 }
[email protected]d52bb8a2010-05-10 21:05:35251 void SendPicasawebRequestProxy() {
252 if (handler_) {
253 handler_->SendPicasawebRequest();
254 }
255 }
[email protected]9d6b9aff2009-12-11 17:39:18256 void FireUploadCompleteProxy() {
257 if (handler_) {
258 handler_->FireUploadComplete();
259 }
260 }
[email protected]a67fa08e2010-02-12 20:43:55261
262 void DeleteFileProxy() {
263 if (handler_) {
[email protected]d3d9b4fb2010-09-24 16:24:27264 handler_->DeleteFile(src_);
265 }
266 }
267
268 void CopyFileProxy() {
269 if (handler_) {
270 handler_->CopyFile(src_, dest_);
[email protected]a67fa08e2010-02-12 20:43:55271 }
272 }
273
274 void FireDeleteCompleteProxy() {
275 if (handler_) {
[email protected]d3d9b4fb2010-09-24 16:24:27276 handler_->FireDeleteComplete(src_);
277 }
278 }
279 void FireCopyCompleteProxy() {
280 if (handler_) {
281 handler_->FireCopyComplete(src_, dest_);
[email protected]a67fa08e2010-02-12 20:43:55282 }
283 }
[email protected]23ebd2302010-11-04 16:23:20284
285 void ValidateSavePathOnFileThread() {
286 if (handler_)
287 handler_->ValidateSavePathOnFileThread(src_);
288 }
289 void FireOnValidatedSavePathOnUIThread(bool valid,
290 const FilePath& save_path) {
291 if (handler_)
292 handler_->FireOnValidatedSavePathOnUIThread(valid, save_path);
293 }
294
[email protected]9d6b9aff2009-12-11 17:39:18295 private:
296 base::WeakPtr<FilebrowseHandler> handler_;
[email protected]d3d9b4fb2010-09-24 16:24:27297 FilePath src_;
298 FilePath dest_;
[email protected]9d6b9aff2009-12-11 17:39:18299 friend class base::RefCountedThreadSafe<TaskProxy>;
[email protected]068a71f2010-05-11 22:35:48300 DISALLOW_COPY_AND_ASSIGN(TaskProxy);
[email protected]9d6b9aff2009-12-11 17:39:18301};
302
303
[email protected]698601e2009-10-21 22:43:37304////////////////////////////////////////////////////////////////////////////////
305//
306// FileBrowseHTMLSource
307//
308////////////////////////////////////////////////////////////////////////////////
309
310FileBrowseUIHTMLSource::FileBrowseUIHTMLSource()
311 : DataSource(chrome::kChromeUIFileBrowseHost, MessageLoop::current()) {
312}
313
314void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path,
[email protected]e42ae9b2010-03-28 00:55:05315 bool is_off_the_record,
316 int request_id) {
[email protected]698601e2009-10-21 22:43:37317 DictionaryValue localized_strings;
[email protected]11f4857282009-11-13 19:56:17318 // TODO(dhg): Add stirings to localized strings, also add more strings
[email protected]dcd23fe2009-11-12 20:21:18319 // that are currently hardcoded.
[email protected]e4fbe8e2010-08-07 07:00:46320 localized_strings.SetString("title",
321 l10n_util::GetStringUTF16(IDS_FILEBROWSER_TITLE));
322 localized_strings.SetString("pause",
323 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PAUSE));
324 localized_strings.SetString("resume",
325 l10n_util::GetStringUTF16(IDS_FILEBROWSER_RESUME));
326 localized_strings.SetString("scanning",
327 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SCANNING));
328 localized_strings.SetString("confirmdelete",
329 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DELETE));
330 localized_strings.SetString("confirmyes",
331 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_YES));
332 localized_strings.SetString("confirmcancel",
333 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_CANCEL));
334 localized_strings.SetString("allowdownload",
335 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DOWNLOAD));
336 localized_strings.SetString("filenameprompt",
337 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PROMPT_FILENAME));
338 localized_strings.SetString("save",
339 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SAVE));
340 localized_strings.SetString("newfolder",
341 l10n_util::GetStringUTF16(IDS_FILEBROWSER_NEW_FOLDER));
342 localized_strings.SetString("open",
343 l10n_util::GetStringUTF16(IDS_FILEBROWSER_OPEN));
344 localized_strings.SetString("picasaweb",
345 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_PICASAWEB));
346 localized_strings.SetString("flickr",
347 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_FLICKR));
348 localized_strings.SetString("email",
349 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_EMAIL));
350 localized_strings.SetString("delete",
351 l10n_util::GetStringUTF16(IDS_FILEBROWSER_DELETE));
352 localized_strings.SetString("enqueue",
353 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ENQUEUE));
354 localized_strings.SetString("mediapath", kMediaPath);
[email protected]88f03da02010-06-10 16:21:13355 FilePath default_download_path;
356 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
357 &default_download_path)) {
358 NOTREACHED();
359 }
[email protected]e4fbe8e2010-08-07 07:00:46360 // TODO(viettrungluu): this is wrong -- FilePath's need not be Unicode.
361 localized_strings.SetString("downloadpath", default_download_path.value());
362 localized_strings.SetString("error_unknown_file_type",
363 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ERROR_UNKNOWN_FILE_TYPE));
[email protected]698601e2009-10-21 22:43:37364 SetFontAndTextDirection(&localized_strings);
365
366 static const base::StringPiece filebrowse_html(
367 ResourceBundle::GetSharedInstance().GetRawDataResource(
368 IDR_FILEBROWSE_HTML));
369 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
370 filebrowse_html, &localized_strings);
371
372 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
373 html_bytes->data.resize(full_html.size());
374 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
375
376 SendResponse(request_id, html_bytes);
377}
378
379////////////////////////////////////////////////////////////////////////////////
380//
[email protected]dcd23fe2009-11-12 20:21:18381// FilebrowseHandler
[email protected]698601e2009-10-21 22:43:37382//
383////////////////////////////////////////////////////////////////////////////////
[email protected]dcd23fe2009-11-12 20:21:18384FilebrowseHandler::FilebrowseHandler()
[email protected]274e42b2010-01-29 22:03:57385 : profile_(NULL),
[email protected]93a58bf72010-06-04 23:01:20386 tab_contents_(NULL),
[email protected]a67fa08e2010-02-12 20:43:55387 is_refresh_(false),
[email protected]d52bb8a2010-05-10 21:05:35388 fetch_(NULL),
[email protected]377b4cc2010-05-18 17:25:19389 download_manager_(NULL),
390 got_first_download_list_(false) {
[email protected]a67fa08e2010-02-12 20:43:55391 lister_ = NULL;
[email protected]07046ab2010-01-20 21:42:44392#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24393 chromeos::MountLibrary* lib =
394 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44395 lib->AddObserver(this);
396#endif
[email protected]698601e2009-10-21 22:43:37397}
398
[email protected]dcd23fe2009-11-12 20:21:18399FilebrowseHandler::~FilebrowseHandler() {
[email protected]07046ab2010-01-20 21:42:44400#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24401 chromeos::MountLibrary* lib =
402 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44403 lib->RemoveObserver(this);
404#endif
[email protected]698601e2009-10-21 22:43:37405 if (lister_.get()) {
406 lister_->Cancel();
407 lister_->set_delegate(NULL);
408 }
[email protected]274e42b2010-01-29 22:03:57409
410 ClearDownloadItems();
411 download_manager_->RemoveObserver(this);
[email protected]068a71f2010-05-11 22:35:48412 URLFetcher* fetch = fetch_.release();
413 if (fetch) {
414 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath_);
415 task->AddRef();
[email protected]2dc383ce2010-10-09 03:54:00416 BrowserThread::PostTask(
417 BrowserThread::FILE, FROM_HERE,
[email protected]068a71f2010-05-11 22:35:48418 NewRunnableMethod(
419 task, &TaskProxy::DeleteFetcher, fetch));
420 }
[email protected]698601e2009-10-21 22:43:37421}
422
[email protected]36e12172011-02-08 23:46:02423WebUIMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) {
[email protected]698601e2009-10-21 22:43:37424 // Create our favicon data source.
[email protected]dcd23fe2009-11-12 20:21:18425 profile_ = dom_ui->GetProfile();
[email protected]248ce192011-02-10 15:26:34426 profile_->GetChromeURLDataManager()->AddDataSource(
427 new WebUIFavIconSource(profile_));
[email protected]93a58bf72010-06-04 23:01:20428 tab_contents_ = dom_ui->tab_contents();
[email protected]36e12172011-02-08 23:46:02429 return WebUIMessageHandler::Attach(dom_ui);
[email protected]698601e2009-10-21 22:43:37430}
431
[email protected]274e42b2010-01-29 22:03:57432void FilebrowseHandler::Init() {
[email protected]f7e9fd62010-09-28 15:45:06433 download_manager_ = profile_->GetDownloadManager();
[email protected]274e42b2010-01-29 22:03:57434 download_manager_->AddObserver(this);
[email protected]d52bb8a2010-05-10 21:05:35435 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath_);
436 task->AddRef();
437 current_task_ = task;
438 static bool sent_request = false;
439 if (!sent_request) {
440 // If we have not sent a request before, we should do one in order to
441 // ensure that we have the correct cookies. This is for uploads.
[email protected]2dc383ce2010-10-09 03:54:00442 BrowserThread::PostTask(
443 BrowserThread::FILE, FROM_HERE,
[email protected]d52bb8a2010-05-10 21:05:35444 NewRunnableMethod(
445 task, &TaskProxy::SendPicasawebRequestProxy));
446 sent_request = true;
447 }
[email protected]274e42b2010-01-29 22:03:57448}
449
[email protected]dcd23fe2009-11-12 20:21:18450void FilebrowseHandler::RegisterMessages() {
[email protected]698601e2009-10-21 22:43:37451 dom_ui_->RegisterMessageCallback("getRoots",
[email protected]dcd23fe2009-11-12 20:21:18452 NewCallback(this, &FilebrowseHandler::HandleGetRoots));
[email protected]698601e2009-10-21 22:43:37453 dom_ui_->RegisterMessageCallback("getChildren",
[email protected]dcd23fe2009-11-12 20:21:18454 NewCallback(this, &FilebrowseHandler::HandleGetChildren));
[email protected]698601e2009-10-21 22:43:37455 dom_ui_->RegisterMessageCallback("getMetadata",
[email protected]dcd23fe2009-11-12 20:21:18456 NewCallback(this, &FilebrowseHandler::HandleGetMetadata));
457 dom_ui_->RegisterMessageCallback("openNewPopupWindow",
458 NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow));
459 dom_ui_->RegisterMessageCallback("openNewFullWindow",
460 NewCallback(this, &FilebrowseHandler::OpenNewFullWindow));
[email protected]9d6b9aff2009-12-11 17:39:18461 dom_ui_->RegisterMessageCallback("uploadToPicasaweb",
462 NewCallback(this, &FilebrowseHandler::UploadToPicasaweb));
[email protected]274e42b2010-01-29 22:03:57463 dom_ui_->RegisterMessageCallback("getDownloads",
464 NewCallback(this, &FilebrowseHandler::HandleGetDownloads));
465 dom_ui_->RegisterMessageCallback("createNewFolder",
466 NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder));
[email protected]17496bb2010-03-10 19:48:23467 dom_ui_->RegisterMessageCallback("playMediaFile",
468 NewCallback(this, &FilebrowseHandler::PlayMediaFile));
[email protected]89a7e3812010-06-02 19:38:07469 dom_ui_->RegisterMessageCallback("enqueueMediaFile",
470 NewCallback(this, &FilebrowseHandler::EnqueueMediaFile));
[email protected]a67fa08e2010-02-12 20:43:55471 dom_ui_->RegisterMessageCallback("pauseToggleDownload",
472 NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
473 dom_ui_->RegisterMessageCallback("deleteFile",
474 NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
[email protected]d3d9b4fb2010-09-24 16:24:27475 dom_ui_->RegisterMessageCallback("copyFile",
476 NewCallback(this, &FilebrowseHandler::HandleCopyFile));
[email protected]c4a530b2010-03-08 17:33:03477 dom_ui_->RegisterMessageCallback("cancelDownload",
478 NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
479 dom_ui_->RegisterMessageCallback("allowDownload",
480 NewCallback(this, &FilebrowseHandler::HandleAllowDownload));
481 dom_ui_->RegisterMessageCallback("refreshDirectory",
482 NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
[email protected]6ba198f2010-07-02 20:32:05483 dom_ui_->RegisterMessageCallback("isAdvancedEnabled",
484 NewCallback(this, &FilebrowseHandler::HandleIsAdvancedEnabled));
[email protected]23ebd2302010-11-04 16:23:20485 dom_ui_->RegisterMessageCallback("validateSavePath",
486 NewCallback(this, &FilebrowseHandler::HandleValidateSavePath));
[email protected]9d6b9aff2009-12-11 17:39:18487}
488
[email protected]a67fa08e2010-02-12 20:43:55489
490void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
491 // We notify the UI by telling it to refresh its contents.
492 FilePath dir_path = path.DirName();
493 GetChildrenForPath(dir_path, true);
494};
495
[email protected]d3d9b4fb2010-09-24 16:24:27496void FilebrowseHandler::FireCopyComplete(const FilePath& src,
497 const FilePath& dest) {
498 // Notify the UI somehow.
499 FilePath dir_path = dest.DirName();
500 GetChildrenForPath(dir_path, true);
501};
502
[email protected]9d6b9aff2009-12-11 17:39:18503void FilebrowseHandler::FireUploadComplete() {
[email protected]d52bb8a2010-05-10 21:05:35504#if defined(OS_CHROMEOS)
[email protected]9d6b9aff2009-12-11 17:39:18505 DictionaryValue info_value;
[email protected]e4fbe8e2010-08-07 07:00:46506 info_value.SetString("path", current_file_uploaded_);
[email protected]9d6b9aff2009-12-11 17:39:18507
508 std::string username;
[email protected]d52bb8a2010-05-10 21:05:35509 chromeos::UserManager* user_man = chromeos::UserManager::Get();
510 username = user_man->logged_in_user().email();
[email protected]9d6b9aff2009-12-11 17:39:18511
512 if (username.empty()) {
513 LOG(ERROR) << "Unable to get username";
514 return;
515 }
516 int location = username.find_first_of('@',0);
517 if (location <= 0) {
518 LOG(ERROR) << "Username not formatted correctly";
519 return;
520 }
521 username = username.erase(username.find_first_of('@',0));
[email protected]e4fbe8e2010-08-07 07:00:46522 std::string picture_url = kPicasawebBaseUrl;
[email protected]9d6b9aff2009-12-11 17:39:18523 picture_url += username;
524 picture_url += kPicasawebDropBox;
[email protected]e4fbe8e2010-08-07 07:00:46525 info_value.SetString("url", picture_url);
526 info_value.SetInteger("status_code", upload_response_code_);
[email protected]9d6b9aff2009-12-11 17:39:18527 dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value);
[email protected]d52bb8a2010-05-10 21:05:35528#endif
[email protected]9d6b9aff2009-12-11 17:39:18529}
530
[email protected]07046ab2010-01-20 21:42:44531#if defined(OS_CHROMEOS)
532void FilebrowseHandler::MountChanged(chromeos::MountLibrary* obj,
533 chromeos::MountEventType evt,
534 const std::string& path) {
535 if (evt == chromeos::DISK_REMOVED ||
536 evt == chromeos::DISK_CHANGED) {
537 dom_ui_->CallJavascriptFunction(L"rootsChanged");
538 }
539}
540#endif
541
[email protected]9d6b9aff2009-12-11 17:39:18542void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source,
543 const GURL& url,
[email protected]f90bf0d92011-01-13 02:12:44544 const net::URLRequestStatus& status,
[email protected]9d6b9aff2009-12-11 17:39:18545 int response_code,
546 const ResponseCookies& cookies,
547 const std::string& data) {
548 upload_response_code_ = response_code;
[email protected]666205032010-10-21 20:56:58549 VLOG(1) << "Response code: " << response_code;
550 VLOG(1) << "Request url: " << url;
[email protected]068a71f2010-05-11 22:35:48551 if (StartsWithASCII(url.spec(), kPicasawebUserPrefix, true)) {
[email protected]2dc383ce2010-10-09 03:54:00552 BrowserThread::PostTask(
553 BrowserThread::UI, FROM_HERE,
[email protected]068a71f2010-05-11 22:35:48554 NewRunnableMethod(current_task_, &TaskProxy::FireUploadCompleteProxy));
555 }
556 fetch_.reset();
[email protected]698601e2009-10-21 22:43:37557}
558
[email protected]88942a22010-08-19 20:34:43559void FilebrowseHandler::HandleGetRoots(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37560 ListValue results_value;
561 DictionaryValue info_value;
[email protected]698601e2009-10-21 22:43:37562 // TODO(dhg): add other entries, make this more general
[email protected]07046ab2010-01-20 21:42:44563#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24564 chromeos::MountLibrary* lib =
565 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44566 const chromeos::MountLibrary::DiskVector& disks = lib->disks();
567
568 for (size_t i = 0; i < disks.size(); ++i) {
569 if (!disks[i].mount_path.empty()) {
570 DictionaryValue* page_value = new DictionaryValue();
571 page_value->SetString(kPropertyPath, disks[i].mount_path);
[email protected]88942a22010-08-19 20:34:43572 FilePath currentpath(disks[i].mount_path);
[email protected]07046ab2010-01-20 21:42:44573 std::string filename;
574 filename = currentpath.BaseName().value();
575 page_value->SetString(kPropertyTitle, filename);
576 page_value->SetBoolean(kPropertyDirectory, true);
577 results_value.Append(page_value);
578 }
579 }
580#else
581 DictionaryValue* page_value = new DictionaryValue();
582 page_value->SetString(kPropertyPath, "/media");
583 page_value->SetString(kPropertyTitle, "Removeable");
[email protected]698601e2009-10-21 22:43:37584 page_value->SetBoolean(kPropertyDirectory, true);
585
586 results_value.Append(page_value);
[email protected]07046ab2010-01-20 21:42:44587#endif
588 FilePath default_download_path;
589 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
590 &default_download_path)) {
591 NOTREACHED();
592 }
593
594 DictionaryValue* download_value = new DictionaryValue();
595 download_value->SetString(kPropertyPath, default_download_path.value());
596 download_value->SetString(kPropertyTitle, "File Shelf");
597 download_value->SetBoolean(kPropertyDirectory, true);
598
599 results_value.Append(download_value);
[email protected]698601e2009-10-21 22:43:37600
[email protected]e4fbe8e2010-08-07 07:00:46601 info_value.SetString("functionCall", "getRoots");
[email protected]07046ab2010-01-20 21:42:44602 info_value.SetString(kPropertyPath, "");
[email protected]9d6b9aff2009-12-11 17:39:18603 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37604 info_value, results_value);
605}
606
[email protected]88942a22010-08-19 20:34:43607void FilebrowseHandler::HandleCreateNewFolder(const ListValue* args) {
[email protected]274e42b2010-01-29 22:03:57608#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43609 std::string path = WideToUTF8(ExtractStringValue(args));
610 FilePath currentpath(path);
[email protected]274e42b2010-01-29 22:03:57611
[email protected]88942a22010-08-19 20:34:43612 if (!file_util::CreateDirectory(currentpath))
613 LOG(ERROR) << "unable to create directory";
[email protected]274e42b2010-01-29 22:03:57614#endif
615}
616
[email protected]88942a22010-08-19 20:34:43617void FilebrowseHandler::PlayMediaFile(const ListValue* args) {
[email protected]17496bb2010-03-10 19:48:23618#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43619 std::string url = WideToUTF8(ExtractStringValue(args));
620 GURL gurl(url);
[email protected]17496bb2010-03-10 19:48:23621
[email protected]88942a22010-08-19 20:34:43622 Browser* browser = Browser::GetBrowserForController(
623 &tab_contents_->controller(), NULL);
[email protected]dc8caba2010-12-13 16:52:35624 MediaPlayer* mediaplayer = MediaPlayer::GetInstance();
[email protected]88942a22010-08-19 20:34:43625 mediaplayer->ForcePlayMediaURL(gurl, browser);
[email protected]89a7e3812010-06-02 19:38:07626#endif
627}
628
[email protected]88942a22010-08-19 20:34:43629void FilebrowseHandler::EnqueueMediaFile(const ListValue* args) {
[email protected]89a7e3812010-06-02 19:38:07630#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43631 std::string url = WideToUTF8(ExtractStringValue(args));
632 GURL gurl(url);
[email protected]89a7e3812010-06-02 19:38:07633
[email protected]88942a22010-08-19 20:34:43634 Browser* browser = Browser::GetBrowserForController(
635 &tab_contents_->controller(), NULL);
[email protected]dc8caba2010-12-13 16:52:35636 MediaPlayer* mediaplayer = MediaPlayer::GetInstance();
[email protected]88942a22010-08-19 20:34:43637 mediaplayer->EnqueueMediaURL(gurl, browser);
[email protected]17496bb2010-03-10 19:48:23638#endif
639}
640
[email protected]88942a22010-08-19 20:34:43641void FilebrowseHandler::HandleIsAdvancedEnabled(const ListValue* args) {
[email protected]6ba198f2010-07-02 20:32:05642#if defined(OS_CHROMEOS)
[email protected]ba8164242010-11-16 21:31:00643 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
644 switches::kEnableAdvancedFileSystem);
645 bool mp_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
646 switches::kEnableMediaPlayer);
[email protected]6ba198f2010-07-02 20:32:05647 DictionaryValue info_value;
[email protected]e4fbe8e2010-08-07 07:00:46648 info_value.SetBoolean("enabled", is_enabled);
649 info_value.SetBoolean("mpEnabled", mp_enabled);
[email protected]6ba198f2010-07-02 20:32:05650 dom_ui_->CallJavascriptFunction(L"enabledResult",
651 info_value);
[email protected]f872b3e2010-08-13 16:26:10652
[email protected]6ba198f2010-07-02 20:32:05653#endif
654}
[email protected]c4a530b2010-03-08 17:33:03655
[email protected]88942a22010-08-19 20:34:43656void FilebrowseHandler::HandleRefreshDirectory(const ListValue* args) {
[email protected]a67fa08e2010-02-12 20:43:55657#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43658 std::string path = WideToUTF8(ExtractStringValue(args));
659 FilePath currentpath(path);
660 GetChildrenForPath(currentpath, true);
[email protected]a67fa08e2010-02-12 20:43:55661#endif
662}
663
[email protected]88942a22010-08-19 20:34:43664void FilebrowseHandler::HandlePauseToggleDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03665#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43666 int id;
667 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27668 if ((id - 1) >= (int)active_download_items_.size()) {
669 return;
670 }
[email protected]88942a22010-08-19 20:34:43671 DownloadItem* item = active_download_items_[id];
672 item->TogglePause();
[email protected]c4a530b2010-03-08 17:33:03673#endif
674}
675
[email protected]88942a22010-08-19 20:34:43676void FilebrowseHandler::HandleAllowDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03677#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43678 int id;
679 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27680 if ((id - 1) >= (int)active_download_items_.size()) {
681 return;
682 }
683
[email protected]88942a22010-08-19 20:34:43684 DownloadItem* item = active_download_items_[id];
685 download_manager_->DangerousDownloadValidated(item);
[email protected]c4a530b2010-03-08 17:33:03686#endif
687}
688
[email protected]88942a22010-08-19 20:34:43689void FilebrowseHandler::HandleCancelDownload(const ListValue* args) {
690#if defined(OS_CHROMEOS)
691 int id;
692 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27693 if ((id - 1) >= (int)active_download_items_.size()) {
694 return;
695 }
[email protected]88942a22010-08-19 20:34:43696 DownloadItem* item = active_download_items_[id];
[email protected]88942a22010-08-19 20:34:43697 FilePath path = item->full_path();
[email protected]d3d9b4fb2010-09-24 16:24:27698 item->Cancel(true);
[email protected]88942a22010-08-19 20:34:43699 FilePath dir_path = path.DirName();
700 item->Remove(true);
701 GetChildrenForPath(dir_path, true);
702#endif
[email protected]dcd23fe2009-11-12 20:21:18703}
[email protected]698601e2009-10-21 22:43:37704
[email protected]88942a22010-08-19 20:34:43705void FilebrowseHandler::OpenNewFullWindow(const ListValue* args) {
706 OpenNewWindow(args, false);
[email protected]dcd23fe2009-11-12 20:21:18707}
708
[email protected]88942a22010-08-19 20:34:43709void FilebrowseHandler::OpenNewPopupWindow(const ListValue* args) {
710 OpenNewWindow(args, true);
711}
[email protected]dcd23fe2009-11-12 20:21:18712
[email protected]88942a22010-08-19 20:34:43713void FilebrowseHandler::OpenNewWindow(const ListValue* args, bool popup) {
714 std::string url = WideToUTF8(ExtractStringValue(args));
715 Browser* browser = popup ?
716 Browser::CreateForType(Browser::TYPE_APP_PANEL, profile_) :
717 BrowserList::GetLastActive();
[email protected]616381f02010-11-02 15:15:33718 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
719 params.disposition = NEW_FOREGROUND_TAB;
720 browser::Navigate(&params);
721 // TODO(beng): The following two calls should be automatic by Navigate().
[email protected]88942a22010-08-19 20:34:43722 if (popup) {
723 // TODO(dhg): Remove these from being hardcoded. Allow javascript
724 // to specify.
[email protected]616381f02010-11-02 15:15:33725 params.browser->window()->SetBounds(gfx::Rect(0, 0, 400, 300));
[email protected]dcd23fe2009-11-12 20:21:18726 }
[email protected]616381f02010-11-02 15:15:33727 params.browser->window()->Show();
[email protected]dcd23fe2009-11-12 20:21:18728}
729
[email protected]d52bb8a2010-05-10 21:05:35730void FilebrowseHandler::SendPicasawebRequest() {
[email protected]068a71f2010-05-11 22:35:48731#if defined(OS_CHROMEOS)
732 chromeos::UserManager* user_man = chromeos::UserManager::Get();
733 std::string username = user_man->logged_in_user().email();
734
735 if (username.empty()) {
736 LOG(ERROR) << "Unable to get username";
737 return;
738 }
739
[email protected]d52bb8a2010-05-10 21:05:35740 fetch_.reset(URLFetcher::Create(0,
741 GURL(kPicasawebBaseUrl),
742 URLFetcher::GET,
[email protected]068a71f2010-05-11 22:35:48743 this));
[email protected]d52bb8a2010-05-10 21:05:35744 fetch_->set_request_context(profile_->GetRequestContext());
745 fetch_->Start();
[email protected]068a71f2010-05-11 22:35:48746#endif
[email protected]d52bb8a2010-05-10 21:05:35747}
748
[email protected]9d6b9aff2009-12-11 17:39:18749void FilebrowseHandler::ReadInFile() {
750#if defined(OS_CHROMEOS)
751 // Get the users username
752 std::string username;
[email protected]d52bb8a2010-05-10 21:05:35753 chromeos::UserManager* user_man = chromeos::UserManager::Get();
754 username = user_man->logged_in_user().email();
[email protected]9d6b9aff2009-12-11 17:39:18755
756 if (username.empty()) {
757 LOG(ERROR) << "Unable to get username";
758 return;
759 }
760 int location = username.find_first_of('@',0);
761 if (location <= 0) {
762 LOG(ERROR) << "Username not formatted correctly";
763 return;
764 }
765 username = username.erase(username.find_first_of('@',0));
766 std::string url = kPicasawebUserPrefix;
767 url += username;
768 url += kPicasawebDefault;
769
[email protected]88942a22010-08-19 20:34:43770 FilePath currentpath(current_file_uploaded_);
[email protected]9d6b9aff2009-12-11 17:39:18771 // Get the filename
772 std::string filename;
773 filename = currentpath.BaseName().value();
774 std::string filecontents;
775 if (!file_util::ReadFileToString(currentpath, &filecontents)) {
776 LOG(ERROR) << "Unable to read this file:" << currentpath.value();
777 return;
778 }
[email protected]d52bb8a2010-05-10 21:05:35779 fetch_.reset(URLFetcher::Create(0,
780 GURL(url),
781 URLFetcher::POST,
782 this));
783 fetch_->set_upload_data("image/jpeg", filecontents);
[email protected]9d6b9aff2009-12-11 17:39:18784 // Set the filename on the server
785 std::string slug = "Slug: ";
786 slug += filename;
[email protected]d52bb8a2010-05-10 21:05:35787 fetch_->set_extra_request_headers(slug);
788 fetch_->set_request_context(profile_->GetRequestContext());
789 fetch_->Start();
[email protected]9d6b9aff2009-12-11 17:39:18790#endif
791}
792
793// This is just a prototype for allowing generic uploads to various sites
794// TODO(dhg): Remove this and implement general upload.
[email protected]88942a22010-08-19 20:34:43795void FilebrowseHandler::UploadToPicasaweb(const ListValue* args) {
[email protected]9d6b9aff2009-12-11 17:39:18796#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43797 std::string search_string = WideToUTF8(ExtractStringValue(args));
798 current_file_uploaded_ = search_string;
[email protected]9d6b9aff2009-12-11 17:39:18799 // ReadInFile();
[email protected]88942a22010-08-19 20:34:43800 FilePath current_path(search_string);
[email protected]a67fa08e2010-02-12 20:43:55801 TaskProxy* task = new TaskProxy(AsWeakPtr(), current_path);
[email protected]9d6b9aff2009-12-11 17:39:18802 task->AddRef();
[email protected]d52bb8a2010-05-10 21:05:35803 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:00804 BrowserThread::PostTask(
805 BrowserThread::FILE, FROM_HERE,
[email protected]9d6b9aff2009-12-11 17:39:18806 NewRunnableMethod(
807 task, &TaskProxy::ReadInFileProxy));
808#endif
809}
810
[email protected]a67fa08e2010-02-12 20:43:55811void FilebrowseHandler::GetChildrenForPath(FilePath& path, bool is_refresh) {
812 filelist_value_.reset(new ListValue());
[email protected]88942a22010-08-19 20:34:43813 currentpath_ = path;
[email protected]a67fa08e2010-02-12 20:43:55814
815 if (lister_.get()) {
816 lister_->Cancel();
817 lister_->set_delegate(NULL);
818 lister_ = NULL;
819 }
820
821 is_refresh_ = is_refresh;
[email protected]df53d2d2010-11-19 08:56:12822
823#if defined(OS_CHROMEOS)
824 // Don't allow listing files in inaccessible dirs.
[email protected]300bb2a2010-12-12 09:59:20825 if (net::URLRequestFileJob::AccessDisabled(path))
[email protected]df53d2d2010-11-19 08:56:12826 return;
827#endif // OS_CHROMEOS
828
[email protected]f872b3e2010-08-13 16:26:10829 FilePath default_download_path;
830 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
831 &default_download_path)) {
832 NOTREACHED();
833 }
834 if (currentpath_ == default_download_path) {
835 lister_ = new net::DirectoryLister(currentpath_,
[email protected]9ee2c8d2010-08-21 23:25:22836 false,
[email protected]f872b3e2010-08-13 16:26:10837 net::DirectoryLister::DATE,
838 this);
839 } else {
840 lister_ = new net::DirectoryLister(currentpath_, this);
841 }
[email protected]a67fa08e2010-02-12 20:43:55842 lister_->Start();
843}
844
[email protected]88942a22010-08-19 20:34:43845void FilebrowseHandler::HandleGetChildren(const ListValue* args) {
846#if defined(OS_CHROMEOS)
847 std::string path = WideToUTF8(ExtractStringValue(args));
848 FilePath currentpath(path);
[email protected]698601e2009-10-21 22:43:37849 filelist_value_.reset(new ListValue());
[email protected]698601e2009-10-21 22:43:37850
[email protected]a67fa08e2010-02-12 20:43:55851 GetChildrenForPath(currentpath, false);
[email protected]88942a22010-08-19 20:34:43852#endif
[email protected]698601e2009-10-21 22:43:37853}
854
[email protected]dcd23fe2009-11-12 20:21:18855void FilebrowseHandler::OnListFile(
[email protected]9ee2c8d2010-08-21 23:25:22856 const net::DirectoryLister::DirectoryListerData& data) {
[email protected]07046ab2010-01-20 21:42:44857#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22858 if (data.info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
[email protected]07046ab2010-01-20 21:42:44859 return;
860 }
861#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22862 if (data.info.filename[0] == '.') {
[email protected]07046ab2010-01-20 21:42:44863 return;
864 }
865#endif
866
[email protected]698601e2009-10-21 22:43:37867 DictionaryValue* file_value = new DictionaryValue();
868
869#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22870 int64 size = (static_cast<int64>(data.info.nFileSizeHigh) << 32) |
871 data.info.nFileSizeLow;
872 file_value->SetString(kPropertyTitle, data.info.cFileName);
[email protected]698601e2009-10-21 22:43:37873 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22874 currentpath_.Append(data.info.cFileName).value());
[email protected]698601e2009-10-21 22:43:37875 file_value->SetBoolean(kPropertyDirectory,
[email protected]9ee2c8d2010-08-21 23:25:22876 (data.info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
[email protected]698601e2009-10-21 22:43:37877#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22878 file_value->SetString(kPropertyTitle, data.info.filename);
[email protected]698601e2009-10-21 22:43:37879 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22880 currentpath_.Append(data.info.filename).value());
881 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode));
[email protected]698601e2009-10-21 22:43:37882#endif
883 filelist_value_->Append(file_value);
884}
885
[email protected]dcd23fe2009-11-12 20:21:18886void FilebrowseHandler::OnListDone(int error) {
[email protected]698601e2009-10-21 22:43:37887 DictionaryValue info_value;
[email protected]a67fa08e2010-02-12 20:43:55888 if (is_refresh_) {
[email protected]e4fbe8e2010-08-07 07:00:46889 info_value.SetString("functionCall", "refresh");
[email protected]a67fa08e2010-02-12 20:43:55890 } else {
[email protected]e4fbe8e2010-08-07 07:00:46891 info_value.SetString("functionCall", "getChildren");
[email protected]a67fa08e2010-02-12 20:43:55892 }
[email protected]698601e2009-10-21 22:43:37893 info_value.SetString(kPropertyPath, currentpath_.value());
[email protected]9d6b9aff2009-12-11 17:39:18894 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37895 info_value, *(filelist_value_.get()));
[email protected]698601e2009-10-21 22:43:37896}
897
[email protected]88942a22010-08-19 20:34:43898void FilebrowseHandler::HandleGetMetadata(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37899}
900
[email protected]88942a22010-08-19 20:34:43901void FilebrowseHandler::HandleGetDownloads(const ListValue* args) {
[email protected]ebdd2012011-01-19 11:06:57902 UpdateDownloadList();
[email protected]274e42b2010-01-29 22:03:57903}
904
905void FilebrowseHandler::ModelChanged() {
[email protected]ebdd2012011-01-19 11:06:57906 if (!currentpath_.empty())
907 GetChildrenForPath(currentpath_, true);
908 else
909 UpdateDownloadList();
910}
911
912void FilebrowseHandler::UpdateDownloadList() {
[email protected]274e42b2010-01-29 22:03:57913 ClearDownloadItems();
[email protected]274e42b2010-01-29 22:03:57914
[email protected]0e2b59a2010-07-29 22:27:05915 std::vector<DownloadItem*> downloads;
916 download_manager_->GetAllDownloads(FilePath(), &downloads);
917
[email protected]377b4cc2010-05-18 17:25:19918 std::vector<DownloadItem*> new_downloads;
[email protected]274e42b2010-01-29 22:03:57919 // Scan for any in progress downloads and add ourself to them as an observer.
920 for (DownloadList::iterator it = downloads.begin();
921 it != downloads.end(); ++it) {
922 DownloadItem* download = *it;
923 // We want to know what happens as the download progresses and be notified
924 // when the user validates the dangerous download.
925 if (download->state() == DownloadItem::IN_PROGRESS ||
926 download->safety_state() == DownloadItem::DANGEROUS) {
927 download->AddObserver(this);
[email protected]377b4cc2010-05-18 17:25:19928 active_download_items_.push_back(download);
[email protected]274e42b2010-01-29 22:03:57929 }
[email protected]377b4cc2010-05-18 17:25:19930 DownloadList::iterator item = find(download_items_.begin(),
931 download_items_.end(),
932 download);
933 if (item == download_items_.end() && got_first_download_list_) {
934 SendNewDownload(download);
935 }
936 new_downloads.push_back(download);
[email protected]274e42b2010-01-29 22:03:57937 }
[email protected]377b4cc2010-05-18 17:25:19938 download_items_.swap(new_downloads);
939 got_first_download_list_ = true;
[email protected]274e42b2010-01-29 22:03:57940 SendCurrentDownloads();
941}
942
[email protected]377b4cc2010-05-18 17:25:19943void FilebrowseHandler::SendNewDownload(DownloadItem* download) {
944 ListValue results_value;
945 results_value.Append(download_util::CreateDownloadItemValue(download, -1));
946 dom_ui_->CallJavascriptFunction(L"newDownload", results_value);
947}
948
[email protected]a67fa08e2010-02-12 20:43:55949void FilebrowseHandler::DeleteFile(const FilePath& path) {
950 if (!file_util::Delete(path, true)) {
951 LOG(ERROR) << "unable to delete directory";
952 }
[email protected]2dc383ce2010-10-09 03:54:00953 BrowserThread::PostTask(
954 BrowserThread::UI, FROM_HERE,
[email protected]d52bb8a2010-05-10 21:05:35955 NewRunnableMethod(current_task_, &TaskProxy::FireDeleteCompleteProxy));
[email protected]a67fa08e2010-02-12 20:43:55956}
957
[email protected]d3d9b4fb2010-09-24 16:24:27958void FilebrowseHandler::CopyFile(const FilePath& src, const FilePath& dest) {
959 if (file_util::DirectoryExists(src)) {
960 if (!file_util::CopyDirectory(src, dest, true)) {
961 LOG(ERROR) << "unable to copy directory:" << src.value();
962 }
963 } else {
964 if (!file_util::CopyFile(src, dest)) {
965 LOG(ERROR) << "unable to copy file" << src.value();
966 }
967 }
[email protected]2dc383ce2010-10-09 03:54:00968 BrowserThread::PostTask(
969 BrowserThread::UI, FROM_HERE,
[email protected]d3d9b4fb2010-09-24 16:24:27970 NewRunnableMethod(current_task_, &TaskProxy::FireCopyCompleteProxy));
971}
972
[email protected]88942a22010-08-19 20:34:43973void FilebrowseHandler::HandleDeleteFile(const ListValue* args) {
974#if defined(OS_CHROMEOS)
975 std::string path = WideToUTF8(ExtractStringValue(args));
976 FilePath currentpath(path);
[email protected]df53d2d2010-11-19 08:56:12977
978 // Don't allow file deletion in inaccessible dirs.
[email protected]300bb2a2010-12-12 09:59:20979 if (net::URLRequestFileJob::AccessDisabled(currentpath))
[email protected]df53d2d2010-11-19 08:56:12980 return;
981
[email protected]88942a22010-08-19 20:34:43982 for (unsigned int x = 0; x < active_download_items_.size(); x++) {
983 FilePath item = active_download_items_[x]->full_path();
984 if (item == currentpath) {
985 active_download_items_[x]->Cancel(true);
986 active_download_items_[x]->Remove(true);
987 FilePath dir_path = item.DirName();
988 GetChildrenForPath(dir_path, true);
[email protected]a67fa08e2010-02-12 20:43:55989 return;
990 }
991 }
[email protected]88942a22010-08-19 20:34:43992 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath);
993 task->AddRef();
994 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:00995 BrowserThread::PostTask(
996 BrowserThread::FILE, FROM_HERE,
[email protected]88942a22010-08-19 20:34:43997 NewRunnableMethod(
998 task, &TaskProxy::DeleteFileProxy));
[email protected]a67fa08e2010-02-12 20:43:55999#endif
1000}
1001
[email protected]d3d9b4fb2010-09-24 16:24:271002void FilebrowseHandler::HandleCopyFile(const ListValue* value) {
1003#if defined(OS_CHROMEOS)
1004 if (value && value->GetType() == Value::TYPE_LIST) {
1005 const ListValue* list_value = static_cast<const ListValue*>(value);
1006 std::string src;
1007 std::string dest;
1008
1009 // Get path string.
1010 if (list_value->GetString(0, &src) &&
1011 list_value->GetString(1, &dest)) {
1012 FilePath SrcPath = FilePath(src);
1013 FilePath DestPath = FilePath(dest);
1014
[email protected]df53d2d2010-11-19 08:56:121015 // Don't allow file copy to inaccessible dirs.
[email protected]300bb2a2010-12-12 09:59:201016 if (net::URLRequestFileJob::AccessDisabled(DestPath))
[email protected]df53d2d2010-11-19 08:56:121017 return;
1018
[email protected]d3d9b4fb2010-09-24 16:24:271019 TaskProxy* task = new TaskProxy(AsWeakPtr(), SrcPath, DestPath);
1020 task->AddRef();
1021 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:001022 BrowserThread::PostTask(
1023 BrowserThread::FILE, FROM_HERE,
[email protected]d3d9b4fb2010-09-24 16:24:271024 NewRunnableMethod(
1025 task, &TaskProxy::CopyFileProxy));
1026 } else {
1027 LOG(ERROR) << "Unable to get string";
1028 return;
1029 }
1030 }
1031#endif
1032}
1033
[email protected]23ebd2302010-11-04 16:23:201034void FilebrowseHandler::HandleValidateSavePath(const ListValue* args) {
1035 std::string string_path;
1036 if (!args || !args->GetString(0, &string_path)) {
1037 FireOnValidatedSavePathOnUIThread(false, FilePath()); // Invalid save path.
1038 return;
1039 }
1040
1041 FilePath save_path(string_path);
1042
1043#if defined(OS_CHROMEOS)
1044 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
1045 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1046 NewRunnableMethod(task.get(), &TaskProxy::ValidateSavePathOnFileThread));
1047#else
1048 // No save path checking for non-ChromeOS platforms.
1049 FireOnValidatedSavePathOnUIThread(true, save_path);
1050#endif
1051}
1052
1053void FilebrowseHandler::ValidateSavePathOnFileThread(
1054 const FilePath& save_path) {
1055#if defined(OS_CHROMEOS)
1056 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1057
1058 FilePath default_download_path;
1059 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
1060 &default_download_path)) {
1061 NOTREACHED();
1062 }
1063
1064 // Get containing folder of save_path.
1065 FilePath save_dir = save_path.DirName();
1066
1067 // Valid save path must be inside default download dir.
1068 bool valid = default_download_path == save_dir ||
1069 file_util::ContainsPath(default_download_path, save_dir);
1070
1071 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
1072 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1073 NewRunnableMethod(task.get(),
1074 &TaskProxy::FireOnValidatedSavePathOnUIThread,
1075 valid, save_path));
1076#endif
1077}
1078
1079void FilebrowseHandler::FireOnValidatedSavePathOnUIThread(bool valid,
1080 const FilePath& save_path) {
1081 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1082
1083 FundamentalValue valid_value(valid);
1084 StringValue path_value(save_path.value());
1085 dom_ui_->CallJavascriptFunction(L"onValidatedSavePath",
1086 valid_value, path_value);
1087}
[email protected]d3d9b4fb2010-09-24 16:24:271088
[email protected]274e42b2010-01-29 22:03:571089void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
[email protected]377b4cc2010-05-18 17:25:191090 DownloadList::iterator it = find(active_download_items_.begin(),
1091 active_download_items_.end(),
[email protected]274e42b2010-01-29 22:03:571092 download);
[email protected]377b4cc2010-05-18 17:25:191093 if (it == active_download_items_.end())
[email protected]274e42b2010-01-29 22:03:571094 return;
[email protected]377b4cc2010-05-18 17:25:191095 const int id = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:571096
[email protected]499d97c2010-10-25 23:12:151097 scoped_ptr<DictionaryValue> download_item(
1098 download_util::CreateDownloadItemValue(download, id));
1099 dom_ui_->CallJavascriptFunction(L"downloadUpdated", *download_item.get());
[email protected]274e42b2010-01-29 22:03:571100}
1101
1102void FilebrowseHandler::ClearDownloadItems() {
[email protected]377b4cc2010-05-18 17:25:191103 for (DownloadList::iterator it = active_download_items_.begin();
1104 it != active_download_items_.end(); ++it) {
[email protected]274e42b2010-01-29 22:03:571105 (*it)->RemoveObserver(this);
1106 }
[email protected]377b4cc2010-05-18 17:25:191107 active_download_items_.clear();
[email protected]274e42b2010-01-29 22:03:571108}
1109
1110void FilebrowseHandler::SendCurrentDownloads() {
1111 ListValue results_value;
[email protected]377b4cc2010-05-18 17:25:191112 for (DownloadList::iterator it = active_download_items_.begin();
1113 it != active_download_items_.end(); ++it) {
1114 int index = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:571115 results_value.Append(download_util::CreateDownloadItemValue(*it, index));
1116 }
1117
1118 dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
1119}
1120
[email protected]ebdd2012011-01-19 11:06:571121void FilebrowseHandler::OnDownloadFileCompleted(DownloadItem* download) {
1122 GetChildrenForPath(currentpath_, true);
1123}
1124
[email protected]698601e2009-10-21 22:43:371125////////////////////////////////////////////////////////////////////////////////
1126//
[email protected]f5bf8ccf2010-02-05 18:19:251127// FileBrowseUI
[email protected]698601e2009-10-21 22:43:371128//
1129////////////////////////////////////////////////////////////////////////////////
1130
[email protected]274e42b2010-01-29 22:03:571131FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) {
[email protected]9d6b9aff2009-12-11 17:39:181132 FilebrowseHandler* handler = new FilebrowseHandler();
1133 AddMessageHandler((handler)->Attach(this));
[email protected]274e42b2010-01-29 22:03:571134 handler->Init();
[email protected]698601e2009-10-21 22:43:371135 FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource();
1136
1137 // Set up the chrome://filebrowse/ source.
[email protected]248ce192011-02-10 15:26:341138 contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
[email protected]698601e2009-10-21 22:43:371139}
[email protected]f5bf8ccf2010-02-05 18:19:251140
1141// static
[email protected]1717246f2010-02-10 17:08:151142Browser* FileBrowseUI::OpenPopup(Profile* profile,
[email protected]467293292010-04-16 19:41:561143 const std::string& hashArgument,
1144 int width,
1145 int height) {
[email protected]1717246f2010-02-10 17:08:151146 // Get existing pop up for given hashArgument.
[email protected]f7e9fd62010-09-28 15:45:061147 Browser* browser = GetPopupForPath(hashArgument, profile);
[email protected]f5bf8ccf2010-02-05 18:19:251148
[email protected]1717246f2010-02-10 17:08:151149 // Create new browser if no matching pop up found.
1150 if (browser == NULL) {
[email protected]9ee17e8c2010-08-10 19:17:311151 browser = Browser::CreateForType(Browser::TYPE_APP_PANEL, profile);
[email protected]f59f1162010-04-23 21:19:291152 std::string url;
1153 if (hashArgument.empty()) {
1154 url = chrome::kChromeUIFileBrowseURL;
1155 } else {
1156 url = kFilebrowseURLHash;
1157 url.append(hashArgument);
1158 }
[email protected]f5bf8ccf2010-02-05 18:19:251159
[email protected]616381f02010-11-02 15:15:331160 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
1161 params.disposition = NEW_FOREGROUND_TAB;
1162 browser::Navigate(&params);
1163 // TODO(beng): The following two calls should be automatic by Navigate().
1164 params.browser->window()->SetBounds(gfx::Rect(kPopupLeft,
1165 kPopupTop,
1166 width,
1167 height));
[email protected]1717246f2010-02-10 17:08:151168
[email protected]616381f02010-11-02 15:15:331169 params.browser->window()->Show();
[email protected]9ee17e8c2010-08-10 19:17:311170 } else {
1171 browser->window()->Show();
[email protected]1717246f2010-02-10 17:08:151172 }
[email protected]f5bf8ccf2010-02-05 18:19:251173
1174 return browser;
1175}
[email protected]1717246f2010-02-10 17:08:151176
[email protected]f7e9fd62010-09-28 15:45:061177Browser* FileBrowseUI::GetPopupForPath(const std::string& path,
1178 Profile* profile) {
[email protected]9ee17e8c2010-08-10 19:17:311179 std::string current_path = path;
1180 if (current_path.empty()) {
[email protected]ba8164242010-11-16 21:31:001181 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
1182 switches::kEnableAdvancedFileSystem);
[email protected]9ee17e8c2010-08-10 19:17:311183 if (!is_enabled) {
1184 FilePath default_download_path;
1185 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
1186 &default_download_path)) {
1187 NOTREACHED();
1188 }
1189 current_path = default_download_path.value();
1190 }
1191 }
1192
[email protected]1717246f2010-02-10 17:08:151193 for (BrowserList::const_iterator it = BrowserList::begin();
1194 it != BrowserList::end(); ++it) {
[email protected]9ee17e8c2010-08-10 19:17:311195 if (((*it)->type() == Browser::TYPE_APP_PANEL)) {
[email protected]d519bed2010-05-28 18:42:031196 TabContents* tab_contents = (*it)->GetSelectedTabContents();
1197 DCHECK(tab_contents);
1198 if (!tab_contents)
1199 continue;
1200 const GURL& url = tab_contents->GetURL();
[email protected]1717246f2010-02-10 17:08:151201
1202 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1203 url.host() == chrome::kChromeUIFileBrowseHost &&
[email protected]f7e9fd62010-09-28 15:45:061204 url.ref() == current_path &&
1205 (*it)->profile() == profile) {
[email protected]1717246f2010-02-10 17:08:151206 return (*it);
1207 }
1208 }
1209 }
1210
1211 return NULL;
1212}
[email protected]467293292010-04-16 19:41:561213
1214const int FileBrowseUI::kPopupWidth = 250;
1215const int FileBrowseUI::kPopupHeight = 300;
1216const int FileBrowseUI::kSmallPopupWidth = 250;
1217const int FileBrowseUI::kSmallPopupHeight = 50;