blob: 6876d0d994e0a7db5cdffcf6f534d88736bfb05b [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
[email protected]265a1492011-02-27 05:58:075#include "chrome/browser/ui/webui/filebrowse_ui.h"
[email protected]698601e2009-10-21 22:43:376
[email protected]9fec6ff2011-02-10 23:47:107#include <algorithm>
8#include <vector>
9
[email protected]2041cf342010-02-19 03:15:5910#include "base/callback.h"
[email protected]ba8164242010-11-16 21:31:0011#include "base/command_line.h"
[email protected]23ebd2302010-11-04 16:23:2012#include "base/file_util.h"
[email protected]698601e2009-10-21 22:43:3713#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1514#include "base/memory/singleton.h"
15#include "base/memory/weak_ptr.h"
[email protected]698601e2009-10-21 22:43:3716#include "base/message_loop.h"
[email protected]07046ab2010-01-20 21:42:4417#include "base/path_service.h"
[email protected]698601e2009-10-21 22:43:3718#include "base/string_piece.h"
19#include "base/string_util.h"
[email protected]34b99632011-01-01 01:01:0620#include "base/threading/thread.h"
[email protected]698601e2009-10-21 22:43:3721#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2222#include "base/utf_string_conversions.h"
[email protected]698601e2009-10-21 22:43:3723#include "base/values.h"
[email protected]698601e2009-10-21 22:43:3724#include "chrome/browser/bookmarks/bookmark_model.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]c848d3d92010-09-16 21:57:4531#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]2ad4a902010-11-17 06:05:1332#include "chrome/browser/ui/browser.h"
33#include "chrome/browser/ui/browser_list.h"
[email protected]339d6dd2010-11-12 00:41:5834#include "chrome/browser/ui/browser_navigator.h"
[email protected]2ad4a902010-11-17 06:05:1335#include "chrome/browser/ui/browser_window.h"
[email protected]fd42ac30f2011-02-27 19:33:3636#include "chrome/browser/ui/webui/favicon_source.h"
[email protected]265a1492011-02-27 05:58:0737#include "chrome/browser/ui/webui/mediaplayer_ui.h"
[email protected]07046ab2010-01-20 21:42:4438#include "chrome/common/chrome_paths.h"
[email protected]ba8164242010-11-16 21:31:0039#include "chrome/common/chrome_switches.h"
[email protected]698601e2009-10-21 22:43:3740#include "chrome/common/jstemplate_builder.h"
[email protected]68d2a05f2010-05-07 21:39:5541#include "chrome/common/net/url_fetcher.h"
[email protected]698601e2009-10-21 22:43:3742#include "chrome/common/time_format.h"
43#include "chrome/common/url_constants.h"
[email protected]1625ffd2011-03-01 17:51:5044#include "content/browser/browser_thread.h"
45#include "content/browser/tab_contents/tab_contents.h"
[email protected]698601e2009-10-21 22:43:3746#include "grit/browser_resources.h"
47#include "grit/chromium_strings.h"
48#include "grit/generated_resources.h"
49#include "grit/locale_settings.h"
[email protected]c848d3d92010-09-16 21:57:4550#include "net/base/escape.h"
[email protected]df53d2d2010-11-19 08:56:1251#include "net/url_request/url_request_file_job.h"
[email protected]c051a1b2011-01-21 23:30:1752#include "ui/base/l10n/l10n_util.h"
[email protected]42ce29d2011-01-20 23:19:4653#include "ui/base/resource/resource_bundle.h"
[email protected]698601e2009-10-21 22:43:3754
[email protected]07046ab2010-01-20 21:42:4455#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:2456#include "chrome/browser/chromeos/cros/cros_library.h"
[email protected]268b02f2010-02-04 21:07:1557#include "chrome/browser/chromeos/cros/mount_library.h"
[email protected]d52bb8a2010-05-10 21:05:3558#include "chrome/browser/chromeos/login/user_manager.h"
[email protected]07046ab2010-01-20 21:42:4459#endif
60
[email protected]698601e2009-10-21 22:43:3761// Maximum number of search results to return in a given search. We should
62// eventually remove this.
63static const int kMaxSearchResults = 100;
[email protected]e4fbe8e2010-08-07 07:00:4664static const char kPropertyPath[] = "path";
65static const char kPropertyTitle[] = "title";
66static const char kPropertyDirectory[] = "isDirectory";
[email protected]e4fbe8e2010-08-07 07:00:4667static const char kMediaPath[] = "/media";
68static const char kFilebrowseURLHash[] = "chrome://filebrowse#";
[email protected]f5bf8ccf2010-02-05 18:19:2569static const int kPopupLeft = 0;
70static const int kPopupTop = 0;
[email protected]f5bf8ccf2010-02-05 18:19:2571
[email protected]698601e2009-10-21 22:43:3772class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource {
73 public:
74 FileBrowseUIHTMLSource();
75
76 // Called when the network layer has requested a resource underneath
77 // the path we registered.
[email protected]f09d93792009-11-17 00:10:3678 virtual void StartDataRequest(const std::string& path,
79 bool is_off_the_record,
80 int request_id);
[email protected]698601e2009-10-21 22:43:3781 virtual std::string GetMimeType(const std::string&) const {
82 return "text/html";
83 }
84
85 private:
[email protected]8de85a62009-11-06 08:32:1786 ~FileBrowseUIHTMLSource() {}
87
[email protected]698601e2009-10-21 22:43:3788 DISALLOW_COPY_AND_ASSIGN(FileBrowseUIHTMLSource);
89};
90
[email protected]9d6b9aff2009-12-11 17:39:1891class TaskProxy;
92
[email protected]698601e2009-10-21 22:43:3793// The handler for Javascript messages related to the "filebrowse" view.
[email protected]dcd23fe2009-11-12 20:21:1894class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
[email protected]36e12172011-02-08 23:46:0295 public WebUIMessageHandler,
[email protected]07046ab2010-01-20 21:42:4496#if defined(OS_CHROMEOS)
97 public chromeos::MountLibrary::Observer,
98#endif
[email protected]9d6b9aff2009-12-11 17:39:1899 public base::SupportsWeakPtr<FilebrowseHandler>,
[email protected]274e42b2010-01-29 22:03:57100 public DownloadManager::Observer,
101 public DownloadItem::Observer {
[email protected]698601e2009-10-21 22:43:37102 public:
[email protected]dcd23fe2009-11-12 20:21:18103 FilebrowseHandler();
104 virtual ~FilebrowseHandler();
[email protected]698601e2009-10-21 22:43:37105
[email protected]274e42b2010-01-29 22:03:57106 // Init work after Attach.
107 void Init();
108
[email protected]698601e2009-10-21 22:43:37109 // DirectoryLister::DirectoryListerDelegate methods:
[email protected]9ee2c8d2010-08-21 23:25:22110 virtual void OnListFile(
111 const net::DirectoryLister::DirectoryListerData& data);
[email protected]698601e2009-10-21 22:43:37112 virtual void OnListDone(int error);
113
[email protected]36e12172011-02-08 23:46:02114 // WebUIMessageHandler implementation.
[email protected]c9f5be0e2011-02-11 22:05:05115 virtual WebUIMessageHandler* Attach(WebUI* web_ui);
[email protected]698601e2009-10-21 22:43:37116 virtual void RegisterMessages();
117
[email protected]07046ab2010-01-20 21:42:44118#if defined(OS_CHROMEOS)
[email protected]0bcf47f2011-03-17 22:07:12119 // chromeos::MountLibrary::Observer interface
120 virtual void DiskChanged(chromeos::MountLibraryEventType event,
121 const chromeos::MountLibrary::Disk* disk);
122 virtual void DeviceChanged(chromeos::MountLibraryEventType event,
123 const std::string& device_path);
[email protected]07046ab2010-01-20 21:42:44124#endif
125
[email protected]274e42b2010-01-29 22:03:57126 // DownloadItem::Observer interface
127 virtual void OnDownloadUpdated(DownloadItem* download);
[email protected]ebdd2012011-01-19 11:06:57128 virtual void OnDownloadFileCompleted(DownloadItem* download);
[email protected]274e42b2010-01-29 22:03:57129 virtual void OnDownloadOpened(DownloadItem* download) { }
130
131 // DownloadManager::Observer interface
132 virtual void ModelChanged();
[email protected]82f37b02010-07-29 22:04:57133
[email protected]698601e2009-10-21 22:43:37134 // Callback for the "getRoots" message.
[email protected]88942a22010-08-19 20:34:43135 void HandleGetRoots(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37136
[email protected]9fec6ff2011-02-10 23:47:10137 void GetChildrenForPath(const FilePath& path, bool is_refresh);
[email protected]a67fa08e2010-02-12 20:43:55138
[email protected]698601e2009-10-21 22:43:37139 // Callback for the "getChildren" message.
[email protected]88942a22010-08-19 20:34:43140 void HandleGetChildren(const ListValue* args);
[email protected]9fec6ff2011-02-10 23:47:10141 // Callback for the "refreshDirectory" message.
[email protected]88942a22010-08-19 20:34:43142 void HandleRefreshDirectory(const ListValue* args);
143 void HandleIsAdvancedEnabled(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37144
145 // Callback for the "getMetadata" message.
[email protected]88942a22010-08-19 20:34:43146 void HandleGetMetadata(const ListValue* args);
[email protected]698601e2009-10-21 22:43:37147
[email protected]9fec6ff2011-02-10 23:47:10148 // Callback for the "openNewWindow" message.
[email protected]88942a22010-08-19 20:34:43149 void OpenNewFullWindow(const ListValue* args);
150 void OpenNewPopupWindow(const ListValue* args);
[email protected]dcd23fe2009-11-12 20:21:18151
[email protected]274e42b2010-01-29 22:03:57152 // Callback for the "getDownloads" message.
[email protected]88942a22010-08-19 20:34:43153 void HandleGetDownloads(const ListValue* args);
[email protected]274e42b2010-01-29 22:03:57154
[email protected]88942a22010-08-19 20:34:43155 void HandleCreateNewFolder(const ListValue* args);
[email protected]274e42b2010-01-29 22:03:57156
[email protected]88942a22010-08-19 20:34:43157 void PlayMediaFile(const ListValue* args);
158 void EnqueueMediaFile(const ListValue* args);
[email protected]17496bb2010-03-10 19:48:23159
[email protected]88942a22010-08-19 20:34:43160 void HandleDeleteFile(const ListValue* args);
[email protected]d3d9b4fb2010-09-24 16:24:27161 void HandleCopyFile(const ListValue* value);
[email protected]9fec6ff2011-02-10 23:47:10162 void CopyFile(const FilePath& src, const FilePath& dest, TaskProxy* task);
163 void DeleteFile(const FilePath& path, TaskProxy* task);
[email protected]a67fa08e2010-02-12 20:43:55164 void FireDeleteComplete(const FilePath& path);
[email protected]d3d9b4fb2010-09-24 16:24:27165 void FireCopyComplete(const FilePath& src, const FilePath& dest);
[email protected]a67fa08e2010-02-12 20:43:55166
[email protected]88942a22010-08-19 20:34:43167 void HandlePauseToggleDownload(const ListValue* args);
[email protected]a67fa08e2010-02-12 20:43:55168
[email protected]88942a22010-08-19 20:34:43169 void HandleCancelDownload(const ListValue* args);
170 void HandleAllowDownload(const ListValue* args);
[email protected]c4a530b2010-03-08 17:33:03171
[email protected]9fec6ff2011-02-10 23:47:10172 void CreateNewFolder(const FilePath& path) const;
173
[email protected]23ebd2302010-11-04 16:23:20174 // Callback for the "validateSavePath" message.
175 void HandleValidateSavePath(const ListValue* args);
176
177 // Validate a save path on file thread.
[email protected]9fec6ff2011-02-10 23:47:10178 void ValidateSavePathOnFileThread(const FilePath& save_path, TaskProxy* task);
[email protected]23ebd2302010-11-04 16:23:20179
180 // Fire save path validation result to JS onValidatedSavePath.
181 void FireOnValidatedSavePathOnUIThread(bool valid, const FilePath& save_path);
182
[email protected]698601e2009-10-21 22:43:37183 private:
[email protected]dcd23fe2009-11-12 20:21:18184
[email protected]ebdd2012011-01-19 11:06:57185 // Retrieves downloads from the DownloadManager and updates the page.
186 void UpdateDownloadList();
187
[email protected]88942a22010-08-19 20:34:43188 void OpenNewWindow(const ListValue* args, bool popup);
[email protected]dcd23fe2009-11-12 20:21:18189
[email protected]274e42b2010-01-29 22:03:57190 // Clear all download items and their observers.
191 void ClearDownloadItems();
192
193 // Send the current list of downloads to the page.
194 void SendCurrentDownloads();
195
[email protected]377b4cc2010-05-18 17:25:19196 void SendNewDownload(DownloadItem* download);
197
[email protected]9fec6ff2011-02-10 23:47:10198 bool ValidateSaveDir(const FilePath& save_dir, bool exists) const;
199 bool AccessDisabled(const FilePath& path) const;
200
[email protected]698601e2009-10-21 22:43:37201 scoped_ptr<ListValue> filelist_value_;
202 FilePath currentpath_;
[email protected]dcd23fe2009-11-12 20:21:18203 Profile* profile_;
[email protected]93a58bf72010-06-04 23:01:20204 TabContents* tab_contents_;
[email protected]9d6b9aff2009-12-11 17:39:18205 std::string current_file_contents_;
[email protected]d52bb8a2010-05-10 21:05:35206 TaskProxy* current_task_;
[email protected]698601e2009-10-21 22:43:37207 scoped_refptr<net::DirectoryLister> lister_;
[email protected]a67fa08e2010-02-12 20:43:55208 bool is_refresh_;
[email protected]698601e2009-10-21 22:43:37209
[email protected]274e42b2010-01-29 22:03:57210 DownloadManager* download_manager_;
211 typedef std::vector<DownloadItem*> DownloadList;
[email protected]377b4cc2010-05-18 17:25:19212 DownloadList active_download_items_;
[email protected]274e42b2010-01-29 22:03:57213 DownloadList download_items_;
[email protected]377b4cc2010-05-18 17:25:19214 bool got_first_download_list_;
[email protected]dcd23fe2009-11-12 20:21:18215 DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler);
[email protected]698601e2009-10-21 22:43:37216};
217
[email protected]9d6b9aff2009-12-11 17:39:18218class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
219 public:
[email protected]d3d9b4fb2010-09-24 16:24:27220 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
221 const FilePath& path, const FilePath& dest)
[email protected]a67fa08e2010-02-12 20:43:55222 : handler_(handler),
[email protected]d3d9b4fb2010-09-24 16:24:27223 src_(path),
224 dest_(dest) {}
225 TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
226 const FilePath& path)
227 : handler_(handler),
228 src_(path) {}
[email protected]9fec6ff2011-02-10 23:47:10229
230 // TaskProxy is created on the UI thread, so in some cases,
231 // we need to post back to the UI thread for destruction.
232 void DeleteOnUIThread() {
233 BrowserThread::PostTask(
234 BrowserThread::UI, FROM_HERE,
235 NewRunnableMethod(this, &TaskProxy::DoNothing));
[email protected]9d6b9aff2009-12-11 17:39:18236 }
[email protected]9fec6ff2011-02-10 23:47:10237
238 void DoNothing() {}
239
[email protected]a67fa08e2010-02-12 20:43:55240 void DeleteFileProxy() {
[email protected]9fec6ff2011-02-10 23:47:10241 if (handler_)
242 handler_->DeleteFile(src_, this);
[email protected]d3d9b4fb2010-09-24 16:24:27243 }
244
245 void CopyFileProxy() {
[email protected]9fec6ff2011-02-10 23:47:10246 if (handler_)
247 handler_->CopyFile(src_, dest_, this);
248 }
249
250 void CreateNewFolderProxy() {
251 if (handler_)
252 handler_->CreateNewFolder(src_);
253 DeleteOnUIThread();
[email protected]a67fa08e2010-02-12 20:43:55254 }
255
256 void FireDeleteCompleteProxy() {
[email protected]9fec6ff2011-02-10 23:47:10257 if (handler_)
[email protected]d3d9b4fb2010-09-24 16:24:27258 handler_->FireDeleteComplete(src_);
[email protected]d3d9b4fb2010-09-24 16:24:27259 }
260 void FireCopyCompleteProxy() {
[email protected]9fec6ff2011-02-10 23:47:10261 if (handler_)
[email protected]d3d9b4fb2010-09-24 16:24:27262 handler_->FireCopyComplete(src_, dest_);
[email protected]a67fa08e2010-02-12 20:43:55263 }
[email protected]23ebd2302010-11-04 16:23:20264
265 void ValidateSavePathOnFileThread() {
266 if (handler_)
[email protected]9fec6ff2011-02-10 23:47:10267 handler_->ValidateSavePathOnFileThread(src_, this);
[email protected]23ebd2302010-11-04 16:23:20268 }
[email protected]9fec6ff2011-02-10 23:47:10269
270 void FireOnValidatedSavePathOnUIThread(bool valid) {
[email protected]23ebd2302010-11-04 16:23:20271 if (handler_)
[email protected]9fec6ff2011-02-10 23:47:10272 handler_->FireOnValidatedSavePathOnUIThread(valid, src_);
[email protected]23ebd2302010-11-04 16:23:20273 }
274
[email protected]9d6b9aff2009-12-11 17:39:18275 private:
276 base::WeakPtr<FilebrowseHandler> handler_;
[email protected]d3d9b4fb2010-09-24 16:24:27277 FilePath src_;
278 FilePath dest_;
[email protected]9d6b9aff2009-12-11 17:39:18279 friend class base::RefCountedThreadSafe<TaskProxy>;
[email protected]068a71f2010-05-11 22:35:48280 DISALLOW_COPY_AND_ASSIGN(TaskProxy);
[email protected]9d6b9aff2009-12-11 17:39:18281};
282
283
[email protected]698601e2009-10-21 22:43:37284////////////////////////////////////////////////////////////////////////////////
285//
286// FileBrowseHTMLSource
287//
288////////////////////////////////////////////////////////////////////////////////
289
290FileBrowseUIHTMLSource::FileBrowseUIHTMLSource()
291 : DataSource(chrome::kChromeUIFileBrowseHost, MessageLoop::current()) {
292}
293
294void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path,
[email protected]e42ae9b2010-03-28 00:55:05295 bool is_off_the_record,
296 int request_id) {
[email protected]698601e2009-10-21 22:43:37297 DictionaryValue localized_strings;
[email protected]11f4857282009-11-13 19:56:17298 // TODO(dhg): Add stirings to localized strings, also add more strings
[email protected]dcd23fe2009-11-12 20:21:18299 // that are currently hardcoded.
[email protected]e4fbe8e2010-08-07 07:00:46300 localized_strings.SetString("title",
301 l10n_util::GetStringUTF16(IDS_FILEBROWSER_TITLE));
302 localized_strings.SetString("pause",
303 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PAUSE));
304 localized_strings.SetString("resume",
305 l10n_util::GetStringUTF16(IDS_FILEBROWSER_RESUME));
306 localized_strings.SetString("scanning",
307 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SCANNING));
308 localized_strings.SetString("confirmdelete",
309 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DELETE));
310 localized_strings.SetString("confirmyes",
311 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_YES));
312 localized_strings.SetString("confirmcancel",
313 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_CANCEL));
314 localized_strings.SetString("allowdownload",
315 l10n_util::GetStringUTF16(IDS_FILEBROWSER_CONFIRM_DOWNLOAD));
316 localized_strings.SetString("filenameprompt",
317 l10n_util::GetStringUTF16(IDS_FILEBROWSER_PROMPT_FILENAME));
318 localized_strings.SetString("save",
319 l10n_util::GetStringUTF16(IDS_FILEBROWSER_SAVE));
320 localized_strings.SetString("newfolder",
321 l10n_util::GetStringUTF16(IDS_FILEBROWSER_NEW_FOLDER));
322 localized_strings.SetString("open",
323 l10n_util::GetStringUTF16(IDS_FILEBROWSER_OPEN));
[email protected]e4fbe8e2010-08-07 07:00:46324 localized_strings.SetString("delete",
325 l10n_util::GetStringUTF16(IDS_FILEBROWSER_DELETE));
326 localized_strings.SetString("enqueue",
327 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ENQUEUE));
328 localized_strings.SetString("mediapath", kMediaPath);
[email protected]88f03da02010-06-10 16:21:13329 FilePath default_download_path;
330 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
331 &default_download_path)) {
332 NOTREACHED();
333 }
[email protected]e4fbe8e2010-08-07 07:00:46334 // TODO(viettrungluu): this is wrong -- FilePath's need not be Unicode.
335 localized_strings.SetString("downloadpath", default_download_path.value());
336 localized_strings.SetString("error_unknown_file_type",
337 l10n_util::GetStringUTF16(IDS_FILEBROWSER_ERROR_UNKNOWN_FILE_TYPE));
[email protected]698601e2009-10-21 22:43:37338 SetFontAndTextDirection(&localized_strings);
339
340 static const base::StringPiece filebrowse_html(
341 ResourceBundle::GetSharedInstance().GetRawDataResource(
342 IDR_FILEBROWSE_HTML));
343 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
344 filebrowse_html, &localized_strings);
345
346 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
347 html_bytes->data.resize(full_html.size());
348 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
349
350 SendResponse(request_id, html_bytes);
351}
352
353////////////////////////////////////////////////////////////////////////////////
354//
[email protected]dcd23fe2009-11-12 20:21:18355// FilebrowseHandler
[email protected]698601e2009-10-21 22:43:37356//
357////////////////////////////////////////////////////////////////////////////////
[email protected]dcd23fe2009-11-12 20:21:18358FilebrowseHandler::FilebrowseHandler()
[email protected]274e42b2010-01-29 22:03:57359 : profile_(NULL),
[email protected]93a58bf72010-06-04 23:01:20360 tab_contents_(NULL),
[email protected]a67fa08e2010-02-12 20:43:55361 is_refresh_(false),
[email protected]377b4cc2010-05-18 17:25:19362 download_manager_(NULL),
363 got_first_download_list_(false) {
[email protected]a67fa08e2010-02-12 20:43:55364 lister_ = NULL;
[email protected]07046ab2010-01-20 21:42:44365#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24366 chromeos::MountLibrary* lib =
367 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44368 lib->AddObserver(this);
369#endif
[email protected]698601e2009-10-21 22:43:37370}
371
[email protected]dcd23fe2009-11-12 20:21:18372FilebrowseHandler::~FilebrowseHandler() {
[email protected]07046ab2010-01-20 21:42:44373#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24374 chromeos::MountLibrary* lib =
375 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44376 lib->RemoveObserver(this);
377#endif
[email protected]698601e2009-10-21 22:43:37378 if (lister_.get()) {
379 lister_->Cancel();
380 lister_->set_delegate(NULL);
381 }
[email protected]274e42b2010-01-29 22:03:57382
383 ClearDownloadItems();
384 download_manager_->RemoveObserver(this);
[email protected]698601e2009-10-21 22:43:37385}
386
[email protected]c9f5be0e2011-02-11 22:05:05387WebUIMessageHandler* FilebrowseHandler::Attach(WebUI* web_ui) {
[email protected]698601e2009-10-21 22:43:37388 // Create our favicon data source.
[email protected]c9f5be0e2011-02-11 22:05:05389 profile_ = web_ui->GetProfile();
[email protected]248ce192011-02-10 15:26:34390 profile_->GetChromeURLDataManager()->AddDataSource(
[email protected]16835e62011-03-16 14:13:08391 new FaviconSource(profile_));
[email protected]c9f5be0e2011-02-11 22:05:05392 tab_contents_ = web_ui->tab_contents();
393 return WebUIMessageHandler::Attach(web_ui);
[email protected]698601e2009-10-21 22:43:37394}
395
[email protected]274e42b2010-01-29 22:03:57396void FilebrowseHandler::Init() {
[email protected]f7e9fd62010-09-28 15:45:06397 download_manager_ = profile_->GetDownloadManager();
[email protected]274e42b2010-01-29 22:03:57398 download_manager_->AddObserver(this);
[email protected]274e42b2010-01-29 22:03:57399}
400
[email protected]dcd23fe2009-11-12 20:21:18401void FilebrowseHandler::RegisterMessages() {
[email protected]7b748982011-02-14 19:28:23402 web_ui_->RegisterMessageCallback("getRoots",
[email protected]dcd23fe2009-11-12 20:21:18403 NewCallback(this, &FilebrowseHandler::HandleGetRoots));
[email protected]7b748982011-02-14 19:28:23404 web_ui_->RegisterMessageCallback("getChildren",
[email protected]dcd23fe2009-11-12 20:21:18405 NewCallback(this, &FilebrowseHandler::HandleGetChildren));
[email protected]7b748982011-02-14 19:28:23406 web_ui_->RegisterMessageCallback("getMetadata",
[email protected]dcd23fe2009-11-12 20:21:18407 NewCallback(this, &FilebrowseHandler::HandleGetMetadata));
[email protected]7b748982011-02-14 19:28:23408 web_ui_->RegisterMessageCallback("openNewPopupWindow",
[email protected]dcd23fe2009-11-12 20:21:18409 NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow));
[email protected]7b748982011-02-14 19:28:23410 web_ui_->RegisterMessageCallback("openNewFullWindow",
[email protected]dcd23fe2009-11-12 20:21:18411 NewCallback(this, &FilebrowseHandler::OpenNewFullWindow));
[email protected]7b748982011-02-14 19:28:23412 web_ui_->RegisterMessageCallback("getDownloads",
[email protected]274e42b2010-01-29 22:03:57413 NewCallback(this, &FilebrowseHandler::HandleGetDownloads));
[email protected]7b748982011-02-14 19:28:23414 web_ui_->RegisterMessageCallback("createNewFolder",
[email protected]274e42b2010-01-29 22:03:57415 NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder));
[email protected]7b748982011-02-14 19:28:23416 web_ui_->RegisterMessageCallback("playMediaFile",
[email protected]17496bb2010-03-10 19:48:23417 NewCallback(this, &FilebrowseHandler::PlayMediaFile));
[email protected]7b748982011-02-14 19:28:23418 web_ui_->RegisterMessageCallback("enqueueMediaFile",
[email protected]89a7e3812010-06-02 19:38:07419 NewCallback(this, &FilebrowseHandler::EnqueueMediaFile));
[email protected]7b748982011-02-14 19:28:23420 web_ui_->RegisterMessageCallback("pauseToggleDownload",
[email protected]a67fa08e2010-02-12 20:43:55421 NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
[email protected]7b748982011-02-14 19:28:23422 web_ui_->RegisterMessageCallback("deleteFile",
[email protected]a67fa08e2010-02-12 20:43:55423 NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
[email protected]7b748982011-02-14 19:28:23424 web_ui_->RegisterMessageCallback("copyFile",
[email protected]d3d9b4fb2010-09-24 16:24:27425 NewCallback(this, &FilebrowseHandler::HandleCopyFile));
[email protected]7b748982011-02-14 19:28:23426 web_ui_->RegisterMessageCallback("cancelDownload",
[email protected]c4a530b2010-03-08 17:33:03427 NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
[email protected]7b748982011-02-14 19:28:23428 web_ui_->RegisterMessageCallback("allowDownload",
[email protected]c4a530b2010-03-08 17:33:03429 NewCallback(this, &FilebrowseHandler::HandleAllowDownload));
[email protected]7b748982011-02-14 19:28:23430 web_ui_->RegisterMessageCallback("refreshDirectory",
[email protected]c4a530b2010-03-08 17:33:03431 NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
[email protected]7b748982011-02-14 19:28:23432 web_ui_->RegisterMessageCallback("isAdvancedEnabled",
[email protected]6ba198f2010-07-02 20:32:05433 NewCallback(this, &FilebrowseHandler::HandleIsAdvancedEnabled));
[email protected]7b748982011-02-14 19:28:23434 web_ui_->RegisterMessageCallback("validateSavePath",
[email protected]23ebd2302010-11-04 16:23:20435 NewCallback(this, &FilebrowseHandler::HandleValidateSavePath));
[email protected]9d6b9aff2009-12-11 17:39:18436}
437
[email protected]a67fa08e2010-02-12 20:43:55438
439void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
440 // We notify the UI by telling it to refresh its contents.
441 FilePath dir_path = path.DirName();
442 GetChildrenForPath(dir_path, true);
443};
444
[email protected]d3d9b4fb2010-09-24 16:24:27445void FilebrowseHandler::FireCopyComplete(const FilePath& src,
446 const FilePath& dest) {
447 // Notify the UI somehow.
448 FilePath dir_path = dest.DirName();
449 GetChildrenForPath(dir_path, true);
450};
451
[email protected]d52bb8a2010-05-10 21:05:35452#if defined(OS_CHROMEOS)
[email protected]0bcf47f2011-03-17 22:07:12453void FilebrowseHandler::DiskChanged(chromeos::MountLibraryEventType event,
454 const chromeos::MountLibrary::Disk* disk) {
455 if (event == chromeos::MOUNT_DISK_REMOVED ||
456 event == chromeos::MOUNT_DISK_CHANGED) {
[email protected]adcf8492011-03-09 22:41:39457 web_ui_->CallJavascriptFunction("rootsChanged");
[email protected]07046ab2010-01-20 21:42:44458 }
459}
[email protected]07046ab2010-01-20 21:42:44460
[email protected]0bcf47f2011-03-17 22:07:12461void FilebrowseHandler::DeviceChanged(chromeos::MountLibraryEventType event,
462 const std::string& device_path) {
[email protected]698601e2009-10-21 22:43:37463}
[email protected]0bcf47f2011-03-17 22:07:12464#endif
[email protected]698601e2009-10-21 22:43:37465
[email protected]88942a22010-08-19 20:34:43466void FilebrowseHandler::HandleGetRoots(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37467 ListValue results_value;
468 DictionaryValue info_value;
[email protected]698601e2009-10-21 22:43:37469 // TODO(dhg): add other entries, make this more general
[email protected]07046ab2010-01-20 21:42:44470#if defined(OS_CHROMEOS)
[email protected]0bcf47f2011-03-17 22:07:12471 chromeos::MountLibrary* lib = chromeos::CrosLibrary::Get()->GetMountLibrary();
472 for (chromeos::MountLibrary::DiskMap::const_iterator iter =
473 lib->disks().begin();
474 iter != lib->disks().end();
475 ++iter) {
476 const chromeos::MountLibrary::Disk* disk = iter->second;
477 if (!disk->mount_path().empty()) {
[email protected]07046ab2010-01-20 21:42:44478 DictionaryValue* page_value = new DictionaryValue();
[email protected]0bcf47f2011-03-17 22:07:12479 page_value->SetString(kPropertyPath, disk->mount_path());
480 FilePath currentpath(disk->mount_path());
[email protected]07046ab2010-01-20 21:42:44481 std::string filename;
482 filename = currentpath.BaseName().value();
483 page_value->SetString(kPropertyTitle, filename);
484 page_value->SetBoolean(kPropertyDirectory, true);
485 results_value.Append(page_value);
486 }
487 }
488#else
489 DictionaryValue* page_value = new DictionaryValue();
490 page_value->SetString(kPropertyPath, "/media");
491 page_value->SetString(kPropertyTitle, "Removeable");
[email protected]698601e2009-10-21 22:43:37492 page_value->SetBoolean(kPropertyDirectory, true);
[email protected]698601e2009-10-21 22:43:37493 results_value.Append(page_value);
[email protected]07046ab2010-01-20 21:42:44494#endif
495 FilePath default_download_path;
496 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
497 &default_download_path)) {
498 NOTREACHED();
499 }
500
501 DictionaryValue* download_value = new DictionaryValue();
502 download_value->SetString(kPropertyPath, default_download_path.value());
503 download_value->SetString(kPropertyTitle, "File Shelf");
504 download_value->SetBoolean(kPropertyDirectory, true);
505
506 results_value.Append(download_value);
[email protected]698601e2009-10-21 22:43:37507
[email protected]e4fbe8e2010-08-07 07:00:46508 info_value.SetString("functionCall", "getRoots");
[email protected]07046ab2010-01-20 21:42:44509 info_value.SetString(kPropertyPath, "");
[email protected]adcf8492011-03-09 22:41:39510 web_ui_->CallJavascriptFunction("browseFileResult",
[email protected]698601e2009-10-21 22:43:37511 info_value, results_value);
512}
513
[email protected]88942a22010-08-19 20:34:43514void FilebrowseHandler::HandleCreateNewFolder(const ListValue* args) {
[email protected]274e42b2010-01-29 22:03:57515#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39516 std::string path = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43517 FilePath currentpath(path);
[email protected]274e42b2010-01-29 22:03:57518
[email protected]9fec6ff2011-02-10 23:47:10519 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), currentpath);
520 BrowserThread::PostTask(
521 BrowserThread::FILE, FROM_HERE,
522 NewRunnableMethod(
523 task.get(), &TaskProxy::CreateNewFolderProxy));
[email protected]274e42b2010-01-29 22:03:57524#endif
525}
526
[email protected]9fec6ff2011-02-10 23:47:10527void FilebrowseHandler::CreateNewFolder(const FilePath& currentpath) const {
528 if (!ValidateSaveDir(currentpath, false) ||
529 !file_util::CreateDirectory(currentpath))
530 LOG(ERROR) << "Unable to create directory " << currentpath.value();
531}
532
[email protected]88942a22010-08-19 20:34:43533void FilebrowseHandler::PlayMediaFile(const ListValue* args) {
[email protected]17496bb2010-03-10 19:48:23534#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39535 std::string url = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43536 GURL gurl(url);
[email protected]17496bb2010-03-10 19:48:23537
[email protected]88942a22010-08-19 20:34:43538 Browser* browser = Browser::GetBrowserForController(
539 &tab_contents_->controller(), NULL);
[email protected]dc8caba2010-12-13 16:52:35540 MediaPlayer* mediaplayer = MediaPlayer::GetInstance();
[email protected]88942a22010-08-19 20:34:43541 mediaplayer->ForcePlayMediaURL(gurl, browser);
[email protected]89a7e3812010-06-02 19:38:07542#endif
543}
544
[email protected]88942a22010-08-19 20:34:43545void FilebrowseHandler::EnqueueMediaFile(const ListValue* args) {
[email protected]89a7e3812010-06-02 19:38:07546#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39547 std::string url = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43548 GURL gurl(url);
[email protected]89a7e3812010-06-02 19:38:07549
[email protected]88942a22010-08-19 20:34:43550 Browser* browser = Browser::GetBrowserForController(
551 &tab_contents_->controller(), NULL);
[email protected]dc8caba2010-12-13 16:52:35552 MediaPlayer* mediaplayer = MediaPlayer::GetInstance();
[email protected]88942a22010-08-19 20:34:43553 mediaplayer->EnqueueMediaURL(gurl, browser);
[email protected]17496bb2010-03-10 19:48:23554#endif
555}
556
[email protected]88942a22010-08-19 20:34:43557void FilebrowseHandler::HandleIsAdvancedEnabled(const ListValue* args) {
[email protected]6ba198f2010-07-02 20:32:05558#if defined(OS_CHROMEOS)
[email protected]ba8164242010-11-16 21:31:00559 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
560 switches::kEnableAdvancedFileSystem);
561 bool mp_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
562 switches::kEnableMediaPlayer);
[email protected]6ba198f2010-07-02 20:32:05563 DictionaryValue info_value;
[email protected]e4fbe8e2010-08-07 07:00:46564 info_value.SetBoolean("enabled", is_enabled);
565 info_value.SetBoolean("mpEnabled", mp_enabled);
[email protected]adcf8492011-03-09 22:41:39566 web_ui_->CallJavascriptFunction("enabledResult",
[email protected]6ba198f2010-07-02 20:32:05567 info_value);
[email protected]f872b3e2010-08-13 16:26:10568
[email protected]6ba198f2010-07-02 20:32:05569#endif
570}
[email protected]c4a530b2010-03-08 17:33:03571
[email protected]88942a22010-08-19 20:34:43572void FilebrowseHandler::HandleRefreshDirectory(const ListValue* args) {
[email protected]a67fa08e2010-02-12 20:43:55573#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39574 std::string path = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43575 FilePath currentpath(path);
576 GetChildrenForPath(currentpath, true);
[email protected]a67fa08e2010-02-12 20:43:55577#endif
578}
579
[email protected]88942a22010-08-19 20:34:43580void FilebrowseHandler::HandlePauseToggleDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03581#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43582 int id;
583 ExtractIntegerValue(args, &id);
[email protected]9fec6ff2011-02-10 23:47:10584 if ((id - 1) >= static_cast<int>(active_download_items_.size())) {
[email protected]d3d9b4fb2010-09-24 16:24:27585 return;
586 }
[email protected]88942a22010-08-19 20:34:43587 DownloadItem* item = active_download_items_[id];
588 item->TogglePause();
[email protected]c4a530b2010-03-08 17:33:03589#endif
590}
591
[email protected]88942a22010-08-19 20:34:43592void FilebrowseHandler::HandleAllowDownload(const ListValue* args) {
[email protected]c4a530b2010-03-08 17:33:03593#if defined(OS_CHROMEOS)
[email protected]88942a22010-08-19 20:34:43594 int id;
595 ExtractIntegerValue(args, &id);
[email protected]9fec6ff2011-02-10 23:47:10596 if ((id - 1) >= static_cast<int>(active_download_items_.size())) {
[email protected]d3d9b4fb2010-09-24 16:24:27597 return;
598 }
599
[email protected]88942a22010-08-19 20:34:43600 DownloadItem* item = active_download_items_[id];
601 download_manager_->DangerousDownloadValidated(item);
[email protected]c4a530b2010-03-08 17:33:03602#endif
603}
604
[email protected]88942a22010-08-19 20:34:43605void FilebrowseHandler::HandleCancelDownload(const ListValue* args) {
606#if defined(OS_CHROMEOS)
607 int id;
608 ExtractIntegerValue(args, &id);
[email protected]9fec6ff2011-02-10 23:47:10609 if ((id - 1) >= static_cast<int>(active_download_items_.size())) {
[email protected]d3d9b4fb2010-09-24 16:24:27610 return;
611 }
[email protected]88942a22010-08-19 20:34:43612 DownloadItem* item = active_download_items_[id];
[email protected]88942a22010-08-19 20:34:43613 FilePath path = item->full_path();
[email protected]d3d9b4fb2010-09-24 16:24:27614 item->Cancel(true);
[email protected]88942a22010-08-19 20:34:43615 FilePath dir_path = path.DirName();
616 item->Remove(true);
617 GetChildrenForPath(dir_path, true);
618#endif
[email protected]dcd23fe2009-11-12 20:21:18619}
[email protected]698601e2009-10-21 22:43:37620
[email protected]88942a22010-08-19 20:34:43621void FilebrowseHandler::OpenNewFullWindow(const ListValue* args) {
622 OpenNewWindow(args, false);
[email protected]dcd23fe2009-11-12 20:21:18623}
624
[email protected]88942a22010-08-19 20:34:43625void FilebrowseHandler::OpenNewPopupWindow(const ListValue* args) {
626 OpenNewWindow(args, true);
627}
[email protected]dcd23fe2009-11-12 20:21:18628
[email protected]88942a22010-08-19 20:34:43629void FilebrowseHandler::OpenNewWindow(const ListValue* args, bool popup) {
[email protected]adcf8492011-03-09 22:41:39630 std::string url = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43631 Browser* browser = popup ?
632 Browser::CreateForType(Browser::TYPE_APP_PANEL, profile_) :
633 BrowserList::GetLastActive();
[email protected]616381f02010-11-02 15:15:33634 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
635 params.disposition = NEW_FOREGROUND_TAB;
636 browser::Navigate(&params);
637 // TODO(beng): The following two calls should be automatic by Navigate().
[email protected]88942a22010-08-19 20:34:43638 if (popup) {
639 // TODO(dhg): Remove these from being hardcoded. Allow javascript
640 // to specify.
[email protected]616381f02010-11-02 15:15:33641 params.browser->window()->SetBounds(gfx::Rect(0, 0, 400, 300));
[email protected]dcd23fe2009-11-12 20:21:18642 }
[email protected]616381f02010-11-02 15:15:33643 params.browser->window()->Show();
[email protected]dcd23fe2009-11-12 20:21:18644}
645
[email protected]9d6b9aff2009-12-11 17:39:18646
[email protected]9fec6ff2011-02-10 23:47:10647void FilebrowseHandler::GetChildrenForPath(const FilePath& path,
648 bool is_refresh) {
[email protected]d73d5f662011-02-16 21:01:41649 if (path.empty())
650 return;
651
[email protected]a67fa08e2010-02-12 20:43:55652 filelist_value_.reset(new ListValue());
[email protected]88942a22010-08-19 20:34:43653 currentpath_ = path;
[email protected]a67fa08e2010-02-12 20:43:55654
655 if (lister_.get()) {
656 lister_->Cancel();
657 lister_->set_delegate(NULL);
658 lister_ = NULL;
659 }
660
661 is_refresh_ = is_refresh;
[email protected]df53d2d2010-11-19 08:56:12662
663#if defined(OS_CHROMEOS)
664 // Don't allow listing files in inaccessible dirs.
[email protected]9fec6ff2011-02-10 23:47:10665 if (AccessDisabled(path))
[email protected]df53d2d2010-11-19 08:56:12666 return;
[email protected]9fec6ff2011-02-10 23:47:10667#endif
[email protected]df53d2d2010-11-19 08:56:12668
[email protected]f872b3e2010-08-13 16:26:10669 FilePath default_download_path;
670 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
671 &default_download_path)) {
672 NOTREACHED();
673 }
[email protected]9fec6ff2011-02-10 23:47:10674
[email protected]f872b3e2010-08-13 16:26:10675 if (currentpath_ == default_download_path) {
676 lister_ = new net::DirectoryLister(currentpath_,
[email protected]9ee2c8d2010-08-21 23:25:22677 false,
[email protected]f872b3e2010-08-13 16:26:10678 net::DirectoryLister::DATE,
679 this);
680 } else {
681 lister_ = new net::DirectoryLister(currentpath_, this);
682 }
[email protected]a67fa08e2010-02-12 20:43:55683 lister_->Start();
684}
685
[email protected]88942a22010-08-19 20:34:43686void FilebrowseHandler::HandleGetChildren(const ListValue* args) {
687#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39688 std::string path = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43689 FilePath currentpath(path);
[email protected]698601e2009-10-21 22:43:37690 filelist_value_.reset(new ListValue());
[email protected]698601e2009-10-21 22:43:37691
[email protected]a67fa08e2010-02-12 20:43:55692 GetChildrenForPath(currentpath, false);
[email protected]88942a22010-08-19 20:34:43693#endif
[email protected]698601e2009-10-21 22:43:37694}
695
[email protected]dcd23fe2009-11-12 20:21:18696void FilebrowseHandler::OnListFile(
[email protected]9ee2c8d2010-08-21 23:25:22697 const net::DirectoryLister::DirectoryListerData& data) {
[email protected]07046ab2010-01-20 21:42:44698#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22699 if (data.info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
[email protected]07046ab2010-01-20 21:42:44700 return;
701 }
702#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22703 if (data.info.filename[0] == '.') {
[email protected]07046ab2010-01-20 21:42:44704 return;
705 }
[email protected]9fec6ff2011-02-10 23:47:10706
707 // Suppress .crdownload files.
708 static const char crdownload[] = (".crdownload");
709 static const size_t crdownload_size = arraysize(crdownload);
710 const std::string& filename = data.info.filename;
711 if ((filename.size() > crdownload_size) &&
712 (filename.rfind(crdownload) == (filename.size() - crdownload_size)))
713 return;
[email protected]07046ab2010-01-20 21:42:44714#endif
715
[email protected]698601e2009-10-21 22:43:37716 DictionaryValue* file_value = new DictionaryValue();
717
718#if defined(OS_WIN)
[email protected]9ee2c8d2010-08-21 23:25:22719 int64 size = (static_cast<int64>(data.info.nFileSizeHigh) << 32) |
720 data.info.nFileSizeLow;
721 file_value->SetString(kPropertyTitle, data.info.cFileName);
[email protected]698601e2009-10-21 22:43:37722 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22723 currentpath_.Append(data.info.cFileName).value());
[email protected]698601e2009-10-21 22:43:37724 file_value->SetBoolean(kPropertyDirectory,
[email protected]9ee2c8d2010-08-21 23:25:22725 (data.info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
[email protected]698601e2009-10-21 22:43:37726#elif defined(OS_POSIX)
[email protected]9ee2c8d2010-08-21 23:25:22727 file_value->SetString(kPropertyTitle, data.info.filename);
[email protected]698601e2009-10-21 22:43:37728 file_value->SetString(kPropertyPath,
[email protected]9ee2c8d2010-08-21 23:25:22729 currentpath_.Append(data.info.filename).value());
730 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode));
[email protected]698601e2009-10-21 22:43:37731#endif
732 filelist_value_->Append(file_value);
733}
734
[email protected]dcd23fe2009-11-12 20:21:18735void FilebrowseHandler::OnListDone(int error) {
[email protected]698601e2009-10-21 22:43:37736 DictionaryValue info_value;
[email protected]a67fa08e2010-02-12 20:43:55737 if (is_refresh_) {
[email protected]e4fbe8e2010-08-07 07:00:46738 info_value.SetString("functionCall", "refresh");
[email protected]a67fa08e2010-02-12 20:43:55739 } else {
[email protected]e4fbe8e2010-08-07 07:00:46740 info_value.SetString("functionCall", "getChildren");
[email protected]a67fa08e2010-02-12 20:43:55741 }
[email protected]698601e2009-10-21 22:43:37742 info_value.SetString(kPropertyPath, currentpath_.value());
[email protected]adcf8492011-03-09 22:41:39743 web_ui_->CallJavascriptFunction("browseFileResult",
[email protected]698601e2009-10-21 22:43:37744 info_value, *(filelist_value_.get()));
[email protected]698601e2009-10-21 22:43:37745}
746
[email protected]88942a22010-08-19 20:34:43747void FilebrowseHandler::HandleGetMetadata(const ListValue* args) {
[email protected]698601e2009-10-21 22:43:37748}
749
[email protected]88942a22010-08-19 20:34:43750void FilebrowseHandler::HandleGetDownloads(const ListValue* args) {
[email protected]ebdd2012011-01-19 11:06:57751 UpdateDownloadList();
[email protected]274e42b2010-01-29 22:03:57752}
753
754void FilebrowseHandler::ModelChanged() {
[email protected]ebdd2012011-01-19 11:06:57755 if (!currentpath_.empty())
756 GetChildrenForPath(currentpath_, true);
757 else
758 UpdateDownloadList();
759}
760
761void FilebrowseHandler::UpdateDownloadList() {
[email protected]274e42b2010-01-29 22:03:57762 ClearDownloadItems();
[email protected]274e42b2010-01-29 22:03:57763
[email protected]0e2b59a2010-07-29 22:27:05764 std::vector<DownloadItem*> downloads;
765 download_manager_->GetAllDownloads(FilePath(), &downloads);
766
[email protected]377b4cc2010-05-18 17:25:19767 std::vector<DownloadItem*> new_downloads;
[email protected]274e42b2010-01-29 22:03:57768 // Scan for any in progress downloads and add ourself to them as an observer.
769 for (DownloadList::iterator it = downloads.begin();
770 it != downloads.end(); ++it) {
771 DownloadItem* download = *it;
772 // We want to know what happens as the download progresses and be notified
773 // when the user validates the dangerous download.
774 if (download->state() == DownloadItem::IN_PROGRESS ||
775 download->safety_state() == DownloadItem::DANGEROUS) {
776 download->AddObserver(this);
[email protected]377b4cc2010-05-18 17:25:19777 active_download_items_.push_back(download);
[email protected]274e42b2010-01-29 22:03:57778 }
[email protected]377b4cc2010-05-18 17:25:19779 DownloadList::iterator item = find(download_items_.begin(),
780 download_items_.end(),
781 download);
782 if (item == download_items_.end() && got_first_download_list_) {
783 SendNewDownload(download);
784 }
785 new_downloads.push_back(download);
[email protected]274e42b2010-01-29 22:03:57786 }
[email protected]377b4cc2010-05-18 17:25:19787 download_items_.swap(new_downloads);
788 got_first_download_list_ = true;
[email protected]274e42b2010-01-29 22:03:57789 SendCurrentDownloads();
790}
791
[email protected]377b4cc2010-05-18 17:25:19792void FilebrowseHandler::SendNewDownload(DownloadItem* download) {
793 ListValue results_value;
794 results_value.Append(download_util::CreateDownloadItemValue(download, -1));
[email protected]adcf8492011-03-09 22:41:39795 web_ui_->CallJavascriptFunction("newDownload", results_value);
[email protected]377b4cc2010-05-18 17:25:19796}
797
[email protected]9fec6ff2011-02-10 23:47:10798void FilebrowseHandler::DeleteFile(const FilePath& path, TaskProxy* task) {
[email protected]a67fa08e2010-02-12 20:43:55799 if (!file_util::Delete(path, true)) {
800 LOG(ERROR) << "unable to delete directory";
801 }
[email protected]2dc383ce2010-10-09 03:54:00802 BrowserThread::PostTask(
803 BrowserThread::UI, FROM_HERE,
[email protected]9fec6ff2011-02-10 23:47:10804 NewRunnableMethod(task, &TaskProxy::FireDeleteCompleteProxy));
[email protected]a67fa08e2010-02-12 20:43:55805}
806
[email protected]9fec6ff2011-02-10 23:47:10807void FilebrowseHandler::CopyFile(const FilePath& src,
808 const FilePath& dest,
809 TaskProxy* task) {
[email protected]d3d9b4fb2010-09-24 16:24:27810 if (file_util::DirectoryExists(src)) {
811 if (!file_util::CopyDirectory(src, dest, true)) {
812 LOG(ERROR) << "unable to copy directory:" << src.value();
813 }
814 } else {
815 if (!file_util::CopyFile(src, dest)) {
816 LOG(ERROR) << "unable to copy file" << src.value();
817 }
818 }
[email protected]2dc383ce2010-10-09 03:54:00819 BrowserThread::PostTask(
820 BrowserThread::UI, FROM_HERE,
[email protected]9fec6ff2011-02-10 23:47:10821 NewRunnableMethod(task, &TaskProxy::FireCopyCompleteProxy));
[email protected]d3d9b4fb2010-09-24 16:24:27822}
823
[email protected]88942a22010-08-19 20:34:43824void FilebrowseHandler::HandleDeleteFile(const ListValue* args) {
825#if defined(OS_CHROMEOS)
[email protected]adcf8492011-03-09 22:41:39826 std::string path = UTF16ToUTF8(ExtractStringValue(args));
[email protected]88942a22010-08-19 20:34:43827 FilePath currentpath(path);
[email protected]df53d2d2010-11-19 08:56:12828
829 // Don't allow file deletion in inaccessible dirs.
[email protected]9fec6ff2011-02-10 23:47:10830 if (AccessDisabled(currentpath))
[email protected]df53d2d2010-11-19 08:56:12831 return;
832
[email protected]88942a22010-08-19 20:34:43833 for (unsigned int x = 0; x < active_download_items_.size(); x++) {
834 FilePath item = active_download_items_[x]->full_path();
835 if (item == currentpath) {
836 active_download_items_[x]->Cancel(true);
837 active_download_items_[x]->Remove(true);
838 FilePath dir_path = item.DirName();
839 GetChildrenForPath(dir_path, true);
[email protected]a67fa08e2010-02-12 20:43:55840 return;
841 }
842 }
[email protected]9fec6ff2011-02-10 23:47:10843 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), currentpath);
[email protected]2dc383ce2010-10-09 03:54:00844 BrowserThread::PostTask(
845 BrowserThread::FILE, FROM_HERE,
[email protected]88942a22010-08-19 20:34:43846 NewRunnableMethod(
[email protected]9fec6ff2011-02-10 23:47:10847 task.get(), &TaskProxy::DeleteFileProxy));
[email protected]a67fa08e2010-02-12 20:43:55848#endif
849}
850
[email protected]d3d9b4fb2010-09-24 16:24:27851void FilebrowseHandler::HandleCopyFile(const ListValue* value) {
852#if defined(OS_CHROMEOS)
853 if (value && value->GetType() == Value::TYPE_LIST) {
854 const ListValue* list_value = static_cast<const ListValue*>(value);
855 std::string src;
856 std::string dest;
857
858 // Get path string.
859 if (list_value->GetString(0, &src) &&
860 list_value->GetString(1, &dest)) {
861 FilePath SrcPath = FilePath(src);
862 FilePath DestPath = FilePath(dest);
863
[email protected]df53d2d2010-11-19 08:56:12864 // Don't allow file copy to inaccessible dirs.
[email protected]9fec6ff2011-02-10 23:47:10865 if (AccessDisabled(DestPath))
[email protected]df53d2d2010-11-19 08:56:12866 return;
867
[email protected]9fec6ff2011-02-10 23:47:10868 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(),
869 SrcPath, DestPath);
[email protected]2dc383ce2010-10-09 03:54:00870 BrowserThread::PostTask(
871 BrowserThread::FILE, FROM_HERE,
[email protected]d3d9b4fb2010-09-24 16:24:27872 NewRunnableMethod(
[email protected]9fec6ff2011-02-10 23:47:10873 task.get(), &TaskProxy::CopyFileProxy));
[email protected]d3d9b4fb2010-09-24 16:24:27874 } else {
875 LOG(ERROR) << "Unable to get string";
876 return;
877 }
878 }
879#endif
880}
881
[email protected]23ebd2302010-11-04 16:23:20882void FilebrowseHandler::HandleValidateSavePath(const ListValue* args) {
883 std::string string_path;
884 if (!args || !args->GetString(0, &string_path)) {
885 FireOnValidatedSavePathOnUIThread(false, FilePath()); // Invalid save path.
886 return;
887 }
888
889 FilePath save_path(string_path);
890
891#if defined(OS_CHROMEOS)
892 scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
893 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
894 NewRunnableMethod(task.get(), &TaskProxy::ValidateSavePathOnFileThread));
895#else
896 // No save path checking for non-ChromeOS platforms.
897 FireOnValidatedSavePathOnUIThread(true, save_path);
898#endif
899}
900
901void FilebrowseHandler::ValidateSavePathOnFileThread(
[email protected]9fec6ff2011-02-10 23:47:10902 const FilePath& save_path, TaskProxy* task) {
[email protected]23ebd2302010-11-04 16:23:20903#if defined(OS_CHROMEOS)
904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
905
[email protected]9fec6ff2011-02-10 23:47:10906 const bool valid = ValidateSaveDir(save_path.DirName(), true);
907
908 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
909 NewRunnableMethod(task,
910 &TaskProxy::FireOnValidatedSavePathOnUIThread,
911 valid));
912#endif
913}
914
915bool FilebrowseHandler::ValidateSaveDir(const FilePath& save_dir,
916 bool exists) const {
917#if defined(OS_CHROMEOS)
[email protected]23ebd2302010-11-04 16:23:20918 FilePath default_download_path;
919 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
920 &default_download_path)) {
921 NOTREACHED();
922 }
923
[email protected]9fec6ff2011-02-10 23:47:10924 // Valid save dir must be inside default download dir.
925 if (default_download_path == save_dir)
926 return true;
927 if (exists) {
928 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
929 return file_util::ContainsPath(default_download_path, save_dir);
930 } else {
931 return default_download_path.IsParent(save_dir);
932 }
[email protected]23ebd2302010-11-04 16:23:20933#endif
[email protected]9fec6ff2011-02-10 23:47:10934 return false;
[email protected]23ebd2302010-11-04 16:23:20935}
936
937void FilebrowseHandler::FireOnValidatedSavePathOnUIThread(bool valid,
938 const FilePath& save_path) {
939 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
940
941 FundamentalValue valid_value(valid);
942 StringValue path_value(save_path.value());
[email protected]adcf8492011-03-09 22:41:39943 web_ui_->CallJavascriptFunction("onValidatedSavePath",
[email protected]23ebd2302010-11-04 16:23:20944 valid_value, path_value);
945}
[email protected]d3d9b4fb2010-09-24 16:24:27946
[email protected]274e42b2010-01-29 22:03:57947void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
[email protected]377b4cc2010-05-18 17:25:19948 DownloadList::iterator it = find(active_download_items_.begin(),
949 active_download_items_.end(),
[email protected]274e42b2010-01-29 22:03:57950 download);
[email protected]377b4cc2010-05-18 17:25:19951 if (it == active_download_items_.end())
[email protected]274e42b2010-01-29 22:03:57952 return;
[email protected]377b4cc2010-05-18 17:25:19953 const int id = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:57954
[email protected]499d97c2010-10-25 23:12:15955 scoped_ptr<DictionaryValue> download_item(
956 download_util::CreateDownloadItemValue(download, id));
[email protected]adcf8492011-03-09 22:41:39957 web_ui_->CallJavascriptFunction("downloadUpdated", *download_item.get());
[email protected]274e42b2010-01-29 22:03:57958}
959
960void FilebrowseHandler::ClearDownloadItems() {
[email protected]377b4cc2010-05-18 17:25:19961 for (DownloadList::iterator it = active_download_items_.begin();
962 it != active_download_items_.end(); ++it) {
[email protected]274e42b2010-01-29 22:03:57963 (*it)->RemoveObserver(this);
964 }
[email protected]377b4cc2010-05-18 17:25:19965 active_download_items_.clear();
[email protected]274e42b2010-01-29 22:03:57966}
967
968void FilebrowseHandler::SendCurrentDownloads() {
969 ListValue results_value;
[email protected]377b4cc2010-05-18 17:25:19970 for (DownloadList::iterator it = active_download_items_.begin();
971 it != active_download_items_.end(); ++it) {
972 int index = static_cast<int>(it - active_download_items_.begin());
[email protected]274e42b2010-01-29 22:03:57973 results_value.Append(download_util::CreateDownloadItemValue(*it, index));
974 }
975
[email protected]adcf8492011-03-09 22:41:39976 web_ui_->CallJavascriptFunction("downloadsList", results_value);
[email protected]274e42b2010-01-29 22:03:57977}
978
[email protected]ebdd2012011-01-19 11:06:57979void FilebrowseHandler::OnDownloadFileCompleted(DownloadItem* download) {
980 GetChildrenForPath(currentpath_, true);
981}
982
[email protected]9fec6ff2011-02-10 23:47:10983bool FilebrowseHandler::AccessDisabled(const FilePath& path) const {
984 return !ValidateSaveDir(path, false) &&
985 net::URLRequestFileJob::AccessDisabled(path);
986}
987
[email protected]698601e2009-10-21 22:43:37988////////////////////////////////////////////////////////////////////////////////
989//
[email protected]f5bf8ccf2010-02-05 18:19:25990// FileBrowseUI
[email protected]698601e2009-10-21 22:43:37991//
992////////////////////////////////////////////////////////////////////////////////
993
[email protected]274e42b2010-01-29 22:03:57994FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) {
[email protected]9d6b9aff2009-12-11 17:39:18995 FilebrowseHandler* handler = new FilebrowseHandler();
996 AddMessageHandler((handler)->Attach(this));
[email protected]274e42b2010-01-29 22:03:57997 handler->Init();
[email protected]698601e2009-10-21 22:43:37998 FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource();
999
1000 // Set up the chrome://filebrowse/ source.
[email protected]248ce192011-02-10 15:26:341001 contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
[email protected]698601e2009-10-21 22:43:371002}
[email protected]f5bf8ccf2010-02-05 18:19:251003
1004// static
[email protected]1717246f2010-02-10 17:08:151005Browser* FileBrowseUI::OpenPopup(Profile* profile,
[email protected]467293292010-04-16 19:41:561006 const std::string& hashArgument,
1007 int width,
1008 int height) {
[email protected]1717246f2010-02-10 17:08:151009 // Get existing pop up for given hashArgument.
[email protected]f7e9fd62010-09-28 15:45:061010 Browser* browser = GetPopupForPath(hashArgument, profile);
[email protected]f5bf8ccf2010-02-05 18:19:251011
[email protected]1717246f2010-02-10 17:08:151012 // Create new browser if no matching pop up found.
1013 if (browser == NULL) {
[email protected]9ee17e8c2010-08-10 19:17:311014 browser = Browser::CreateForType(Browser::TYPE_APP_PANEL, profile);
[email protected]f59f1162010-04-23 21:19:291015 std::string url;
1016 if (hashArgument.empty()) {
1017 url = chrome::kChromeUIFileBrowseURL;
1018 } else {
1019 url = kFilebrowseURLHash;
1020 url.append(hashArgument);
1021 }
[email protected]f5bf8ccf2010-02-05 18:19:251022
[email protected]616381f02010-11-02 15:15:331023 browser::NavigateParams params(browser, GURL(url), PageTransition::LINK);
1024 params.disposition = NEW_FOREGROUND_TAB;
1025 browser::Navigate(&params);
1026 // TODO(beng): The following two calls should be automatic by Navigate().
1027 params.browser->window()->SetBounds(gfx::Rect(kPopupLeft,
1028 kPopupTop,
1029 width,
1030 height));
[email protected]1717246f2010-02-10 17:08:151031
[email protected]616381f02010-11-02 15:15:331032 params.browser->window()->Show();
[email protected]9ee17e8c2010-08-10 19:17:311033 } else {
1034 browser->window()->Show();
[email protected]1717246f2010-02-10 17:08:151035 }
[email protected]f5bf8ccf2010-02-05 18:19:251036
1037 return browser;
1038}
[email protected]1717246f2010-02-10 17:08:151039
[email protected]f7e9fd62010-09-28 15:45:061040Browser* FileBrowseUI::GetPopupForPath(const std::string& path,
1041 Profile* profile) {
[email protected]9ee17e8c2010-08-10 19:17:311042 std::string current_path = path;
1043 if (current_path.empty()) {
[email protected]ba8164242010-11-16 21:31:001044 bool is_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
1045 switches::kEnableAdvancedFileSystem);
[email protected]9ee17e8c2010-08-10 19:17:311046 if (!is_enabled) {
1047 FilePath default_download_path;
1048 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
1049 &default_download_path)) {
1050 NOTREACHED();
1051 }
1052 current_path = default_download_path.value();
1053 }
1054 }
1055
[email protected]1717246f2010-02-10 17:08:151056 for (BrowserList::const_iterator it = BrowserList::begin();
1057 it != BrowserList::end(); ++it) {
[email protected]9ee17e8c2010-08-10 19:17:311058 if (((*it)->type() == Browser::TYPE_APP_PANEL)) {
[email protected]d519bed2010-05-28 18:42:031059 TabContents* tab_contents = (*it)->GetSelectedTabContents();
1060 DCHECK(tab_contents);
1061 if (!tab_contents)
1062 continue;
1063 const GURL& url = tab_contents->GetURL();
[email protected]1717246f2010-02-10 17:08:151064
1065 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1066 url.host() == chrome::kChromeUIFileBrowseHost &&
[email protected]f7e9fd62010-09-28 15:45:061067 url.ref() == current_path &&
1068 (*it)->profile() == profile) {
[email protected]1717246f2010-02-10 17:08:151069 return (*it);
1070 }
1071 }
1072 }
1073
1074 return NULL;
1075}
[email protected]467293292010-04-16 19:41:561076
1077const int FileBrowseUI::kPopupWidth = 250;
1078const int FileBrowseUI::kPopupHeight = 300;
1079const int FileBrowseUI::kSmallPopupWidth = 250;
1080const int FileBrowseUI::kSmallPopupHeight = 50;