devtools_file_helper.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/devtools/devtools_file_helper.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include <set>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/md5.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/value_conversions.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/download_prefs.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/platform_util.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_context.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/download_manager.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/web_contents_view.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/generated_resources.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/select_file_dialog.h"
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::Bind;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::Callback;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserContext;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::DownloadManager;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::RenderViewHost;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents;
492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing std::set;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::LazyInstance<base::FilePath>::Leaky
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_last_save_path = LAZY_INSTANCE_INITIALIZER;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef Callback<void(const base::FilePath&)> SelectedCallback;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef Callback<void(void)> CanceledCallback;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SelectFileDialog : public ui::SelectFileDialog::Listener,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         public base::RefCounted<SelectFileDialog> {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SelectFileDialog(const SelectedCallback& selected_callback,
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   const CanceledCallback& canceled_callback,
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   WebContents* web_contents)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : selected_callback_(selected_callback),
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        canceled_callback_(canceled_callback),
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        web_contents_(web_contents) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    select_file_dialog_ = ui::SelectFileDialog::Create(
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        this, new ChromeSelectFilePolicy(web_contents));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Show(ui::SelectFileDialog::Type type,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            const base::FilePath& default_path) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddRef();  // Balanced in the three listener outcomes.
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    select_file_dialog_->SelectFile(
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      type,
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::string16(),
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      default_path,
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL,
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      0,
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::FilePath::StringType(),
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ui::SelectFileDialog::Listener implementation.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FileSelected(const base::FilePath& path,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            int index,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            void* params) OVERRIDE {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    selected_callback_.Run(path);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Release();  // Balanced in ::Show.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  void* params) OVERRIDE {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Release();  // Balanced in ::Show.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED() << "Should not be able to select multiple files";
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FileSelectionCanceled(void* params) OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    canceled_callback_.Run();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Release();  // Balanced in ::Show.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCounted<SelectFileDialog>;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~SelectFileDialog() {}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SelectedCallback selected_callback_;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CanceledCallback canceled_callback_;
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebContents* web_contents_;
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SelectFileDialog);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WriteToFile(const base::FilePath& path, const std::string& content) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!path.empty());
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_util::WriteFile(path, content.c_str(), content.length());
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppendToFile(const base::FilePath& path, const std::string& content) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!path.empty());
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_util::AppendToFile(path, content.c_str(), content.length());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)fileapi::IsolatedContext* isolated_context() {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fileapi::IsolatedContext* isolated_context =
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::IsolatedContext::GetInstance();
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(isolated_context);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return isolated_context;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string RegisterFileSystem(WebContents* web_contents,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const base::FilePath& path,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               std::string* registered_name) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents->GetURL().SchemeIs(content::kChromeDevToolsScheme));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string file_system_id = isolated_context()->RegisterFileSystemForPath(
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeNativeLocal, path, registered_name);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::ChildProcessSecurityPolicy* policy =
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::ChildProcessSecurityPolicy::GetInstance();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int renderer_id = render_view_host->GetProcess()->GetID();
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy->GrantReadFileSystem(renderer_id, file_system_id);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy->GrantWriteFileSystem(renderer_id, file_system_id);
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  policy->GrantCreateFileForFileSystem(renderer_id, file_system_id);
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  policy->GrantDeleteFromFileSystem(renderer_id, file_system_id);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We only need file level access for reading FileEntries. Saving FileEntries
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // just needs the file system to have read/write access, which is granted
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // above if required.
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!policy->CanReadFile(renderer_id, path))
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy->GrantReadFile(renderer_id, path);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return file_system_id;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsFileHelper::FileSystem CreateFileSystemStruct(
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* web_contents,
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& file_system_id,
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& registered_name,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& file_system_path) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL origin = web_contents->GetURL().GetOrigin();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string file_system_name = fileapi::GetIsolatedFileSystemName(
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_id);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string root_url = fileapi::GetIsolatedFileSystemRootURIString(
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin,
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_id,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      registered_name);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DevToolsFileHelper::FileSystem(file_system_name,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        root_url,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        file_system_path);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochset<std::string> GetAddedFileSystemPaths(Profile* profile) {
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* file_systems_paths_value =
1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      profile->GetPrefs()->GetDictionary(prefs::kDevToolsFileSystemPaths);
1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  set<std::string> result;
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*file_systems_paths_value);
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !it.IsAtEnd(); it.Advance()) {
1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    result.insert(it.key());
1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return result;
1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsFileHelper::FileSystem::FileSystem() {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsFileHelper::FileSystem::FileSystem(const std::string& file_system_name,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const std::string& root_url,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           const std::string& file_system_path)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : file_system_name(file_system_name),
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_url(root_url),
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_system_path(file_system_path) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsFileHelper::DevToolsFileHelper(WebContents* web_contents,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       Profile* profile)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : web_contents_(web_contents),
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_(profile),
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsFileHelper::~DevToolsFileHelper() {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::Save(const std::string& url,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& content,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool save_as,
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              const SaveCallback& saveCallback,
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              const SaveCallback& cancelCallback) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PathsMap::iterator it = saved_files_.find(url);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it != saved_files_.end() && !save_as) {
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SaveAsFileSelected(url, content, saveCallback, it->second);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* file_map =
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetPrefs()->GetDictionary(prefs::kDevToolsEditedFiles);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath initial_path;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* path_value;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (file_map->Get(base::MD5String(url), &path_value))
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::GetValueAsFilePath(*path_value, &initial_path);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (initial_path.empty()) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL gurl(url);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string suggested_file_name = gurl.is_valid() ?
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gurl.ExtractFileName() : url;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (suggested_file_name.length() > 64)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      suggested_file_name = suggested_file_name.substr(0, 64);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!g_last_save_path.Pointer()->empty()) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initial_path = g_last_save_path.Pointer()->DirName().AppendASCII(
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          suggested_file_name);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath download_path = DownloadPrefs::FromDownloadManager(
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          BrowserContext::GetDownloadManager(profile_))->DownloadPath();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initial_path = download_path.AppendASCII(suggested_file_name);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SelectFileDialog> select_file_dialog = new SelectFileDialog(
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&DevToolsFileHelper::SaveAsFileSelected,
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           weak_factory_.GetWeakPtr(),
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           url,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           content,
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           saveCallback),
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&DevToolsFileHelper::SaveAsFileSelectionCanceled,
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           weak_factory_.GetWeakPtr(),
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           cancelCallback),
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      web_contents_);
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  select_file_dialog->Show(ui::SelectFileDialog::SELECT_SAVEAS_FILE,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           initial_path);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::Append(const std::string& url,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const std::string& content,
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const AppendCallback& callback) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PathsMap::iterator it = saved_files_.find(url);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == saved_files_.end())
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run();
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          Bind(&AppendToFile, it->second, content));
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::SaveAsFileSelected(const std::string& url,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const std::string& content,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const SaveCallback& callback,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const base::FilePath& path) {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *g_last_save_path.Pointer() = path;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  saved_files_[url] = path;
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryPrefUpdate update(profile_->GetPrefs(),
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              prefs::kDevToolsEditedFiles);
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* files_map = update.Get();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  files_map->SetWithoutPathExpansion(base::MD5String(url),
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     base::CreateFilePathValue(path));
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run();
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          Bind(&WriteToFile, path, content));
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DevToolsFileHelper::SaveAsFileSelectionCanceled(
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SaveCallback& callback) {
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsFileHelper::AddFileSystem(
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const AddFileSystemCallback& callback,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ShowInfoBarCallback& show_info_bar_callback) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SelectFileDialog> select_file_dialog = new SelectFileDialog(
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&DevToolsFileHelper::InnerAddFileSystem,
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           weak_factory_.GetWeakPtr(),
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           callback,
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           show_info_bar_callback),
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      Bind(callback, FileSystem()),
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      web_contents_);
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  select_file_dialog->Show(ui::SelectFileDialog::SELECT_FOLDER,
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           base::FilePath());
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DevToolsFileHelper::UpgradeDraggedFileSystemPermissions(
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& file_system_url,
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const AddFileSystemCallback& callback,
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const ShowInfoBarCallback& show_info_bar_callback) {
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fileapi::FileSystemURL root_url =
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      isolated_context()->CrackURL(GURL(file_system_url));
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!root_url.is_valid() || !root_url.path().empty()) {
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    callback.Run(FileSystem());
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::vector<fileapi::MountPoints::MountPointInfo> mount_points;
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  isolated_context()->GetDraggedFileInfo(root_url.filesystem_id(),
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         &mount_points);
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::vector<fileapi::MountPoints::MountPointInfo>::const_iterator it =
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      mount_points.begin();
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (; it != mount_points.end(); ++it)
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    InnerAddFileSystem(callback, show_info_bar_callback, it->path);
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::InnerAddFileSystem(
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AddFileSystemCallback& callback,
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ShowInfoBarCallback& show_info_bar_callback,
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string file_system_path = path.AsUTF8Unsafe();
345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* file_systems_paths_value =
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      profile_->GetPrefs()->GetDictionary(prefs::kDevToolsFileSystemPaths);
348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (file_systems_paths_value->HasKey(file_system_path)) {
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    callback.Run(FileSystem());
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
353c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  std::string path_display_name = path.AsEndingWithSeparator().AsUTF8Unsafe();
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::string16 message = l10n_util::GetStringFUTF16(
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IDS_DEV_TOOLS_CONFIRM_ADD_FILE_SYSTEM_MESSAGE,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::UTF8ToUTF16(path_display_name));
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  show_info_bar_callback.Run(
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message,
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Bind(&DevToolsFileHelper::AddUserConfirmedFileSystem,
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           weak_factory_.GetWeakPtr(),
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           callback, path));
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsFileHelper::AddUserConfirmedFileSystem(
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AddFileSystemCallback& callback,
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::FilePath& path,
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool allowed) {
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!allowed) {
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(FileSystem());
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string registered_name;
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string file_system_id = RegisterFileSystem(web_contents_,
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  path,
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  &registered_name);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string file_system_path = path.AsUTF8Unsafe();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryPrefUpdate update(profile_->GetPrefs(),
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              prefs::kDevToolsFileSystemPaths);
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* file_systems_paths_value = update.Get();
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_systems_paths_value->SetWithoutPathExpansion(
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_system_path, base::Value::CreateNullValue());
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystem filesystem = CreateFileSystemStruct(web_contents_,
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 file_system_id,
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 registered_name,
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 file_system_path);
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(filesystem);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::RequestFileSystems(
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const RequestFileSystemsCallback& callback) {
3932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  set<std::string> file_system_paths = GetAddedFileSystemPaths(profile_);
3942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  set<std::string>::const_iterator it = file_system_paths.begin();
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<FileSystem> file_systems;
3962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (; it != file_system_paths.end(); ++it) {
3972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    std::string file_system_path = *it;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string registered_name;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string file_system_id = RegisterFileSystem(web_contents_,
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                    path,
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    &registered_name);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystem filesystem = CreateFileSystemStruct(web_contents_,
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   file_system_id,
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   registered_name,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   file_system_path);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_systems.push_back(filesystem);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(file_systems);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsFileHelper::RemoveFileSystem(const std::string& file_system_path) {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  isolated_context()->RevokeFileSystemByPath(path);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryPrefUpdate update(profile_->GetPrefs(),
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              prefs::kDevToolsFileSystemPaths);
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* file_systems_paths_value = update.Get();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_systems_paths_value->RemoveWithoutPathExpansion(file_system_path, NULL);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
4242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool DevToolsFileHelper::IsFileSystemAdded(
4252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::string& file_system_path) {
4262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  set<std::string> file_system_paths = GetAddedFileSystemPaths(profile_);
4282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return file_system_paths.find(file_system_path) != file_system_paths.end();
4292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
430