Index: chrome/browser/system_monitor/removable_device_notifications_window_win.cc |
diff --git a/chrome/browser/system_monitor/removable_device_notifications_window_win.cc b/chrome/browser/system_monitor/removable_device_notifications_window_win.cc |
index 2f04fe968cca535ddfe7ddd48758bd7dcda516e1..7c059b431e78b1943ff6a4b0660bd0abc3317f21 100644 |
--- a/chrome/browser/system_monitor/removable_device_notifications_window_win.cc |
+++ b/chrome/browser/system_monitor/removable_device_notifications_window_win.cc |
@@ -9,7 +9,7 @@ |
#include <fileapi.h> |
#include "base/file_path.h" |
-#include "base/metrics/histogram.h" |
+#include "base/i18n/case_conversion.h" |
#include "base/string_number_conversions.h" |
#include "base/string_util.h" |
#include "base/system_monitor/system_monitor.h" |
@@ -17,10 +17,12 @@ |
#include "base/win/wrapped_window_proc.h" |
#include "chrome/browser/system_monitor/media_device_notifications_utils.h" |
#include "chrome/browser/system_monitor/media_storage_util.h" |
+#include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_win.h" |
#include "content/public/browser/browser_thread.h" |
using base::SystemMonitor; |
using base::win::WrappedWindowProc; |
+using chrome::mtp::MediaTransferProtocolDeviceObserverWin; |
using content::BrowserThread; |
namespace { |
@@ -29,6 +31,9 @@ const DWORD kMaxPathBufLen = MAX_PATH + 1; |
const char16 kWindowClassName[] = L"Chrome_RemovableDeviceNotificationWindow"; |
+// Windows portable device interface GUID constant. |
+const char16 kWPDDevInterfaceGUID[] = L"{6ac27878-a6fa-4155-ba85-f98f491d4f33}"; |
+ |
static chrome::RemovableDeviceNotificationsWindowWin* |
g_removable_device_notifications_window_win = NULL; |
@@ -78,6 +83,39 @@ bool GetDeviceInfo(const FilePath& device_path, string16* device_location, |
return true; |
} |
+// Returns true if |data| represents a logical volume structure. |
+bool IsLogicalVolumeStructure(LPARAM data) { |
+ DEV_BROADCAST_HDR* broadcast_hdr = |
+ reinterpret_cast<DEV_BROADCAST_HDR*>(data); |
+ return broadcast_hdr != NULL && |
+ broadcast_hdr->dbch_devicetype == DBT_DEVTYP_VOLUME; |
+} |
+ |
+// Returns true if |data| represents a class of portable devices. |
+bool IsPortableDeviceStructure(LPARAM data) { |
+ DEV_BROADCAST_HDR* broadcast_hdr = |
+ reinterpret_cast<DEV_BROADCAST_HDR*>(data); |
+ if (!broadcast_hdr || |
+ broadcast_hdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) { |
+ return false; |
+ } |
+ |
+ GUID guidDevInterface = GUID_NULL; |
+ CLSIDFromString(kWPDDevInterfaceGUID, &guidDevInterface); |
+ DEV_BROADCAST_DEVICEINTERFACE* dev_interface = |
+ reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data); |
+ return (IsEqualGUID(dev_interface->dbcc_classguid, guidDevInterface) != 0); |
+} |
+ |
+// Returns the portable device plug and play device ID string. |
+string16 GetPnpDeviceId(LPARAM data) { |
+ DEV_BROADCAST_DEVICEINTERFACE* dev_interface = |
+ reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data); |
+ if (!dev_interface) |
+ return string16(); |
+ return base::i18n::ToLower(dev_interface->dbcc_name); |
+} |
+ |
std::vector<FilePath> GetAttachedDevices() { |
std::vector<FilePath> result; |
char16 volume_name[kMaxPathBufLen]; |
@@ -202,30 +240,29 @@ void RemovableDeviceNotificationsWindowWin::OnDeviceChange(UINT event_type, |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
switch (event_type) { |
case DBT_DEVICEARRIVAL: { |
- DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
- for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
- if (!(unitmask & 0x01)) |
- continue; |
- AddNewDevice(DriveNumberToFilePath(i)); |
+ if (IsLogicalVolumeStructure(data)) { |
+ DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
+ for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
+ if (!(unitmask & 0x01)) |
+ continue; |
+ AddNewDevice(DriveNumberToFilePath(i)); |
+ } |
+ } else if (IsPortableDeviceStructure(data)) { |
+ HandleMtpDeviceEventOnUIThread(true, GetPnpDeviceId(data)); |
} |
break; |
} |
case DBT_DEVICEREMOVECOMPLETE: { |
- DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
- for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
- if (!(unitmask & 0x01)) |
- continue; |
- |
- FilePath device = DriveNumberToFilePath(i); |
- MountPointDeviceIdMap::const_iterator device_info = |
- device_ids_.find(device); |
- // If the devices isn't type removable (like a CD), it won't be there. |
- if (device_info == device_ids_.end()) |
- continue; |
- |
- SystemMonitor::Get()->ProcessRemovableStorageDetached( |
- device_info->second); |
- device_ids_.erase(device_info); |
+ if (IsLogicalVolumeStructure(data)) { |
+ DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
+ for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
+ if (!(unitmask & 0x01)) |
+ continue; |
+ HandleMassStorageDeviceDetachEventOnUIThread( |
+ DriveNumberToFilePath(i).value()); |
+ } |
+ } else if (IsPortableDeviceStructure(data)) { |
+ HandleMtpDeviceEventOnUIThread(false, GetPnpDeviceId(data)); |
} |
break; |
} |
@@ -247,6 +284,23 @@ RemovableDeviceNotificationsWindowWin:: |
// static |
LRESULT CALLBACK RemovableDeviceNotificationsWindowWin::WndProcThunk( |
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
+#if defined(DBT_DEVTYP_DEVICEINTERFACE) && defined(DEVICE_NOTIFY_WINDOW_HANDLE) |
+ static HDEVNOTIFY hDeviceNotify; |
+ if (message == WM_CREATE) { |
vandebo (ex-Chrome)
2012/10/16 17:42:36
content/browser/system_message_window_win.cc just
kmadhusu
2012/10/19 04:01:38
This code is very similar to the SystemMessageWind
|
+ GUID guidDevInterface = GUID_NULL; |
+ HRESULT hr = CLSIDFromString(kWPDDevInterfaceGUID, &guidDevInterface); |
+ if (SUCCEEDED(hr)) { |
+ DEV_BROADCAST_DEVICEINTERFACE db = {0}; |
+ db.dbcc_size = sizeof(db); |
+ db.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; |
+ db.dbcc_classguid = guidDevInterface; |
+ hDeviceNotify = RegisterDeviceNotification(hwnd, &db, |
+ DEVICE_NOTIFY_WINDOW_HANDLE); |
+ } |
+ } else if (message == WM_CLOSE) { |
+ UnregisterDeviceNotification(hDeviceNotify); |
+ } |
+#endif |
RemovableDeviceNotificationsWindowWin* msg_wnd = |
reinterpret_cast<RemovableDeviceNotificationsWindowWin*>( |
GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
@@ -331,21 +385,48 @@ void RemovableDeviceNotificationsWindowWin::CheckDeviceTypeOnFileThread( |
std::string device_id = MediaStorageUtil::MakeDeviceId(type, unique_id); |
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
- &RemovableDeviceNotificationsWindowWin::ProcessDeviceAttachedOnUIThread, |
- this, device_id, device_name, device)); |
+ &RemovableDeviceNotificationsWindowWin:: |
+ HandleMassStorageDeviceAttachEventOnUIThread, |
+ this, device_id, device_name, device.value())); |
} |
-void RemovableDeviceNotificationsWindowWin::ProcessDeviceAttachedOnUIThread( |
+void RemovableDeviceNotificationsWindowWin:: |
+HandleMassStorageDeviceAttachEventOnUIThread( |
const std::string& device_id, |
- const FilePath::StringType& device_name, |
- const FilePath& device) { |
+ const string16& device_name, |
+ const string16& device_location) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
// TODO(kmadhusu) Record device info histogram. |
- device_ids_[device] = device_id; |
+ device_ids_[device_location] = device_id; |
SystemMonitor::Get()->ProcessRemovableStorageAttached(device_id, |
device_name, |
- device.value()); |
+ device_location); |
+} |
+ |
+void RemovableDeviceNotificationsWindowWin:: |
+HandleMassStorageDeviceDetachEventOnUIThread(const string16& device_location) { |
+ MountPointDeviceIdMap::const_iterator device_info = |
+ device_ids_.find(device_location); |
+ // If the devices isn't type removable (like a CD), it won't be there. |
+ if (device_info == device_ids_.end()) |
+ return; |
+ |
+ SystemMonitor::Get()->ProcessRemovableStorageDetached(device_info->second); |
+ device_ids_.erase(device_info); |
+} |
+ |
+void RemovableDeviceNotificationsWindowWin:: |
+HandleMtpDeviceEventOnUIThread(bool is_attach, const string16& pnp_device_id) { |
+ if (pnp_device_id.empty()) |
+ return; |
+ |
+ MediaTransferProtocolDeviceObserverWin* mtp_device_observer = |
+ MediaTransferProtocolDeviceObserverWin::GetInstance(); |
+ if (mtp_device_observer) { |
+ mtp_device_observer->HandleMtpDeviceEventOnUIThread(is_attach, |
+ pnp_device_id); |
+ } |
} |
} // namespace chrome |