diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-03 07:31:12 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-03 07:31:12 +0000 |
commit | cf4b6d6d8a47f92b87674420c11f986239c51f99 (patch) | |
tree | fe4e403a914f00704904bad8bfaa7e9d0a32de6b | |
parent | eca0309696107bfe15da47f43b67c36d6790f1f8 (diff) | |
download | chromium_src-cf4b6d6d8a47f92b87674420c11f986239c51f99.zip chromium_src-cf4b6d6d8a47f92b87674420c11f986239c51f99.tar.gz chromium_src-cf4b6d6d8a47f92b87674420c11f986239c51f99.tar.bz2 |
Isolated FS for Media devices.
Implemented a skeleton code to handle media file systems.
BUG=140332
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10781014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149807 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 888 insertions, 24 deletions
diff --git a/base/system_monitor/system_monitor.cc b/base/system_monitor/system_monitor.cc index 22f91d7..d1dd439 100644 --- a/base/system_monitor/system_monitor.cc +++ b/base/system_monitor/system_monitor.cc @@ -104,8 +104,9 @@ void SystemMonitor::ProcessMediaDeviceAttached( void SystemMonitor::ProcessMediaDeviceDetached(const std::string& id) { MediaDeviceMap::iterator it = media_device_map_.find(id); - if (it != media_device_map_.end()) - media_device_map_.erase(it); + if (it == media_device_map_.end()) + return; + media_device_map_.erase(it); NotifyMediaDeviceDetached(id); } diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system_monitor/system_monitor_unittest.cc index d3a99fb..e724e83 100644 --- a/base/system_monitor/system_monitor_unittest.cc +++ b/base/system_monitor/system_monitor_unittest.cc @@ -131,7 +131,7 @@ TEST_F(SystemMonitorTest, DeviceChangeNotifications) { EXPECT_CALL(observers[index], OnMediaDeviceDetached(kDeviceId1)) .InSequence(mock_sequencer[index]); EXPECT_CALL(observers[index], OnMediaDeviceDetached(kDeviceId2)) - .InSequence(mock_sequencer[index]); + .Times(0).InSequence(mock_sequencer[index]); } system_monitor_->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_UNKNOWN); diff --git a/chrome/browser/intents/device_attached_intent_source.cc b/chrome/browser/intents/device_attached_intent_source.cc index 3a2e5d5..1526606 100644 --- a/chrome/browser/intents/device_attached_intent_source.cc +++ b/chrome/browser/intents/device_attached_intent_source.cc @@ -15,6 +15,13 @@ #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/isolated_context.h" #include "webkit/glue/web_intent_data.h" +#include "webkit/fileapi/media/media_file_system_config.h" + +#if defined(SUPPORT_MEDIA_FILESYSTEM) +#include "webkit/fileapi/media/media_device_map_service.h" + +using fileapi::MediaDeviceMapService; +#endif using base::SystemMonitor; using content::WebContentsDelegate; @@ -42,6 +49,7 @@ void DeviceAttachedIntentSource::OnMediaDeviceAttached( return; // Only handle FilePaths for now. + // TODO(kmadhusu): Handle all device types. http://crbug.com/140353. if (type != SystemMonitor::TYPE_PATH) return; @@ -50,6 +58,10 @@ void DeviceAttachedIntentSource::OnMediaDeviceAttached( if (!device_path.IsAbsolute() || device_path.ReferencesParent()) return; + // Store the media device info locally. + SystemMonitor::MediaDeviceInfo device_info(id, name, type, location); + device_id_map_.insert(std::make_pair(id, device_info)); + std::string device_name; // Register device path as an isolated file system. @@ -68,3 +80,25 @@ void DeviceAttachedIntentSource::OnMediaDeviceAttached( delegate_->WebIntentDispatch(NULL /* no WebContents */, content::WebIntentsDispatcher::Create(intent)); } + +void DeviceAttachedIntentSource::OnMediaDeviceDetached(const std::string& id) { + DeviceIdToInfoMap::iterator it = device_id_map_.find(id); + if (it == device_id_map_.end()) + return; + + // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340. + + FilePath path(it->second.location); + fileapi::IsolatedContext::GetInstance()->RevokeFileSystemByPath(path); + switch (it->second.type) { + case SystemMonitor::TYPE_MTP: +#if defined(SUPPORT_MEDIA_FILESYSTEM) + MediaDeviceMapService::GetInstance()->RemoveMediaDevice( + it->second.location); +#endif + break; + case SystemMonitor::TYPE_PATH: + break; + } + device_id_map_.erase(it); +} diff --git a/chrome/browser/intents/device_attached_intent_source.h b/chrome/browser/intents/device_attached_intent_source.h index 96fd51c..f8c914c 100644 --- a/chrome/browser/intents/device_attached_intent_source.h +++ b/chrome/browser/intents/device_attached_intent_source.h @@ -33,11 +33,16 @@ class DeviceAttachedIntentSource const string16& name, base::SystemMonitor::MediaDeviceType type, const FilePath::StringType& location) OVERRIDE; + virtual void OnMediaDeviceDetached(const std::string& id) OVERRIDE; private: + typedef std::map<std::string, base::SystemMonitor::MediaDeviceInfo> + DeviceIdToInfoMap; + // Weak pointer to browser to which intents will be dispatched. Browser* browser_; content::WebContentsDelegate* delegate_; + DeviceIdToInfoMap device_id_map_; DISALLOW_COPY_AND_ASSIGN(DeviceAttachedIntentSource); }; diff --git a/chrome/browser/media_gallery/media_device_notifications_window_win_unittest.cc b/chrome/browser/media_gallery/media_device_notifications_window_win_unittest.cc index c83154d..a0c66aa 100644 --- a/chrome/browser/media_gallery/media_device_notifications_window_win_unittest.cc +++ b/chrome/browser/media_gallery/media_device_notifications_window_win_unittest.cc @@ -125,7 +125,8 @@ void MediaDeviceNotificationsWindowWinTest::DoDevicesDetachedTest( it != device_indices.end(); ++it) { volume_broadcast.dbcv_unitmask |= 0x1 << *it; - EXPECT_CALL(observer_, OnMediaDeviceDetached(base::IntToString(*it))); + EXPECT_CALL(observer_, OnMediaDeviceDetached(base::IntToString(*it))) + .Times(0); } } window_->OnDeviceChange(DBT_DEVICEREMOVECOMPLETE, diff --git a/chrome/browser/media_gallery/media_file_system_registry.cc b/chrome/browser/media_gallery/media_file_system_registry.cc index ed53081..d1b8e21 100644 --- a/chrome/browser/media_gallery/media_file_system_registry.cc +++ b/chrome/browser/media_gallery/media_file_system_registry.cc @@ -21,6 +21,13 @@ #include "content/public/browser/render_process_host.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/isolated_context.h" +#include "webkit/fileapi/media/media_file_system_config.h" + +#if defined(SUPPORT_MEDIA_FILESYSTEM) +#include "webkit/fileapi/media/media_device_map_service.h" + +using fileapi::MediaDeviceMapService; +#endif namespace chrome { @@ -76,7 +83,8 @@ MediaFileSystemRegistry::GetMediaFileSystemsForExtension( if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path) && IsGalleryPermittedForExtension(extension, SystemMonitor::TYPE_PATH, pictures_path.value())) { - std::string fsid = RegisterPathAsFileSystem(pictures_path); + std::string fsid = RegisterPathAsFileSystem(SystemMonitor::TYPE_PATH, + pictures_path); child_it->second.insert(std::make_pair(pictures_path, fsid)); } } @@ -89,9 +97,11 @@ MediaFileSystemRegistry::GetMediaFileSystemsForExtension( if (media_devices[i].type == SystemMonitor::TYPE_PATH && IsGalleryPermittedForExtension(extension, media_devices[i].type, media_devices[i].location)) { + device_id_map_.insert(std::make_pair(media_devices[i].unique_id, + media_devices[i])); FilePath path(media_devices[i].location); - device_id_map_.insert(std::make_pair(media_devices[i].unique_id, path)); - const std::string fsid = RegisterPathAsFileSystem(path); + const std::string fsid = RegisterPathAsFileSystem(media_devices[i].type, + path); child_it->second.insert(std::make_pair(path, fsid)); } } @@ -113,10 +123,12 @@ MediaFileSystemRegistry::GetMediaFileSystemsForExtension( void MediaFileSystemRegistry::OnMediaDeviceDetached(const std::string& id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DeviceIdToMediaPathMap::iterator it = device_id_map_.find(id); + DeviceIdToInfoMap::iterator it = device_id_map_.find(id); if (it == device_id_map_.end()) return; - RevokeMediaFileSystem(it->second); + + FilePath path(it->second.location); + RevokeMediaFileSystem(it->second.type, path); device_id_map_.erase(it); } @@ -165,24 +177,35 @@ void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications( } std::string MediaFileSystemRegistry::RegisterPathAsFileSystem( - const FilePath& path) { + const SystemMonitor::MediaDeviceType& device_type, const FilePath& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Sanity checks for |path|. CHECK(path.IsAbsolute()); CHECK(!path.ReferencesParent()); + fileapi::FileSystemType type = fileapi::kFileSystemTypeUnknown; + switch (device_type) { + case SystemMonitor::TYPE_MTP: + type = fileapi::kFileSystemTypeDeviceMedia; + break; + case SystemMonitor::TYPE_PATH: + type = fileapi::kFileSystemTypeNativeMedia; + break; + } + // The directory name is not exposed to the js layer and we simply use // a fixed name (as we only register a single directory per file system). std::string register_name(extension_misc::kMediaFileSystemPathPart); const std::string fsid = IsolatedContext::GetInstance()->RegisterFileSystemForPath( - fileapi::kFileSystemTypeIsolated, path, ®ister_name); + type, path, ®ister_name); CHECK(!fsid.empty()); return fsid; } -void MediaFileSystemRegistry::RevokeMediaFileSystem(const FilePath& path) { +void MediaFileSystemRegistry::RevokeMediaFileSystem( + const SystemMonitor::MediaDeviceType& device_type, const FilePath& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); IsolatedContext* isolated_context = IsolatedContext::GetInstance(); @@ -195,6 +218,19 @@ void MediaFileSystemRegistry::RevokeMediaFileSystem(const FilePath& path) { MediaPathToFSIDMap::iterator media_path_it = child_map.find(path); if (media_path_it == child_map.end()) continue; + + // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340. + + // Do the clean up tasks related to the file system. + switch (device_type) { + case SystemMonitor::TYPE_MTP: +#if defined(SUPPORT_MEDIA_FILESYSTEM) + MediaDeviceMapService::GetInstance()->RemoveMediaDevice(path.value()); +#endif + break; + case SystemMonitor::TYPE_PATH: + break; + } child_map.erase(media_path_it); } } diff --git a/chrome/browser/media_gallery/media_file_system_registry.h b/chrome/browser/media_gallery/media_file_system_registry.h index a405571..5f1ff98 100644 --- a/chrome/browser/media_gallery/media_file_system_registry.h +++ b/chrome/browser/media_gallery/media_file_system_registry.h @@ -72,8 +72,9 @@ class MediaFileSystemRegistry typedef std::map<const content::RenderProcessHost*, MediaPathToFSIDMap> ChildIdToMediaFSMap; - // Mapping of device id to mount path. - typedef std::map<std::string, FilePath> DeviceIdToMediaPathMap; + // Mapping of device id to media device info. + typedef std::map<std::string, base::SystemMonitor::MediaDeviceInfo> + DeviceIdToInfoMap; // Obtain an instance of this class via GetInstance(). MediaFileSystemRegistry(); @@ -85,16 +86,21 @@ class MediaFileSystemRegistry void UnregisterForRPHGoneNotifications(const content::RenderProcessHost* rph); // Registers a path as a media file system and return the filesystem id. - std::string RegisterPathAsFileSystem(const FilePath& path); + std::string RegisterPathAsFileSystem( + const base::SystemMonitor::MediaDeviceType& device_type, + const FilePath& path); + // Revoke a media file system with a given |path|. - void RevokeMediaFileSystem(const FilePath& path); + void RevokeMediaFileSystem( + const base::SystemMonitor::MediaDeviceType& device_type, + const FilePath& path); // Only accessed on the UI thread. ChildIdToMediaFSMap media_fs_map_; // Only accessed on the UI thread. - DeviceIdToMediaPathMap device_id_map_; + DeviceIdToInfoMap device_id_map_; // Is only used on the UI thread. content::NotificationRegistrar registrar_; diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc index 3e3679e..702dfc0 100644 --- a/webkit/fileapi/file_system_context.cc +++ b/webkit/fileapi/file_system_context.cc @@ -61,7 +61,7 @@ FileSystemContext::FileSystemContext( file_task_runner, profile_path, options)), - isolated_provider_(new IsolatedMountPointProvider) { + isolated_provider_(new IsolatedMountPointProvider(profile_path)) { if (quota_manager_proxy) { quota_manager_proxy->RegisterClient(CreateQuotaClient( this, options.is_incognito())); diff --git a/webkit/fileapi/file_system_operation_context.h b/webkit/fileapi/file_system_operation_context.h index 7b26539..3a8cc39 100644 --- a/webkit/fileapi/file_system_operation_context.h +++ b/webkit/fileapi/file_system_operation_context.h @@ -12,6 +12,11 @@ #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_file_util.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/media/media_file_system_config.h" + +#if defined(SUPPORT_MEDIA_FILESYSTEM) +#include "webkit/fileapi/media/media_device_interface_impl.h" +#endif namespace base { class SequencedTaskRunner; @@ -35,6 +40,16 @@ class FILEAPI_EXPORT_PRIVATE FileSystemOperationContext { } int64 allowed_bytes_growth() const { return allowed_bytes_growth_; } +#if defined(SUPPORT_MEDIA_FILESYSTEM) + void set_media_device(MediaDeviceInterfaceImpl* media_device) { + media_device_ = media_device; + } + + MediaDeviceInterfaceImpl* media_device() const { + return media_device_.get(); + } +#endif + base::SequencedTaskRunner* file_task_runner() const; void set_media_path_filter(MediaPathFilter* media_path_filter) { @@ -50,6 +65,11 @@ class FILEAPI_EXPORT_PRIVATE FileSystemOperationContext { int64 allowed_bytes_growth_; MediaPathFilter* media_path_filter_; + +#if defined(SUPPORT_MEDIA_FILESYSTEM) + // Store the current media device. + scoped_refptr<MediaDeviceInterfaceImpl> media_device_; +#endif }; } // namespace fileapi diff --git a/webkit/fileapi/isolated_mount_point_provider.cc b/webkit/fileapi/isolated_mount_point_provider.cc index bca05fa..cdd83c9 100644 --- a/webkit/fileapi/isolated_mount_point_provider.cc +++ b/webkit/fileapi/isolated_mount_point_provider.cc @@ -21,10 +21,16 @@ #include "webkit/fileapi/isolated_file_util.h" #include "webkit/fileapi/local_file_stream_writer.h" #include "webkit/fileapi/local_file_system_operation.h" +#include "webkit/fileapi/media/media_file_system_config.h" #include "webkit/fileapi/media/media_path_filter.h" #include "webkit/fileapi/media/native_media_file_util.h" #include "webkit/fileapi/native_file_util.h" +#if defined(SUPPORT_MEDIA_FILESYSTEM) +#include "webkit/fileapi/media/device_media_file_util.h" +#include "webkit/fileapi/media/media_device_map_service.h" +#endif + namespace fileapi { namespace { @@ -33,13 +39,27 @@ IsolatedContext* isolated_context() { return IsolatedContext::GetInstance(); } +#if defined(SUPPORT_MEDIA_FILESYSTEM) +MediaDeviceInterfaceImpl* GetDeviceForUrl(const FileSystemURL& url, + FileSystemContext* context) { + return MediaDeviceMapService::GetInstance()->CreateOrGetMediaDevice( + url.filesystem_id(), context->file_task_runner()); +} +#endif + } // namespace -IsolatedMountPointProvider::IsolatedMountPointProvider() - : media_path_filter_(new MediaPathFilter()), +IsolatedMountPointProvider::IsolatedMountPointProvider( + const FilePath& profile_path) + : profile_path_(profile_path), + media_path_filter_(new MediaPathFilter()), isolated_file_util_(new IsolatedFileUtil()), dragged_file_util_(new DraggedFileUtil()), native_media_file_util_(new NativeMediaFileUtil()) { + // TODO(kmadhusu): Initialize device_media_file_util_ in initialization list. +#if defined(SUPPORT_MEDIA_FILESYSTEM) + device_media_file_util_.reset(new DeviceMediaFileUtil(profile_path_)); +#endif } IsolatedMountPointProvider::~IsolatedMountPointProvider() { @@ -87,8 +107,11 @@ FileSystemFileUtil* IsolatedMountPointProvider::GetFileUtil( return dragged_file_util_.get(); case kFileSystemTypeNativeMedia: return native_media_file_util_.get(); - case kFileSystemTypeDeviceMedia: +#if defined(SUPPORT_MEDIA_FILESYSTEM) + return device_media_file_util_.get(); +#endif + case kFileSystemTypeTemporary: case kFileSystemTypePersistent: case kFileSystemTypeExternal: @@ -115,6 +138,14 @@ IsolatedMountPointProvider::CreateFileSystemOperation( if (url.type() == kFileSystemTypeNativeMedia || url.type() == kFileSystemTypeDeviceMedia) operation_context->set_media_path_filter(media_path_filter_.get()); + +#if defined(SUPPORT_MEDIA_FILESYSTEM) + if (url.type() == kFileSystemTypeDeviceMedia) { + // GetDeviceForUrl can return NULL. We will handle in DeviceMediaFileUtil. + operation_context->set_media_device(GetDeviceForUrl(url, context)); + } +#endif + return new LocalFileSystemOperation(context, operation_context.Pass()); } diff --git a/webkit/fileapi/isolated_mount_point_provider.h b/webkit/fileapi/isolated_mount_point_provider.h index f6340dc..9f36b94 100644 --- a/webkit/fileapi/isolated_mount_point_provider.h +++ b/webkit/fileapi/isolated_mount_point_provider.h @@ -5,10 +5,9 @@ #ifndef WEBKIT_FILEAPI_ISOLATED_MOUNT_POINT_PROVIDER_H_ #define WEBKIT_FILEAPI_ISOLATED_MOUNT_POINT_PROVIDER_H_ -#include <vector> - #include "base/memory/scoped_ptr.h" #include "webkit/fileapi/file_system_mount_point_provider.h" +#include "webkit/fileapi/media/media_file_system_config.h" namespace fileapi { @@ -18,12 +17,16 @@ class IsolatedFileUtil; class MediaPathFilter; class NativeMediaFileUtil; +#if defined(SUPPORT_MEDIA_FILESYSTEM) +class DeviceMediaFileUtil; +#endif + class IsolatedMountPointProvider : public FileSystemMountPointProvider { public: using FileSystemMountPointProvider::ValidateFileSystemCallback; using FileSystemMountPointProvider::DeleteFileSystemCallback; - IsolatedMountPointProvider(); + explicit IsolatedMountPointProvider(const FilePath& profile_path); virtual ~IsolatedMountPointProvider(); // FileSystemMountPointProvider implementation. @@ -63,11 +66,18 @@ class IsolatedMountPointProvider : public FileSystemMountPointProvider { const DeleteFileSystemCallback& callback) OVERRIDE; private: + // Store the profile path. We need this to create temporary snapshot files. + const FilePath profile_path_; + scoped_ptr<MediaPathFilter> media_path_filter_; scoped_ptr<IsolatedFileUtil> isolated_file_util_; scoped_ptr<DraggedFileUtil> dragged_file_util_; scoped_ptr<NativeMediaFileUtil> native_media_file_util_; + +#if defined(SUPPORT_MEDIA_FILESYSTEM) + scoped_ptr<DeviceMediaFileUtil> device_media_file_util_; +#endif }; } // namespace fileapi diff --git a/webkit/fileapi/media/device_media_file_util.cc b/webkit/fileapi/media/device_media_file_util.cc new file mode 100644 index 0000000..37b04a9 --- /dev/null +++ b/webkit/fileapi/media/device_media_file_util.cc @@ -0,0 +1,202 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/media/device_media_file_util.h" + +#include "base/file_util.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop_proxy.h" +#include "webkit/blob/shareable_file_reference.h" +#include "webkit/fileapi/file_system_operation_context.h" +#include "webkit/fileapi/file_system_url.h" +#include "webkit/fileapi/isolated_context.h" +#include "webkit/fileapi/media/media_device_interface_impl.h" +#include "webkit/fileapi/media/media_device_map_service.h" + +using base::PlatformFileError; +using base::PlatformFileInfo; +using webkit_blob::ShareableFileReference; + +namespace fileapi { + +namespace { + +const FilePath::CharType kDeviceMediaFileUtilTempDir[] = + FILE_PATH_LITERAL("DeviceMediaFileSystem"); + +} // namespace + +DeviceMediaFileUtil::DeviceMediaFileUtil(const FilePath& profile_path) + : profile_path_(profile_path) { +} + +PlatformFileError DeviceMediaFileUtil::CreateOrOpen( + FileSystemOperationContext* context, + const FileSystemURL& url, int file_flags, + PlatformFile* file_handle, bool* created) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::Close( + FileSystemOperationContext* context, + PlatformFile file_handle) { + // We don't allow open thus Close won't be called. + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::EnsureFileExists( + FileSystemOperationContext* context, + const FileSystemURL& url, + bool* created) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::CreateDirectory( + FileSystemOperationContext* context, + const FileSystemURL& url, + bool exclusive, + bool recursive) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::GetFileInfo( + FileSystemOperationContext* context, + const FileSystemURL& url, + PlatformFileInfo* file_info, + FilePath* platform_path) { + if (!context->media_device()) + return base::PLATFORM_FILE_ERROR_NOT_FOUND; + return context->media_device()->GetFileInfo(url.path(), file_info); +} + +FileSystemFileUtil::AbstractFileEnumerator* +DeviceMediaFileUtil::CreateFileEnumerator( + FileSystemOperationContext* context, + const FileSystemURL& url, + bool recursive) { + if (!context->media_device()) + return new FileSystemFileUtil::EmptyFileEnumerator(); + return context->media_device()->CreateFileEnumerator(url.path(), recursive); +} + +PlatformFileError DeviceMediaFileUtil::GetLocalFilePath( + FileSystemOperationContext* context, + const FileSystemURL& file_system_url, + FilePath* local_file_path) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::Touch( + FileSystemOperationContext* context, + const FileSystemURL& url, + const base::Time& last_access_time, + const base::Time& last_modified_time) { + if (!context->media_device()) + return base::PLATFORM_FILE_ERROR_NOT_FOUND; + return context->media_device()->Touch(url.path(), last_access_time, + last_modified_time); +} + +PlatformFileError DeviceMediaFileUtil::Truncate( + FileSystemOperationContext* context, + const FileSystemURL& url, + int64 length) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +bool DeviceMediaFileUtil::PathExists( + FileSystemOperationContext* context, + const FileSystemURL& url) { + if (!context->media_device()) + return false; + return context->media_device()->PathExists(url.path()); +} + +bool DeviceMediaFileUtil::DirectoryExists( + FileSystemOperationContext* context, + const FileSystemURL& url) { + if (!context->media_device()) + return false; + return context->media_device()->DirectoryExists(url.path()); +} + +bool DeviceMediaFileUtil::IsDirectoryEmpty( + FileSystemOperationContext* context, + const FileSystemURL& url) { + if (!context->media_device()) + return false; + return context->media_device()->IsDirectoryEmpty(url.path()); +} + +PlatformFileError DeviceMediaFileUtil::CopyOrMoveFile( + FileSystemOperationContext* context, + const FileSystemURL& src_url, + const FileSystemURL& dest_url, + bool copy) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::CopyInForeignFile( + FileSystemOperationContext* context, + const FilePath& src_file_path, + const FileSystemURL& dest_url) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::DeleteFile( + FileSystemOperationContext* context, + const FileSystemURL& url) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +PlatformFileError DeviceMediaFileUtil::DeleteSingleDirectory( + FileSystemOperationContext* context, + const FileSystemURL& url) { + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +scoped_refptr<ShareableFileReference> DeviceMediaFileUtil::CreateSnapshotFile( + FileSystemOperationContext* context, + const FileSystemURL& url, + base::PlatformFileError* result, + base::PlatformFileInfo* file_info, + FilePath* local_path) { + DCHECK(result); + DCHECK(file_info); + DCHECK(local_path); + + scoped_refptr<ShareableFileReference> file_ref; + if (!context->media_device()) { + *result = base::PLATFORM_FILE_ERROR_NOT_FOUND; + return file_ref; + } + + *result = base::PLATFORM_FILE_ERROR_FAILED; + + // Create a temp file in "profile_path_/kDeviceMediaFileUtilTempDir". + FilePath isolated_media_file_system_dir_path = + profile_path_.Append(kDeviceMediaFileUtilTempDir); + bool dir_exists = file_util::DirectoryExists( + isolated_media_file_system_dir_path); + if (!dir_exists) { + if (!file_util::CreateDirectory(isolated_media_file_system_dir_path)) + return file_ref; + } + + bool file_created = file_util::CreateTemporaryFileInDir( + isolated_media_file_system_dir_path, local_path); + if (!file_created) + return file_ref; + + *result = context->media_device()->CreateSnapshotFile(url.path(), *local_path, + file_info); + if (*result == base::PLATFORM_FILE_OK) { + file_ref = ShareableFileReference::GetOrCreate( + *local_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE, + context->file_task_runner()); + } + return file_ref; +} + +} // namespace fileapi diff --git a/webkit/fileapi/media/device_media_file_util.h b/webkit/fileapi/media/device_media_file_util.h new file mode 100644 index 0000000..b0745a6 --- /dev/null +++ b/webkit/fileapi/media/device_media_file_util.h @@ -0,0 +1,106 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_DEVICE_MEDIA_FILE_UTIL_H_ +#define WEBKIT_FILEAPI_MEDIA_DEVICE_MEDIA_FILE_UTIL_H_ + +#include "base/file_path.h" +#include "base/platform_file.h" +#include "webkit/fileapi/fileapi_export.h" +#include "webkit/fileapi/file_system_file_util.h" + +namespace base { +class Time; +} + +namespace fileapi { + +class FileSystemOperationContext; + +class FILEAPI_EXPORT_PRIVATE DeviceMediaFileUtil : public FileSystemFileUtil { + public: + explicit DeviceMediaFileUtil(const FilePath& profile_path); + virtual ~DeviceMediaFileUtil() {} + + // FileSystemFileUtil overrides. + virtual base::PlatformFileError CreateOrOpen( + FileSystemOperationContext* context, + const FileSystemURL& url, + int file_flags, + base::PlatformFile* file_handle, + bool* created) OVERRIDE; + virtual base::PlatformFileError Close( + FileSystemOperationContext* context, + base::PlatformFile file) OVERRIDE; + virtual base::PlatformFileError EnsureFileExists( + FileSystemOperationContext* context, + const FileSystemURL& url, bool* created) OVERRIDE; + virtual base::PlatformFileError CreateDirectory( + FileSystemOperationContext* context, + const FileSystemURL& url, + bool exclusive, + bool recursive) OVERRIDE; + virtual base::PlatformFileError GetFileInfo( + FileSystemOperationContext* context, + const FileSystemURL& url, + base::PlatformFileInfo* file_info, + FilePath* platform_path) OVERRIDE; + virtual AbstractFileEnumerator* CreateFileEnumerator( + FileSystemOperationContext* context, + const FileSystemURL& root_url, + bool recursive) OVERRIDE; + virtual PlatformFileError GetLocalFilePath( + FileSystemOperationContext* context, + const FileSystemURL& file_system_url, + FilePath* local_file_path) OVERRIDE; + virtual base::PlatformFileError Touch( + FileSystemOperationContext* context, + const FileSystemURL& url, + const base::Time& last_access_time, + const base::Time& last_modified_time) OVERRIDE; + virtual base::PlatformFileError Truncate( + FileSystemOperationContext* context, + const FileSystemURL& url, + int64 length) OVERRIDE; + virtual bool PathExists( + FileSystemOperationContext* context, + const FileSystemURL& url) OVERRIDE; + virtual bool DirectoryExists( + FileSystemOperationContext* context, + const FileSystemURL& url) OVERRIDE; + virtual bool IsDirectoryEmpty( + FileSystemOperationContext* context, + const FileSystemURL& url) OVERRIDE; + virtual base::PlatformFileError CopyOrMoveFile( + FileSystemOperationContext* context, + const FileSystemURL& src_url, + const FileSystemURL& dest_url, + bool copy) OVERRIDE; + virtual base::PlatformFileError CopyInForeignFile( + FileSystemOperationContext* context, + const FilePath& src_file_path, + const FileSystemURL& dest_url) OVERRIDE; + virtual base::PlatformFileError DeleteFile( + FileSystemOperationContext* context, + const FileSystemURL& url) OVERRIDE; + virtual base::PlatformFileError DeleteSingleDirectory( + FileSystemOperationContext* context, + const FileSystemURL& url) OVERRIDE; + virtual scoped_refptr<webkit_blob::ShareableFileReference> + CreateSnapshotFile(FileSystemOperationContext* context, + const FileSystemURL& url, + base::PlatformFileError* result, + base::PlatformFileInfo* file_info, + FilePath* platform_path) OVERRIDE; + + private: + // Profile path + const FilePath profile_path_; + + DISALLOW_COPY_AND_ASSIGN(DeviceMediaFileUtil); +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MEDIA_DEVICE_MEDIA_FILE_UTIL_H_ diff --git a/webkit/fileapi/media/media_device_interface.h b/webkit/fileapi/media/media_device_interface.h new file mode 100644 index 0000000..a9db7e9 --- /dev/null +++ b/webkit/fileapi/media/media_device_interface.h @@ -0,0 +1,44 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_H_ +#define WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_H_ + +#include "base/file_path.h" +#include "base/platform_file.h" +#include "base/timer.h" +#include "webkit/fileapi/file_system_file_util.h" + +namespace base { +struct PlatformFileInfo; +class Time; +} + +namespace fileapi { + +// Helper interface to support media device isolated file system operations. +class MediaDeviceInterface { + public: + virtual base::PlatformFileError GetFileInfo( + const FilePath& file_path, + base::PlatformFileInfo* file_info) = 0; + virtual FileSystemFileUtil::AbstractFileEnumerator* CreateFileEnumerator( + const FilePath& root, + bool recursive) = 0; + virtual base::PlatformFileError Touch( + const FilePath& file_path, + const base::Time& last_access_time, + const base::Time& last_modified_time) = 0; + virtual bool PathExists(const FilePath& file_path) = 0; + virtual bool DirectoryExists(const FilePath& file_path) = 0; + virtual bool IsDirectoryEmpty(const FilePath& file_path) = 0; + virtual PlatformFileError CreateSnapshotFile( + const FilePath& device_file_path, + const FilePath& local_path, + base::PlatformFileInfo* file_info) = 0; +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_H_ diff --git a/webkit/fileapi/media/media_device_interface_impl.h b/webkit/fileapi/media/media_device_interface_impl.h new file mode 100644 index 0000000..37455a3 --- /dev/null +++ b/webkit/fileapi/media/media_device_interface_impl.h @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_IMPL_H_ +#define WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_IMPL_H_ + +#include "build/build_config.h" + +#if defined(OS_LINUX) +#include "webkit/fileapi/media/mtp_device_interface_impl_linux.h" +#endif + +namespace fileapi { + +// TODO(kmadhusu): Implement mtp device interface on other platforms. +#if defined(OS_LINUX) + typedef class MtpDeviceInterfaceImplLinux MediaDeviceInterfaceImpl; +#endif + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_INTERFACE_IMPL_H_ diff --git a/webkit/fileapi/media/media_device_map_service.cc b/webkit/fileapi/media/media_device_map_service.cc new file mode 100644 index 0000000..2aab493 --- /dev/null +++ b/webkit/fileapi/media/media_device_map_service.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/media/media_device_map_service.h" + +#include <utility> + +#include "webkit/fileapi/isolated_context.h" + +namespace fileapi { + +using base::SequencedTaskRunner; + +// static +MediaDeviceMapService* MediaDeviceMapService::GetInstance() { + return Singleton<MediaDeviceMapService>::get(); +} + +MediaDeviceInterfaceImpl* MediaDeviceMapService::CreateOrGetMediaDevice( + const std::string& filesystem_id, + SequencedTaskRunner* media_task_runner) { + DCHECK(media_task_runner); + + base::AutoLock lock(media_device_map_lock_); + + FilePath device_path; + if (!IsolatedContext::GetInstance()->GetRegisteredPath(filesystem_id, + &device_path)) { + return NULL; + } + + FilePath::StringType device_location = device_path.value(); + DCHECK(!device_location.empty()); + + MediaDeviceMap::const_iterator it = media_device_map_.find(device_location); + if (it == media_device_map_.end()) { + media_device_map_.insert(std::make_pair( + device_location, new MediaDeviceInterfaceImpl(device_location, + media_task_runner))); + } + return media_device_map_[device_location].get(); +} + +void MediaDeviceMapService::RemoveMediaDevice( + const std::string& device_location) { + base::AutoLock lock(media_device_map_lock_); + MediaDeviceMap::iterator it = media_device_map_.find(device_location); + if (it != media_device_map_.end()) + media_device_map_.erase(it); +} + +MediaDeviceMapService::MediaDeviceMapService() { +} + +MediaDeviceMapService::~MediaDeviceMapService() { +} + +} // namespace fileapi diff --git a/webkit/fileapi/media/media_device_map_service.h b/webkit/fileapi/media/media_device_map_service.h new file mode 100644 index 0000000..1b09c56 --- /dev/null +++ b/webkit/fileapi/media/media_device_map_service.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_MAP_SERVICE_H_ +#define WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_MAP_SERVICE_H_ + +#include <map> + +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/memory/singleton.h" +#include "base/synchronization/lock.h" +#include "webkit/fileapi/media/media_device_interface_impl.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace fileapi { + +// Helper class to manage media device interfaces. +class FILEAPI_EXPORT MediaDeviceMapService { + public: + static MediaDeviceMapService* GetInstance(); + + // Create or get media device interface associated with |filesystem_id|. + // Return NULL if the |filesystem_id| is no longer valid (e.g. because the + // corresponding device is detached etc). This function is called on IO + // thread. + MediaDeviceInterfaceImpl* CreateOrGetMediaDevice( + const std::string& filesystem_id, + base::SequencedTaskRunner* media_task_runner); + + // This function is called on UI thread. + void RemoveMediaDevice(const FilePath::StringType& device_location); + + private: + friend struct DefaultSingletonTraits<MediaDeviceMapService>; + + typedef scoped_refptr<MediaDeviceInterfaceImpl> MediaDeviceRefPtr; + typedef std::map<FilePath::StringType, MediaDeviceRefPtr> MediaDeviceMap; + + // Get access to this class using GetInstance() method. + MediaDeviceMapService(); + ~MediaDeviceMapService(); + + base::Lock media_device_map_lock_; + + // Store a map of attached mtp devices. + // Key: Device location. + // Value: MtpDeviceInterface. + MediaDeviceMap media_device_map_; + + DISALLOW_COPY_AND_ASSIGN(MediaDeviceMapService); +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MEDIA_MEDIA_DEVICE_MAP_SERVICE_H_ diff --git a/webkit/fileapi/media/media_file_system_config.h b/webkit/fileapi/media/media_file_system_config.h new file mode 100644 index 0000000..11f4a1e --- /dev/null +++ b/webkit/fileapi/media/media_file_system_config.h @@ -0,0 +1,14 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_MEDIA_FILE_SYSTEM_CONFIG_H_ +#define WEBKIT_FILEAPI_MEDIA_MEDIA_FILE_SYSTEM_CONFIG_H_ + +#include "build/build_config.h" + +#if defined(OS_LINUX) +#define SUPPORT_MEDIA_FILESYSTEM +#endif + +#endif // WEBKIT_FILEAPI_MEDIA_MEDIA_FILE_SYSTEM_CONFIG_H_ diff --git a/webkit/fileapi/media/mtp_device_interface_impl_linux.cc b/webkit/fileapi/media/mtp_device_interface_impl_linux.cc new file mode 100644 index 0000000..6626d8e --- /dev/null +++ b/webkit/fileapi/media/mtp_device_interface_impl_linux.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/media/mtp_device_interface_impl_linux.h" + +#include "base/sequenced_task_runner.h" + +using base::PlatformFileError; +using base::PlatformFileInfo; +using base::Time; + +namespace fileapi { + +MtpDeviceInterfaceImplLinux::MtpDeviceInterfaceImplLinux( + const FilePath::StringType& device_id, + base::SequencedTaskRunner* media_task_runner) + : device_id_(device_id), + media_task_runner_(media_task_runner) { + // Initialize the device in LazyInit() function. + // This object is constructed on IO thread. +} + +MtpDeviceInterfaceImplLinux::~MtpDeviceInterfaceImplLinux() { + // Do the clean up in DeleteOnCorrectThread() function. + // This object must be destructed on media_task_runner. +} + +bool MtpDeviceInterfaceImplLinux::LazyInit() { + DCHECK(media_task_runner_->RunsTasksOnCurrentThread()); + + // TODO(kmadhusu, thestig): Open the device for communication. If is already + // opened, return. + return true; +} + +void MtpDeviceInterfaceImplLinux::DeleteOnCorrectThread() const { + if (!media_task_runner_->RunsTasksOnCurrentThread()) { + media_task_runner_->DeleteSoon(FROM_HERE, this); + return; + } + delete this; +} + +PlatformFileError MtpDeviceInterfaceImplLinux::GetFileInfo( + const FilePath& file_path, + PlatformFileInfo* file_info) { + if (!LazyInit()) + return base::PLATFORM_FILE_ERROR_SECURITY; + + NOTIMPLEMENTED(); + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +FileSystemFileUtil::AbstractFileEnumerator* +MtpDeviceInterfaceImplLinux::CreateFileEnumerator( + const FilePath& root, + bool recursive) { + if (!LazyInit()) + return new FileSystemFileUtil::EmptyFileEnumerator(); + + NOTIMPLEMENTED(); + return new FileSystemFileUtil::EmptyFileEnumerator(); +} + +PlatformFileError MtpDeviceInterfaceImplLinux::Touch( + const FilePath& file_path, + const base::Time& last_access_time, + const base::Time& last_modified_time) { + if (!LazyInit()) + return base::PLATFORM_FILE_ERROR_SECURITY; + + NOTIMPLEMENTED(); + return base::PLATFORM_FILE_ERROR_SECURITY; +} + +bool MtpDeviceInterfaceImplLinux::PathExists(const FilePath& file_path) { + if (!LazyInit()) + return false; + + NOTIMPLEMENTED(); + return false; +} + +bool MtpDeviceInterfaceImplLinux::DirectoryExists(const FilePath& file_path) { + if (!LazyInit()) + return false; + + NOTIMPLEMENTED(); + return false; +} + +bool MtpDeviceInterfaceImplLinux::IsDirectoryEmpty(const FilePath& file_path) { + if (!LazyInit()) + return false; + + NOTIMPLEMENTED(); + return true; +} + +PlatformFileError MtpDeviceInterfaceImplLinux::CreateSnapshotFile( + const FilePath& device_file_path, + const FilePath& local_path, + PlatformFileInfo* file_info) { + if (!LazyInit()) + return base::PLATFORM_FILE_ERROR_FAILED; + + // Write the device_file_path data to local_path file and set the file_info + // accordingly. + + NOTIMPLEMENTED(); + return base::PLATFORM_FILE_ERROR_FAILED; +} + +} // namespace fileapi diff --git a/webkit/fileapi/media/mtp_device_interface_impl_linux.h b/webkit/fileapi/media/mtp_device_interface_impl_linux.h new file mode 100644 index 0000000..0b618f06 --- /dev/null +++ b/webkit/fileapi/media/mtp_device_interface_impl_linux.h @@ -0,0 +1,84 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_MEDIA_MTP_DEVICE_INTERFACE_IMPL_LINUX_H_ +#define WEBKIT_FILEAPI_MEDIA_MTP_DEVICE_INTERFACE_IMPL_LINUX_H_ + +#include "base/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/sequenced_task_runner_helpers.h" +#include "webkit/fileapi/file_system_file_util.h" +#include "webkit/fileapi/media/media_device_interface.h" + +namespace base { +struct PlatformFileInfo; +class SequencedTaskRunner; +class Time; +} + +namespace fileapi { + +struct DefaultMtpDeviceInterfaceImplDeleter; + +// Helper class to support MTP device isolated file system operations. This +// class contains platform specific code to communicate with the attached +// MTP device. We instantiate this class per MTP device. MTP device is +// opened for communication during initialization and closed during +// destruction. +class MtpDeviceInterfaceImplLinux + : public MediaDeviceInterface, + public base::RefCountedThreadSafe<MtpDeviceInterfaceImplLinux, + DefaultMtpDeviceInterfaceImplDeleter> { + public: + MtpDeviceInterfaceImplLinux( + const FilePath::StringType& device_id, + base::SequencedTaskRunner* media_task_runner); + + // MediaDeviceInterface methods. + virtual base::PlatformFileError GetFileInfo( + const FilePath& file_path, + base::PlatformFileInfo* file_info) OVERRIDE; + virtual FileSystemFileUtil::AbstractFileEnumerator* CreateFileEnumerator( + const FilePath& root, + bool recursive) OVERRIDE; + virtual base::PlatformFileError Touch( + const FilePath& file_path, + const base::Time& last_access_time, + const base::Time& last_modified_time) OVERRIDE; + virtual bool PathExists(const FilePath& file_path) OVERRIDE; + virtual bool DirectoryExists(const FilePath& file_path) OVERRIDE; + virtual bool IsDirectoryEmpty(const FilePath& file_path) OVERRIDE; + virtual base::PlatformFileError CreateSnapshotFile( + const FilePath& device_file_path, + const FilePath& local_path, + base::PlatformFileInfo* file_info) OVERRIDE; + + private: + friend struct DefaultMtpDeviceInterfaceImplDeleter; + friend class base::DeleteHelper<MtpDeviceInterfaceImplLinux>; + friend class base::RefCountedThreadSafe<MtpDeviceInterfaceImplLinux, + DefaultMtpDeviceInterfaceImplDeleter>; + + virtual ~MtpDeviceInterfaceImplLinux(); + void DeleteOnCorrectThread() const; + + // Device initialization should be done in |media_task_runner_|. + bool LazyInit(); + + // Mtp device id. + FilePath::StringType device_id_; + scoped_refptr<base::SequencedTaskRunner> media_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(MtpDeviceInterfaceImplLinux); +}; + +struct DefaultMtpDeviceInterfaceImplDeleter { + static void Destruct(const MtpDeviceInterfaceImplLinux* device_impl) { + device_impl->DeleteOnCorrectThread(); + } +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_MEDIA_MTP_DEVICE_INTERFACE_IMPL_LINUX_H_ diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi index 1bd5b5f..126a0a9 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -72,6 +72,7 @@ 'local_file_stream_writer.h', 'local_file_system_operation.cc', 'local_file_system_operation.h', + 'media/media_file_system_config.h', 'media/media_path_filter.cc', 'media/media_path_filter.h', 'media/native_media_file_util.cc', @@ -95,6 +96,18 @@ '<(DEPTH)/webkit/support/setup_third_party.gyp:third_party_headers', ], }], + ['OS == "linux"', { + 'sources': [ + 'media/device_media_file_util.cc', + 'media/device_media_file_util.h', + 'media/media_device_interface.h', + 'media/media_device_interface_impl.h', + 'media/media_device_map_service.cc', + 'media/media_device_map_service.h', + 'media/mtp_device_interface_impl_linux.cc', + 'media/mtp_device_interface_impl_linux.h', + ], + }], ['chromeos==1', { 'sources': [ '../chromeos/fileapi/async_file_stream.h', |