OLD | NEW |
| (Empty) |
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/volume_manager.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/files/file_path.h" | |
9 #include "base/logging.h" | |
10 #include "base/memory/singleton.h" | |
11 #include "base/path_service.h" | |
12 #include "base/prefs/pref_service.h" | |
13 #include "chrome/browser/chromeos/extensions/file_manager/volume_manager_factory
.h" | |
14 #include "chrome/browser/chromeos/extensions/file_manager/volume_manager_observe
r.h" | |
15 #include "chrome/browser/profiles/profile.h" | |
16 #include "chrome/common/pref_names.h" | |
17 #include "chromeos/dbus/cros_disks_client.h" | |
18 #include "chromeos/disks/disk_mount_manager.h" | |
19 #include "content/public/browser/browser_thread.h" | |
20 | |
21 namespace file_manager { | |
22 namespace { | |
23 | |
24 VolumeType MountTypeToVolumeType( | |
25 chromeos::MountType type) { | |
26 switch (type) { | |
27 case chromeos::MOUNT_TYPE_DEVICE: | |
28 return VOLUME_TYPE_REMOVABLE_DISK_PARTITION; | |
29 case chromeos::MOUNT_TYPE_ARCHIVE: | |
30 return VOLUME_TYPE_MOUNTED_ARCHIVE_FILE; | |
31 default: | |
32 NOTREACHED(); | |
33 } | |
34 | |
35 return VOLUME_TYPE_DOWNLOADS_DIRECTORY; | |
36 } | |
37 | |
38 VolumeInfo CreateDownloadsVolumeInfo( | |
39 const base::FilePath& downloads_path) { | |
40 VolumeInfo volume_info; | |
41 volume_info.type = VOLUME_TYPE_DOWNLOADS_DIRECTORY; | |
42 // Keep source_path empty. | |
43 volume_info.mount_path = downloads_path; | |
44 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE; | |
45 return volume_info; | |
46 } | |
47 | |
48 VolumeInfo CreateVolumeInfoFromMountPointInfo( | |
49 const chromeos::disks::DiskMountManager::MountPointInfo& mount_point) { | |
50 VolumeInfo volume_info; | |
51 volume_info.type = MountTypeToVolumeType(mount_point.mount_type); | |
52 volume_info.source_path = base::FilePath(mount_point.source_path); | |
53 volume_info.mount_path = base::FilePath(mount_point.mount_path); | |
54 volume_info.mount_condition = mount_point.mount_condition; | |
55 return volume_info; | |
56 } | |
57 | |
58 } // namespace | |
59 | |
60 VolumeManager::VolumeManager( | |
61 Profile* profile, | |
62 chromeos::disks::DiskMountManager* disk_mount_manager) | |
63 : profile_(profile), | |
64 disk_mount_manager_(disk_mount_manager) { | |
65 DCHECK(disk_mount_manager); | |
66 } | |
67 | |
68 VolumeManager::~VolumeManager() { | |
69 } | |
70 | |
71 VolumeManager* VolumeManager::Get(content::BrowserContext* context) { | |
72 return VolumeManagerFactory::Get(context); | |
73 } | |
74 | |
75 void VolumeManager::Initialize() { | |
76 disk_mount_manager_->AddObserver(this); | |
77 disk_mount_manager_->RequestMountInfoRefresh(); | |
78 } | |
79 | |
80 void VolumeManager::Shutdown() { | |
81 disk_mount_manager_->RemoveObserver(this); | |
82 } | |
83 | |
84 void VolumeManager::AddObserver(VolumeManagerObserver* observer) { | |
85 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
86 DCHECK(observer); | |
87 observers_.AddObserver(observer); | |
88 } | |
89 | |
90 void VolumeManager::RemoveObserver(VolumeManagerObserver* observer) { | |
91 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
92 DCHECK(observer); | |
93 observers_.RemoveObserver(observer); | |
94 } | |
95 | |
96 std::vector<VolumeInfo> VolumeManager::GetVolumeInfoList() const { | |
97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
98 | |
99 std::vector<VolumeInfo> result; | |
100 | |
101 // TODO(hidehiko): Adds Drive if available. | |
102 | |
103 // Adds "Downloads". | |
104 base::FilePath home_path; | |
105 if (PathService::Get(base::DIR_HOME, &home_path)) { | |
106 result.push_back( | |
107 CreateDownloadsVolumeInfo(home_path.AppendASCII("Downloads"))); | |
108 } | |
109 | |
110 // Adds disks (both removable disks and zip archives). | |
111 const chromeos::disks::DiskMountManager::MountPointMap& mount_points = | |
112 disk_mount_manager_->mount_points(); | |
113 for (chromeos::disks::DiskMountManager::MountPointMap::const_iterator it = | |
114 mount_points.begin(); | |
115 it != mount_points.end(); ++it) { | |
116 if (it->second.mount_type == chromeos::MOUNT_TYPE_DEVICE || | |
117 it->second.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) | |
118 result.push_back(CreateVolumeInfoFromMountPointInfo(it->second)); | |
119 } | |
120 | |
121 return result; | |
122 } | |
123 | |
124 void VolumeManager::OnDiskEvent( | |
125 chromeos::disks::DiskMountManager::DiskEvent event, | |
126 const chromeos::disks::DiskMountManager::Disk* disk) { | |
127 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
128 | |
129 // Disregard hidden devices. | |
130 if (disk->is_hidden()) | |
131 return; | |
132 | |
133 switch (event) { | |
134 case chromeos::disks::DiskMountManager::DISK_ADDED: { | |
135 if (disk->device_path().empty()) { | |
136 DVLOG(1) << "Empty system path for " << disk->device_path(); | |
137 return; | |
138 } | |
139 | |
140 bool mounting = false; | |
141 if (disk->mount_path().empty() && disk->has_media() && | |
142 !profile_->GetPrefs()->GetBoolean(prefs::kExternalStorageDisabled)) { | |
143 // If disk is not mounted yet and it has media and there is no policy | |
144 // forbidding external storage, give it a try. | |
145 // Initiate disk mount operation. MountPath auto-detects the filesystem | |
146 // format if the second argument is empty. The third argument (mount | |
147 // label) is not used in a disk mount operation. | |
148 disk_mount_manager_->MountPath( | |
149 disk->device_path(), std::string(), std::string(), | |
150 chromeos::MOUNT_TYPE_DEVICE); | |
151 mounting = true; | |
152 } | |
153 | |
154 // Notify to observers. | |
155 FOR_EACH_OBSERVER(VolumeManagerObserver, observers_, | |
156 OnDiskAdded(*disk, mounting)); | |
157 return; | |
158 } | |
159 | |
160 case chromeos::disks::DiskMountManager::DISK_REMOVED: | |
161 // If the disk is already mounted, unmount it. | |
162 if (!disk->mount_path().empty()) { | |
163 disk_mount_manager_->UnmountPath( | |
164 disk->mount_path(), | |
165 chromeos::UNMOUNT_OPTIONS_LAZY, | |
166 chromeos::disks::DiskMountManager::UnmountPathCallback()); | |
167 } | |
168 | |
169 // Notify to observers. | |
170 FOR_EACH_OBSERVER(VolumeManagerObserver, observers_, | |
171 OnDiskRemoved(*disk)); | |
172 return; | |
173 | |
174 case chromeos::disks::DiskMountManager::DISK_CHANGED: | |
175 DVLOG(1) << "Ignore CHANGED event."; | |
176 return; | |
177 } | |
178 NOTREACHED(); | |
179 } | |
180 | |
181 void VolumeManager::OnDeviceEvent( | |
182 chromeos::disks::DiskMountManager::DeviceEvent event, | |
183 const std::string& device_path) { | |
184 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
185 DVLOG(1) << "OnDeviceEvent: " << event << ", " << device_path; | |
186 | |
187 switch (event) { | |
188 case chromeos::disks::DiskMountManager::DEVICE_ADDED: | |
189 FOR_EACH_OBSERVER(VolumeManagerObserver, observers_, | |
190 OnDeviceAdded(device_path)); | |
191 return; | |
192 case chromeos::disks::DiskMountManager::DEVICE_REMOVED: | |
193 FOR_EACH_OBSERVER(VolumeManagerObserver, observers_, | |
194 OnDeviceRemoved(device_path)); | |
195 return; | |
196 case chromeos::disks::DiskMountManager::DEVICE_SCANNED: | |
197 DVLOG(1) << "Ignore SCANNED event: " << device_path; | |
198 return; | |
199 } | |
200 NOTREACHED(); | |
201 } | |
202 | |
203 void VolumeManager::OnMountEvent( | |
204 chromeos::disks::DiskMountManager::MountEvent event, | |
205 chromeos::MountError error_code, | |
206 const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) { | |
207 // TODO(hidehiko): Move the implementation from EventRouter. | |
208 } | |
209 | |
210 void VolumeManager::OnFormatEvent( | |
211 chromeos::disks::DiskMountManager::FormatEvent event, | |
212 chromeos::FormatError error_code, | |
213 const std::string& device_path) { | |
214 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
215 DVLOG(1) << "OnDeviceEvent: " << event << ", " << error_code | |
216 << ", " << device_path; | |
217 | |
218 switch (event) { | |
219 case chromeos::disks::DiskMountManager::FORMAT_STARTED: | |
220 FOR_EACH_OBSERVER( | |
221 VolumeManagerObserver, observers_, | |
222 OnFormatStarted(device_path, | |
223 error_code == chromeos::FORMAT_ERROR_NONE)); | |
224 return; | |
225 case chromeos::disks::DiskMountManager::FORMAT_COMPLETED: | |
226 if (error_code == chromeos::FORMAT_ERROR_NONE) { | |
227 // If format is completed successfully, try to mount the device. | |
228 // MountPath auto-detects filesystem format if second argument is | |
229 // empty. The third argument (mount label) is not used in a disk mount | |
230 // operation. | |
231 disk_mount_manager_->MountPath( | |
232 device_path, std::string(), std::string(), | |
233 chromeos::MOUNT_TYPE_DEVICE); | |
234 } | |
235 | |
236 FOR_EACH_OBSERVER( | |
237 VolumeManagerObserver, observers_, | |
238 OnFormatCompleted(device_path, | |
239 error_code == chromeos::FORMAT_ERROR_NONE)); | |
240 | |
241 return; | |
242 } | |
243 NOTREACHED(); | |
244 } | |
245 | |
246 } // namespace file_manager | |
OLD | NEW |