summaryrefslogtreecommitdiffstats
path: root/components/storage_monitor/portable_device_watcher_win.h
blob: becb7eaa1083f0bdabe84d4aa5773bb9ab13b49c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_
#define COMPONENTS_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_

#include <portabledeviceapi.h>

#include <map>
#include <string>
#include <vector>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "components/storage_monitor/storage_monitor.h"

namespace base {
class SequencedTaskRunner;
}

namespace storage_monitor {

class TestPortableDeviceWatcherWin;

// This class watches the portable device mount points and sends notifications
// about the attached/detached media transfer protocol (MTP) devices.
// This is a singleton class instantiated by StorageMonitorWin. This class is
// created, destroyed and operates on the UI thread, except for long running
// tasks it spins off to a SequencedTaskRunner.
class PortableDeviceWatcherWin {
 public:
  typedef std::vector<base::string16> StorageObjectIDs;

  struct DeviceStorageObject {
    DeviceStorageObject(const base::string16& temporary_id,
                        const std::string& persistent_id);

    // Storage object temporary identifier, e.g. "s10001". This string ID
    // uniquely identifies the object on the device. This ID need not be
    // persistent across sessions. This ID is obtained from WPD_OBJECT_ID
    // property.
    base::string16 object_temporary_id;

    // Storage object persistent identifier,
    // e.g. "StorageSerial:<SID-{10001,D,31080448}>:<123456789>".
    std::string object_persistent_id;
  };
  typedef std::vector<DeviceStorageObject> StorageObjects;

  // Struct to store attached MTP device details.
  struct DeviceDetails {
    DeviceDetails();
    ~DeviceDetails();

    // Device name.
    base::string16 name;

    // Device interface path.
    base::string16 location;

    // Device storage details. A device can have multiple data partitions.
    StorageObjects storage_objects;
  };
  typedef std::vector<DeviceDetails> Devices;

  // TODO(gbillock): Change to take the device notifications object as
  // an argument.
  PortableDeviceWatcherWin();
  virtual ~PortableDeviceWatcherWin();

  // Must be called after the browser blocking pool is ready for use.
  // StorageMonitorWin::Init() will call this function.
  void Init(HWND hwnd);

  // Processes DEV_BROADCAST_DEVICEINTERFACE messages and triggers a
  // notification if appropriate.
  void OnWindowMessage(UINT event_type, LPARAM data);

  // Gets the information of the MTP storage specified by |storage_device_id|.
  // On success, returns true and fills in |device_location| with device
  // interface details and |storage_object_id| with storage object temporary
  // identifier.
  virtual bool GetMTPStorageInfoFromDeviceId(
      const std::string& storage_device_id,
      base::string16* device_location,
      base::string16* storage_object_id) const;

  // Constructs and returns a storage path from storage unique identifier.
  static base::string16 GetStoragePathFromStorageId(
      const std::string& storage_unique_id);

  // Set the volume notifications object to be used when new
  // devices are found.
  void SetNotifications(StorageMonitor::Receiver* notifications);

  void EjectDevice(const std::string& device_id,
                   base::Callback<void(StorageMonitor::EjectStatus)> callback);

 private:
  friend class TestPortableDeviceWatcherWin;

  // Key: MTP device storage unique id.
  // Value: Metadata for the given storage.
  typedef std::map<std::string, StorageInfo> MTPStorageMap;

  // Key: MTP device plug and play ID string.
  // Value: Vector of device storage objects.
  typedef std::map<base::string16, StorageObjects> MTPDeviceMap;

  // Helpers to enumerate existing MTP storage devices.
  virtual void EnumerateAttachedDevices();
  void OnDidEnumerateAttachedDevices(const Devices* devices,
                                     const bool result);

  // Helpers to handle device attach event.
  virtual void HandleDeviceAttachEvent(const base::string16& pnp_device_id);
  void OnDidHandleDeviceAttachEvent(const DeviceDetails* device_details,
                                    const bool result);

  // Handles the detach event of the device specified by |pnp_device_id|.
  void HandleDeviceDetachEvent(const base::string16& pnp_device_id);

  // The portable device notifications handle.
  HDEVNOTIFY notifications_;

  // Attached media transfer protocol device map.
  MTPDeviceMap device_map_;

  // Attached media transfer protocol device storage objects map.
  MTPStorageMap storage_map_;

  // The task runner used to execute tasks that may take a long time and thus
  // should not be performed on the UI thread.
  scoped_refptr<base::SequencedTaskRunner> media_task_runner_;

  // The notifications object to use to signal newly attached devices.
  StorageMonitor::Receiver* storage_notifications_;

  // Used by |media_task_runner_| to create cancelable callbacks.
  base::WeakPtrFactory<PortableDeviceWatcherWin> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(PortableDeviceWatcherWin);
};

}  // namespace storage_monitor

#endif  // COMPONENTS_STORAGE_MONITOR_PORTABLE_DEVICE_WATCHER_WIN_H_