15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <portabledeviceapi.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/storage_monitor/storage_monitor.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SequencedTaskRunner;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestPortableDeviceWatcherWin;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class watches the portable device mount points and sends notifications
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// about the attached/detached media transfer protocol (MTP) devices.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is a singleton class instantiated by StorageMonitorWin. This class is
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// created, destroyed and operates on the UI thread, except for long running
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// tasks it spins off to a SequencedTaskRunner.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PortableDeviceWatcherWin {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<string16> StorageObjectIDs;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct DeviceStorageObject {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceStorageObject(const string16& temporary_id,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& persistent_id);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Storage object temporary identifier, e.g. "s10001". This string ID
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // uniquely identifies the object on the device. This ID need not be
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // persistent across sessions. This ID is obtained from WPD_OBJECT_ID
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // property.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 object_temporary_id;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Storage object persistent identifier,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // e.g. "StorageSerial:<SID-{10001,D,31080448}>:<123456789>".
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string object_persistent_id;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<DeviceStorageObject> StorageObjects;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Struct to store attached MTP device details.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct DeviceDetails {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Device name.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 name;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Device interface path.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 location;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Device storage details. A device can have multiple data partitions.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StorageObjects storage_objects;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<DeviceDetails> Devices;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gbillock): Change to take the device notifications object as
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // an argument.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PortableDeviceWatcherWin();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PortableDeviceWatcherWin();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must be called after the browser blocking pool is ready for use.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // StorageMonitorWin::Init() will call this function.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(HWND hwnd);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Processes DEV_BROADCAST_DEVICEINTERFACE messages and triggers a
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // notification if appropriate.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWindowMessage(UINT event_type, LPARAM data);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Gets the information of the MTP storage specified by |storage_device_id|.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On success, returns true and fills in |device_location| with device
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // interface details and |storage_object_id| with storage object temporary
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // identifier.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool GetMTPStorageInfoFromDeviceId(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& storage_device_id,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      string16* device_location,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      string16* storage_object_id) const;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Constructs and returns a storage path from storage unique identifier.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static string16 GetStoragePathFromStorageId(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& storage_unique_id);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the volume notifications object to be used when new
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // devices are found.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetNotifications(StorageMonitor::Receiver* notifications);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void EjectDevice(const std::string& device_id,
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                   base::Callback<void(StorageMonitor::EjectStatus)> callback);
99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class test::TestPortableDeviceWatcherWin;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Key: MTP device storage unique id.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Value: Metadata for the given storage.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<std::string, StorageInfo> MTPStorageMap;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Key: MTP device plug and play ID string.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Value: Vector of device storage objects.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<string16, StorageObjects> MTPDeviceMap;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helpers to enumerate existing MTP storage devices.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EnumerateAttachedDevices();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDidEnumerateAttachedDevices(const Devices* devices,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const bool result);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helpers to handle device attach event.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void HandleDeviceAttachEvent(const string16& pnp_device_id);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnDidHandleDeviceAttachEvent(const DeviceDetails* device_details,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const bool result);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the detach event of the device specified by |pnp_device_id|.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleDeviceDetachEvent(const string16& pnp_device_id);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The portable device notifications handle.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDEVNOTIFY notifications_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attached media transfer protocol device map.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MTPDeviceMap device_map_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attached media transfer protocol device storage objects map.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MTPStorageMap storage_map_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The task runner used to execute tasks that may take a long time and thus
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should not be performed on the UI thread.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used by |media_task_runner_| to create cancelable callbacks.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<PortableDeviceWatcherWin> weak_ptr_factory_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The notifications object to use to signal newly attached devices.
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StorageMonitor::Receiver* storage_notifications_;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PortableDeviceWatcherWin);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CHROME_BROWSER_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_
149