blob: 36f588f4fd1a1bf0145c3ee933b6da1347c44a8d [file] [log] [blame]
[email protected]698601e2009-10-21 22:43:371// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/dom_ui/filebrowse_ui.h"
6
7#include "app/l10n_util.h"
8#include "app/resource_bundle.h"
[email protected]2041cf342010-02-19 03:15:599#include "base/callback.h"
[email protected]698601e2009-10-21 22:43:3710#include "base/logging.h"
11#include "base/message_loop.h"
[email protected]07046ab2010-01-20 21:42:4412#include "base/path_service.h"
[email protected]5c4c7402009-10-30 19:58:0613#include "base/singleton.h"
[email protected]698601e2009-10-21 22:43:3714#include "base/string_piece.h"
15#include "base/string_util.h"
16#include "base/thread.h"
17#include "base/time.h"
18#include "base/values.h"
[email protected]9d6b9aff2009-12-11 17:39:1819#include "base/weak_ptr.h"
[email protected]698601e2009-10-21 22:43:3720#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]dcd23fe2009-11-12 20:21:1821#include "chrome/browser/browser.h"
[email protected]1717246f2010-02-10 17:08:1522#include "chrome/browser/browser_list.h"
[email protected]dcd23fe2009-11-12 20:21:1823#include "chrome/browser/browser_window.h"
[email protected]fae20792009-10-28 20:31:5824#include "chrome/browser/chrome_thread.h"
[email protected]698601e2009-10-21 22:43:3725#include "chrome/browser/dom_ui/dom_ui_favicon_source.h"
[email protected]274e42b2010-01-29 22:03:5726#include "chrome/browser/download/download_manager.h"
27#include "chrome/browser/download/download_util.h"
[email protected]1717246f2010-02-10 17:08:1528#include "chrome/browser/history/history_types.h"
[email protected]698601e2009-10-21 22:43:3729#include "chrome/browser/metrics/user_metrics.h"
[email protected]9d6b9aff2009-12-11 17:39:1830#include "chrome/browser/net/url_fetcher.h"
[email protected]698601e2009-10-21 22:43:3731#include "chrome/browser/profile.h"
[email protected]1717246f2010-02-10 17:08:1532#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]07046ab2010-01-20 21:42:4433#include "chrome/common/chrome_paths.h"
[email protected]698601e2009-10-21 22:43:3734#include "chrome/common/jstemplate_builder.h"
35#include "chrome/common/time_format.h"
36#include "chrome/common/url_constants.h"
[email protected]17496bb2010-03-10 19:48:2337#include "chrome/browser/dom_ui/mediaplayer_ui.h"
[email protected]698601e2009-10-21 22:43:3738#include "net/base/escape.h"
39
40#include "grit/browser_resources.h"
41#include "grit/chromium_strings.h"
42#include "grit/generated_resources.h"
43#include "grit/locale_settings.h"
44
[email protected]07046ab2010-01-20 21:42:4445#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:2446#include "chrome/browser/chromeos/cros/cros_library.h"
[email protected]268b02f2010-02-04 21:07:1547#include "chrome/browser/chromeos/cros/mount_library.h"
[email protected]07046ab2010-01-20 21:42:4448#endif
49
[email protected]698601e2009-10-21 22:43:3750// Maximum number of search results to return in a given search. We should
51// eventually remove this.
52static const int kMaxSearchResults = 100;
53static const std::wstring kPropertyPath = L"path";
54static const std::wstring kPropertyTitle = L"title";
55static const std::wstring kPropertyDirectory = L"isDirectory";
[email protected]9d6b9aff2009-12-11 17:39:1856static const std::string kPicasawebUserPrefix =
57 "http://picasaweb.google.com/data/feed/api/user/";
58static const std::string kPicasawebDefault = "/albumid/default";
59static const std::string kPicasawebDropBox = "/DropBox";
60static const std::string kPicasawebBaseUrl = "http://picasaweb.google.com/";
[email protected]698601e2009-10-21 22:43:3761
[email protected]f5bf8ccf2010-02-05 18:19:2562static const char* kFilebrowseURLHash = "chrome://filebrowse#";
63static const int kPopupLeft = 0;
64static const int kPopupTop = 0;
[email protected]f5bf8ccf2010-02-05 18:19:2565
[email protected]698601e2009-10-21 22:43:3766class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource {
67 public:
68 FileBrowseUIHTMLSource();
69
70 // Called when the network layer has requested a resource underneath
71 // the path we registered.
[email protected]f09d93792009-11-17 00:10:3672 virtual void StartDataRequest(const std::string& path,
73 bool is_off_the_record,
74 int request_id);
[email protected]698601e2009-10-21 22:43:3775 virtual std::string GetMimeType(const std::string&) const {
76 return "text/html";
77 }
78
79 private:
[email protected]8de85a62009-11-06 08:32:1780 ~FileBrowseUIHTMLSource() {}
81
[email protected]698601e2009-10-21 22:43:3782 DISALLOW_COPY_AND_ASSIGN(FileBrowseUIHTMLSource);
83};
84
[email protected]9d6b9aff2009-12-11 17:39:1885class TaskProxy;
86
[email protected]698601e2009-10-21 22:43:3787// The handler for Javascript messages related to the "filebrowse" view.
[email protected]dcd23fe2009-11-12 20:21:1888class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
[email protected]9d6b9aff2009-12-11 17:39:1889 public DOMMessageHandler,
[email protected]07046ab2010-01-20 21:42:4490#if defined(OS_CHROMEOS)
91 public chromeos::MountLibrary::Observer,
92#endif
[email protected]9d6b9aff2009-12-11 17:39:1893 public base::SupportsWeakPtr<FilebrowseHandler>,
[email protected]274e42b2010-01-29 22:03:5794 public URLFetcher::Delegate,
95 public DownloadManager::Observer,
96 public DownloadItem::Observer {
[email protected]698601e2009-10-21 22:43:3797 public:
[email protected]dcd23fe2009-11-12 20:21:1898 FilebrowseHandler();
99 virtual ~FilebrowseHandler();
[email protected]698601e2009-10-21 22:43:37100
[email protected]274e42b2010-01-29 22:03:57101 // Init work after Attach.
102 void Init();
103
[email protected]698601e2009-10-21 22:43:37104 // DirectoryLister::DirectoryListerDelegate methods:
105 virtual void OnListFile(const file_util::FileEnumerator::FindInfo& data);
106 virtual void OnListDone(int error);
107
108 // DOMMessageHandler implementation.
109 virtual DOMMessageHandler* Attach(DOMUI* dom_ui);
110 virtual void RegisterMessages();
111
[email protected]07046ab2010-01-20 21:42:44112#if defined(OS_CHROMEOS)
113 void MountChanged(chromeos::MountLibrary* obj,
114 chromeos::MountEventType evt,
115 const std::string& path);
116#endif
117
[email protected]274e42b2010-01-29 22:03:57118 // DownloadItem::Observer interface
119 virtual void OnDownloadUpdated(DownloadItem* download);
120 virtual void OnDownloadFileCompleted(DownloadItem* download) { }
121 virtual void OnDownloadOpened(DownloadItem* download) { }
122
123 // DownloadManager::Observer interface
124 virtual void ModelChanged();
125 virtual void SetDownloads(std::vector<DownloadItem*>& downloads);
126
[email protected]698601e2009-10-21 22:43:37127 // Callback for the "getRoots" message.
128 void HandleGetRoots(const Value* value);
129
[email protected]a67fa08e2010-02-12 20:43:55130 void GetChildrenForPath(FilePath& path, bool is_refresh);
131
[email protected]9d6b9aff2009-12-11 17:39:18132 void OnURLFetchComplete(const URLFetcher* source,
133 const GURL& url,
134 const URLRequestStatus& status,
135 int response_code,
136 const ResponseCookies& cookies,
137 const std::string& data);
138
[email protected]698601e2009-10-21 22:43:37139 // Callback for the "getChildren" message.
140 void HandleGetChildren(const Value* value);
[email protected]c4a530b2010-03-08 17:33:03141 // Callback for the "refreshDirectory" message.
142 void HandleRefreshDirectory(const Value* value);
[email protected]698601e2009-10-21 22:43:37143
144 // Callback for the "getMetadata" message.
145 void HandleGetMetadata(const Value* value);
146
[email protected]9d6b9aff2009-12-11 17:39:18147 // Callback for the "openNewWindow" message.
[email protected]dcd23fe2009-11-12 20:21:18148 void OpenNewFullWindow(const Value* value);
149 void OpenNewPopupWindow(const Value* value);
150
[email protected]9d6b9aff2009-12-11 17:39:18151 // Callback for the "uploadToPicasaweb" message.
152 void UploadToPicasaweb(const Value* value);
153
[email protected]274e42b2010-01-29 22:03:57154 // Callback for the "getDownloads" message.
155 void HandleGetDownloads(const Value* value);
156
157 void HandleCreateNewFolder(const Value* value);
158
[email protected]17496bb2010-03-10 19:48:23159 void PlayMediaFile(const Value* value);
160
[email protected]a67fa08e2010-02-12 20:43:55161 void HandleDeleteFile(const Value* value);
162 void DeleteFile(const FilePath& path);
163 void FireDeleteComplete(const FilePath& path);
164
165 void HandlePauseToggleDownload(const Value* value);
166
[email protected]c4a530b2010-03-08 17:33:03167 void HandleCancelDownload(const Value* value);
168 void HandleAllowDownload(const Value* value);
169
[email protected]9d6b9aff2009-12-11 17:39:18170 void ReadInFile();
171 void FireUploadComplete();
172
[email protected]698601e2009-10-21 22:43:37173 private:
[email protected]dcd23fe2009-11-12 20:21:18174
175 void OpenNewWindow(const Value* value, bool popup);
176
[email protected]274e42b2010-01-29 22:03:57177 // Clear all download items and their observers.
178 void ClearDownloadItems();
179
180 // Send the current list of downloads to the page.
181 void SendCurrentDownloads();
182
[email protected]698601e2009-10-21 22:43:37183 scoped_ptr<ListValue> filelist_value_;
184 FilePath currentpath_;
[email protected]dcd23fe2009-11-12 20:21:18185 Profile* profile_;
[email protected]9d6b9aff2009-12-11 17:39:18186 std::string current_file_contents_;
187 std::string current_file_uploaded_;
188 int upload_response_code_;
189 TaskProxy* CurrentTask_;
[email protected]698601e2009-10-21 22:43:37190 scoped_refptr<net::DirectoryLister> lister_;
[email protected]a67fa08e2010-02-12 20:43:55191 bool is_refresh_;
[email protected]698601e2009-10-21 22:43:37192
[email protected]274e42b2010-01-29 22:03:57193 DownloadManager* download_manager_;
194 typedef std::vector<DownloadItem*> DownloadList;
195 DownloadList download_items_;
196
[email protected]dcd23fe2009-11-12 20:21:18197 DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler);
[email protected]698601e2009-10-21 22:43:37198};
199
[email protected]9d6b9aff2009-12-11 17:39:18200class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
201 public:
[email protected]a67fa08e2010-02-12 20:43:55202 explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler, FilePath& path)
203 : handler_(handler),
204 path_(path) {}
[email protected]9d6b9aff2009-12-11 17:39:18205 void ReadInFileProxy() {
206 if (handler_) {
207 handler_->ReadInFile();
208 }
209 }
210
211 void FireUploadCompleteProxy() {
212 if (handler_) {
213 handler_->FireUploadComplete();
214 }
215 }
[email protected]a67fa08e2010-02-12 20:43:55216
217 void DeleteFileProxy() {
218 if (handler_) {
219 handler_->DeleteFile(path_);
220 }
221 }
222
223 void FireDeleteCompleteProxy() {
224 if (handler_) {
225 handler_->FireDeleteComplete(path_);
226 }
227 }
[email protected]9d6b9aff2009-12-11 17:39:18228 private:
229 base::WeakPtr<FilebrowseHandler> handler_;
[email protected]a67fa08e2010-02-12 20:43:55230 FilePath path_;
[email protected]9d6b9aff2009-12-11 17:39:18231 friend class base::RefCountedThreadSafe<TaskProxy>;
232};
233
234
[email protected]698601e2009-10-21 22:43:37235////////////////////////////////////////////////////////////////////////////////
236//
237// FileBrowseHTMLSource
238//
239////////////////////////////////////////////////////////////////////////////////
240
241FileBrowseUIHTMLSource::FileBrowseUIHTMLSource()
242 : DataSource(chrome::kChromeUIFileBrowseHost, MessageLoop::current()) {
243}
244
245void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path,
[email protected]e42ae9b2010-03-28 00:55:05246 bool is_off_the_record,
247 int request_id) {
[email protected]698601e2009-10-21 22:43:37248 DictionaryValue localized_strings;
[email protected]11f4857282009-11-13 19:56:17249 // TODO(dhg): Add stirings to localized strings, also add more strings
[email protected]dcd23fe2009-11-12 20:21:18250 // that are currently hardcoded.
[email protected]f95f0752010-03-09 16:47:10251 localized_strings.SetString(L"title",
252 l10n_util::GetString(IDS_FILEBROWSER_TITLE));
253 localized_strings.SetString(L"pause",
254 l10n_util::GetString(IDS_FILEBROWSER_PAUSE));
255 localized_strings.SetString(L"resume",
256 l10n_util::GetString(IDS_FILEBROWSER_RESUME));
257 localized_strings.SetString(L"scanning",
258 l10n_util::GetString(IDS_FILEBROWSER_SCANNING));
259 localized_strings.SetString(L"confirmdelete",
260 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_DELETE));
261 localized_strings.SetString(L"confirmyes",
262 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_YES));
263 localized_strings.SetString(L"confirmcancel",
264 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_CANCEL));
265 localized_strings.SetString(L"allowdownload",
266 l10n_util::GetString(IDS_FILEBROWSER_CONFIRM_DOWNLOAD));
267 localized_strings.SetString(L"filenameprompt",
268 l10n_util::GetString(IDS_FILEBROWSER_PROMPT_FILENAME));
269 localized_strings.SetString(L"save",
270 l10n_util::GetString(IDS_FILEBROWSER_SAVE));
271 localized_strings.SetString(L"newfolder",
272 l10n_util::GetString(IDS_FILEBROWSER_NEW_FOLDER));
273 localized_strings.SetString(L"open",
274 l10n_util::GetString(IDS_FILEBROWSER_OPEN));
275 localized_strings.SetString(L"picasaweb",
276 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_PICASAWEB));
[email protected]a25802d2010-04-21 16:18:20277 localized_strings.SetString(L"flickr",
278 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_FLICKR));
[email protected]f95f0752010-03-09 16:47:10279 localized_strings.SetString(L"email",
280 l10n_util::GetString(IDS_FILEBROWSER_UPLOAD_EMAIL));
281 localized_strings.SetString(L"delete",
282 l10n_util::GetString(IDS_FILEBROWSER_DELETE));
[email protected]698601e2009-10-21 22:43:37283
284 SetFontAndTextDirection(&localized_strings);
285
286 static const base::StringPiece filebrowse_html(
287 ResourceBundle::GetSharedInstance().GetRawDataResource(
288 IDR_FILEBROWSE_HTML));
289 const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
290 filebrowse_html, &localized_strings);
291
292 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
293 html_bytes->data.resize(full_html.size());
294 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
295
296 SendResponse(request_id, html_bytes);
297}
298
299////////////////////////////////////////////////////////////////////////////////
300//
[email protected]dcd23fe2009-11-12 20:21:18301// FilebrowseHandler
[email protected]698601e2009-10-21 22:43:37302//
303////////////////////////////////////////////////////////////////////////////////
[email protected]dcd23fe2009-11-12 20:21:18304FilebrowseHandler::FilebrowseHandler()
[email protected]274e42b2010-01-29 22:03:57305 : profile_(NULL),
[email protected]a67fa08e2010-02-12 20:43:55306 is_refresh_(false),
[email protected]274e42b2010-01-29 22:03:57307 download_manager_(NULL) {
[email protected]a67fa08e2010-02-12 20:43:55308 lister_ = NULL;
[email protected]07046ab2010-01-20 21:42:44309#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24310 chromeos::MountLibrary* lib =
311 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44312 lib->AddObserver(this);
313#endif
[email protected]698601e2009-10-21 22:43:37314}
315
[email protected]dcd23fe2009-11-12 20:21:18316FilebrowseHandler::~FilebrowseHandler() {
[email protected]07046ab2010-01-20 21:42:44317#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24318 chromeos::MountLibrary* lib =
319 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44320 lib->RemoveObserver(this);
321#endif
[email protected]698601e2009-10-21 22:43:37322 if (lister_.get()) {
323 lister_->Cancel();
324 lister_->set_delegate(NULL);
325 }
[email protected]274e42b2010-01-29 22:03:57326
327 ClearDownloadItems();
328 download_manager_->RemoveObserver(this);
[email protected]698601e2009-10-21 22:43:37329}
330
[email protected]dcd23fe2009-11-12 20:21:18331DOMMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) {
[email protected]698601e2009-10-21 22:43:37332 // Create our favicon data source.
[email protected]fae20792009-10-28 20:31:58333 ChromeThread::PostTask(
334 ChromeThread::IO, FROM_HERE,
335 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:09336 Singleton<ChromeURLDataManager>::get(),
[email protected]fae20792009-10-28 20:31:58337 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:23338 make_scoped_refptr(new DOMUIFavIconSource(dom_ui->GetProfile()))));
[email protected]dcd23fe2009-11-12 20:21:18339 profile_ = dom_ui->GetProfile();
[email protected]274e42b2010-01-29 22:03:57340
[email protected]698601e2009-10-21 22:43:37341 return DOMMessageHandler::Attach(dom_ui);
342}
343
[email protected]274e42b2010-01-29 22:03:57344void FilebrowseHandler::Init() {
345 download_manager_ = profile_->GetOriginalProfile()->GetDownloadManager();
346 download_manager_->AddObserver(this);
347}
348
[email protected]dcd23fe2009-11-12 20:21:18349void FilebrowseHandler::RegisterMessages() {
[email protected]698601e2009-10-21 22:43:37350 dom_ui_->RegisterMessageCallback("getRoots",
[email protected]dcd23fe2009-11-12 20:21:18351 NewCallback(this, &FilebrowseHandler::HandleGetRoots));
[email protected]698601e2009-10-21 22:43:37352 dom_ui_->RegisterMessageCallback("getChildren",
[email protected]dcd23fe2009-11-12 20:21:18353 NewCallback(this, &FilebrowseHandler::HandleGetChildren));
[email protected]698601e2009-10-21 22:43:37354 dom_ui_->RegisterMessageCallback("getMetadata",
[email protected]dcd23fe2009-11-12 20:21:18355 NewCallback(this, &FilebrowseHandler::HandleGetMetadata));
356 dom_ui_->RegisterMessageCallback("openNewPopupWindow",
357 NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow));
358 dom_ui_->RegisterMessageCallback("openNewFullWindow",
359 NewCallback(this, &FilebrowseHandler::OpenNewFullWindow));
[email protected]9d6b9aff2009-12-11 17:39:18360 dom_ui_->RegisterMessageCallback("uploadToPicasaweb",
361 NewCallback(this, &FilebrowseHandler::UploadToPicasaweb));
[email protected]274e42b2010-01-29 22:03:57362 dom_ui_->RegisterMessageCallback("getDownloads",
363 NewCallback(this, &FilebrowseHandler::HandleGetDownloads));
364 dom_ui_->RegisterMessageCallback("createNewFolder",
365 NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder));
[email protected]17496bb2010-03-10 19:48:23366 dom_ui_->RegisterMessageCallback("playMediaFile",
367 NewCallback(this, &FilebrowseHandler::PlayMediaFile));
[email protected]a67fa08e2010-02-12 20:43:55368 dom_ui_->RegisterMessageCallback("pauseToggleDownload",
369 NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
370 dom_ui_->RegisterMessageCallback("deleteFile",
371 NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
[email protected]c4a530b2010-03-08 17:33:03372 dom_ui_->RegisterMessageCallback("cancelDownload",
373 NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
374 dom_ui_->RegisterMessageCallback("allowDownload",
375 NewCallback(this, &FilebrowseHandler::HandleAllowDownload));
376 dom_ui_->RegisterMessageCallback("refreshDirectory",
377 NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
[email protected]9d6b9aff2009-12-11 17:39:18378}
379
[email protected]a67fa08e2010-02-12 20:43:55380
381void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
382 // We notify the UI by telling it to refresh its contents.
383 FilePath dir_path = path.DirName();
384 GetChildrenForPath(dir_path, true);
385};
386
[email protected]9d6b9aff2009-12-11 17:39:18387void FilebrowseHandler::FireUploadComplete() {
388 DictionaryValue info_value;
389 info_value.SetString(L"path", current_file_uploaded_);
390
391 std::string username;
392 username = getenv("CHROMEOS_USER");
393
394 if (username.empty()) {
395 LOG(ERROR) << "Unable to get username";
396 return;
397 }
398 int location = username.find_first_of('@',0);
399 if (location <= 0) {
400 LOG(ERROR) << "Username not formatted correctly";
401 return;
402 }
403 username = username.erase(username.find_first_of('@',0));
404 std::string picture_url;
405 picture_url = kPicasawebBaseUrl;
406 picture_url += username;
407 picture_url += kPicasawebDropBox;
408 info_value.SetString(L"url", picture_url);
409 info_value.SetInteger(L"status_code", upload_response_code_);
410 dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value);
411}
412
[email protected]07046ab2010-01-20 21:42:44413#if defined(OS_CHROMEOS)
414void FilebrowseHandler::MountChanged(chromeos::MountLibrary* obj,
415 chromeos::MountEventType evt,
416 const std::string& path) {
417 if (evt == chromeos::DISK_REMOVED ||
418 evt == chromeos::DISK_CHANGED) {
419 dom_ui_->CallJavascriptFunction(L"rootsChanged");
420 }
421}
422#endif
423
[email protected]9d6b9aff2009-12-11 17:39:18424void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source,
425 const GURL& url,
426 const URLRequestStatus& status,
427 int response_code,
428 const ResponseCookies& cookies,
429 const std::string& data) {
430 upload_response_code_ = response_code;
431
432 ChromeThread::PostTask(
433 ChromeThread::UI, FROM_HERE,
434 NewRunnableMethod(CurrentTask_, &TaskProxy::FireUploadCompleteProxy));
[email protected]698601e2009-10-21 22:43:37435}
436
[email protected]dcd23fe2009-11-12 20:21:18437void FilebrowseHandler::HandleGetRoots(const Value* value) {
[email protected]698601e2009-10-21 22:43:37438 ListValue results_value;
439 DictionaryValue info_value;
[email protected]698601e2009-10-21 22:43:37440 // TODO(dhg): add other entries, make this more general
[email protected]07046ab2010-01-20 21:42:44441#if defined(OS_CHROMEOS)
[email protected]62c7ef32010-03-23 23:44:24442 chromeos::MountLibrary* lib =
443 chromeos::CrosLibrary::Get()->GetMountLibrary();
[email protected]07046ab2010-01-20 21:42:44444 const chromeos::MountLibrary::DiskVector& disks = lib->disks();
445
446 for (size_t i = 0; i < disks.size(); ++i) {
447 if (!disks[i].mount_path.empty()) {
448 DictionaryValue* page_value = new DictionaryValue();
449 page_value->SetString(kPropertyPath, disks[i].mount_path);
450 FilePath currentpath;
451 currentpath = FilePath(disks[i].mount_path);
452 std::string filename;
453 filename = currentpath.BaseName().value();
454 page_value->SetString(kPropertyTitle, filename);
455 page_value->SetBoolean(kPropertyDirectory, true);
456 results_value.Append(page_value);
457 }
458 }
459#else
460 DictionaryValue* page_value = new DictionaryValue();
461 page_value->SetString(kPropertyPath, "/media");
462 page_value->SetString(kPropertyTitle, "Removeable");
[email protected]698601e2009-10-21 22:43:37463 page_value->SetBoolean(kPropertyDirectory, true);
464
465 results_value.Append(page_value);
[email protected]07046ab2010-01-20 21:42:44466#endif
467 FilePath default_download_path;
468 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
469 &default_download_path)) {
470 NOTREACHED();
471 }
472
473 DictionaryValue* download_value = new DictionaryValue();
474 download_value->SetString(kPropertyPath, default_download_path.value());
475 download_value->SetString(kPropertyTitle, "File Shelf");
476 download_value->SetBoolean(kPropertyDirectory, true);
477
478 results_value.Append(download_value);
[email protected]698601e2009-10-21 22:43:37479
[email protected]9d6b9aff2009-12-11 17:39:18480 info_value.SetString(L"functionCall", "getRoots");
[email protected]07046ab2010-01-20 21:42:44481 info_value.SetString(kPropertyPath, "");
[email protected]9d6b9aff2009-12-11 17:39:18482 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37483 info_value, results_value);
484}
485
[email protected]274e42b2010-01-29 22:03:57486void FilebrowseHandler::HandleCreateNewFolder(const Value* value) {
487#if defined(OS_CHROMEOS)
488 if (value && value->GetType() == Value::TYPE_LIST) {
489 const ListValue* list_value = static_cast<const ListValue*>(value);
490 std::string path;
491
492 // Get path string.
493 if (list_value->GetString(0, &path)) {
494
495 FilePath currentpath;
496 currentpath = FilePath(path);
497
498 if (!file_util::CreateDirectory(currentpath)) {
499 LOG(ERROR) << "unable to create directory";
500 }
501 } else {
502 LOG(ERROR) << "Unable to get string";
503 return;
504 }
505 }
506#endif
507}
508
[email protected]17496bb2010-03-10 19:48:23509void FilebrowseHandler::PlayMediaFile(const Value* value) {
510#if defined(OS_CHROMEOS)
511 if (value && value->GetType() == Value::TYPE_LIST) {
512 const ListValue* list_value = static_cast<const ListValue*>(value);
513 std::string path;
514
515 // Get path string.
516 if (list_value->GetString(0, &path)) {
517 FilePath currentpath;
518 currentpath = FilePath(path);
519
520 MediaPlayer* mediaplayer = MediaPlayer::Get();
521 std::string url = currentpath.value();
522
523 GURL gurl(url);
524
525 mediaplayer->EnqueueMediaURL(gurl);
526 } else {
527 LOG(ERROR) << "Unable to get string";
528 return;
529 }
530 }
531#endif
532}
533
[email protected]c4a530b2010-03-08 17:33:03534void FilebrowseHandler::HandleRefreshDirectory(const Value* value) {
535 if (value && value->GetType() == Value::TYPE_LIST) {
536 const ListValue* list_value = static_cast<const ListValue*>(value);
537 std::string path;
538
539 // Get path string.
540 if (list_value->GetString(0, &path)) {
541 FilePath currentpath;
542#if defined(OS_WIN)
543 currentpath = FilePath(ASCIIToWide(path));
544#else
545 currentpath = FilePath(path);
546#endif
547 GetChildrenForPath(currentpath, true);
548 } else {
549 LOG(ERROR) << "Unable to get string";
550 return;
551 }
552 }
553}
554
[email protected]a67fa08e2010-02-12 20:43:55555void FilebrowseHandler::HandlePauseToggleDownload(const Value* value) {
556#if defined(OS_CHROMEOS)
557 if (value && value->GetType() == Value::TYPE_LIST) {
558 const ListValue* list_value = static_cast<const ListValue*>(value);
559 int id;
560 std::string str_id;
561
562 if (list_value->GetString(0, &str_id)) {
563 id = atoi(str_id.c_str());
564 DownloadItem* item = download_items_[id];
565 item->TogglePause();
566 } else {
567 LOG(ERROR) << "Unable to get id for download to pause";
568 return;
569 }
570 }
571#endif
572}
573
[email protected]c4a530b2010-03-08 17:33:03574void FilebrowseHandler::HandleAllowDownload(const Value* value) {
575#if defined(OS_CHROMEOS)
576 if (value && value->GetType() == Value::TYPE_LIST) {
577 const ListValue* list_value = static_cast<const ListValue*>(value);
578 int id;
579 std::string str_id;
580
581 if (list_value->GetString(0, &str_id)) {
582 id = atoi(str_id.c_str());
583 DownloadItem* item = download_items_[id];
584 download_manager_->DangerousDownloadValidated(item);
585 } else {
586 LOG(ERROR) << "Unable to get id for download to pause";
587 return;
588 }
589 }
590#endif
591}
592
593void FilebrowseHandler::HandleCancelDownload(const Value* value) {
594#if defined(OS_CHROMEOS)
595 if (value && value->GetType() == Value::TYPE_LIST) {
596 const ListValue* list_value = static_cast<const ListValue*>(value);
597 int id;
598 std::string str_id;
599
600 if (list_value->GetString(0, &str_id)) {
601 id = atoi(str_id.c_str());
602 DownloadItem* item = download_items_[id];
603 item->Cancel(true);
604 FilePath path = item->full_path();
605 FilePath dir_path = path.DirName();
606 item->Remove(true);
607 GetChildrenForPath(dir_path, true);
608 } else {
609 LOG(ERROR) << "Unable to get id for download to pause";
610 return;
611 }
612 }
613#endif
614}
615
[email protected]dcd23fe2009-11-12 20:21:18616void FilebrowseHandler::OpenNewFullWindow(const Value* value) {
617 OpenNewWindow(value, false);
618}
[email protected]698601e2009-10-21 22:43:37619
[email protected]dcd23fe2009-11-12 20:21:18620void FilebrowseHandler::OpenNewPopupWindow(const Value* value) {
621 OpenNewWindow(value, true);
622}
623
624void FilebrowseHandler::OpenNewWindow(const Value* value, bool popup) {
625 if (value && value->GetType() == Value::TYPE_LIST) {
626 const ListValue* list_value = static_cast<const ListValue*>(value);
627 Value* list_member;
628 std::string path;
629
630 // Get path string.
631 if (list_value->Get(0, &list_member) &&
632 list_member->GetType() == Value::TYPE_STRING) {
633 const StringValue* string_value =
634 static_cast<const StringValue*>(list_member);
635 string_value->GetAsString(&path);
636 } else {
637 LOG(ERROR) << "Unable to get string";
638 return;
639 }
640 Browser* browser;
641 if (popup) {
642 browser = Browser::CreateForPopup(profile_);
643 } else {
[email protected]9419bcf2010-04-12 17:26:10644 browser = BrowserList::GetLastActive();
[email protected]dcd23fe2009-11-12 20:21:18645 }
646 browser->AddTabWithURL(
647 GURL(path), GURL(), PageTransition::LINK,
648 true, -1, false, NULL);
649 if (popup) {
650 // TODO(dhg): Remove these from being hardcoded. Allow javascript
651 // to specify.
[email protected]e561e202010-03-24 17:57:12652 browser->window()->SetBounds(gfx::Rect(0, 0, 400, 300));
[email protected]dcd23fe2009-11-12 20:21:18653 }
654 browser->window()->Show();
655 } else {
656 LOG(ERROR) << "Wasn't able to get the List if requested files.";
657 return;
658 }
659}
660
[email protected]9d6b9aff2009-12-11 17:39:18661void FilebrowseHandler::ReadInFile() {
662#if defined(OS_CHROMEOS)
663 // Get the users username
664 std::string username;
665 username = getenv("CHROMEOS_USER");
666
667 if (username.empty()) {
668 LOG(ERROR) << "Unable to get username";
669 return;
670 }
671 int location = username.find_first_of('@',0);
672 if (location <= 0) {
673 LOG(ERROR) << "Username not formatted correctly";
674 return;
675 }
676 username = username.erase(username.find_first_of('@',0));
677 std::string url = kPicasawebUserPrefix;
678 url += username;
679 url += kPicasawebDefault;
680
681 FilePath currentpath;
682 currentpath = FilePath(current_file_uploaded_);
683 // Get the filename
684 std::string filename;
685 filename = currentpath.BaseName().value();
686 std::string filecontents;
687 if (!file_util::ReadFileToString(currentpath, &filecontents)) {
688 LOG(ERROR) << "Unable to read this file:" << currentpath.value();
689 return;
690 }
691
692 URLFetcher* fetcher = URLFetcher::Create(0,
693 GURL(url),
694 URLFetcher::POST,
695 this);
696 fetcher->set_upload_data("image/jpeg", filecontents);
697
698 // Set the filename on the server
699 std::string slug = "Slug: ";
700 slug += filename;
701 fetcher->set_extra_request_headers(slug);
702 fetcher->set_request_context(Profile::GetDefaultRequestContext());
703 fetcher->Start();
704#endif
705}
706
707// This is just a prototype for allowing generic uploads to various sites
708// TODO(dhg): Remove this and implement general upload.
709void FilebrowseHandler::UploadToPicasaweb(const Value* value) {
710 std::string path;
711#if defined(OS_CHROMEOS)
712 if (value && value->GetType() == Value::TYPE_LIST) {
713 const ListValue* list_value = static_cast<const ListValue*>(value);
714 Value* list_member;
715
716 // Get search string.
717 if (list_value->Get(0, &list_member) &&
718 list_member->GetType() == Value::TYPE_STRING) {
719 const StringValue* string_value =
720 static_cast<const StringValue*>(list_member);
721 string_value->GetAsString(&path);
722 }
723
724 } else {
725 LOG(ERROR) << "Wasn't able to get the List if requested files.";
726 return;
727 }
728 current_file_uploaded_ = path;
729 // ReadInFile();
[email protected]a67fa08e2010-02-12 20:43:55730 FilePath current_path(path);
731 TaskProxy* task = new TaskProxy(AsWeakPtr(), current_path);
[email protected]9d6b9aff2009-12-11 17:39:18732 task->AddRef();
733 CurrentTask_ = task;
734 ChromeThread::PostTask(
735 ChromeThread::FILE, FROM_HERE,
736 NewRunnableMethod(
737 task, &TaskProxy::ReadInFileProxy));
738#endif
739}
740
[email protected]a67fa08e2010-02-12 20:43:55741void FilebrowseHandler::GetChildrenForPath(FilePath& path, bool is_refresh) {
742 filelist_value_.reset(new ListValue());
743 currentpath_ = FilePath(path);
744
745 if (lister_.get()) {
746 lister_->Cancel();
747 lister_->set_delegate(NULL);
748 lister_ = NULL;
749 }
750
751 is_refresh_ = is_refresh;
752 lister_ = new net::DirectoryLister(currentpath_, this);
753 lister_->Start();
754}
755
[email protected]dcd23fe2009-11-12 20:21:18756void FilebrowseHandler::HandleGetChildren(const Value* value) {
757 std::string path;
[email protected]698601e2009-10-21 22:43:37758 if (value && value->GetType() == Value::TYPE_LIST) {
759 const ListValue* list_value = static_cast<const ListValue*>(value);
760 Value* list_member;
761
762 // Get search string.
763 if (list_value->Get(0, &list_member) &&
764 list_member->GetType() == Value::TYPE_STRING) {
765 const StringValue* string_value =
766 static_cast<const StringValue*>(list_member);
767 string_value->GetAsString(&path);
768 }
769
770 } else {
[email protected]dcd23fe2009-11-12 20:21:18771 LOG(ERROR) << "Wasn't able to get the List if requested files.";
[email protected]698601e2009-10-21 22:43:37772 return;
773 }
774 filelist_value_.reset(new ListValue());
[email protected]a67fa08e2010-02-12 20:43:55775 FilePath currentpath;
[email protected]698601e2009-10-21 22:43:37776#if defined(OS_WIN)
[email protected]a67fa08e2010-02-12 20:43:55777 currentpath = FilePath(ASCIIToWide(path));
[email protected]698601e2009-10-21 22:43:37778#else
[email protected]a67fa08e2010-02-12 20:43:55779 currentpath = FilePath(path);
[email protected]698601e2009-10-21 22:43:37780#endif
781
[email protected]a67fa08e2010-02-12 20:43:55782 GetChildrenForPath(currentpath, false);
[email protected]698601e2009-10-21 22:43:37783}
784
[email protected]dcd23fe2009-11-12 20:21:18785void FilebrowseHandler::OnListFile(
[email protected]698601e2009-10-21 22:43:37786 const file_util::FileEnumerator::FindInfo& data) {
[email protected]07046ab2010-01-20 21:42:44787#if defined(OS_WIN)
788 if (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
789 return;
790 }
791#elif defined(OS_POSIX)
792 if (data.filename[0] == '.') {
793 return;
794 }
795#endif
796
[email protected]698601e2009-10-21 22:43:37797 DictionaryValue* file_value = new DictionaryValue();
798
799#if defined(OS_WIN)
800 int64 size = (static_cast<int64>(data.nFileSizeHigh) << 32) |
801 data.nFileSizeLow;
802 file_value->SetString(kPropertyTitle, data.cFileName);
803 file_value->SetString(kPropertyPath,
804 currentpath_.Append(data.cFileName).value());
805 file_value->SetBoolean(kPropertyDirectory,
806 (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
807
808#elif defined(OS_POSIX)
809 file_value->SetString(kPropertyTitle, data.filename);
810 file_value->SetString(kPropertyPath,
811 currentpath_.Append(data.filename).value());
812 file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.stat.st_mode));
813#endif
814 filelist_value_->Append(file_value);
815}
816
[email protected]dcd23fe2009-11-12 20:21:18817void FilebrowseHandler::OnListDone(int error) {
[email protected]698601e2009-10-21 22:43:37818 DictionaryValue info_value;
[email protected]a67fa08e2010-02-12 20:43:55819 if (is_refresh_) {
820 info_value.SetString(L"functionCall", "refresh");
821 } else {
822 info_value.SetString(L"functionCall", "getChildren");
823 }
[email protected]698601e2009-10-21 22:43:37824 info_value.SetString(kPropertyPath, currentpath_.value());
[email protected]9d6b9aff2009-12-11 17:39:18825 dom_ui_->CallJavascriptFunction(L"browseFileResult",
[email protected]698601e2009-10-21 22:43:37826 info_value, *(filelist_value_.get()));
[email protected]a67fa08e2010-02-12 20:43:55827 SendCurrentDownloads();
[email protected]698601e2009-10-21 22:43:37828}
829
[email protected]dcd23fe2009-11-12 20:21:18830void FilebrowseHandler::HandleGetMetadata(const Value* value) {
[email protected]698601e2009-10-21 22:43:37831}
832
[email protected]274e42b2010-01-29 22:03:57833void FilebrowseHandler::HandleGetDownloads(const Value* value) {
834 ModelChanged();
835}
836
837void FilebrowseHandler::ModelChanged() {
838 ClearDownloadItems();
[email protected]c4a530b2010-03-08 17:33:03839 download_manager_->GetCurrentDownloads(this, FilePath());
[email protected]274e42b2010-01-29 22:03:57840}
841
842void FilebrowseHandler::SetDownloads(std::vector<DownloadItem*>& downloads) {
843 ClearDownloadItems();
[email protected]274e42b2010-01-29 22:03:57844 // Scan for any in progress downloads and add ourself to them as an observer.
845 for (DownloadList::iterator it = downloads.begin();
846 it != downloads.end(); ++it) {
847 DownloadItem* download = *it;
848 // We want to know what happens as the download progresses and be notified
849 // when the user validates the dangerous download.
850 if (download->state() == DownloadItem::IN_PROGRESS ||
851 download->safety_state() == DownloadItem::DANGEROUS) {
852 download->AddObserver(this);
853 download_items_.push_back(download);
854 }
855 }
856
857 SendCurrentDownloads();
858}
859
[email protected]a67fa08e2010-02-12 20:43:55860void FilebrowseHandler::DeleteFile(const FilePath& path) {
861 if (!file_util::Delete(path, true)) {
862 LOG(ERROR) << "unable to delete directory";
863 }
864 ChromeThread::PostTask(
865 ChromeThread::UI, FROM_HERE,
866 NewRunnableMethod(CurrentTask_, &TaskProxy::FireDeleteCompleteProxy));
867}
868
869void FilebrowseHandler::HandleDeleteFile(const Value* value) {
870 #if defined(OS_CHROMEOS)
871 if (value && value->GetType() == Value::TYPE_LIST) {
872 const ListValue* list_value = static_cast<const ListValue*>(value);
873 std::string path;
874
875 // Get path string.
876 if (list_value->GetString(0, &path)) {
877
878 FilePath currentpath;
879 currentpath = FilePath(path);
[email protected]c4a530b2010-03-08 17:33:03880 for (unsigned int x = 0; x < download_items_.size(); x++) {
881 FilePath item = download_items_[x]->full_path();
882 if (item == currentpath) {
883 download_items_[x]->Cancel(true);
884 download_items_[x]->Remove(true);
885 FilePath dir_path = item.DirName();
886 GetChildrenForPath(dir_path, true);
887 return;
888 }
889 }
[email protected]a67fa08e2010-02-12 20:43:55890 TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath);
891 task->AddRef();
892 CurrentTask_ = task;
893 ChromeThread::PostTask(
894 ChromeThread::FILE, FROM_HERE,
895 NewRunnableMethod(
896 task, &TaskProxy::DeleteFileProxy));
897 } else {
898 LOG(ERROR) << "Unable to get string";
899 return;
900 }
901 }
902#endif
903}
904
[email protected]274e42b2010-01-29 22:03:57905void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
906 DownloadList::iterator it = find(download_items_.begin(),
907 download_items_.end(),
908 download);
909 if (it == download_items_.end())
910 return;
911 const int id = static_cast<int>(it - download_items_.begin());
912
913 ListValue results_value;
914 results_value.Append(download_util::CreateDownloadItemValue(download, id));
915 dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value);
916}
917
918void FilebrowseHandler::ClearDownloadItems() {
919 for (DownloadList::iterator it = download_items_.begin();
920 it != download_items_.end(); ++it) {
921 (*it)->RemoveObserver(this);
922 }
923 download_items_.clear();
924}
925
926void FilebrowseHandler::SendCurrentDownloads() {
927 ListValue results_value;
928 for (DownloadList::iterator it = download_items_.begin();
929 it != download_items_.end(); ++it) {
930 int index = static_cast<int>(it - download_items_.begin());
931 results_value.Append(download_util::CreateDownloadItemValue(*it, index));
932 }
933
934 dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
935}
936
[email protected]698601e2009-10-21 22:43:37937////////////////////////////////////////////////////////////////////////////////
938//
[email protected]f5bf8ccf2010-02-05 18:19:25939// FileBrowseUI
[email protected]698601e2009-10-21 22:43:37940//
941////////////////////////////////////////////////////////////////////////////////
942
[email protected]274e42b2010-01-29 22:03:57943FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) {
[email protected]9d6b9aff2009-12-11 17:39:18944 FilebrowseHandler* handler = new FilebrowseHandler();
945 AddMessageHandler((handler)->Attach(this));
[email protected]274e42b2010-01-29 22:03:57946 handler->Init();
[email protected]698601e2009-10-21 22:43:37947 FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource();
948
949 // Set up the chrome://filebrowse/ source.
[email protected]fae20792009-10-28 20:31:58950 ChromeThread::PostTask(
951 ChromeThread::IO, FROM_HERE,
952 NewRunnableMethod(
[email protected]576a4ca2009-11-05 01:41:09953 Singleton<ChromeURLDataManager>::get(),
[email protected]698601e2009-10-21 22:43:37954 &ChromeURLDataManager::AddDataSource,
[email protected]f8f82502009-11-20 23:14:23955 make_scoped_refptr(html_source)));
[email protected]698601e2009-10-21 22:43:37956}
[email protected]f5bf8ccf2010-02-05 18:19:25957
958// static
[email protected]1717246f2010-02-10 17:08:15959Browser* FileBrowseUI::OpenPopup(Profile* profile,
[email protected]467293292010-04-16 19:41:56960 const std::string& hashArgument,
961 int width,
962 int height) {
[email protected]1717246f2010-02-10 17:08:15963 // Get existing pop up for given hashArgument.
964 Browser* browser = GetPopupForPath(hashArgument);
[email protected]f5bf8ccf2010-02-05 18:19:25965
[email protected]1717246f2010-02-10 17:08:15966 // Create new browser if no matching pop up found.
967 if (browser == NULL) {
968 browser = Browser::CreateForPopup(profile);
[email protected]f5bf8ccf2010-02-05 18:19:25969
[email protected]1717246f2010-02-10 17:08:15970 std::string url(kFilebrowseURLHash);
971 url.append(hashArgument);
[email protected]f5bf8ccf2010-02-05 18:19:25972
[email protected]1717246f2010-02-10 17:08:15973 browser->AddTabWithURL(
974 GURL(url), GURL(), PageTransition::LINK,
975 true, -1, false, NULL);
976 browser->window()->SetBounds(gfx::Rect(kPopupLeft,
977 kPopupTop,
[email protected]467293292010-04-16 19:41:56978 width,
979 height));
[email protected]1717246f2010-02-10 17:08:15980
981 browser->window()->Show();
982 }
[email protected]f5bf8ccf2010-02-05 18:19:25983
984 return browser;
985}
[email protected]1717246f2010-02-10 17:08:15986
987Browser* FileBrowseUI::GetPopupForPath(const std::string& path) {
988 for (BrowserList::const_iterator it = BrowserList::begin();
989 it != BrowserList::end(); ++it) {
990 if ((*it)->type() == Browser::TYPE_POPUP) {
991 const GURL& url =
992 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL();
993
994 if (url.SchemeIs(chrome::kChromeUIScheme) &&
995 url.host() == chrome::kChromeUIFileBrowseHost &&
996 url.ref() == path) {
997 return (*it);
998 }
999 }
1000 }
1001
1002 return NULL;
1003}
[email protected]467293292010-04-16 19:41:561004
1005const int FileBrowseUI::kPopupWidth = 250;
1006const int FileBrowseUI::kPopupHeight = 300;
1007const int FileBrowseUI::kSmallPopupWidth = 250;
1008const int FileBrowseUI::kSmallPopupHeight = 50;