| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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/usb_mount_observer.h" | |
| 6 | |
| 7 #include "base/command_line.h" | |
| 8 #include "base/json/json_writer.h" | |
| 9 #include "base/singleton.h" | |
| 10 #include "chrome/browser/chromeos/cros/cros_library.h" | |
| 11 #include "chrome/browser/profiles/profile.h" | |
| 12 #include "chrome/browser/ui/browser.h" | |
| 13 #include "chrome/browser/ui/browser_list.h" | |
| 14 #include "chrome/browser/ui/browser_window.h" | |
| 15 #include "chrome/browser/ui/webui/filebrowse_ui.h" | |
| 16 #include "chrome/common/chrome_switches.h" | |
| 17 #include "chrome/common/url_constants.h" | |
| 18 #include "content/browser/tab_contents/tab_contents.h" | |
| 19 | |
| 20 | |
| 21 namespace chromeos { | |
| 22 | |
| 23 const char* kFilebrowseURLHash = "chrome://filebrowse#"; | |
| 24 const char* kFilebrowseScanning = "scanningdevice"; | |
| 25 const int kPopupLeft = 0; | |
| 26 const int kPopupTop = 0; | |
| 27 const int kPopupWidth = 250; | |
| 28 const int kPopupHeight = 300; | |
| 29 | |
| 30 // static | |
| 31 USBMountObserver* USBMountObserver::GetInstance() { | |
| 32 return Singleton<USBMountObserver>::get(); | |
| 33 } | |
| 34 | |
| 35 void USBMountObserver::Observe(NotificationType type, | |
| 36 const NotificationSource& source, | |
| 37 const NotificationDetails& details) { | |
| 38 DCHECK(type == NotificationType::BROWSER_CLOSED); | |
| 39 for (BrowserIterator i = browsers_.begin(); i != browsers_.end(); | |
| 40 ++i) { | |
| 41 if (Source<Browser>(source).ptr() == i->browser) { | |
| 42 i->browser = NULL; | |
| 43 registrar_.Remove(this, | |
| 44 NotificationType::BROWSER_CLOSED, | |
| 45 source); | |
| 46 return; | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 void USBMountObserver::OpenFileBrowse(const std::string& url, | |
| 52 const std::string& device_path, | |
| 53 bool small) { | |
| 54 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 55 switches::kEnableAdvancedFileSystem)) { | |
| 56 return; | |
| 57 } | |
| 58 Browser* browser; | |
| 59 Profile* profile; | |
| 60 browser = BrowserList::GetLastActive(); | |
| 61 if (browser == NULL) { | |
| 62 return; | |
| 63 } | |
| 64 profile = browser->profile(); | |
| 65 if (small) { | |
| 66 browser = FileBrowseUI::OpenPopup(profile, | |
| 67 url, | |
| 68 FileBrowseUI::kSmallPopupWidth, | |
| 69 FileBrowseUI::kSmallPopupHeight); | |
| 70 } else { | |
| 71 browser = FileBrowseUI::OpenPopup(profile, | |
| 72 url, | |
| 73 FileBrowseUI::kPopupWidth, | |
| 74 FileBrowseUI::kPopupHeight); | |
| 75 } | |
| 76 | |
| 77 BrowserIterator iter = FindBrowserForPath(device_path); | |
| 78 if (iter == browsers_.end()) { | |
| 79 registrar_.Add(this, | |
| 80 NotificationType::BROWSER_CLOSED, | |
| 81 Source<Browser>(browser)); | |
| 82 BrowserWithPath new_browser; | |
| 83 new_browser.browser = browser; | |
| 84 new_browser.device_path = device_path; | |
| 85 browsers_.push_back(new_browser); | |
| 86 } else { | |
| 87 iter->browser = browser; | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 void USBMountObserver::DiskChanged(MountLibraryEventType event, | |
| 92 const MountLibrary::Disk* disk) { | |
| 93 if (event == MOUNT_DISK_ADDED) { | |
| 94 OnDiskAdded(disk); | |
| 95 } else if (event == MOUNT_DISK_REMOVED) { | |
| 96 OnDiskRemoved(disk); | |
| 97 } else if (event == MOUNT_DISK_CHANGED) { | |
| 98 OnDiskChanged(disk); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 void USBMountObserver::DeviceChanged(MountLibraryEventType event, | |
| 103 const std::string& device_path) { | |
| 104 if (event == MOUNT_DEVICE_ADDED) { | |
| 105 OnDeviceAdded(device_path); | |
| 106 }else if (event == MOUNT_DEVICE_REMOVED) { | |
| 107 OnDeviceRemoved(device_path); | |
| 108 } else if (event == MOUNT_DEVICE_SCANNED) { | |
| 109 OnDeviceScanned(device_path); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 void USBMountObserver::FireFileSystemChanged( | |
| 114 const std::string& web_path) { | |
| 115 // TODO(zelidrag): Send message to all extensions that file system has | |
| 116 // changed. | |
| 117 return; | |
| 118 } | |
| 119 | |
| 120 void USBMountObserver::OnDiskAdded(const MountLibrary::Disk* disk) { | |
| 121 VLOG(1) << "Disk added: " << disk->device_path(); | |
| 122 if (disk->device_path().empty()) { | |
| 123 VLOG(1) << "Empty system path for " << disk->device_path(); | |
| 124 return; | |
| 125 } | |
| 126 if (disk->is_parent()) { | |
| 127 if (!disk->has_media()) | |
| 128 RemoveBrowserFromVector(disk->system_path()); | |
| 129 return; | |
| 130 } | |
| 131 | |
| 132 // If disk is not mounted yet, give it a try. | |
| 133 if (disk->mount_path().empty()) { | |
| 134 // Initiate disk mount operation. | |
| 135 chromeos::MountLibrary* lib = | |
| 136 chromeos::CrosLibrary::Get()->GetMountLibrary(); | |
| 137 lib->MountPath(disk->device_path().c_str()); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void USBMountObserver::OnDiskRemoved(const MountLibrary::Disk* disk) { | |
| 142 VLOG(1) << "Disk removed: " << disk->device_path(); | |
| 143 RemoveBrowserFromVector(disk->system_path()); | |
| 144 MountPointMap::iterator iter = mounted_devices_.find(disk->device_path()); | |
| 145 if (iter == mounted_devices_.end()) | |
| 146 return; | |
| 147 | |
| 148 chromeos::MountLibrary* lib = | |
| 149 chromeos::CrosLibrary::Get()->GetMountLibrary(); | |
| 150 // TODO(zelidrag): This for some reason does not work as advertized. | |
| 151 // we might need to clean up mount directory on FILE thread here as well. | |
| 152 lib->UnmountPath(disk->device_path().c_str()); | |
| 153 | |
| 154 FireFileSystemChanged(iter->second); | |
| 155 mounted_devices_.erase(iter); | |
| 156 } | |
| 157 | |
| 158 void USBMountObserver::OnDiskChanged(const MountLibrary::Disk* disk) { | |
| 159 VLOG(1) << "Disk changed : " << disk->device_path(); | |
| 160 if (!disk->mount_path().empty()) { | |
| 161 // Remember this mount point. | |
| 162 mounted_devices_.insert( | |
| 163 std::pair<std::string, std::string>(disk->device_path(), | |
| 164 disk->mount_path())); | |
| 165 FireFileSystemChanged(disk->mount_path()); | |
| 166 | |
| 167 // TODO(zelidrag): We should remove old file browser stuff later. | |
| 168 // Doing second search to see if the current disk has already | |
| 169 // been popped up due to its parent device being plugged in. | |
| 170 BrowserIterator iter = FindBrowserForPath(disk->system_path()); | |
| 171 if (iter != browsers_.end() && iter->browser) { | |
| 172 std::string url = kFilebrowseURLHash; | |
| 173 url += disk->mount_path(); | |
| 174 TabContents* tab = iter->browser->GetSelectedTabContents(); | |
| 175 iter->browser->window()->SetBounds(gfx::Rect( | |
| 176 0, 0, FileBrowseUI::kPopupWidth, FileBrowseUI::kPopupHeight)); | |
| 177 tab->OpenURL(GURL(url), GURL(), CURRENT_TAB, | |
| 178 PageTransition::LINK); | |
| 179 tab->NavigateToPendingEntry(NavigationController::RELOAD); | |
| 180 iter->device_path = disk->device_path(); | |
| 181 iter->mount_path = disk->mount_path(); | |
| 182 } else { | |
| 183 OpenFileBrowse(disk->mount_path(), disk->device_path(), false); | |
| 184 } | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 void USBMountObserver::OnDeviceAdded(const std::string& device_path) { | |
| 189 VLOG(1) << "Device added : " << device_path; | |
| 190 OpenFileBrowse(kFilebrowseScanning, device_path, true); | |
| 191 } | |
| 192 | |
| 193 void USBMountObserver::OnDeviceRemoved(const std::string& system_path) { | |
| 194 // New device is added, initiate disk rescan. | |
| 195 RemoveBrowserFromVector(system_path); | |
| 196 } | |
| 197 | |
| 198 void USBMountObserver::OnDeviceScanned(const std::string& device_path) { | |
| 199 VLOG(1) << "Device scanned : " << device_path; | |
| 200 } | |
| 201 | |
| 202 USBMountObserver::BrowserIterator USBMountObserver::FindBrowserForPath( | |
| 203 const std::string& path) { | |
| 204 for (BrowserIterator i = browsers_.begin();i != browsers_.end(); | |
| 205 ++i) { | |
| 206 const std::string& device_path = i->device_path; | |
| 207 // Doing a substring match so that we find if this new one is a subdevice | |
| 208 // of another already inserted device. | |
| 209 if (path.find(device_path) != std::string::npos) { | |
| 210 return i; | |
| 211 } | |
| 212 } | |
| 213 return browsers_.end(); | |
| 214 } | |
| 215 | |
| 216 void USBMountObserver::RemoveBrowserFromVector(const std::string& system_path) { | |
| 217 BrowserIterator i = FindBrowserForPath(system_path); | |
| 218 std::string mount_path; | |
| 219 if (i != browsers_.end()) { | |
| 220 registrar_.Remove(this, | |
| 221 NotificationType::BROWSER_CLOSED, | |
| 222 Source<Browser>(i->browser)); | |
| 223 mount_path = i->mount_path; | |
| 224 browsers_.erase(i); | |
| 225 } | |
| 226 std::vector<Browser*> close_these; | |
| 227 for (BrowserList::const_iterator it = BrowserList::begin(); | |
| 228 it != BrowserList::end(); ++it) { | |
| 229 if ((*it)->type() == Browser::TYPE_POPUP) { | |
| 230 if (*it && (*it)->GetTabContentsAt((*it)->selected_index())) { | |
| 231 const GURL& url = | |
| 232 (*it)->GetTabContentsAt((*it)->selected_index())->GetURL(); | |
| 233 if (url.SchemeIs(chrome::kChromeUIScheme) && | |
| 234 url.host() == chrome::kChromeUIFileBrowseHost && | |
| 235 url.ref().find(mount_path) != std::string::npos && | |
| 236 !mount_path.empty()) { | |
| 237 close_these.push_back(*it); | |
| 238 } | |
| 239 } | |
| 240 } | |
| 241 } | |
| 242 for (size_t x = 0; x < close_these.size(); x++) { | |
| 243 if (close_these[x]->window()) { | |
| 244 close_these[x]->window()->Close(); | |
| 245 } | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 } // namespace chromeos | |
| OLD | NEW |