OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/intents/device_attached_intent_source.h" | 5 #include "chrome/browser/intents/device_attached_intent_source.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/bind.h" |
9 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| 11 #include "base/string16.h" |
| 12 #include "base/memory/ref_counted.h" |
10 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/intents/web_intents_registry.h" |
| 15 #include "chrome/browser/intents/web_intents_registry_factory.h" |
| 16 #include "chrome/browser/profiles/profile.h" |
11 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
12 #include "chrome/browser/ui/browser_window.h" | 18 #include "chrome/browser/ui/browser_window.h" |
13 #include "content/public/browser/web_intents_dispatcher.h" | 19 #include "content/public/browser/web_intents_dispatcher.h" |
14 #include "content/public/browser/web_contents_delegate.h" | 20 #include "content/public/browser/web_contents_delegate.h" |
15 #include "webkit/fileapi/file_system_types.h" | 21 #include "webkit/fileapi/file_system_types.h" |
16 #include "webkit/fileapi/isolated_context.h" | 22 #include "webkit/fileapi/isolated_context.h" |
17 #include "webkit/glue/web_intent_data.h" | 23 #include "webkit/glue/web_intent_data.h" |
| 24 #include "webkit/glue/web_intent_service_data.h" |
18 #include "webkit/fileapi/media/media_file_system_config.h" | 25 #include "webkit/fileapi/media/media_file_system_config.h" |
19 | 26 |
20 #if defined(SUPPORT_MEDIA_FILESYSTEM) | 27 #if defined(SUPPORT_MEDIA_FILESYSTEM) |
21 #include "webkit/fileapi/media/media_device_map_service.h" | 28 #include "webkit/fileapi/media/media_device_map_service.h" |
22 | 29 |
23 using fileapi::MediaDeviceMapService; | 30 using fileapi::MediaDeviceMapService; |
24 #endif | 31 #endif |
25 | 32 |
26 using base::SystemMonitor; | 33 using base::SystemMonitor; |
27 using content::WebContentsDelegate; | 34 using content::WebContentsDelegate; |
| 35 using webkit_glue::WebIntentServiceData; |
| 36 |
| 37 namespace { |
| 38 |
| 39 // Specifies device attached web intent kAction. |
| 40 const char kAction[] = "chrome-extension://attach"; |
| 41 |
| 42 // Specifies device attached web intent type. |
| 43 const char kIntentType[] = "chrome-extension://filesystem"; |
| 44 |
| 45 // Dispatch intent only when there is a list of registered services. This is a |
| 46 // helper class that stores the attached media device information and decides |
| 47 // whether to dispatch an intent or not. |
| 48 class DispatchIntentTaskHelper |
| 49 : public base::RefCountedThreadSafe<DispatchIntentTaskHelper> { |
| 50 public: |
| 51 DispatchIntentTaskHelper( |
| 52 const base::WeakPtr<DeviceAttachedIntentSource> source, |
| 53 SystemMonitor::MediaDeviceInfo device_info) |
| 54 : source_(source), |
| 55 device_info_(device_info) { |
| 56 } |
| 57 |
| 58 // Query callback for WebIntentsRegistry::GetIntentServices function. |
| 59 void MayDispatchIntentForService( |
| 60 const std::vector<WebIntentServiceData>& services) { |
| 61 if (!services.empty() && source_) |
| 62 source_->DispatchIntentsForService(device_info_); |
| 63 } |
| 64 |
| 65 private: |
| 66 friend class base::RefCountedThreadSafe<DispatchIntentTaskHelper>; |
| 67 |
| 68 ~DispatchIntentTaskHelper() {} |
| 69 |
| 70 // A weak pointer to |DeviceAttachedIntentSource| object to dispatch a |
| 71 // web intent. |
| 72 base::WeakPtr<DeviceAttachedIntentSource> source_; |
| 73 |
| 74 // Store the device info. This is used while registering the device as file |
| 75 // system. |
| 76 const SystemMonitor::MediaDeviceInfo device_info_; |
| 77 |
| 78 DISALLOW_COPY_AND_ASSIGN(DispatchIntentTaskHelper); |
| 79 }; |
| 80 |
| 81 } // namespace |
28 | 82 |
29 DeviceAttachedIntentSource::DeviceAttachedIntentSource( | 83 DeviceAttachedIntentSource::DeviceAttachedIntentSource( |
30 Browser* browser, WebContentsDelegate* delegate) | 84 Browser* browser, WebContentsDelegate* delegate) |
31 : browser_(browser), delegate_(delegate) { | 85 : browser_(browser), delegate_(delegate) { |
32 SystemMonitor* sys_monitor = SystemMonitor::Get(); | 86 SystemMonitor* sys_monitor = SystemMonitor::Get(); |
33 if (sys_monitor) | 87 if (sys_monitor) |
34 sys_monitor->AddDevicesChangedObserver(this); | 88 sys_monitor->AddDevicesChangedObserver(this); |
35 } | 89 } |
36 | 90 |
37 DeviceAttachedIntentSource::~DeviceAttachedIntentSource() { | 91 DeviceAttachedIntentSource::~DeviceAttachedIntentSource() { |
38 SystemMonitor* sys_monitor = SystemMonitor::Get(); | 92 SystemMonitor* sys_monitor = SystemMonitor::Get(); |
39 if (sys_monitor) | 93 if (sys_monitor) |
40 sys_monitor->RemoveDevicesChangedObserver(this); | 94 sys_monitor->RemoveDevicesChangedObserver(this); |
41 } | 95 } |
42 | 96 |
43 void DeviceAttachedIntentSource::OnMediaDeviceAttached( | 97 void DeviceAttachedIntentSource::OnMediaDeviceAttached( |
44 const std::string& id, | 98 const std::string& id, |
45 const string16& name, | 99 const string16& name, |
46 base::SystemMonitor::MediaDeviceType type, | 100 base::SystemMonitor::MediaDeviceType device_type, |
47 const FilePath::StringType& location) { | 101 const FilePath::StringType& location) { |
48 if (!browser_->window()->IsActive()) | 102 if (!browser_->window()->IsActive()) |
49 return; | 103 return; |
50 | 104 |
| 105 // TODO(kmadhusu): Dispatch intents on incognito window. |
| 106 if (browser_->profile()->IsOffTheRecord()) |
| 107 return; |
| 108 |
51 // Only handle FilePaths for now. | 109 // Only handle FilePaths for now. |
52 // TODO(kmadhusu): Handle all device types. http://crbug.com/140353. | 110 // TODO(kmadhusu): Handle all device types. http://crbug.com/140353. |
53 if (type != SystemMonitor::TYPE_PATH) | 111 if (device_type != SystemMonitor::TYPE_PATH) |
54 return; | 112 return; |
55 | 113 |
56 // Sanity checks for |device_path|. | 114 // Sanity checks for |device_path|. |
57 const FilePath device_path(location); | 115 const FilePath device_path(location); |
58 if (!device_path.IsAbsolute() || device_path.ReferencesParent()) | 116 if (!device_path.IsAbsolute() || device_path.ReferencesParent()) |
59 return; | 117 return; |
60 | 118 |
| 119 SystemMonitor::MediaDeviceInfo device_info(id, name, device_type, location); |
| 120 scoped_refptr<DispatchIntentTaskHelper> task = new DispatchIntentTaskHelper( |
| 121 AsWeakPtr(), device_info); |
| 122 WebIntentsRegistryFactory::GetForProfile(browser_->profile())-> |
| 123 GetIntentServices( |
| 124 UTF8ToUTF16(kAction), UTF8ToUTF16(kIntentType), |
| 125 base::Bind(&DispatchIntentTaskHelper::MayDispatchIntentForService, |
| 126 task.get())); |
| 127 } |
| 128 |
| 129 void DeviceAttachedIntentSource::DispatchIntentsForService( |
| 130 const base::SystemMonitor::MediaDeviceInfo& device_info) { |
61 // Store the media device info locally. | 131 // Store the media device info locally. |
62 SystemMonitor::MediaDeviceInfo device_info(id, name, type, location); | 132 device_id_map_.insert(std::make_pair(device_info.unique_id, device_info)); |
63 device_id_map_.insert(std::make_pair(id, device_info)); | |
64 | 133 |
65 std::string device_name(UTF16ToUTF8(name)); | 134 std::string device_name(UTF16ToUTF8(device_info.name)); |
| 135 const FilePath device_path(device_info.location); |
66 | 136 |
67 // Register device path as an isolated file system. | |
68 // TODO(kinuko, kmadhusu): Use a different file system type for MTP. | 137 // TODO(kinuko, kmadhusu): Use a different file system type for MTP. |
69 const std::string filesystem_id = | 138 const std::string fs_id = fileapi::IsolatedContext::GetInstance()-> |
70 fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath( | 139 RegisterFileSystemForPath(fileapi::kFileSystemTypeNativeMedia, |
71 fileapi::kFileSystemTypeNativeMedia, device_path, &device_name); | 140 device_path, &device_name); |
72 | 141 |
73 CHECK(!filesystem_id.empty()); | 142 DCHECK(!fs_id.empty()); |
74 webkit_glue::WebIntentData intent( | 143 webkit_glue::WebIntentData intent( |
75 ASCIIToUTF16("chrome-extension://attach"), | 144 UTF8ToUTF16(kAction), UTF8ToUTF16(kIntentType), device_name, fs_id); |
76 ASCIIToUTF16("chrome-extension://filesystem"), | |
77 device_name, | |
78 filesystem_id); | |
79 | 145 |
80 delegate_->WebIntentDispatch(NULL /* no WebContents */, | 146 delegate_->WebIntentDispatch(NULL /* no WebContents */, |
81 content::WebIntentsDispatcher::Create(intent)); | 147 content::WebIntentsDispatcher::Create(intent)); |
82 } | 148 } |
83 | 149 |
84 void DeviceAttachedIntentSource::OnMediaDeviceDetached(const std::string& id) { | 150 void DeviceAttachedIntentSource::OnMediaDeviceDetached(const std::string& id) { |
85 DeviceIdToInfoMap::iterator it = device_id_map_.find(id); | 151 DeviceIdToInfoMap::iterator it = device_id_map_.find(id); |
86 if (it == device_id_map_.end()) | 152 if (it == device_id_map_.end()) |
87 return; | 153 return; |
88 | 154 |
89 // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340. | 155 // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340. |
90 | 156 |
91 FilePath path(it->second.location); | 157 FilePath path(it->second.location); |
92 fileapi::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path); | 158 fileapi::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path); |
93 switch (it->second.type) { | 159 switch (it->second.type) { |
94 case SystemMonitor::TYPE_MTP: | 160 case SystemMonitor::TYPE_MTP: |
95 #if defined(SUPPORT_MEDIA_FILESYSTEM) | 161 #if defined(SUPPORT_MEDIA_FILESYSTEM) |
96 MediaDeviceMapService::GetInstance()->RemoveMediaDevice( | 162 MediaDeviceMapService::GetInstance()->RemoveMediaDevice( |
97 it->second.location); | 163 it->second.location); |
98 #endif | 164 #endif |
99 break; | 165 break; |
100 case SystemMonitor::TYPE_PATH: | 166 case SystemMonitor::TYPE_PATH: |
101 break; | 167 break; |
102 } | 168 } |
103 device_id_map_.erase(it); | 169 device_id_map_.erase(it); |
104 } | 170 } |
OLD | NEW |