blob: 9e5a3d5aefaf027dbfe016dcefc5d7547e4e3295 [file] [log] [blame]
[email protected]666205032010-10-21 20:56:581// Copyright (c) 2010 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
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]ba8164242010-11-16 21:31:0010#include "base/command_line.h"
[email protected]23ebd2302010-11-04 16:23:2011#include "base/file_util.h"
[email protected]698601e2009-10-21 22:43:3712#include "base/logging.h"
13#include "base/message_loop.h"
[email protected]07046ab2010-01-20 21:42:4414#include "base/path_service.h"
[email protected]5c4c7402009-10-30 19:58:0615#include "base/singleton.h"
[email protected]698601e2009-10-21 22:43:3716#include "base/string_piece.h"
17#include "base/string_util.h"
18#include "base/thread.h"
19#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2220#include "base/utf_string_conversions.h"
[email protected]698601e2009-10-21 22:43:3721#include "base/values.h"
[email protected]9d6b9aff2009-12-11 17:39:1822#include "base/weak_ptr.h"
[email protected]698601e2009-10-21 22:43:3723#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]facac1532010-10-11 22:59:5024#include "chrome/browser/browser_thread.h"
[email protected]698601e2009-10-21 22:43:3725#include "chrome/browser/dom_ui/dom_ui_favicon_source.h"
[email protected]c848d3d92010-09-16 21:57:4526#include "chrome/browser/dom_ui/mediaplayer_ui.h"
[email protected]75986612010-07-16 22:23:5727#include "chrome/browser/download/download_item.h"
[email protected]274e42b2010-01-29 22:03:5728#include "chrome/browser/download/download_manager.h"
29#include "chrome/browser/download/download_util.h"
[email protected]1717246f2010-02-10 17:08:1530#include "chrome/browser/history/history_types.h"
[email protected]698601e2009-10-21 22:43:3731#include "chrome/browser/metrics/user_metrics.h"
[email protected]698601e2009-10-21 22:43:3732#include "chrome/browser/profile.h"
[email protected]1717246f2010-02-10 17:08:1533#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]c848d3d92010-09-16 21:57:4534#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]2ad4a902010-11-17 06:05:1335#include "chrome/browser/ui/browser.h"
36#include "chrome/browser/ui/browser_list.h"
[email protected]339d6dd2010-11-12 00:41:5837#include "chrome/browser/ui/browser_navigator.h"
[email protected]2ad4a902010-11-17 06:05:1338#include "chrome/browser/ui/browser_window.h"
[email protected]07046ab2010-01-20 21:42:4439#include "chrome/common/chrome_paths.h"
[email protected]ba8164242010-11-16 21:31:0040#include "chrome/common/chrome_switches.h"
[email protected]698601e2009-10-21 22:43:3741#include "chrome/common/jstemplate_builder.h"
[email protected]68d2a05f2010-05-07 21:39:5542#include "chrome/common/net/url_fetcher.h"
[email protected]698601e2009-10-21 22:43:3743#include "chrome/common/time_format.h"
44#include "chrome/common/url_constants.h"
[email protected]698601e2009-10-21 22:43:3745#include "grit/browser_resources.h"
46#include "grit/chromium_strings.h"
47#include "grit/generated_resources.h"
48#include "grit/locale_settings.h"
[email protected]c848d3d92010-09-16 21:57:4549#include "net/base/escape.h"
[email protected]df53d2d2010-11-19 08:56:1250#include "net/url_request/url_request_file_job.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]9d6b9aff2009-12-11 17:39:1897 public DOMMessageHandler,
[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
117 // DOMMessageHandler implementation.
118 virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
119 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);
129 virtual void OnDownloadFileCompleted(DownloadItem* download) { }
130 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,
142 const URLRequestStatus& status,
143 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]88942a22010-08-19 20:34:43199 void OpenNewWindow(const ListValue* args, bool popup);
[email protected]dcd23fe2009-11-12 20:21:18200
[email protected]274e42b2010-01-29 22:03:57201 // Clear all download items and their observers.
202 void ClearDownloadItems();
203
204 // Send the current list of downloads to the page.
205 void SendCurrentDownloads();
206
[email protected]377b4cc2010-05-18 17:25:19207 void SendNewDownload(DownloadItem* download);
208
[email protected]698601e2009-10-21 22:43:37209 scoped_ptr<ListValue> filelist_value_;
210 FilePath currentpath_;
[email protected]dcd23fe2009-11-12 20:21:18211 Profile* profile_;
[email protected]93a58bf72010-06-04 23:01:20212 TabContents* tab_contents_;
[email protected]9d6b9aff2009-12-11 17:39:18213 std::string current_file_contents_;
214 std::string current_file_uploaded_;
215 int upload_response_code_;
[email protected]d52bb8a2010-05-10 21:05:35216 TaskProxy* current_task_;
[email protected]698601e2009-10-21 22:43:37217 scoped_refptr<net::DirectoryLister> lister_;
[email protected]a67fa08e2010-02-12 20:43:55218 bool is_refresh_;
[email protected]d52bb8a2010-05-10 21:05:35219 scoped_ptr<URLFetcher> fetch_;
[email protected]698601e2009-10-21 22:43:37220
[email protected]274e42b2010-01-29 22:03:57221 DownloadManager* download_manager_;
222 typedef std::vector<DownloadItem*> DownloadList;
[email protected]377b4cc2010-05-18 17:25:19223 DownloadList active_download_items_;
[email protected]274e42b2010-01-29 22:03:57224 DownloadList download_items_;
[email protected]377b4cc2010-05-18 17:25:19225 bool got_first_download_list_;
[email protected]dcd23fe2009-11-12 20:21:18226 DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler);
[email protected]698601e2009-10-21 22:43:37227};
228
[email protected]9d6b9aff2009-12-11 17:39:18229class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
230 public:
[email protected]d3d9b4fb2010-09-24 16:24:27231 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
232 const FilePath& path, const FilePath& dest)
[email protected]a67fa08e2010-02-12 20:43:55233 : handler_(handler),
[email protected]d3d9b4fb2010-09-24 16:24:27234 src_(path),
235 dest_(dest) {}
236 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
237 const FilePath& path)
238 : handler_(handler),
239 src_(path) {}
[email protected]9d6b9aff2009-12-11 17:39:18240 void ReadInFileProxy() {
241 if (handler_) {
242 handler_->ReadInFile();
243 }
244 }
[email protected]068a71f2010-05-11 22:35:48245 void DeleteFetcher(URLFetcher* fetch) {
246 delete fetch;
247 }
[email protected]d52bb8a2010-05-10 21:05:35248 void SendPicasawebRequestProxy() {
249 if (handler_) {
250 handler_->SendPicasawebRequest();
251 }
252 }
[email protected]9d6b9aff2009-12-11 17:39:18253 void FireUploadCompleteProxy() {
254 if (handler_) {
255 handler_->FireUploadComplete();
256 }
257 }
[email protected]a67fa08e2010-02-12 20:43:55258
259 void DeleteFileProxy() {
260 if (handler_) {
[email protected]d3d9b4fb2010-09-24 16:24:27261 handler_->DeleteFile(src_);
262 }
263 }
264
265 void CopyFileProxy() {
266 if (handler_) {
267 handler_->CopyFile(src_, dest_);
[email protected]a67fa08e2010-02-12 20:43:55268 }
269 }
270
271 void FireDeleteCompleteProxy() {
272 if (handler_) {
[email protected]d3d9b4fb2010-09-24 16:24:27273 handler_->FireDeleteComplete(src_);
274 }
275 }
276 void FireCopyCompleteProxy() {
277 if (handler_) {
278 handler_->FireCopyComplete(src_, dest_);
[email protected]a67fa08e2010-02-12 20:43:55279 }
280 }
[email protected]23ebd2302010-11-04 16:23:20281
282 void ValidateSavePathOnFileThread() {
283 if (handler_)
284 handler_->ValidateSavePathOnFileThread(src_);
285 }
286 void FireOnValidatedSavePathOnUIThread(bool valid,
287 const FilePath& save_path) {
288 if (handler_)
289 handler_->FireOnValidatedSavePathOnUIThread(valid, save_path);
290 }
291
[email protected]9d6b9aff2009-12-11 17:39:18292 private:
293 base::WeakPtr<FilebrowseHandler> handler_;
[email protected]d3d9b4fb2010-09-24 16:24:27294 FilePath src_;
295 FilePath dest_;
[email protected]9d6b9aff2009-12-11 17:39:18296 friend class base::RefCountedThreadSafe<TaskProxy>;
[email protected]068a71f2010-05-11 22:35:48297 DISALLOW_COPY_AND_ASSIGN(TaskProxy);
[email protected]9d6b9aff2009-12-11 17:39:18298};
299
300
[email protected]698601e2009-10-21 22:43:37301////////////////////////////////////////////////////////////////////////////////
302//
303// FileBrowseHTMLSource
304//
305////////////////////////////////////////////////////////////////////////////////
306
307FileBrowseUIHTMLSource::FileBrowseUIHTMLSource()
308 : DataSource(chrome::kChromeUIFileBrowseHost, MessageLoop::current()) {
309}
310
311void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path,
[email protected]e42ae9b2010-03-28 00:55:05312 bool is_off_the_record,
313 int request_id) {
[email protected]698601e2009-10-21 22:43:37314 DictionaryValue localized_strings;
[email protected]11f4857282009-11-13 19:56:17315 // TODO(dhg): Add stirings to localized strings, also add more strings
[email protected]dcd23fe2009-11-12 20:21:18316 // that are currently hardcoded.
[email protected]e4fbe8e2010-08-07 07:00:46317 localized_strings.SetString("title",
318 l10n_util::GetStringUTF16(IDS_FILEBROWSER_TITLE));
319 localized_strings.SetString("pause",
320 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PAUSE));
321 localized_strings.SetString("resume",
322 l10n_util::GetStringUTF16(IDS_FILEBROWSER_RESUME));
323 localized_strings.SetString("scanning",
324 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SCANNING));
325 localized_strings.SetString("confirmdelete",
326 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DELETE));
327 localized_strings.SetString("confirmyes",
328 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_YES));
329 localized_strings.SetString("confirmcancel",
330 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_CANCEL));
331 localized_strings.SetString("allowdownload",
332 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DOWNLOAD));
333 localized_strings.SetString("filenameprompt",
334 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PROMPT_FILENAME));
335 localized_strings.SetString("save",
336 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SAVE));
337 localized_strings.SetString("newfolder",
338 l10n_util::GetStringUTF16(IDS_FILEBROWSER_NEW_FOLDER));
339 localized_strings.SetString("open",
340 l10n_util::GetStringUTF16(IDS_FILEBROWSER_OPEN));
341 localized_strings.SetString("picasaweb",
342 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_PICASAWEB));
343 localized_strings.SetString("flickr",
344 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_FLICKR));
345 localized_strings.SetString("email",
346 l10n_util::GetStringUTF16(IDS_FILEBROWSER_UPLOAD_EMAIL));
347 localized_strings.SetString("delete",
348 l10n_util::GetStringUTF16(IDS_FILEBROWSER_DELETE));
349 localized_strings.SetString("enqueue",
350 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ENQUEUE));
351 localized_strings.SetString("mediapath", kMediaPath);
[email protected]88f03da02010-06-10 16:21:13352 FilePath default_download_path;
353 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
354 &default_download_path)) {
355 NOTREACHED();
356 }
[email protected]e4fbe8e2010-08-07 07:00:46357 // TODO(viettrungluu): this is wrong -- FilePath's need not be Unicode.
358 localized_strings.SetString("downloadpath", default_download_path.value());
359 localized_strings.SetString("error_unknown_file_type",
360 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ERROR_UNKNOWN_FILE_TYPE));
[email protected]698601e2009-10-21 22:43:37361 SetFontAndTextDirection(&localized_strings);
362
363 static const base::StringPiece filebrowse_html(
364 ResourceBundle::GetSharedInstance().GetRawDataResource(
365 IDR_FILEBROWSE_HTML));
366 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
367 filebrowse_html, &localized_strings);
368
369 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
370 html_bytes->data.resize(full_html.size());
371 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
372
373 SendResponse(request_id, html_bytes);
374}
375
376////////////////////////////////////////////////////////////////////////////////
377//
[email protected]dcd23fe2009-11-12 20:21:18378// FilebrowseHandler
[email protected]698601e2009-10-21 22:43:37379//
380////////////////////////////////////////////////////////////////////////////////
[email protected]dcd23fe2009-11-12 20:21:18381FilebrowseHandler::FilebrowseHandler()
[email protected]274e42b2010-01-29 22:03:57382 : profile_(NULL),
[email protected]93a58bf72010-06-04 23:01:20383 tab_contents_(NULL),
[email protected]a67fa08e2010-02-12 20:43:55384 is_refresh_(false),
[email protected]d52bb8a2010-05-10 21:05:35385 fetch_(NULL),
[email protected]377b4cc2010-05-18 17:25:19386 download_manager_(NULL),
387 got_first_download_list_(false) {
[email protected]a67fa08e2010-02-12 20:43:55388 lister_ = NULL;
[email protected]07046ab2010-01-20 21:42:44389#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24390 chromeos::MountLibrary* lib =
391 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44392 lib->AddObserver(this);
393#endif
[email protected]698601e2009-10-21 22:43:37394}
395
[email protected]dcd23fe2009-11-12 20:21:18396FilebrowseHandler::~FilebrowseHandler() {
[email protected]07046ab2010-01-20 21:42:44397#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24398 chromeos::MountLibrary* lib =
399 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44400 lib->RemoveObserver(this);
401#endif
[email protected]698601e2009-10-21 22:43:37402 if (lister_.get()) {
403 lister_->Cancel();
404 lister_->set_delegate(NULL);
405 }
[email protected]274e42b2010-01-29 22:03:57406
407 ClearDownloadItems();
408 download_manager_->RemoveObserver(this);
[email protected]068a71f2010-05-11 22:35:48409 URLFetcher* fetch = fetch_.release();
410 if (fetch) {
411 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath_);
412 task->AddRef();
[email protected]2dc383ce2010-10-09 03:54:00413 BrowserThread::PostTask(
414 BrowserThread::FILE, FROM_HERE,
[email protected]068a71f2010-05-11 22:35:48415 NewRunnableMethod(
416 task, &TaskProxy::DeleteFetcher, fetch));
417 }
[email protected]698601e2009-10-21 22:43:37418}
419
[email protected]dcd23fe2009-11-12 20:21:18420DOMMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) {
[email protected]698601e2009-10-21 22:43:37421 // Create our favicon data source.
[email protected]2dc383ce2010-10-09 03:54:00422 BrowserThread::PostTask(
423 BrowserThread::IO, FROM_HERE,
[email protected]fae20792009-10-28 20:31:58424 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:09425 Singleton<ChromeURLDataManager>::get(),
[email protected]fae20792009-10-28 20:31:58426 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:23427 make_scoped_refptr(new DOMUIFavIconSource(dom_ui->GetProfile()))));
[email protected]dcd23fe2009-11-12 20:21:18428 profile_ = dom_ui->GetProfile();
[email protected]93a58bf72010-06-04 23:01:20429 tab_contents_ = dom_ui->tab_contents();
[email protected]698601e2009-10-21 22:43:37430 return DOMMessageHandler::Attach(dom_ui);
431}
432
[email protected]274e42b2010-01-29 22:03:57433void FilebrowseHandler::Init() {
[email protected]f7e9fd62010-09-28 15:45:06434 download_manager_ = profile_->GetDownloadManager();
[email protected]274e42b2010-01-29 22:03:57435 download_manager_->AddObserver(this);
[email protected]d52bb8a2010-05-10 21:05:35436 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath_);
437 task->AddRef();
438 current_task_ = task;
439 static bool sent_request = false;
440 if (!sent_request) {
441 // If we have not sent a request before, we should do one in order to
442 // ensure that we have the correct cookies. This is for uploads.
[email protected]2dc383ce2010-10-09 03:54:00443 BrowserThread::PostTask(
444 BrowserThread::FILE, FROM_HERE,
[email protected]d52bb8a2010-05-10 21:05:35445 NewRunnableMethod(
446 task, &TaskProxy::SendPicasawebRequestProxy));
447 sent_request = true;
448 }
[email protected]274e42b2010-01-29 22:03:57449}
450
[email protected]dcd23fe2009-11-12 20:21:18451void FilebrowseHandler::RegisterMessages() {
[email protected]698601e2009-10-21 22:43:37452 dom_ui_->RegisterMessageCallback("getRoots",
[email protected]dcd23fe2009-11-12 20:21:18453 NewCallback(this, &FilebrowseHandler::HandleGetRoots));
[email protected]698601e2009-10-21 22:43:37454 dom_ui_->RegisterMessageCallback("getChildren",
[email protected]dcd23fe2009-11-12 20:21:18455 NewCallback(this, &FilebrowseHandler::HandleGetChildren));
[email protected]698601e2009-10-21 22:43:37456 dom_ui_->RegisterMessageCallback("getMetadata",
[email protected]dcd23fe2009-11-12 20:21:18457 NewCallback(this, &FilebrowseHandler::HandleGetMetadata));
458 dom_ui_->RegisterMessageCallback("openNewPopupWindow",
459 NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow));
460 dom_ui_->RegisterMessageCallback("openNewFullWindow",
461 NewCallback(this, &FilebrowseHandler::OpenNewFullWindow));
[email protected]9d6b9aff2009-12-11 17:39:18462 dom_ui_->RegisterMessageCallback("uploadToPicasaweb",
463 NewCallback(this, &FilebrowseHandler::UploadToPicasaweb));
[email protected]274e42b2010-01-29 22:03:57464 dom_ui_->RegisterMessageCallback("getDownloads",
465 NewCallback(this, &FilebrowseHandler::HandleGetDownloads));
466 dom_ui_->RegisterMessageCallback("createNewFolder",
467 NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder));
[email protected]17496bb2010-03-10 19:48:23468 dom_ui_->RegisterMessageCallback("playMediaFile",
469 NewCallback(this, &FilebrowseHandler::PlayMediaFile));
[email protected]89a7e3812010-06-02 19:38:07470 dom_ui_->RegisterMessageCallback("enqueueMediaFile",
471 NewCallback(this, &FilebrowseHandler::EnqueueMediaFile));
[email protected]a67fa08e2010-02-12 20:43:55472 dom_ui_->RegisterMessageCallback("pauseToggleDownload",
473 NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
474 dom_ui_->RegisterMessageCallback("deleteFile",
475 NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
[email protected]d3d9b4fb2010-09-24 16:24:27476 dom_ui_->RegisterMessageCallback("copyFile",
477 NewCallback(this, &FilebrowseHandler::HandleCopyFile));
[email protected]c4a530b2010-03-08 17:33:03478 dom_ui_->RegisterMessageCallback("cancelDownload",
479 NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
480 dom_ui_->RegisterMessageCallback("allowDownload",
481 NewCallback(this, &FilebrowseHandler::HandleAllowDownload));
482 dom_ui_->RegisterMessageCallback("refreshDirectory",
483 NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
[email protected]6ba198f2010-07-02 20:32:05484 dom_ui_->RegisterMessageCallback("isAdvancedEnabled",
485 NewCallback(this, &FilebrowseHandler::HandleIsAdvancedEnabled));
[email protected]23ebd2302010-11-04 16:23:20486 dom_ui_->RegisterMessageCallback("validateSavePath",
487 NewCallback(this, &FilebrowseHandler::HandleValidateSavePath));
[email protected]9d6b9aff2009-12-11 17:39:18488}
489
[email protected]a67fa08e2010-02-12 20:43:55490
491void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
492 // We notify the UI by telling it to refresh its contents.
493 FilePath dir_path = path.DirName();
494 GetChildrenForPath(dir_path, true);
495};
496
[email protected]d3d9b4fb2010-09-24 16:24:27497void FilebrowseHandler::FireCopyComplete(const FilePath& src,
498 const FilePath& dest) {
499 // Notify the UI somehow.
500 FilePath dir_path = dest.DirName();
501 GetChildrenForPath(dir_path, true);
502};
503
[email protected]9d6b9aff2009-12-11 17:39:18504void FilebrowseHandler::FireUploadComplete() {
[email protected]d52bb8a2010-05-10 21:05:35505#if defined(OS_CHROMEOS)
[email protected]9d6b9aff2009-12-11 17:39:18506 DictionaryValue info_value;
[email protected]e4fbe8e2010-08-07 07:00:46507 info_value.SetString("path", current_file_uploaded_);
[email protected]9d6b9aff2009-12-11 17:39:18508
509 std::string username;
[email protected]d52bb8a2010-05-10 21:05:35510 chromeos::UserManager* user_man = chromeos::UserManager::Get();
511 username = user_man->logged_in_user().email();
[email protected]9d6b9aff2009-12-11 17:39:18512
513 if (username.empty()) {
514 LOG(ERROR) << "Unable to get username";
515 return;
516 }
517 int location = username.find_first_of('@',0);
518 if (location <= 0) {
519 LOG(ERROR) << "Username not formatted correctly";
520 return;
521 }
522 username = username.erase(username.find_first_of('@',0));
[email protected]e4fbe8e2010-08-07 07:00:46523 std::string picture_url = kPicasawebBaseUrl;
[email protected]9d6b9aff2009-12-11 17:39:18524 picture_url += username;
525 picture_url += kPicasawebDropBox;
[email protected]e4fbe8e2010-08-07 07:00:46526 info_value.SetString("url", picture_url);
527 info_value.SetInteger("status_code", upload_response_code_);
[email protected]9d6b9aff2009-12-11 17:39:18528 dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value);
[email protected]d52bb8a2010-05-10 21:05:35529#endif
[email protected]9d6b9aff2009-12-11 17:39:18530}
531
[email protected]07046ab2010-01-20 21:42:44532#if defined(OS_CHROMEOS)
533void FilebrowseHandler::MountChanged(chromeos::MountLibrary* obj,
534 chromeos::MountEventType evt,
535 const std::string& path) {
536 if (evt == chromeos::DISK_REMOVED ||
537 evt == chromeos::DISK_CHANGED) {
538 dom_ui_->CallJavascriptFunction(L"rootsChanged");
539 }
540}
541#endif
542
[email protected]9d6b9aff2009-12-11 17:39:18543void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source,
544 const GURL& url,
545 const URLRequestStatus& status,
546 int response_code,
547 const ResponseCookies& cookies,
548 const std::string& data) {
549 upload_response_code_ = response_code;
[email protected]666205032010-10-21 20:56:58550 VLOG(1) << "Response code: " << response_code;
551 VLOG(1) << "Request url: " << url;
[email protected]068a71f2010-05-11 22:35:48552 if (StartsWithASCII(url.spec(), kPicasawebUserPrefix, true)) {
[email protected]2dc383ce2010-10-09 03:54:00553 BrowserThread::PostTask(
554 BrowserThread::UI, FROM_HERE,
[email protected]068a71f2010-05-11 22:35:48555 NewRunnableMethod(current_task_, &TaskProxy::FireUploadCompleteProxy));
556 }
557 fetch_.reset();
[email protected]698601e2009-10-21 22:43:37558}
559
[email protected]88942a22010-08-19 20:34:43560void FilebrowseHandler::HandleGetRoots(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37561 ListValue results_value;
562 DictionaryValue info_value;
[email protected]698601e2009-10-21 22:43:37563 // TODO(dhg): add other entries, make this more general
[email protected]07046ab2010-01-20 21:42:44564#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24565 chromeos::MountLibrary* lib =
566 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44567 const chromeos::MountLibrary::DiskVector& disks = lib->disks();
568
569 for (size_t i = 0; i < disks.size(); ++i) {
570 if (!disks[i].mount_path.empty()) {
571 DictionaryValue* page_value = new DictionaryValue();
572 page_value->SetString(kPropertyPath, disks[i].mount_path);
[email protected]88942a22010-08-19 20:34:43573 FilePath currentpath(disks[i].mount_path);
[email protected]07046ab2010-01-20 21:42:44574 std::string filename;
575 filename = currentpath.BaseName().value();
576 page_value->SetString(kPropertyTitle, filename);
577 page_value->SetBoolean(kPropertyDirectory, true);
578 results_value.Append(page_value);
579 }
580 }
581#else
582 DictionaryValue* page_value = new DictionaryValue();
583 page_value->SetString(kPropertyPath, "/media");
584 page_value->SetString(kPropertyTitle, "Removeable");
[email protected]698601e2009-10-21 22:43:37585 page_value->SetBoolean(kPropertyDirectory, true);
586
587 results_value.Append(page_value);
[email protected]07046ab2010-01-20 21:42:44588#endif
589 FilePath default_download_path;
590 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
591 &default_download_path)) {
592 NOTREACHED();
593 }
594
595 DictionaryValue* download_value = new DictionaryValue();
596 download_value->SetString(kPropertyPath, default_download_path.value());
597 download_value->SetString(kPropertyTitle, "File Shelf");
598 download_value->SetBoolean(kPropertyDirectory, true);
599
600 results_value.Append(download_value);
[email protected]698601e2009-10-21 22:43:37601
[email protected]e4fbe8e2010-08-07 07:00:46602 info_value.SetString("functionCall", "getRoots");
[email protected]07046ab2010-01-20 21:42:44603 info_value.SetString(kPropertyPath, "");
[email protected]9d6b9aff2009-12-11 17:39:18604 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37605 info_value, results_value);
606}
607
[email protected]88942a22010-08-19 20:34:43608void FilebrowseHandler::HandleCreateNewFolder(const ListValue* args) {
[email protected]274e42b2010-01-29 22:03:57609#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43610 std::string path = WideToUTF8(ExtractStringValue(args));
611 FilePath currentpath(path);
[email protected]274e42b2010-01-29 22:03:57612
[email protected]88942a22010-08-19 20:34:43613 if (!file_util::CreateDirectory(currentpath))
614 LOG(ERROR) << "unable to create directory";
[email protected]274e42b2010-01-29 22:03:57615#endif
616}
617
[email protected]88942a22010-08-19 20:34:43618void FilebrowseHandler::PlayMediaFile(const ListValue* args) {
[email protected]17496bb2010-03-10 19:48:23619#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43620 std::string url = WideToUTF8(ExtractStringValue(args));
621 GURL gurl(url);
[email protected]17496bb2010-03-10 19:48:23622
[email protected]88942a22010-08-19 20:34:43623 Browser* browser = Browser::GetBrowserForController(
624 &tab_contents_->controller(), NULL);
625 MediaPlayer* mediaplayer = MediaPlayer::Get();
626 mediaplayer->ForcePlayMediaURL(gurl, browser);
[email protected]89a7e3812010-06-02 19:38:07627#endif
628}
629
[email protected]88942a22010-08-19 20:34:43630void FilebrowseHandler::EnqueueMediaFile(const ListValue* args) {
[email protected]89a7e3812010-06-02 19:38:07631#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43632 std::string url = WideToUTF8(ExtractStringValue(args));
633 GURL gurl(url);
[email protected]89a7e3812010-06-02 19:38:07634
[email protected]88942a22010-08-19 20:34:43635 Browser* browser = Browser::GetBrowserForController(
636 &tab_contents_->controller(), NULL);
637 MediaPlayer* mediaplayer = MediaPlayer::Get();
638 mediaplayer->EnqueueMediaURL(gurl, browser);
[email protected]17496bb2010-03-10 19:48:23639#endif
640}
641
[email protected]88942a22010-08-19 20:34:43642void FilebrowseHandler::HandleIsAdvancedEnabled(const ListValue* args) {
[email protected]6ba198f2010-07-02 20:32:05643#if defined(OS_CHROMEOS)
[email protected]ba8164242010-11-16 21:31:00644 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
645 switches::kEnableAdvancedFileSystem);
646 bool mp_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
647 switches::kEnableMediaPlayer);
[email protected]6ba198f2010-07-02 20:32:05648 DictionaryValue info_value;
[email protected]e4fbe8e2010-08-07 07:00:46649 info_value.SetBoolean("enabled", is_enabled);
650 info_value.SetBoolean("mpEnabled", mp_enabled);
[email protected]6ba198f2010-07-02 20:32:05651 dom_ui_->CallJavascriptFunction(L"enabledResult",
652 info_value);
[email protected]f872b3e2010-08-13 16:26:10653
[email protected]6ba198f2010-07-02 20:32:05654#endif
655}
[email protected]c4a530b2010-03-08 17:33:03656
[email protected]88942a22010-08-19 20:34:43657void FilebrowseHandler::HandleRefreshDirectory(const ListValue* args) {
[email protected]a67fa08e2010-02-12 20:43:55658#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43659 std::string path = WideToUTF8(ExtractStringValue(args));
660 FilePath currentpath(path);
661 GetChildrenForPath(currentpath, true);
[email protected]a67fa08e2010-02-12 20:43:55662#endif
663}
664
[email protected]88942a22010-08-19 20:34:43665void FilebrowseHandler::HandlePauseToggleDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03666#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43667 int id;
668 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27669 if ((id - 1) >= (int)active_download_items_.size()) {
670 return;
671 }
[email protected]88942a22010-08-19 20:34:43672 DownloadItem* item = active_download_items_[id];
673 item->TogglePause();
[email protected]c4a530b2010-03-08 17:33:03674#endif
675}
676
[email protected]88942a22010-08-19 20:34:43677void FilebrowseHandler::HandleAllowDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03678#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43679 int id;
680 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27681 if ((id - 1) >= (int)active_download_items_.size()) {
682 return;
683 }
684
[email protected]88942a22010-08-19 20:34:43685 DownloadItem* item = active_download_items_[id];
686 download_manager_->DangerousDownloadValidated(item);
[email protected]c4a530b2010-03-08 17:33:03687#endif
688}
689
[email protected]88942a22010-08-19 20:34:43690void FilebrowseHandler::HandleCancelDownload(const ListValue* args) {
691#if defined(OS_CHROMEOS)
692 int id;
693 ExtractIntegerValue(args, &id);
[email protected]d3d9b4fb2010-09-24 16:24:27694 if ((id - 1) >= (int)active_download_items_.size()) {
695 return;
696 }
[email protected]88942a22010-08-19 20:34:43697 DownloadItem* item = active_download_items_[id];
[email protected]88942a22010-08-19 20:34:43698 FilePath path = item->full_path();
[email protected]d3d9b4fb2010-09-24 16:24:27699 item->Cancel(true);
[email protected]88942a22010-08-19 20:34:43700 FilePath dir_path = path.DirName();
701 item->Remove(true);
702 GetChildrenForPath(dir_path, true);
703#endif
[email protected]dcd23fe2009-11-12 20:21:18704}
[email protected]698601e2009-10-21 22:43:37705
[email protected]88942a22010-08-19 20:34:43706void FilebrowseHandler::OpenNewFullWindow(const ListValue* args) {
707 OpenNewWindow(args, false);
[email protected]dcd23fe2009-11-12 20:21:18708}
709
[email protected]88942a22010-08-19 20:34:43710void FilebrowseHandler::OpenNewPopupWindow(const ListValue* args) {
711 OpenNewWindow(args, true);
712}
[email protected]dcd23fe2009-11-12 20:21:18713
[email protected]88942a22010-08-19 20:34:43714void FilebrowseHandler::OpenNewWindow(const ListValue* args, bool popup) {
715 std::string url = WideToUTF8(ExtractStringValue(args));
716 Browser* browser = popup ?
717 Browser::CreateForType(Browser::TYPE_APP_PANEL, profile_) :
718 BrowserList::GetLastActive();
[email protected]616381f02010-11-02 15:15:33719 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
720 params.disposition = NEW_FOREGROUND_TAB;
721 browser::Navigate(&params);
722 // TODO(beng): The following two calls should be automatic by Navigate().
[email protected]88942a22010-08-19 20:34:43723 if (popup) {
724 // TODO(dhg): Remove these from being hardcoded. Allow javascript
725 // to specify.
[email protected]616381f02010-11-02 15:15:33726 params.browser->window()->SetBounds(gfx::Rect(0, 0, 400, 300));
[email protected]dcd23fe2009-11-12 20:21:18727 }
[email protected]616381f02010-11-02 15:15:33728 params.browser->window()->Show();
[email protected]dcd23fe2009-11-12 20:21:18729}
730
[email protected]d52bb8a2010-05-10 21:05:35731void FilebrowseHandler::SendPicasawebRequest() {
[email protected]068a71f2010-05-11 22:35:48732#if defined(OS_CHROMEOS)
733 chromeos::UserManager* user_man = chromeos::UserManager::Get();
734 std::string username = user_man->logged_in_user().email();
735
736 if (username.empty()) {
737 LOG(ERROR) << "Unable to get username";
738 return;
739 }
740
[email protected]d52bb8a2010-05-10 21:05:35741 fetch_.reset(URLFetcher::Create(0,
742 GURL(kPicasawebBaseUrl),
743 URLFetcher::GET,
[email protected]068a71f2010-05-11 22:35:48744 this));
[email protected]d52bb8a2010-05-10 21:05:35745 fetch_->set_request_context(profile_->GetRequestContext());
746 fetch_->Start();
[email protected]068a71f2010-05-11 22:35:48747#endif
[email protected]d52bb8a2010-05-10 21:05:35748}
749
[email protected]9d6b9aff2009-12-11 17:39:18750void FilebrowseHandler::ReadInFile() {
751#if defined(OS_CHROMEOS)
752 // Get the users username
753 std::string username;
[email protected]d52bb8a2010-05-10 21:05:35754 chromeos::UserManager* user_man = chromeos::UserManager::Get();
755 username = user_man->logged_in_user().email();
[email protected]9d6b9aff2009-12-11 17:39:18756
757 if (username.empty()) {
758 LOG(ERROR) << "Unable to get username";
759 return;
760 }
761 int location = username.find_first_of('@',0);
762 if (location <= 0) {
763 LOG(ERROR) << "Username not formatted correctly";
764 return;
765 }
766 username = username.erase(username.find_first_of('@',0));
767 std::string url = kPicasawebUserPrefix;
768 url += username;
769 url += kPicasawebDefault;
770
[email protected]88942a22010-08-19 20:34:43771 FilePath currentpath(current_file_uploaded_);
[email protected]9d6b9aff2009-12-11 17:39:18772 // Get the filename
773 std::string filename;
774 filename = currentpath.BaseName().value();
775 std::string filecontents;
776 if (!file_util::ReadFileToString(currentpath, &filecontents)) {
777 LOG(ERROR) << "Unable to read this file:" << currentpath.value();
778 return;
779 }
[email protected]d52bb8a2010-05-10 21:05:35780 fetch_.reset(URLFetcher::Create(0,
781 GURL(url),
782 URLFetcher::POST,
783 this));
784 fetch_->set_upload_data("image/jpeg", filecontents);
[email protected]9d6b9aff2009-12-11 17:39:18785 // Set the filename on the server
786 std::string slug = "Slug: ";
787 slug += filename;
[email protected]d52bb8a2010-05-10 21:05:35788 fetch_->set_extra_request_headers(slug);
789 fetch_->set_request_context(profile_->GetRequestContext());
790 fetch_->Start();
[email protected]9d6b9aff2009-12-11 17:39:18791#endif
792}
793
794// This is just a prototype for allowing generic uploads to various sites
795// TODO(dhg): Remove this and implement general upload.
[email protected]88942a22010-08-19 20:34:43796void FilebrowseHandler::UploadToPicasaweb(const ListValue* args) {
[email protected]9d6b9aff2009-12-11 17:39:18797#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43798 std::string search_string = WideToUTF8(ExtractStringValue(args));
799 current_file_uploaded_ = search_string;
[email protected]9d6b9aff2009-12-11 17:39:18800 // ReadInFile();
[email protected]88942a22010-08-19 20:34:43801 FilePath current_path(search_string);
[email protected]a67fa08e2010-02-12 20:43:55802 TaskProxy* task = new TaskProxy(AsWeakPtr(), current_path);
[email protected]9d6b9aff2009-12-11 17:39:18803 task->AddRef();
[email protected]d52bb8a2010-05-10 21:05:35804 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:00805 BrowserThread::PostTask(
806 BrowserThread::FILE, FROM_HERE,
[email protected]9d6b9aff2009-12-11 17:39:18807 NewRunnableMethod(
808 task, &TaskProxy::ReadInFileProxy));
809#endif
810}
811
[email protected]a67fa08e2010-02-12 20:43:55812void FilebrowseHandler::GetChildrenForPath(FilePath& path, bool is_refresh) {
813 filelist_value_.reset(new ListValue());
[email protected]88942a22010-08-19 20:34:43814 currentpath_ = path;
[email protected]a67fa08e2010-02-12 20:43:55815
816 if (lister_.get()) {
817 lister_->Cancel();
818 lister_->set_delegate(NULL);
819 lister_ = NULL;
820 }
821
822 is_refresh_ = is_refresh;
[email protected]df53d2d2010-11-19 08:56:12823
824#if defined(OS_CHROMEOS)
825 // Don't allow listing files in inaccessible dirs.
826 if (URLRequestFileJob::AccessDisabled(path))
827 return;
828#endif // OS_CHROMEOS
829
[email protected]f872b3e2010-08-13 16:26:10830 FilePath default_download_path;
831 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
832 &default_download_path)) {
833 NOTREACHED();
834 }
835 if (currentpath_ == default_download_path) {
836 lister_ = new net::DirectoryLister(currentpath_,
[email protected]9ee2c8d2010-08-21 23:25:22837 false,
[email protected]f872b3e2010-08-13 16:26:10838 net::DirectoryLister::DATE,
839 this);
840 } else {
841 lister_ = new net::DirectoryLister(currentpath_, this);
842 }
[email protected]a67fa08e2010-02-12 20:43:55843 lister_->Start();
844}
845
[email protected]88942a22010-08-19 20:34:43846void FilebrowseHandler::HandleGetChildren(const ListValue* args) {
847#if defined(OS_CHROMEOS)
848 std::string path = WideToUTF8(ExtractStringValue(args));
849 FilePath currentpath(path);
[email protected]698601e2009-10-21 22:43:37850 filelist_value_.reset(new ListValue());
[email protected]698601e2009-10-21 22:43:37851
[email protected]a67fa08e2010-02-12 20:43:55852 GetChildrenForPath(currentpath, false);
[email protected]88942a22010-08-19 20:34:43853#endif
[email protected]698601e2009-10-21 22:43:37854}
855
[email protected]dcd23fe2009-11-12 20:21:18856void FilebrowseHandler::OnListFile(
[email protected]9ee2c8d2010-08-21 23:25:22857 const net::DirectoryLister::DirectoryListerData& data) {
[email protected]07046ab2010-01-20 21:42:44858#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22859 if (data.info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
[email protected]07046ab2010-01-20 21:42:44860 return;
861 }
862#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22863 if (data.info.filename[0] == '.') {
[email protected]07046ab2010-01-20 21:42:44864 return;
865 }
866#endif
867
[email protected]698601e2009-10-21 22:43:37868 DictionaryValue* file_value = new DictionaryValue();
869
870#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22871 int64 size = (static_cast<int64>(data.info.nFileSizeHigh) << 32) |
872 data.info.nFileSizeLow;
873 file_value->SetString(kPropertyTitle, data.info.cFileName);
[email protected]698601e2009-10-21 22:43:37874 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22875 currentpath_.Append(data.info.cFileName).value());
[email protected]698601e2009-10-21 22:43:37876 file_value->SetBoolean(kPropertyDirectory,
[email protected]9ee2c8d2010-08-21 23:25:22877 (data.info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
[email protected]698601e2009-10-21 22:43:37878#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22879 file_value->SetString(kPropertyTitle, data.info.filename);
[email protected]698601e2009-10-21 22:43:37880 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22881 currentpath_.Append(data.info.filename).value());
882 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode));
[email protected]698601e2009-10-21 22:43:37883#endif
884 filelist_value_->Append(file_value);
885}
886
[email protected]dcd23fe2009-11-12 20:21:18887void FilebrowseHandler::OnListDone(int error) {
[email protected]698601e2009-10-21 22:43:37888 DictionaryValue info_value;
[email protected]a67fa08e2010-02-12 20:43:55889 if (is_refresh_) {
[email protected]e4fbe8e2010-08-07 07:00:46890 info_value.SetString("functionCall", "refresh");
[email protected]a67fa08e2010-02-12 20:43:55891 } else {
[email protected]e4fbe8e2010-08-07 07:00:46892 info_value.SetString("functionCall", "getChildren");
[email protected]a67fa08e2010-02-12 20:43:55893 }
[email protected]698601e2009-10-21 22:43:37894 info_value.SetString(kPropertyPath, currentpath_.value());
[email protected]9d6b9aff2009-12-11 17:39:18895 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37896 info_value, *(filelist_value_.get()));
[email protected]a67fa08e2010-02-12 20:43:55897 SendCurrentDownloads();
[email protected]698601e2009-10-21 22:43:37898}
899
[email protected]88942a22010-08-19 20:34:43900void FilebrowseHandler::HandleGetMetadata(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37901}
902
[email protected]88942a22010-08-19 20:34:43903void FilebrowseHandler::HandleGetDownloads(const ListValue* args) {
[email protected]274e42b2010-01-29 22:03:57904 ModelChanged();
905}
906
907void FilebrowseHandler::ModelChanged() {
908 ClearDownloadItems();
[email protected]274e42b2010-01-29 22:03:57909
[email protected]0e2b59a2010-07-29 22:27:05910 std::vector<DownloadItem*> downloads;
911 download_manager_->GetAllDownloads(FilePath(), &downloads);
912
[email protected]377b4cc2010-05-18 17:25:19913 std::vector<DownloadItem*> new_downloads;
[email protected]274e42b2010-01-29 22:03:57914 // Scan for any in progress downloads and add ourself to them as an observer.
915 for (DownloadList::iterator it = downloads.begin();
916 it != downloads.end(); ++it) {
917 DownloadItem* download = *it;
918 // We want to know what happens as the download progresses and be notified
919 // when the user validates the dangerous download.
920 if (download->state() == DownloadItem::IN_PROGRESS ||
921 download->safety_state() == DownloadItem::DANGEROUS) {
922 download->AddObserver(this);
[email protected]377b4cc2010-05-18 17:25:19923 active_download_items_.push_back(download);
[email protected]274e42b2010-01-29 22:03:57924 }
[email protected]377b4cc2010-05-18 17:25:19925 DownloadList::iterator item = find(download_items_.begin(),
926 download_items_.end(),
927 download);
928 if (item == download_items_.end() && got_first_download_list_) {
929 SendNewDownload(download);
930 }
931 new_downloads.push_back(download);
[email protected]274e42b2010-01-29 22:03:57932 }
[email protected]377b4cc2010-05-18 17:25:19933 download_items_.swap(new_downloads);
934 got_first_download_list_ = true;
[email protected]274e42b2010-01-29 22:03:57935 SendCurrentDownloads();
936}
937
[email protected]377b4cc2010-05-18 17:25:19938void FilebrowseHandler::SendNewDownload(DownloadItem* download) {
939 ListValue results_value;
940 results_value.Append(download_util::CreateDownloadItemValue(download, -1));
941 dom_ui_->CallJavascriptFunction(L"newDownload", results_value);
942}
943
[email protected]a67fa08e2010-02-12 20:43:55944void FilebrowseHandler::DeleteFile(const FilePath& path) {
945 if (!file_util::Delete(path, true)) {
946 LOG(ERROR) << "unable to delete directory";
947 }
[email protected]2dc383ce2010-10-09 03:54:00948 BrowserThread::PostTask(
949 BrowserThread::UI, FROM_HERE,
[email protected]d52bb8a2010-05-10 21:05:35950 NewRunnableMethod(current_task_, &TaskProxy::FireDeleteCompleteProxy));
[email protected]a67fa08e2010-02-12 20:43:55951}
952
[email protected]d3d9b4fb2010-09-24 16:24:27953void FilebrowseHandler::CopyFile(const FilePath& src, const FilePath& dest) {
954 if (file_util::DirectoryExists(src)) {
955 if (!file_util::CopyDirectory(src, dest, true)) {
956 LOG(ERROR) << "unable to copy directory:" << src.value();
957 }
958 } else {
959 if (!file_util::CopyFile(src, dest)) {
960 LOG(ERROR) << "unable to copy file" << src.value();
961 }
962 }
[email protected]2dc383ce2010-10-09 03:54:00963 BrowserThread::PostTask(
964 BrowserThread::UI, FROM_HERE,
[email protected]d3d9b4fb2010-09-24 16:24:27965 NewRunnableMethod(current_task_, &TaskProxy::FireCopyCompleteProxy));
966}
967
[email protected]88942a22010-08-19 20:34:43968void FilebrowseHandler::HandleDeleteFile(const ListValue* args) {
969#if defined(OS_CHROMEOS)
970 std::string path = WideToUTF8(ExtractStringValue(args));
971 FilePath currentpath(path);
[email protected]df53d2d2010-11-19 08:56:12972
973 // Don't allow file deletion in inaccessible dirs.
974 if (URLRequestFileJob::AccessDisabled(currentpath))
975 return;
976
[email protected]88942a22010-08-19 20:34:43977 for (unsigned int x = 0; x < active_download_items_.size(); x++) {
978 FilePath item = active_download_items_[x]->full_path();
979 if (item == currentpath) {
980 active_download_items_[x]->Cancel(true);
981 active_download_items_[x]->Remove(true);
982 FilePath dir_path = item.DirName();
983 GetChildrenForPath(dir_path, true);
[email protected]a67fa08e2010-02-12 20:43:55984 return;
985 }
986 }
[email protected]88942a22010-08-19 20:34:43987 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath);
988 task->AddRef();
989 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:00990 BrowserThread::PostTask(
991 BrowserThread::FILE, FROM_HERE,
[email protected]88942a22010-08-19 20:34:43992 NewRunnableMethod(
993 task, &TaskProxy::DeleteFileProxy));
[email protected]a67fa08e2010-02-12 20:43:55994#endif
995}
996
[email protected]d3d9b4fb2010-09-24 16:24:27997void FilebrowseHandler::HandleCopyFile(const ListValue* value) {
998#if defined(OS_CHROMEOS)
999 if (value && value->GetType() == Value::TYPE_LIST) {
1000 const ListValue* list_value = static_cast<const ListValue*>(value);
1001 std::string src;
1002 std::string dest;
1003
1004 // Get path string.
1005 if (list_value->GetString(0, &src) &&
1006 list_value->GetString(1, &dest)) {
1007 FilePath SrcPath = FilePath(src);
1008 FilePath DestPath = FilePath(dest);
1009
[email protected]df53d2d2010-11-19 08:56:121010 // Don't allow file copy to inaccessible dirs.
1011 if (URLRequestFileJob::AccessDisabled(DestPath))
1012 return;
1013
[email protected]d3d9b4fb2010-09-24 16:24:271014 TaskProxy* task = new TaskProxy(AsWeakPtr(), SrcPath, DestPath);
1015 task->AddRef();
1016 current_task_ = task;
[email protected]2dc383ce2010-10-09 03:54:001017 BrowserThread::PostTask(
1018 BrowserThread::FILE, FROM_HERE,
[email protected]d3d9b4fb2010-09-24 16:24:271019 NewRunnableMethod(
1020 task, &TaskProxy::CopyFileProxy));
1021 } else {
1022 LOG(ERROR) << "Unable to get string";
1023 return;
1024 }
1025 }
1026#endif
1027}
1028
[email protected]23ebd2302010-11-04 16:23:201029void FilebrowseHandler::HandleValidateSavePath(const ListValue* args) {
1030 std::string string_path;
1031 if (!args || !args->GetString(0, &string_path)) {
1032 FireOnValidatedSavePathOnUIThread(false, FilePath()); // Invalid save path.
1033 return;
1034 }
1035
1036 FilePath save_path(string_path);
1037
1038#if defined(OS_CHROMEOS)
1039 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
1040 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1041 NewRunnableMethod(task.get(), &TaskProxy::ValidateSavePathOnFileThread));
1042#else
1043 // No save path checking for non-ChromeOS platforms.
1044 FireOnValidatedSavePathOnUIThread(true, save_path);
1045#endif
1046}
1047
1048void FilebrowseHandler::ValidateSavePathOnFileThread(
1049 const FilePath& save_path) {
1050#if defined(OS_CHROMEOS)
1051 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1052
1053 FilePath default_download_path;
1054 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
1055 &default_download_path)) {
1056 NOTREACHED();
1057 }
1058
1059 // Get containing folder of save_path.
1060 FilePath save_dir = save_path.DirName();
1061
1062 // Valid save path must be inside default download dir.
1063 bool valid = default_download_path == save_dir ||
1064 file_util::ContainsPath(default_download_path, save_dir);
1065
1066 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
1067 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
1068 NewRunnableMethod(task.get(),
1069 &TaskProxy::FireOnValidatedSavePathOnUIThread,
1070 valid, save_path));
1071#endif
1072}
1073
1074void FilebrowseHandler::FireOnValidatedSavePathOnUIThread(bool valid,
1075 const FilePath& save_path) {
1076 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1077
1078 FundamentalValue valid_value(valid);
1079 StringValue path_value(save_path.value());
1080 dom_ui_->CallJavascriptFunction(L"onValidatedSavePath",
1081 valid_value, path_value);
1082}
[email protected]d3d9b4fb2010-09-24 16:24:271083
[email protected]274e42b2010-01-29 22:03:571084void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
[email protected]377b4cc2010-05-18 17:25:191085 DownloadList::iterator it = find(active_download_items_.begin(),
1086 active_download_items_.end(),
[email protected]274e42b2010-01-29 22:03:571087 download);
[email protected]377b4cc2010-05-18 17:25:191088 if (it == active_download_items_.end())
[email protected]274e42b2010-01-29 22:03:571089 return;
[email protected]377b4cc2010-05-18 17:25:191090 const int id = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:571091
[email protected]499d97c2010-10-25 23:12:151092 scoped_ptr<DictionaryValue> download_item(
1093 download_util::CreateDownloadItemValue(download, id));
1094 dom_ui_->CallJavascriptFunction(L"downloadUpdated", *download_item.get());
[email protected]274e42b2010-01-29 22:03:571095}
1096
1097void FilebrowseHandler::ClearDownloadItems() {
[email protected]377b4cc2010-05-18 17:25:191098 for (DownloadList::iterator it = active_download_items_.begin();
1099 it != active_download_items_.end(); ++it) {
[email protected]274e42b2010-01-29 22:03:571100 (*it)->RemoveObserver(this);
1101 }
[email protected]377b4cc2010-05-18 17:25:191102 active_download_items_.clear();
[email protected]274e42b2010-01-29 22:03:571103}
1104
1105void FilebrowseHandler::SendCurrentDownloads() {
1106 ListValue results_value;
[email protected]377b4cc2010-05-18 17:25:191107 for (DownloadList::iterator it = active_download_items_.begin();
1108 it != active_download_items_.end(); ++it) {
1109 int index = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:571110 results_value.Append(download_util::CreateDownloadItemValue(*it, index));
1111 }
1112
1113 dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
1114}
1115
[email protected]698601e2009-10-21 22:43:371116////////////////////////////////////////////////////////////////////////////////
1117//
[email protected]f5bf8ccf2010-02-05 18:19:251118// FileBrowseUI
[email protected]698601e2009-10-21 22:43:371119//
1120////////////////////////////////////////////////////////////////////////////////
1121
[email protected]274e42b2010-01-29 22:03:571122FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) {
[email protected]9d6b9aff2009-12-11 17:39:181123 FilebrowseHandler* handler = new FilebrowseHandler();
1124 AddMessageHandler((handler)->Attach(this));
[email protected]274e42b2010-01-29 22:03:571125 handler->Init();
[email protected]698601e2009-10-21 22:43:371126 FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource();
1127
1128 // Set up the chrome://filebrowse/ source.
[email protected]2dc383ce2010-10-09 03:54:001129 BrowserThread::PostTask(
1130 BrowserThread::IO, FROM_HERE,
[email protected]fae20792009-10-28 20:31:581131 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:091132 Singleton<ChromeURLDataManager>::get(),
[email protected]698601e2009-10-21 22:43:371133 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:231134 make_scoped_refptr(html_source)));
[email protected]698601e2009-10-21 22:43:371135}
[email protected]f5bf8ccf2010-02-05 18:19:251136
1137// static
[email protected]1717246f2010-02-10 17:08:151138Browser* FileBrowseUI::OpenPopup(Profile* profile,
[email protected]467293292010-04-16 19:41:561139 const std::string& hashArgument,
1140 int width,
1141 int height) {
[email protected]1717246f2010-02-10 17:08:151142 // Get existing pop up for given hashArgument.
[email protected]f7e9fd62010-09-28 15:45:061143 Browser* browser = GetPopupForPath(hashArgument, profile);
[email protected]f5bf8ccf2010-02-05 18:19:251144
[email protected]1717246f2010-02-10 17:08:151145 // Create new browser if no matching pop up found.
1146 if (browser == NULL) {
[email protected]9ee17e8c2010-08-10 19:17:311147 browser = Browser::CreateForType(Browser::TYPE_APP_PANEL, profile);
[email protected]f59f1162010-04-23 21:19:291148 std::string url;
1149 if (hashArgument.empty()) {
1150 url = chrome::kChromeUIFileBrowseURL;
1151 } else {
1152 url = kFilebrowseURLHash;
1153 url.append(hashArgument);
1154 }
[email protected]f5bf8ccf2010-02-05 18:19:251155
[email protected]616381f02010-11-02 15:15:331156 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
1157 params.disposition = NEW_FOREGROUND_TAB;
1158 browser::Navigate(&params);
1159 // TODO(beng): The following two calls should be automatic by Navigate().
1160 params.browser->window()->SetBounds(gfx::Rect(kPopupLeft,
1161 kPopupTop,
1162 width,
1163 height));
[email protected]1717246f2010-02-10 17:08:151164
[email protected]616381f02010-11-02 15:15:331165 params.browser->window()->Show();
[email protected]9ee17e8c2010-08-10 19:17:311166 } else {
1167 browser->window()->Show();
[email protected]1717246f2010-02-10 17:08:151168 }
[email protected]f5bf8ccf2010-02-05 18:19:251169
1170 return browser;
1171}
[email protected]1717246f2010-02-10 17:08:151172
[email protected]f7e9fd62010-09-28 15:45:061173Browser* FileBrowseUI::GetPopupForPath(const std::string& path,
1174 Profile* profile) {
[email protected]9ee17e8c2010-08-10 19:17:311175 std::string current_path = path;
1176 if (current_path.empty()) {
[email protected]ba8164242010-11-16 21:31:001177 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
1178 switches::kEnableAdvancedFileSystem);
[email protected]9ee17e8c2010-08-10 19:17:311179 if (!is_enabled) {
1180 FilePath default_download_path;
1181 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
1182 &default_download_path)) {
1183 NOTREACHED();
1184 }
1185 current_path = default_download_path.value();
1186 }
1187 }
1188
[email protected]1717246f2010-02-10 17:08:151189 for (BrowserList::const_iterator it = BrowserList::begin();
1190 it != BrowserList::end(); ++it) {
[email protected]9ee17e8c2010-08-10 19:17:311191 if (((*it)->type() == Browser::TYPE_APP_PANEL)) {
[email protected]d519bed2010-05-28 18:42:031192 TabContents* tab_contents = (*it)->GetSelectedTabContents();
1193 DCHECK(tab_contents);
1194 if (!tab_contents)
1195 continue;
1196 const GURL& url = tab_contents->GetURL();
[email protected]1717246f2010-02-10 17:08:151197
1198 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1199 url.host() == chrome::kChromeUIFileBrowseHost &&
[email protected]f7e9fd62010-09-28 15:45:061200 url.ref() == current_path &&
1201 (*it)->profile() == profile) {
[email protected]1717246f2010-02-10 17:08:151202 return (*it);
1203 }
1204 }
1205 }
1206
1207 return NULL;
1208}
[email protected]467293292010-04-16 19:41:561209
1210const int FileBrowseUI::kPopupWidth = 250;
1211const int FileBrowseUI::kPopupHeight = 300;
1212const int FileBrowseUI::kSmallPopupWidth = 250;
1213const int FileBrowseUI::kSmallPopupHeight = 50;