Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Unified Diff: chrome/browser/system_monitor/removable_device_notifications_window_win.cc

Issue 11088012: [Win, MediaGallery] Enumerate and handle mtp device attach/detach events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698