Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / storage_monitor / image_capture_device_manager.mm
blob7ed8b5fe243ab49f686a46f38c2ed0b05075a27e
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 #import "chrome/browser/storage_monitor/image_capture_device.h"
10 #include "chrome/browser/storage_monitor/storage_info.h"
11 #include "content/public/browser/browser_thread.h"
13 namespace {
15 ImageCaptureDeviceManager* g_image_capture_device_manager = NULL;
17 }  // namespace
19 // This class is the surface for the Mac ICDeviceBrowser ImageCaptureCore API.
20 // Owned by the ChromeBrowserParts and has browser process lifetime. Upon
21 // creation, it gets a list of attached media volumes (asynchronously) which
22 // it will eventually forward to StorageMonitor. It will also
23 // set up an ImageCaptureCore listener to be told when new devices/volumes
24 // are discovered and existing ones are removed.
25 @interface ImageCaptureDeviceManagerImpl
26     : NSObject<ICDeviceBrowserDelegate> {
27  @private
28   base::scoped_nsobject<ICDeviceBrowser> deviceBrowser_;
29   base::scoped_nsobject<NSMutableArray> cameras_;
31   // Guaranteed to outlive this class.
32   // TODO(gbillock): Update when ownership chains go up through
33   // a StorageMonitor subclass.
34   StorageMonitor::Receiver* notifications_;
37 - (void)setNotifications:(StorageMonitor::Receiver*)notifications;
38 - (void)close;
40 // The UUIDs passed here are available in the device attach notifications.
41 // They're gotten by cracking the device ID and taking the unique ID output.
42 - (ImageCaptureDevice*)deviceForUUID:(const std::string&)uuid;
44 @end
46 @implementation ImageCaptureDeviceManagerImpl
48 - (id)init {
49   if ((self = [super init])) {
50     cameras_.reset([[NSMutableArray alloc] init]);
51     notifications_ = NULL;
53     deviceBrowser_.reset([[ICDeviceBrowser alloc] init]);
54     [deviceBrowser_ setDelegate:self];
55     [deviceBrowser_ setBrowsedDeviceTypeMask:
56         ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal];
57     [deviceBrowser_ start];
58   }
59   return self;
62 - (void)setNotifications:(StorageMonitor::Receiver*)notifications {
63   notifications_ = notifications;
66 - (void)close {
67   [deviceBrowser_ setDelegate:nil];
68   [deviceBrowser_ stop];
69   deviceBrowser_.reset();
70   cameras_.reset();
73 - (ImageCaptureDevice*) deviceForUUID:(const std::string&)uuid {
74   for (ICCameraDevice* camera in cameras_.get()) {
75     NSString* camera_id = [camera UUIDString];
76     if (base::SysNSStringToUTF8(camera_id) == uuid) {
77       return [[[ImageCaptureDevice alloc]
78           initWithCameraDevice:camera] autorelease];
79     }
80   }
81   return nil;
84 - (void)deviceBrowser:(ICDeviceBrowser*)browser
85          didAddDevice:(ICDevice*)addedDevice
86            moreComing:(BOOL)moreComing {
87   if (!(addedDevice.type & ICDeviceTypeCamera))
88     return;
90   // Ignore mass storage attaches -- those will be handled
91   // by Mac's removable storage watcher.
92   if ([addedDevice.transportType isEqualToString:ICTransportTypeMassStorage])
93     return;
95   ICCameraDevice* cameraDevice =
96       base::mac::ObjCCastStrict<ICCameraDevice>(addedDevice);
98   [cameras_ addObject:addedDevice];
100   // TODO(gbillock): use [cameraDevice mountPoint] here when possible.
101   StorageInfo info(
102       StorageInfo::MakeDeviceId(
103           StorageInfo::MAC_IMAGE_CAPTURE,
104           base::SysNSStringToUTF8([cameraDevice UUIDString])),
105       base::SysNSStringToUTF16([cameraDevice name]),
106       "",
107       base::SysNSStringToUTF16([cameraDevice name]),
108       base::string16(),
109       base::string16(),
110       0);
111   notifications_->ProcessAttach(info);
114 - (void)deviceBrowser:(ICDeviceBrowser*)browser
115       didRemoveDevice:(ICDevice*)device
116             moreGoing:(BOOL)moreGoing {
117   if (!(device.type & ICDeviceTypeCamera))
118     return;
120   std::string uuid = base::SysNSStringToUTF8([device UUIDString]);
122   // May delete |device|.
123   [cameras_ removeObject:device];
125   notifications_->ProcessDetach(
126       StorageInfo::MakeDeviceId(StorageInfo::MAC_IMAGE_CAPTURE, uuid));
129 @end  // ImageCaptureDeviceManagerImpl
131 ImageCaptureDeviceManager::ImageCaptureDeviceManager() {
132   device_browser_.reset([[ImageCaptureDeviceManagerImpl alloc] init]);
133   g_image_capture_device_manager = this;
136 ImageCaptureDeviceManager::~ImageCaptureDeviceManager() {
137   g_image_capture_device_manager = NULL;
138   [device_browser_ close];
141 void ImageCaptureDeviceManager::SetNotifications(
142     StorageMonitor::Receiver* notifications) {
143   [device_browser_ setNotifications:notifications];
146 void ImageCaptureDeviceManager::EjectDevice(
147     const std::string& uuid,
148     base::Callback<void(StorageMonitor::EjectStatus)> callback) {
149   base::scoped_nsobject<ImageCaptureDevice> camera_device(
150       [[device_browser_ deviceForUUID:uuid] retain]);
151   [camera_device eject];
152   [camera_device close];
153   callback.Run(StorageMonitor::EJECT_OK);
156 // static
157 ImageCaptureDevice* ImageCaptureDeviceManager::deviceForUUID(
158     const std::string& uuid) {
159   ImageCaptureDeviceManagerImpl* manager =
160       g_image_capture_device_manager->device_browser_;
161   return [manager deviceForUUID:uuid];
164 id<ICDeviceBrowserDelegate> ImageCaptureDeviceManager::device_browser() {
165   return device_browser_.get();