diff options
author | gbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-09 03:39:40 +0000 |
---|---|---|
committer | gbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-09 03:39:40 +0000 |
commit | 292179322e42f0e8c7726b1d6ce50e334a0ef199 (patch) | |
tree | 92e5c2f01997803e649ef4f3451afe3446138bce /chrome/browser/storage_monitor | |
parent | 411e5405ea74b5d76838f92b5adce1d6055f6e93 (diff) | |
download | chromium_src-292179322e42f0e8c7726b1d6ce50e334a0ef199.zip chromium_src-292179322e42f0e8c7726b1d6ce50e334a0ef199.tar.gz chromium_src-292179322e42f0e8c7726b1d6ce50e334a0ef199.tar.bz2 |
[Media Galleries] Support nested directories in Mac PTP.
BUG=144527
Review URL: https://chromiumcodereview.appspot.com/13935004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199093 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/storage_monitor')
3 files changed, 122 insertions, 11 deletions
diff --git a/chrome/browser/storage_monitor/image_capture_device.h b/chrome/browser/storage_monitor/image_capture_device.h index 04c0ef2..71d5736 100644 --- a/chrome/browser/storage_monitor/image_capture_device.h +++ b/chrome/browser/storage_monitor/image_capture_device.h @@ -30,15 +30,18 @@ class ImageCaptureDeviceListener { // Get a notification that a particular item has been found on the device. // These calls will come automatically after a new device is initialized. + // Names are in relative path form, so subdirectories and files in them will + // be passed as "dir/subdir/filename". These same relative filenames should + // be used as keys to download files. virtual void ItemAdded(const std::string& name, const base::PlatformFileInfo& info) = 0; // Called when there are no more items to retrieve. virtual void NoMoreItems() = 0; - // Called upon completion of a file download request. The |path| is the - // requested download file. Note: in NOT_FOUND error case, can be called - // inline with the download request. + // Called upon completion of a file download request. + // Note: in NOT_FOUND error case, may be called inline with the download + // request. virtual void DownloadedFile(const std::string& name, base::PlatformFileError error) = 0; @@ -57,6 +60,7 @@ class ImageCaptureDeviceListener { @private scoped_nsobject<ICCameraDevice> camera_; base::WeakPtr<ImageCaptureDeviceListener> listener_; + bool closing_; } - (id)initWithCameraDevice:(ICCameraDevice*)cameraDevice; @@ -64,8 +68,9 @@ class ImageCaptureDeviceListener { - (void)open; - (void)close; -// Download the given |file| to the provided |local_path|. Completion notice -// will be sent to the listener's DownloadedFile method. +// Download the given file |name| to the provided |local_path|. Completion +// notice will be sent to the listener's DownloadedFile method. The name +// should be of the same form as those sent to the listener's ItemAdded method. - (void)downloadFile:(const std::string&)name localPath:(const base::FilePath&)localPath; diff --git a/chrome/browser/storage_monitor/image_capture_device.mm b/chrome/browser/storage_monitor/image_capture_device.mm index 4f33e4b..a7e45e3 100644 --- a/chrome/browser/storage_monitor/image_capture_device.mm +++ b/chrome/browser/storage_monitor/image_capture_device.mm @@ -33,6 +33,25 @@ base::Time NSDateToBaseTime(NSDate* date) { return base::Time::FromDoubleT([date timeIntervalSince1970]); } +base::FilePath PathForCameraItem(ICCameraItem* item) { + std::string name = base::SysNSStringToUTF8([item name]); + + std::vector<std::string> components; + ICCameraFolder* folder = [item parentFolder]; + while (folder != nil) { + components.push_back(base::SysNSStringToUTF8([folder name])); + folder = [folder parentFolder]; + } + base::FilePath path; + for (std::vector<std::string>::reverse_iterator i = components.rbegin(); + i != components.rend(); ++i) { + path = path.Append(*i); + } + path = path.Append(name); + + return path; +} + } // namespace @implementation ImageCaptureDevice @@ -41,6 +60,7 @@ base::Time NSDateToBaseTime(NSDate* date) { if ((self = [super init])) { camera_.reset([cameraDevice retain]); [camera_ setDelegate:self]; + closing_ = false; } return self; } @@ -66,6 +86,8 @@ base::Time NSDateToBaseTime(NSDate* date) { - (void)close { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + closing_ = true; + [camera_ cancelDownload]; [camera_ requestCloseSession]; [camera_ setDelegate:nil]; listener_.reset(); @@ -74,9 +96,10 @@ base::Time NSDateToBaseTime(NSDate* date) { - (void)downloadFile:(const std::string&)name localPath:(const base::FilePath&)localPath { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + // Find the file with that name and start download. for (ICCameraItem* item in [camera_ mediaFiles]) { - std::string itemName = base::SysNSStringToUTF8([item name]); + std::string itemName = PathForCameraItem(item).value(); if (itemName == name) { // To create save options for ImageCapture, we need to // split the target filename into directory/name @@ -108,18 +131,20 @@ base::Time NSDateToBaseTime(NSDate* date) { } - (void)cameraDevice:(ICCameraDevice*)camera didAddItem:(ICCameraItem*)item { - std::string name = base::SysNSStringToUTF8([item name]); base::PlatformFileInfo info; if ([[item UTI] isEqualToString:base::mac::CFToNSCast(kUTTypeFolder)]) info.is_directory = true; else info.size = [base::mac::ObjCCastStrict<ICCameraFile>(item) fileSize]; + + base::FilePath path = PathForCameraItem(item); + info.last_modified = NSDateToBaseTime([item modificationDate]); info.creation_time = NSDateToBaseTime([item creationDate]); info.last_accessed = info.last_modified; if (listener_) - listener_->ItemAdded(name, info); + listener_->ItemAdded(path.value(), info); } - (void)cameraDevice:(ICCameraDevice*)camera didAddItems:(NSArray*)items { @@ -155,7 +180,10 @@ base::Time NSDateToBaseTime(NSDate* date) { error:(NSError*)error options:(NSDictionary*)options contextInfo:(void*)contextInfo { - std::string name = base::SysNSStringToUTF8([file name]); + if (closing_) + return; + + std::string name = PathForCameraItem(file).value(); if (error) { DLOG(INFO) << "error..." diff --git a/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm b/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm index d6b403e..403458a 100644 --- a/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm +++ b/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm @@ -127,13 +127,43 @@ const char kTestFileContents[] = "test"; @end +@interface MockICCameraFolder : ICCameraFolder { + @private + scoped_nsobject<NSString> name_; +} + +- (id)initWithName:(NSString*)name; + +@end + +@implementation MockICCameraFolder + +- (id)initWithName:(NSString*)name { + if ((self = [super init])) { + name_.reset([name retain]); + } + return self; +} + +- (NSString*)name { + return name_; +} + +- (ICCameraFolder*)parentFolder { + return nil; +} + +@end + @interface MockICCameraFile : ICCameraFile { @private scoped_nsobject<NSString> name_; scoped_nsobject<NSDate> date_; + scoped_nsobject<MockICCameraFolder> parent_; } - (id)init:(NSString*)name; +- (void)setParent:(NSString*)parent; @end @@ -147,8 +177,16 @@ const char kTestFileContents[] = "test"; return self; } +- (void)setParent:(NSString*)parent { + parent_.reset([[MockICCameraFolder alloc] initWithName:parent]); +} + +- (ICCameraFolder*)parentFolder { + return parent_.get(); +} + - (NSString*)name { - return name_.get(); + return name_; } - (NSString*)UTI { @@ -312,7 +350,7 @@ TEST_F(ImageCaptureDeviceManagerTest, RemoveCamera) { } TEST_F(ImageCaptureDeviceManagerTest, DownloadFile) { - scoped_ptr<content::TestBrowserThread> file_thread_( + scoped_ptr<content::TestBrowserThread> file_thread( new content::TestBrowserThread( content::BrowserThread::FILE, &message_loop_)); @@ -368,3 +406,43 @@ TEST_F(ImageCaptureDeviceManagerTest, DownloadFile) { [camera didRemoveDevice:device]; } + +TEST_F(ImageCaptureDeviceManagerTest, TestSubdirectories) { + scoped_ptr<content::TestBrowserThread> file_thread( + new content::TestBrowserThread( + content::BrowserThread::FILE, &message_loop_)); + + chrome::ImageCaptureDeviceManager manager; + manager.SetNotifications(monitor_.receiver()); + MockICCameraDevice* device = AttachDevice(&manager); + + scoped_nsobject<ImageCaptureDevice> camera( + [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId) + retain]); + + [camera setListener:listener_.AsWeakPtr()]; + [camera open]; + + std::string kTestFileName("pic1"); + scoped_nsobject<MockICCameraFile> picture1( + [[MockICCameraFile alloc] + init:base::SysUTF8ToNSString(kTestFileName)]); + [picture1 setParent:base::SysUTF8ToNSString("dir")]; + [device addMediaFile:picture1]; + [camera cameraDevice:nil didAddItem:picture1]; + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath temp_file = temp_dir.path().Append("tempfile"); + + [camera downloadFile:("dir/" + kTestFileName) localPath:temp_file]; + message_loop_.RunUntilIdle(); + + char file_contents[5]; + ASSERT_EQ(4, file_util::ReadFile(temp_file, file_contents, + strlen(kTestFileContents))); + EXPECT_EQ(kTestFileContents, + std::string(file_contents, strlen(kTestFileContents))); + + [camera didRemoveDevice:device]; +} |