Index: chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h |
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h |
index c0332a0c204a4df2fcc0eb48a3960910a7215c24..197aba2766ab4fa29fcc5d15d2b44608d4dbc597 100644 |
--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h |
+++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h |
@@ -8,22 +8,30 @@ |
#include "chrome/common/extensions/api/image_writer_private.h" |
#include "chrome/common/ref_counted_util.h" |
+#if defined(OS_MACOSX) |
+#include <CoreFoundation/CoreFoundation.h> |
+#include <DiskArbitration/DiskArbitration.h> |
+ |
+#include "base/mac/foundation_util.h" |
+#include "base/memory/weak_ptr.h" |
+#endif |
+ |
namespace extensions { |
// TODO(haven): Clean up this class to remove refcounting. http://crbug/370590 |
-typedef RefCountedVector<linked_ptr |
- <api::image_writer_private::RemovableStorageDevice> > StorageDeviceList; |
+typedef RefCountedVector<linked_ptr< |
+ api::image_writer_private::RemovableStorageDevice> > StorageDeviceList; |
+typedef base::Callback<void(scoped_refptr<StorageDeviceList>, bool)> |
+ DeviceListReadyCallback; |
// Abstraction for platform specific implementations of listing removable |
// storage devices |
class RemovableStorageProvider { |
public: |
- typedef base::Callback<void(scoped_refptr<StorageDeviceList>, bool)> |
- DeviceListReadyCallback; |
// Gets the list of all available devices and returns it via callback. |
- static void GetAllDevices(DeviceListReadyCallback callback); |
+ static void GetAllDevices(const DeviceListReadyCallback& callback); |
// Sets the list of devices that will be returned by GetAllDevices during |
// testing. All calls to |GetAllDevices| will return this list until |
@@ -34,9 +42,79 @@ class RemovableStorageProvider { |
static void ClearDeviceListForTesting(); |
private: |
- // Fills the provided empty device list with the available devices. |
- static bool PopulateDeviceList(scoped_refptr<StorageDeviceList> device_list); |
+ // This is the actual implementation of the logic, which will be skipped if a |
+ // testing value is set. |
+ static void GetAllDevicesImpl(const DeviceListReadyCallback& callback); |
+}; |
+ |
+#if defined(OS_MACOSX) |
+// A wrapper around the DiskArbitration state. |
+// |
+// Listing devices on OS X involves asynchronous callbacks through the Disk |
+// Arbitration framework. This class serves to wrap up that state and maintain |
+// it while we still have outstanding calls expected. |
+class DAWrapper : public base::SupportsWeakPtr<DAWrapper> { |
Robert Sesek
2014/06/02 19:56:05
A better name for this would be RemovableStoragePr
Drew Haven
2014/06/03 02:03:23
I think I originally put this here just to make it
|
+ public: |
+ DAWrapper(); |
+ virtual ~DAWrapper(); |
+ |
+ // Gets the list of all available devices and returns it via callback. |
+ void GetDeviceList(const DeviceListReadyCallback& callback); |
+ |
+ // A wrapper for DeviceListReadyCallbacks which will delete the wrapper when |
+ // it is fired. |
+ static void WrapperDeleter(DAWrapper* wrapper, |
+ const DeviceListReadyCallback& callback, |
+ scoped_refptr<StorageDeviceList> device_list, |
+ bool success); |
+ |
+ private: |
+ // A testing spouse. |
+ friend class DAWrapperSpouse; |
+ |
+ // Processes a disk-appeared event. This increments |updates_pending_| and |
+ // then posts a task to AddDisk. This is so we can collect all the immediate |
+ // disk-appeared events and know how many we need to process and thus when to |
+ // call the callback. Operates on the disk-description dictionary. |
+ void ProcessDisk(base::ScopedCFTypeRef<CFDictionaryRef> dict); |
+ // Adds a disk to the disk_list. Decrements |updates_pending_| and triggers |
+ // the callback when it reaches zero. Operates on the disk-description |
+ // dictionary. |
+ void AddDisk(base::ScopedCFTypeRef<CFDictionaryRef> dict); |
+ // Responds to a disk-appeared event. |
+ static void DiskAppearedCallback(DADiskRef disk, void* context); |
+ // Responds to a disk-disappeared event. |
+ static void DiskDisappearedCallback(DADiskRef disk, void* context); |
+ // Checks whether the disk description in |dict| is a valid removable device. |
+ static bool DiskIsValidTarget(CFDictionaryRef dict); |
+ |
+ int updates_pending_; |
+ scoped_refptr<StorageDeviceList> device_list_; |
+ DeviceListReadyCallback callback_; |
+ base::ScopedCFTypeRef<DASessionRef> session_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DAWrapper); |
+}; |
+ |
+// A testing spouse for |DAWrapper|. |
+class DAWrapperSpouse { |
Robert Sesek
2014/06/02 19:56:05
This does not belong in a public .h file.
Drew Haven
2014/06/03 02:03:23
Moved to test_utils.h
|
+ public: |
+ explicit DAWrapperSpouse(DAWrapper* spouse); |
+ virtual ~DAWrapperSpouse(); |
+ |
+ // Sets the |callback_| of the |DAWrapper|. |
+ void SetCallback(const DeviceListReadyCallback& callback); |
+ // Sets the current |device_list_| of the |DAWrapper|. |
+ void SetDeviceList(scoped_refptr<StorageDeviceList> device_list); |
+ // Triggers |ProcessDisk| on the |DAWrapper|. |
+ void ProcessDisk(base::ScopedCFTypeRef<CFDictionaryRef> dict); |
+ // runs |DiskIsValidTarget| on the |DAWrapper|. |
+ static bool DiskIsValidTarget(CFDictionaryRef dict); |
+ |
+ private: |
+ DAWrapper* spouse_; |
}; |
+#endif |
} // namespace extensions |