Roll libvpx 861f35:1fff3e
[chromium-blink-merge.git] / components / storage_monitor / image_capture_device_manager.mm
blobddff960018c941826e36609298acb191e4af93ac
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/image_capture_device_manager.h"
7 #import <ImageCaptureCore/ImageCaptureCore.h>
9 #import "components/storage_monitor/image_capture_device.h"
10 #include "components/storage_monitor/storage_info.h"
12 namespace {
14 storage_monitor::ImageCaptureDeviceManager* g_image_capture_device_manager =
15     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   storage_monitor::StorageMonitor::Receiver* notifications_;
37 - (void)setNotifications:
38         (storage_monitor::StorageMonitor::Receiver*)notifications;
39 - (void)close;
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;
45 @end
47 @implementation ImageCaptureDeviceManagerImpl
49 - (id)init {
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         ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal];
58     [deviceBrowser_ start];
59   }
60   return self;
63 - (void)setNotifications:
64             (storage_monitor::StorageMonitor::Receiver*)notifications {
65   notifications_ = notifications;
68 - (void)close {
69   [deviceBrowser_ setDelegate:nil];
70   [deviceBrowser_ stop];
71   deviceBrowser_.reset();
72   cameras_.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];
81     }
82   }
83   return nil;
86 - (void)deviceBrowser:(ICDeviceBrowser*)browser
87          didAddDevice:(ICDevice*)addedDevice
88            moreComing:(BOOL)moreComing {
89   if (!(addedDevice.type & ICDeviceTypeCamera))
90     return;
92   // Ignore mass storage attaches -- those will be handled
93   // by Mac's removable storage watcher.
94   if ([addedDevice.transportType isEqualToString:ICTransportTypeMassStorage])
95     return;
97   ICCameraDevice* cameraDevice =
98       base::mac::ObjCCastStrict<ICCameraDevice>(addedDevice);
100   [cameras_ addObject:addedDevice];
102   // TODO(gbillock): use [cameraDevice mountPoint] here when possible.
103   storage_monitor::StorageInfo info(
104       storage_monitor::StorageInfo::MakeDeviceId(
105           storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE,
106           base::SysNSStringToUTF8([cameraDevice UUIDString])),
107       std::string(),
108       base::SysNSStringToUTF16([cameraDevice name]),
109       base::string16(),
110       base::string16(),
111       0);
112   notifications_->ProcessAttach(info);
115 - (void)deviceBrowser:(ICDeviceBrowser*)browser
116       didRemoveDevice:(ICDevice*)device
117             moreGoing:(BOOL)moreGoing {
118   if (!(device.type & ICDeviceTypeCamera))
119     return;
121   std::string uuid = base::SysNSStringToUTF8([device UUIDString]);
123   // May delete |device|.
124   [cameras_ removeObject:device];
126   notifications_->ProcessDetach(storage_monitor::StorageInfo::MakeDeviceId(
127       storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE, uuid));
130 @end  // ImageCaptureDeviceManagerImpl
132 namespace storage_monitor {
134 ImageCaptureDeviceManager::ImageCaptureDeviceManager() {
135   device_browser_.reset([[ImageCaptureDeviceManagerImpl alloc] init]);
136   g_image_capture_device_manager = this;
139 ImageCaptureDeviceManager::~ImageCaptureDeviceManager() {
140   g_image_capture_device_manager = NULL;
141   [device_browser_ close];
144 void ImageCaptureDeviceManager::SetNotifications(
145     StorageMonitor::Receiver* notifications) {
146   [device_browser_ setNotifications:notifications];
149 void ImageCaptureDeviceManager::EjectDevice(
150     const std::string& uuid,
151     base::Callback<void(StorageMonitor::EjectStatus)> callback) {
152   base::scoped_nsobject<ImageCaptureDevice> camera_device(
153       [[device_browser_ deviceForUUID:uuid] retain]);
154   [camera_device eject];
155   [camera_device close];
156   callback.Run(StorageMonitor::EJECT_OK);
159 // static
160 ImageCaptureDevice* ImageCaptureDeviceManager::deviceForUUID(
161     const std::string& uuid) {
162   ImageCaptureDeviceManagerImpl* manager =
163       g_image_capture_device_manager->device_browser_;
164   return [manager deviceForUUID:uuid];
167 id<ICDeviceBrowserDelegate> ImageCaptureDeviceManager::device_browser() {
168   return device_browser_.get();
171 }  // namespace storage_monitor