Add a function to create a bookmark app from a WebApplicationInfo.
[chromium-blink-merge.git] / components / storage_monitor / storage_monitor_win.cc
blobfb721bb3284826999bde409d67109cff8699cb6b
1 // Copyright 2014 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.
5 #include "components/storage_monitor/storage_monitor_win.h"
7 #include <windows.h>
8 #include <dbt.h>
9 #include <fileapi.h>
11 #include "base/win/wrapped_window_proc.h"
12 #include "components/storage_monitor/portable_device_watcher_win.h"
13 #include "components/storage_monitor/removable_device_constants.h"
14 #include "components/storage_monitor/storage_info.h"
15 #include "components/storage_monitor/volume_mount_watcher_win.h"
17 // StorageMonitorWin -------------------------------------------------------
19 namespace storage_monitor {
21 StorageMonitorWin::StorageMonitorWin(
22 VolumeMountWatcherWin* volume_mount_watcher,
23 PortableDeviceWatcherWin* portable_device_watcher)
24 : window_class_(0),
25 instance_(NULL),
26 window_(NULL),
27 volume_mount_watcher_(volume_mount_watcher),
28 portable_device_watcher_(portable_device_watcher) {
29 DCHECK(volume_mount_watcher_);
30 DCHECK(portable_device_watcher_);
31 volume_mount_watcher_->SetNotifications(receiver());
32 portable_device_watcher_->SetNotifications(receiver());
35 StorageMonitorWin::~StorageMonitorWin() {
36 volume_mount_watcher_->SetNotifications(NULL);
37 portable_device_watcher_->SetNotifications(NULL);
39 if (window_)
40 DestroyWindow(window_);
42 if (window_class_)
43 UnregisterClass(MAKEINTATOM(window_class_), instance_);
46 void StorageMonitorWin::Init() {
47 WNDCLASSEX window_class;
48 base::win::InitializeWindowClass(
49 L"Chrome_StorageMonitorWindow",
50 &base::win::WrappedWindowProc<StorageMonitorWin::WndProcThunk>,
51 0, 0, 0, NULL, NULL, NULL, NULL, NULL,
52 &window_class);
53 instance_ = window_class.hInstance;
54 window_class_ = RegisterClassEx(&window_class);
55 DCHECK(window_class_);
57 window_ = CreateWindow(MAKEINTATOM(window_class_), 0, 0, 0, 0, 0, 0, 0, 0,
58 instance_, 0);
59 SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
60 volume_mount_watcher_->Init();
61 portable_device_watcher_->Init(window_);
64 bool StorageMonitorWin::GetStorageInfoForPath(const base::FilePath& path,
65 StorageInfo* device_info) const {
66 DCHECK(device_info);
68 // TODO(gbillock): Move this logic up to StorageMonitor.
69 // If we already know the StorageInfo for the path, just return it.
70 // This will account for portable devices as well.
71 std::vector<StorageInfo> attached_devices = GetAllAvailableStorages();
72 size_t best_parent = attached_devices.size();
73 size_t best_length = 0;
74 for (size_t i = 0; i < attached_devices.size(); i++) {
75 if (!StorageInfo::IsRemovableDevice(attached_devices[i].device_id()))
76 continue;
77 base::FilePath relative;
78 if (base::FilePath(attached_devices[i].location()).AppendRelativePath(
79 path, &relative)) {
80 // Note: the relative path is longer for shorter shared path between
81 // the path and the device mount point, so we want the shortest
82 // relative path.
83 if (relative.value().size() < best_length) {
84 best_parent = i;
85 best_length = relative.value().size();
89 if (best_parent != attached_devices.size()) {
90 *device_info = attached_devices[best_parent];
91 return true;
94 return GetDeviceInfo(path, device_info);
97 void StorageMonitorWin::EjectDevice(
98 const std::string& device_id,
99 base::Callback<void(EjectStatus)> callback) {
100 StorageInfo::Type type;
101 if (!StorageInfo::CrackDeviceId(device_id, &type, NULL)) {
102 callback.Run(EJECT_FAILURE);
103 return;
106 if (type == StorageInfo::MTP_OR_PTP)
107 portable_device_watcher_->EjectDevice(device_id, callback);
108 else if (StorageInfo::IsRemovableDevice(device_id))
109 volume_mount_watcher_->EjectDevice(device_id, callback);
110 else
111 callback.Run(EJECT_FAILURE);
114 bool StorageMonitorWin::GetMTPStorageInfoFromDeviceId(
115 const std::string& storage_device_id,
116 base::string16* device_location,
117 base::string16* storage_object_id) const {
118 StorageInfo::Type type;
119 StorageInfo::CrackDeviceId(storage_device_id, &type, NULL);
120 return ((type == StorageInfo::MTP_OR_PTP) &&
121 portable_device_watcher_->GetMTPStorageInfoFromDeviceId(
122 storage_device_id, device_location, storage_object_id));
125 // static
126 LRESULT CALLBACK StorageMonitorWin::WndProcThunk(HWND hwnd, UINT message,
127 WPARAM wparam, LPARAM lparam) {
128 StorageMonitorWin* msg_wnd = reinterpret_cast<StorageMonitorWin*>(
129 GetWindowLongPtr(hwnd, GWLP_USERDATA));
130 if (msg_wnd)
131 return msg_wnd->WndProc(hwnd, message, wparam, lparam);
132 return ::DefWindowProc(hwnd, message, wparam, lparam);
135 LRESULT CALLBACK StorageMonitorWin::WndProc(HWND hwnd, UINT message,
136 WPARAM wparam, LPARAM lparam) {
137 switch (message) {
138 case WM_DEVICECHANGE:
139 OnDeviceChange(static_cast<UINT>(wparam), lparam);
140 return TRUE;
141 default:
142 break;
145 return ::DefWindowProc(hwnd, message, wparam, lparam);
148 bool StorageMonitorWin::GetDeviceInfo(const base::FilePath& device_path,
149 StorageInfo* info) const {
150 DCHECK(info);
152 // TODO(kmadhusu) Implement PortableDeviceWatcherWin::GetDeviceInfo()
153 // function when we have the functionality to add a sub directory of
154 // portable device as a media gallery.
155 return volume_mount_watcher_->GetDeviceInfo(device_path, info);
158 void StorageMonitorWin::OnDeviceChange(UINT event_type, LPARAM data) {
159 volume_mount_watcher_->OnWindowMessage(event_type, data);
160 portable_device_watcher_->OnWindowMessage(event_type, data);
163 StorageMonitor* StorageMonitor::CreateInternal() {
164 return new StorageMonitorWin(new VolumeMountWatcherWin(),
165 new PortableDeviceWatcherWin());
168 } // namespace storage_monitor