Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / components / storage_monitor / image_capture_device_manager.mm
blob7ad7dbc2a703bb253bf70d14f5bf217bdc3c71d5
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         static_cast<ICDeviceTypeMask>(
58             ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal)];
59     [deviceBrowser_ start];
60   }
61   return self;
64 - (void)setNotifications:
65             (storage_monitor::StorageMonitor::Receiver*)notifications {
66   notifications_ = notifications;
69 - (void)close {
70   [deviceBrowser_ setDelegate:nil];
71   [deviceBrowser_ stop];
72   deviceBrowser_.reset();
73   cameras_.reset();
76 - (ImageCaptureDevice*) deviceForUUID:(const std::string&)uuid {
77   for (ICCameraDevice* camera in cameras_.get()) {
78     NSString* camera_id = [camera UUIDString];
79     if (base::SysNSStringToUTF8(camera_id) == uuid) {
80       return [[[ImageCaptureDevice alloc]
81           initWithCameraDevice:camera] autorelease];
82     }
83   }
84   return nil;
87 - (void)deviceBrowser:(ICDeviceBrowser*)browser
88          didAddDevice:(ICDevice*)addedDevice
89            moreComing:(BOOL)moreComing {
90   if (!(addedDevice.type & ICDeviceTypeCamera))
91     return;
93   // Ignore mass storage attaches -- those will be handled
94   // by Mac's removable storage watcher.
95   if ([addedDevice.transportType isEqualToString:ICTransportTypeMassStorage])
96     return;
98   ICCameraDevice* cameraDevice =
99       base::mac::ObjCCastStrict<ICCameraDevice>(addedDevice);
101   [cameras_ addObject:addedDevice];
103   // TODO(gbillock): use [cameraDevice mountPoint] here when possible.
104   storage_monitor::StorageInfo info(
105       storage_monitor::StorageInfo::MakeDeviceId(
106           storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE,
107           base::SysNSStringToUTF8([cameraDevice UUIDString])),
108       std::string(),
109       base::SysNSStringToUTF16([cameraDevice name]),
110       base::string16(),
111       base::string16(),
112       0);
113   notifications_->ProcessAttach(info);
116 - (void)deviceBrowser:(ICDeviceBrowser*)browser
117       didRemoveDevice:(ICDevice*)device
118             moreGoing:(BOOL)moreGoing {
119   if (!(device.type & ICDeviceTypeCamera))
120     return;
122   std::string uuid = base::SysNSStringToUTF8([device UUIDString]);
124   // May delete |device|.
125   [cameras_ removeObject:device];
127   notifications_->ProcessDetach(storage_monitor::StorageInfo::MakeDeviceId(
128       storage_monitor::StorageInfo::MAC_IMAGE_CAPTURE, uuid));
131 @end  // ImageCaptureDeviceManagerImpl
133 namespace storage_monitor {
135 ImageCaptureDeviceManager::ImageCaptureDeviceManager() {
136   device_browser_.reset([[ImageCaptureDeviceManagerImpl alloc] init]);
137   g_image_capture_device_manager = this;
140 ImageCaptureDeviceManager::~ImageCaptureDeviceManager() {
141   g_image_capture_device_manager = NULL;
142   [device_browser_ close];
145 void ImageCaptureDeviceManager::SetNotifications(
146     StorageMonitor::Receiver* notifications) {
147   [device_browser_ setNotifications:notifications];
150 void ImageCaptureDeviceManager::EjectDevice(
151     const std::string& uuid,
152     base::Callback<void(StorageMonitor::EjectStatus)> callback) {
153   base::scoped_nsobject<ImageCaptureDevice> camera_device(
154       [[device_browser_ deviceForUUID:uuid] retain]);
155   [camera_device eject];
156   [camera_device close];
157   callback.Run(StorageMonitor::EJECT_OK);
160 // static
161 ImageCaptureDevice* ImageCaptureDeviceManager::deviceForUUID(
162     const std::string& uuid) {
163   ImageCaptureDeviceManagerImpl* manager =
164       g_image_capture_device_manager->device_browser_;
165   return [manager deviceForUUID:uuid];
168 id<ICDeviceBrowserDelegate> ImageCaptureDeviceManager::device_browser() {
169   return device_browser_.get();
172 }  // namespace storage_monitor