1// Copyright 2013 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/chromeos/extensions/file_manager/private_api_mount.h"
6
7#include "base/format_macros.h"
8#include "base/values.h"
9#include "chrome/browser/chromeos/drive/file_system_interface.h"
10#include "chrome/browser/chromeos/drive/file_system_util.h"
11#include "chrome/browser/chromeos/drive/logging.h"
12#include "chrome/browser/chromeos/extensions/file_manager/event_router.h"
13#include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h"
14#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
15#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
16#include "chrome/browser/chromeos/file_manager/volume_manager.h"
17#include "chrome/browser/profiles/profile.h"
18#include "chrome/common/extensions/api/file_browser_private.h"
19#include "chromeos/disks/disk_mount_manager.h"
20#include "content/public/browser/browser_thread.h"
21#include "ui/shell_dialogs/selected_file_info.h"
22
23using chromeos::disks::DiskMountManager;
24using content::BrowserThread;
25namespace file_browser_private = extensions::api::file_browser_private;
26
27namespace extensions {
28
29bool FileBrowserPrivateAddMountFunction::RunImpl() {
30  using file_browser_private::AddMount::Params;
31  const scoped_ptr<Params> params(Params::Create(*args_));
32  EXTENSION_FUNCTION_VALIDATE(params);
33
34  drive::util::Log(logging::LOG_INFO,
35                   "%s[%d] called. (source: '%s')",
36                   name().c_str(),
37                   request_id(),
38                   params->source.empty() ? "(none)" : params->source.c_str());
39  set_log_on_completion(true);
40
41  const base::FilePath path = file_manager::util::GetLocalPathFromURL(
42      render_view_host(), GetProfile(), GURL(params->source));
43
44  if (path.empty())
45    return false;
46
47  // Check if the source path is under Drive cache directory.
48  if (drive::util::IsUnderDriveMountPoint(path)) {
49    drive::FileSystemInterface* file_system =
50        drive::util::GetFileSystemByProfile(GetProfile());
51    if (!file_system)
52      return false;
53
54    file_system->MarkCacheFileAsMounted(
55        drive::util::ExtractDrivePath(path),
56        base::Bind(
57            &FileBrowserPrivateAddMountFunction::RunAfterMarkCacheFileAsMounted,
58            this, path.BaseName()));
59  } else {
60    RunAfterMarkCacheFileAsMounted(
61        path.BaseName(), drive::FILE_ERROR_OK, path);
62  }
63  return true;
64}
65
66void FileBrowserPrivateAddMountFunction::RunAfterMarkCacheFileAsMounted(
67    const base::FilePath& display_name,
68    drive::FileError error,
69    const base::FilePath& file_path) {
70  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
71
72  if (error != drive::FILE_ERROR_OK) {
73    SendResponse(false);
74    return;
75  }
76
77  // Pass back the actual source path of the mount point.
78  SetResult(new base::StringValue(file_path.AsUTF8Unsafe()));
79  SendResponse(true);
80
81  // MountPath() takes a std::string.
82  DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
83  disk_mount_manager->MountPath(
84      file_path.AsUTF8Unsafe(),
85      base::FilePath(display_name.Extension()).AsUTF8Unsafe(),
86      display_name.AsUTF8Unsafe(),
87      chromeos::MOUNT_TYPE_ARCHIVE);
88}
89
90bool FileBrowserPrivateRemoveMountFunction::RunImpl() {
91  using file_browser_private::RemoveMount::Params;
92  const scoped_ptr<Params> params(Params::Create(*args_));
93  EXTENSION_FUNCTION_VALIDATE(params);
94
95  drive::util::Log(logging::LOG_INFO,
96                   "%s[%d] called. (mount_path: '%s')",
97                   name().c_str(),
98                   request_id(),
99                   params->mount_path.c_str());
100  set_log_on_completion(true);
101
102  std::vector<GURL> file_paths;
103  file_paths.push_back(GURL(params->mount_path));
104  file_manager::util::GetSelectedFileInfo(
105      render_view_host(),
106      GetProfile(),
107      file_paths,
108      file_manager::util::NEED_LOCAL_PATH_FOR_OPENING,
109      base::Bind(
110          &FileBrowserPrivateRemoveMountFunction::GetSelectedFileInfoResponse,
111          this));
112  return true;
113}
114
115void FileBrowserPrivateRemoveMountFunction::GetSelectedFileInfoResponse(
116    const std::vector<ui::SelectedFileInfo>& files) {
117  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118
119  if (files.size() != 1) {
120    SendResponse(false);
121    return;
122  }
123
124  // TODO(tbarzic): Send response when callback is received, it would make more
125  // sense than remembering issued unmount requests in file manager and showing
126  // errors for them when MountCompleted event is received.
127  DiskMountManager::GetInstance()->UnmountPath(
128      files[0].local_path.value(),
129      chromeos::UNMOUNT_OPTIONS_NONE,
130      DiskMountManager::UnmountPathCallback());
131  SendResponse(true);
132}
133
134bool FileBrowserPrivateGetVolumeMetadataListFunction::RunImpl() {
135  if (args_->GetSize())
136    return false;
137
138  const std::vector<file_manager::VolumeInfo>& volume_info_list =
139      file_manager::VolumeManager::Get(GetProfile())->GetVolumeInfoList();
140
141  std::string log_string;
142  std::vector<linked_ptr<file_browser_private::VolumeMetadata> > result;
143  for (size_t i = 0; i < volume_info_list.size(); ++i) {
144    linked_ptr<file_browser_private::VolumeMetadata> volume_metadata(
145        new file_browser_private::VolumeMetadata);
146    file_manager::util::VolumeInfoToVolumeMetadata(
147        GetProfile(), volume_info_list[i], volume_metadata.get());
148    result.push_back(volume_metadata);
149    if (!log_string.empty())
150      log_string += ", ";
151    log_string += volume_info_list[i].mount_path.AsUTF8Unsafe();
152  }
153
154  drive::util::Log(
155      logging::LOG_INFO,
156      "%s[%d] succeeded. (results: '[%s]', %" PRIuS " mount points)",
157      name().c_str(), request_id(), log_string.c_str(), result.size());
158
159  results_ =
160      file_browser_private::GetVolumeMetadataList::Results::Create(result);
161  SendResponse(true);
162  return true;
163}
164
165}  // namespace extensions
166