1// Copyright 2014 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 "base/bind.h" 6#include "base/thread_task_runner_handle.h" 7#include "chrome/browser/chromeos/extensions/file_manager/device_event_router.h" 8#include "chrome/browser/chromeos/file_manager/volume_manager.h" 9#include "content/public/browser/browser_thread.h" 10 11namespace file_manager { 12namespace { 13namespace file_manager_private = extensions::api::file_manager_private; 14using content::BrowserThread; 15} // namespace 16 17DeviceEventRouter::DeviceEventRouter() 18 : resume_time_delta_(base::TimeDelta::FromSeconds(5)), 19 startup_time_delta_(base::TimeDelta::FromSeconds(10)), 20 is_starting_up_(false), 21 is_resuming_(false), 22 weak_factory_(this) { 23} 24 25DeviceEventRouter::DeviceEventRouter(base::TimeDelta overriding_time_delta) 26 : resume_time_delta_(overriding_time_delta), 27 startup_time_delta_(overriding_time_delta), 28 is_starting_up_(false), 29 is_resuming_(false), 30 weak_factory_(this) { 31} 32 33DeviceEventRouter::~DeviceEventRouter() { 34} 35 36void DeviceEventRouter::Startup() { 37 is_starting_up_ = true; 38 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 39 FROM_HERE, 40 base::Bind(&DeviceEventRouter::StartupDelayed, 41 weak_factory_.GetWeakPtr()), 42 startup_time_delta_); 43} 44 45void DeviceEventRouter::StartupDelayed() { 46 DCHECK(thread_checker_.CalledOnValidThread()); 47 is_starting_up_ = false; 48} 49 50void DeviceEventRouter::OnDeviceAdded(const std::string& device_path) { 51 DCHECK(thread_checker_.CalledOnValidThread()); 52 53 SetDeviceState(device_path, DEVICE_STATE_USUAL); 54 if (IsExternalStorageDisabled()) { 55 OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_DISABLED, 56 device_path); 57 return; 58 } 59} 60 61void DeviceEventRouter::OnDeviceRemoved(const std::string& device_path) { 62 DCHECK(thread_checker_.CalledOnValidThread()); 63 SetDeviceState(device_path, DEVICE_STATE_USUAL); 64 OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_REMOVED, device_path); 65} 66 67void DeviceEventRouter::OnDiskAdded( 68 const chromeos::disks::DiskMountManager::Disk& disk, 69 bool mounting) { 70 // Do nothing. 71} 72 73void DeviceEventRouter::OnDiskRemoved( 74 const chromeos::disks::DiskMountManager::Disk& disk) { 75 DCHECK(thread_checker_.CalledOnValidThread()); 76 77 if (is_resuming_ || is_starting_up_) 78 return; 79 80 const std::string& device_path = disk.system_path_prefix(); 81 if (!disk.mount_path().empty() && 82 GetDeviceState(device_path) != DEVICE_HARD_UNPLUGGED_AND_REPORTED) { 83 OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_HARD_UNPLUGGED, 84 device_path); 85 SetDeviceState(device_path, DEVICE_HARD_UNPLUGGED_AND_REPORTED); 86 } 87} 88 89void DeviceEventRouter::OnVolumeMounted(chromeos::MountError error_code, 90 const VolumeInfo& volume_info) { 91 DCHECK(thread_checker_.CalledOnValidThread()); 92 93 const std::string& device_path = 94 volume_info.system_path_prefix.AsUTF8Unsafe(); 95 SetDeviceState(device_path, DEVICE_STATE_USUAL); 96} 97 98void DeviceEventRouter::OnVolumeUnmounted(chromeos::MountError error_code, 99 const VolumeInfo& volume_info) { 100 // Do nothing. 101} 102 103void DeviceEventRouter::OnFormatStarted(const std::string& device_path, 104 bool success) { 105 DCHECK(thread_checker_.CalledOnValidThread()); 106 107 if (success) { 108 OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_FORMAT_START, 109 device_path); 110 } else { 111 OnDeviceEvent(file_manager_private::DEVICE_EVENT_TYPE_FORMAT_FAIL, 112 device_path); 113 } 114} 115 116void DeviceEventRouter::OnFormatCompleted(const std::string& device_path, 117 bool success) { 118 DCHECK(thread_checker_.CalledOnValidThread()); 119 120 OnDeviceEvent(success ? file_manager_private::DEVICE_EVENT_TYPE_FORMAT_SUCCESS 121 : file_manager_private::DEVICE_EVENT_TYPE_FORMAT_FAIL, 122 device_path); 123} 124 125void DeviceEventRouter::SuspendImminent() { 126 DCHECK(thread_checker_.CalledOnValidThread()); 127 is_resuming_ = true; 128} 129 130void DeviceEventRouter::SuspendDone(const base::TimeDelta& sleep_duration) { 131 DCHECK(thread_checker_.CalledOnValidThread()); 132 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 133 FROM_HERE, 134 base::Bind(&DeviceEventRouter::SuspendDoneDelayed, 135 weak_factory_.GetWeakPtr()), 136 resume_time_delta_); 137} 138 139void DeviceEventRouter::SuspendDoneDelayed() { 140 DCHECK(thread_checker_.CalledOnValidThread()); 141 is_resuming_ = false; 142} 143 144DeviceState DeviceEventRouter::GetDeviceState( 145 const std::string& device_path) const { 146 const std::map<std::string, DeviceState>::const_iterator it = 147 device_states_.find(device_path); 148 return it != device_states_.end() ? it->second : DEVICE_STATE_USUAL; 149} 150 151void DeviceEventRouter::SetDeviceState(const std::string& device_path, 152 DeviceState state) { 153 if (state != DEVICE_STATE_USUAL) { 154 device_states_[device_path] = state; 155 } else { 156 const std::map<std::string, DeviceState>::iterator it = 157 device_states_.find(device_path); 158 if (it != device_states_.end()) 159 device_states_.erase(it); 160 } 161} 162 163} // namespace file_manager 164