1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_ 6 #define CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_ 7 8 #include <portabledeviceapi.h> 9 10 #include <map> 11 #include <string> 12 #include <vector> 13 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/strings/string16.h" 17 #include "chrome/browser/storage_monitor/storage_monitor.h" 18 19 namespace base { 20 class SequencedTaskRunner; 21 } 22 23 namespace chrome { 24 25 namespace test { 26 class TestPortableDeviceWatcherWin; 27 } 28 29 // This class watches the portable device mount points and sends notifications 30 // about the attached/detached media transfer protocol (MTP) devices. 31 // This is a singleton class instantiated by StorageMonitorWin. This class is 32 // created, destroyed and operates on the UI thread, except for long running 33 // tasks it spins off to a SequencedTaskRunner. 34 class PortableDeviceWatcherWin { 35 public: 36 typedef std::vector<string16> StorageObjectIDs; 37 38 struct DeviceStorageObject { 39 DeviceStorageObject(const string16& temporary_id, 40 const std::string& persistent_id); 41 42 // Storage object temporary identifier, e.g. "s10001". This string ID 43 // uniquely identifies the object on the device. This ID need not be 44 // persistent across sessions. This ID is obtained from WPD_OBJECT_ID 45 // property. 46 string16 object_temporary_id; 47 48 // Storage object persistent identifier, 49 // e.g. "StorageSerial:<SID-{10001,D,31080448}>:<123456789>". 50 std::string object_persistent_id; 51 }; 52 typedef std::vector<DeviceStorageObject> StorageObjects; 53 54 // Struct to store attached MTP device details. 55 struct DeviceDetails { 56 // Device name. 57 string16 name; 58 59 // Device interface path. 60 string16 location; 61 62 // Device storage details. A device can have multiple data partitions. 63 StorageObjects storage_objects; 64 }; 65 typedef std::vector<DeviceDetails> Devices; 66 67 // TODO(gbillock): Change to take the device notifications object as 68 // an argument. 69 PortableDeviceWatcherWin(); 70 virtual ~PortableDeviceWatcherWin(); 71 72 // Must be called after the browser blocking pool is ready for use. 73 // StorageMonitorWin::Init() will call this function. 74 void Init(HWND hwnd); 75 76 // Processes DEV_BROADCAST_DEVICEINTERFACE messages and triggers a 77 // notification if appropriate. 78 void OnWindowMessage(UINT event_type, LPARAM data); 79 80 // Gets the information of the MTP storage specified by |storage_device_id|. 81 // On success, returns true and fills in |device_location| with device 82 // interface details and |storage_object_id| with storage object temporary 83 // identifier. 84 virtual bool GetMTPStorageInfoFromDeviceId( 85 const std::string& storage_device_id, 86 string16* device_location, 87 string16* storage_object_id) const; 88 89 // Constructs and returns a storage path from storage unique identifier. 90 static string16 GetStoragePathFromStorageId( 91 const std::string& storage_unique_id); 92 93 // Set the volume notifications object to be used when new 94 // devices are found. 95 void SetNotifications(StorageMonitor::Receiver* notifications); 96 97 void EjectDevice(const std::string& device_id, 98 base::Callback<void(StorageMonitor::EjectStatus)> callback); 99 100 private: 101 friend class test::TestPortableDeviceWatcherWin; 102 103 // Key: MTP device storage unique id. 104 // Value: Metadata for the given storage. 105 typedef std::map<std::string, StorageInfo> MTPStorageMap; 106 107 // Key: MTP device plug and play ID string. 108 // Value: Vector of device storage objects. 109 typedef std::map<string16, StorageObjects> MTPDeviceMap; 110 111 // Helpers to enumerate existing MTP storage devices. 112 virtual void EnumerateAttachedDevices(); 113 void OnDidEnumerateAttachedDevices(const Devices* devices, 114 const bool result); 115 116 // Helpers to handle device attach event. 117 virtual void HandleDeviceAttachEvent(const string16& pnp_device_id); 118 void OnDidHandleDeviceAttachEvent(const DeviceDetails* device_details, 119 const bool result); 120 121 // Handles the detach event of the device specified by |pnp_device_id|. 122 void HandleDeviceDetachEvent(const string16& pnp_device_id); 123 124 // The portable device notifications handle. 125 HDEVNOTIFY notifications_; 126 127 // Attached media transfer protocol device map. 128 MTPDeviceMap device_map_; 129 130 // Attached media transfer protocol device storage objects map. 131 MTPStorageMap storage_map_; 132 133 // The task runner used to execute tasks that may take a long time and thus 134 // should not be performed on the UI thread. 135 scoped_refptr<base::SequencedTaskRunner> media_task_runner_; 136 137 // Used by |media_task_runner_| to create cancelable callbacks. 138 base::WeakPtrFactory<PortableDeviceWatcherWin> weak_ptr_factory_; 139 140 // The notifications object to use to signal newly attached devices. 141 StorageMonitor::Receiver* storage_notifications_; 142 143 DISALLOW_COPY_AND_ASSIGN(PortableDeviceWatcherWin); 144 }; 145 146 } // namespace chrome 147 148 #endif // CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_ 149