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.
5 #include "chrome/browser/storage_monitor/image_capture_device_manager.h"
7 #import <ImageCaptureCore/ImageCaptureCore.h>
9 #include "base/file_util.h"
10 #import "chrome/browser/storage_monitor/image_capture_device.h"
11 #include "chrome/browser/storage_monitor/media_storage_util.h"
12 #include "content/public/browser/browser_thread.h"
16 chrome::ImageCaptureDeviceManager* g_image_capture_device_manager = NULL;
20 // This class is the surface for the Mac ICDeviceBrowser ImageCaptureCore API.
21 // Owned by the ChromeBrowserParts and has browser process lifetime. Upon
22 // creation, it gets a list of attached media volumes (asynchronously) which
23 // it will eventually forward to StorageMonitor. It will also
24 // set up an ImageCaptureCore listener to be told when new devices/volumes
25 // are discovered and existing ones are removed.
26 @interface ImageCaptureDeviceManagerImpl
27 : NSObject<ICDeviceBrowserDelegate> {
29 scoped_nsobject<ICDeviceBrowser> deviceBrowser_;
30 scoped_nsobject<NSMutableArray> cameras_;
32 // Guaranteed to outlive this class.
33 // TODO(gbillock): Update when ownership chains go up through
34 // a StorageMonitor subclass.
35 chrome::StorageMonitor::Receiver* notifications_;
38 - (void)setNotifications:(chrome::StorageMonitor::Receiver*)notifications;
41 // The UUIDs passed here are available in the device attach notifications.
42 // They're gotten by cracking the device ID and taking the unique ID output.
43 - (ImageCaptureDevice*)deviceForUUID:(const std::string&)uuid;
47 @implementation ImageCaptureDeviceManagerImpl
50 if ((self = [super init])) {
51 cameras_.reset([[NSMutableArray alloc] init]);
52 notifications_ = NULL;
54 deviceBrowser_.reset([[ICDeviceBrowser alloc] init]);
55 [deviceBrowser_ setDelegate:self];
56 [deviceBrowser_ setBrowsedDeviceTypeMask:
57 [deviceBrowser_ browsedDeviceTypeMask] |
58 ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal];
59 [deviceBrowser_ start];
64 - (void)setNotifications:(chrome::StorageMonitor::Receiver*)notifications {
65 notifications_ = notifications;
69 [deviceBrowser_ setDelegate:nil];
70 [deviceBrowser_ stop];
71 deviceBrowser_.reset();
75 - (ImageCaptureDevice*) deviceForUUID:(const std::string&)uuid {
76 for (ICCameraDevice* camera in cameras_.get()) {
77 NSString* camera_id = [camera UUIDString];
78 if (base::SysNSStringToUTF8(camera_id) == uuid) {
79 return [[[ImageCaptureDevice alloc]
80 initWithCameraDevice:camera] autorelease];
86 - (void)deviceBrowser:(ICDeviceBrowser*)browser
87 didAddDevice:(ICDevice*)addedDevice
88 moreComing:(BOOL)moreComing {
89 if (!(addedDevice.type & ICDeviceTypeCamera))
92 // Ignore mass storage attaches -- those will be handled
93 // by Mac's removable storage watcher.
94 if ([addedDevice.transportType isEqualToString:ICTransportTypeMassStorage])
97 ICCameraDevice* cameraDevice =
98 base::mac::ObjCCastStrict<ICCameraDevice>(addedDevice);
100 [cameras_ addObject:addedDevice];
102 // TODO(gbillock): use [cameraDevice mountPoint] here when possible.
103 chrome::StorageInfo info(
104 chrome::MediaStorageUtil::MakeDeviceId(
105 chrome::MediaStorageUtil::MAC_IMAGE_CAPTURE,
106 base::SysNSStringToUTF8([cameraDevice UUIDString])),
107 base::SysNSStringToUTF16([cameraDevice name]),
113 notifications_->ProcessAttach(info);
116 - (void)deviceBrowser:(ICDeviceBrowser*)browser
117 didRemoveDevice:(ICDevice*)device
118 moreGoing:(BOOL)moreGoing {
119 if (!(device.type & ICDeviceTypeCamera))
122 std::string uuid = base::SysNSStringToUTF8([device UUIDString]);
124 // May delete |device|.
125 [cameras_ removeObject:device];
127 notifications_->ProcessDetach(
128 chrome::MediaStorageUtil::MakeDeviceId(
129 chrome::MediaStorageUtil::MAC_IMAGE_CAPTURE, uuid));
132 @end // ImageCaptureDeviceManagerImpl
136 ImageCaptureDeviceManager::ImageCaptureDeviceManager() {
137 device_browser_.reset([[ImageCaptureDeviceManagerImpl alloc] init]);
138 g_image_capture_device_manager = this;
141 ImageCaptureDeviceManager::~ImageCaptureDeviceManager() {
142 g_image_capture_device_manager = NULL;
143 [device_browser_ close];
146 void ImageCaptureDeviceManager::SetNotifications(
147 StorageMonitor::Receiver* notifications) {
148 [device_browser_ setNotifications:notifications];
152 ImageCaptureDevice* ImageCaptureDeviceManager::deviceForUUID(
153 const std::string& uuid) {
154 ImageCaptureDeviceManagerImpl* manager =
155 g_image_capture_device_manager->device_browser_;
156 return [manager deviceForUUID:uuid];
159 id<ICDeviceBrowserDelegate> ImageCaptureDeviceManager::device_browser() {
160 return device_browser_.get();
163 } // namespace chrome