diff options
Diffstat (limited to 'chrome/browser/chromeos')
16 files changed, 943 insertions, 109 deletions
diff --git a/chrome/browser/chromeos/extensions/file_browser_event_router.cc b/chrome/browser/chromeos/extensions/file_browser_event_router.cc index 18f17c2..c861a9c 100644 --- a/chrome/browser/chromeos/extensions/file_browser_event_router.cc +++ b/chrome/browser/chromeos/extensions/file_browser_event_router.cc @@ -27,7 +27,6 @@ #include "chrome/browser/google_apis/drive_service_interface.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_dependency_manager.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/pref_names.h" #include "content/public/browser/notification_source.h" @@ -108,7 +107,7 @@ FileBrowserEventRouter::~FileBrowserEventRouter() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } -void FileBrowserEventRouter::ShutdownOnUIThread() { +void FileBrowserEventRouter::Shutdown() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(file_watchers_.empty()); @@ -117,7 +116,10 @@ void FileBrowserEventRouter::ShutdownOnUIThread() { NOTREACHED(); return; } - DiskMountManager::GetInstance()->RemoveObserver(this); + + DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance(); + if (disk_mount_manager) + disk_mount_manager->RemoveObserver(this); DriveSystemService* system_service = DriveSystemServiceFactory::FindForProfileRegardlessOfStates(profile_); @@ -126,10 +128,13 @@ void FileBrowserEventRouter::ShutdownOnUIThread() { system_service->drive_service()->RemoveObserver(this); } - chromeos::NetworkLibrary* network_library = - chromeos::CrosLibrary::Get()->GetNetworkLibrary(); - if (network_library) - network_library->RemoveNetworkManagerObserver(this); + chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); + if (cros_library) { + chromeos::NetworkLibrary* network_library = + cros_library->GetNetworkLibrary(); + if (network_library) + network_library->RemoveNetworkManagerObserver(this); + } profile_ = NULL; } @@ -143,9 +148,11 @@ void FileBrowserEventRouter::ObserveFileSystemEvents() { return; DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance(); - disk_mount_manager->RemoveObserver(this); - disk_mount_manager->AddObserver(this); - disk_mount_manager->RequestMountInfoRefresh(); + if (disk_mount_manager) { + disk_mount_manager->RemoveObserver(this); + disk_mount_manager->AddObserver(this); + disk_mount_manager->RequestMountInfoRefresh(); + } DriveSystemService* system_service = DriveSystemServiceFactory::GetForProfileRegardlessOfStates(profile_); @@ -154,10 +161,13 @@ void FileBrowserEventRouter::ObserveFileSystemEvents() { system_service->file_system()->AddObserver(this); } - chromeos::NetworkLibrary* network_library = - chromeos::CrosLibrary::Get()->GetNetworkLibrary(); - if (network_library) + chromeos::CrosLibrary* cros_library = chromeos::CrosLibrary::Get(); + if (cros_library) { + chromeos::NetworkLibrary* network_library = + cros_library->GetNetworkLibrary(); + if (network_library) network_library->AddNetworkManagerObserver(this); + } pref_change_registrar_->Init(profile_->GetPrefs()); @@ -848,38 +858,3 @@ bool FileBrowserEventRouter::FileWatcherExtensions::Watch return file_watcher_->Watch(path, delegate); } - -// static -scoped_refptr<FileBrowserEventRouter> -FileBrowserEventRouterFactory::GetForProfile(Profile* profile) { - return static_cast<FileBrowserEventRouter*>( - GetInstance()->GetServiceForProfile(profile, true).get()); -} - -// static -FileBrowserEventRouterFactory* -FileBrowserEventRouterFactory::GetInstance() { - return Singleton<FileBrowserEventRouterFactory>::get(); -} - -FileBrowserEventRouterFactory::FileBrowserEventRouterFactory() - : RefcountedProfileKeyedServiceFactory("FileBrowserEventRouter", - ProfileDependencyManager::GetInstance()) { - DependsOn(DriveSystemServiceFactory::GetInstance()); -} - -FileBrowserEventRouterFactory::~FileBrowserEventRouterFactory() { -} - -scoped_refptr<RefcountedProfileKeyedService> -FileBrowserEventRouterFactory::BuildServiceInstanceFor(Profile* profile) const { - return scoped_refptr<RefcountedProfileKeyedService>( - new FileBrowserEventRouter(profile)); -} - -bool FileBrowserEventRouterFactory::ServiceHasOwnInstanceInIncognito() const { - // Explicitly and always allow this router in guest login mode. see - // chrome/browser/profiles/profile_keyed_base_factory.h comment - // for the details. - return true; -} diff --git a/chrome/browser/chromeos/extensions/file_browser_event_router.h b/chrome/browser/chromeos/extensions/file_browser_event_router.h index 5c7b79e..b3e7916 100644 --- a/chrome/browser/chromeos/extensions/file_browser_event_router.h +++ b/chrome/browser/chromeos/extensions/file_browser_event_router.h @@ -19,8 +19,6 @@ #include "chrome/browser/chromeos/drive/drive_resource_metadata.h" #include "chrome/browser/google_apis/drive_service_interface.h" #include "chrome/browser/google_apis/operation_registry.h" -#include "chrome/browser/profiles/refcounted_profile_keyed_service.h" -#include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h" #include "chromeos/disks/disk_mount_manager.h" class FileBrowserNotifications; @@ -35,14 +33,13 @@ class DriveFileSystemInterface; // Monitors changes in disk mounts, network connection state and preferences // affecting File Manager. Dispatches appropriate File Browser events. class FileBrowserEventRouter - : public RefcountedProfileKeyedService, + : public base::RefCountedThreadSafe<FileBrowserEventRouter>, public chromeos::disks::DiskMountManager::Observer, public chromeos::NetworkLibrary::NetworkManagerObserver, public drive::DriveFileSystemObserver, public google_apis::DriveServiceObserver { public: - // RefcountedProfileKeyedService overrides. - virtual void ShutdownOnUIThread() OVERRIDE; + void Shutdown(); // Starts observing file system change events. void ObserveFileSystemEvents(); @@ -92,7 +89,8 @@ class FileBrowserEventRouter virtual void OnFileSystemBeingUnmounted() OVERRIDE; private: - friend class FileBrowserEventRouterFactory; + friend class FileBrowserPrivateAPI; + friend class base::RefCountedThreadSafe<FileBrowserEventRouter>; // Helper class for passing through file watch notification events. class FileWatcherDelegate : public base::files::FilePathWatcher::Delegate { @@ -216,31 +214,4 @@ class FileBrowserEventRouter DISALLOW_COPY_AND_ASSIGN(FileBrowserEventRouter); }; -// Singleton that owns all FileBrowserEventRouter and associates -// them with Profiles. -class FileBrowserEventRouterFactory - : public RefcountedProfileKeyedServiceFactory { - public: - // Returns the FileBrowserEventRouter for |profile|, creating it if - // it is not yet created. - static scoped_refptr<FileBrowserEventRouter> GetForProfile(Profile* profile); - - // Returns the FileBrowserEventRouterFactory instance. - static FileBrowserEventRouterFactory* GetInstance(); - - protected: - // ProfileKeyedBasedFactory overrides: - virtual bool ServiceHasOwnInstanceInIncognito() const OVERRIDE; - - private: - friend struct DefaultSingletonTraits<FileBrowserEventRouterFactory>; - - FileBrowserEventRouterFactory(); - virtual ~FileBrowserEventRouterFactory(); - - // ProfileKeyedServiceFactory: - virtual scoped_refptr<RefcountedProfileKeyedService> BuildServiceInstanceFor( - Profile* profile) const OVERRIDE; -}; - #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_EVENT_ROUTER_H_ diff --git a/chrome/browser/chromeos/extensions/file_browser_handler.cc b/chrome/browser/chromeos/extensions/file_browser_handler.cc new file mode 100644 index 0000000..697a0a4 --- /dev/null +++ b/chrome/browser/chromeos/extensions/file_browser_handler.cc @@ -0,0 +1,355 @@ +// 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 "chrome/browser/chromeos/extensions/file_browser_handler.h" + +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/common/extensions/extension_constants.h" +#include "chrome/common/extensions/extension_manifest_constants.h" +#include "content/public/common/url_constants.h" +#include "extensions/common/error_utils.h" +#include "extensions/common/url_pattern.h" +#include "googleurl/src/gurl.h" +#include "googleurl/src/url_util.h" + +namespace keys = extension_manifest_keys; +namespace errors = extension_manifest_errors; + +namespace { + +const char kReadAccessString[] = "read"; +const char kReadWriteAccessString[] = "read-write"; +const char kCreateAccessString[] = "create"; + +unsigned int kPermissionsNotDefined = 0; +unsigned int kReadPermission = 1; +unsigned int kWritePermission = 1 << 1; +unsigned int kCreatePermission = 1 << 2; +unsigned int kInvalidPermission = 1 << 3; + +unsigned int GetAccessPermissionFlagFromString(const std::string& access_str) { + if (access_str == kReadAccessString) + return kReadPermission; + if (access_str == kReadWriteAccessString) + return kReadPermission | kWritePermission; + if (access_str == kCreateAccessString) + return kCreatePermission; + return kInvalidPermission; +} + +const char* const kMIMETypeHandlersWhitelist[] = { + extension_misc::kQuickOfficeExtensionId, + extension_misc::kQuickOfficeDevExtensionId +}; + +// Stored on the Extension. +struct FileBrowserHandlerInfo : public extensions::Extension::ManifestData { + FileBrowserHandler::List file_browser_handlers; + + FileBrowserHandlerInfo(); + virtual ~FileBrowserHandlerInfo(); +}; + +FileBrowserHandlerInfo::FileBrowserHandlerInfo() { +} + +FileBrowserHandlerInfo::~FileBrowserHandlerInfo() { +} + +} // namespace + +// static +bool FileBrowserHandler::ExtensionWhitelistedForMIMETypes( + const std::string& extension_id) { + if (g_test_extension_id_ && extension_id == *g_test_extension_id_) + return true; + for (size_t i = 0; i < arraysize(kMIMETypeHandlersWhitelist); ++i) { + if (extension_id == kMIMETypeHandlersWhitelist[i]) + return true; + } + return false; +} + +// static +std::vector<std::string> FileBrowserHandler::GetMIMETypeWhitelist() { + std::vector<std::string> whitelist; + if (g_test_extension_id_) + whitelist.push_back(*g_test_extension_id_); + for (size_t i = 0; i < arraysize(kMIMETypeHandlersWhitelist); ++i) + whitelist.push_back(kMIMETypeHandlersWhitelist[i]); + return whitelist; +} + +FileBrowserHandler::FileBrowserHandler() + : file_access_permission_flags_(kPermissionsNotDefined) { +} + +FileBrowserHandler::~FileBrowserHandler() { +} + +void FileBrowserHandler::AddPattern(const URLPattern& pattern) { + url_set_.AddPattern(pattern); +} + +void FileBrowserHandler::ClearPatterns() { + url_set_.ClearPatterns(); +} + +bool FileBrowserHandler::MatchesURL(const GURL& url) const { + return url_set_.MatchesURL(url); +} + +void FileBrowserHandler::AddMIMEType(const std::string& mime_type) { + DCHECK(ExtensionWhitelistedForMIMETypes(extension_id())); + mime_type_set_.insert(mime_type); +} + +bool FileBrowserHandler::CanHandleMIMEType(const std::string& mime_type) const { + return mime_type_set_.find(mime_type) != mime_type_set_.end(); +} + +bool FileBrowserHandler::AddFileAccessPermission( + const std::string& access) { + file_access_permission_flags_ |= GetAccessPermissionFlagFromString(access); + return (file_access_permission_flags_ & kInvalidPermission) != 0U; +} + +bool FileBrowserHandler::ValidateFileAccessPermissions() { + bool is_invalid = (file_access_permission_flags_ & kInvalidPermission) != 0U; + bool can_create = (file_access_permission_flags_ & kCreatePermission) != 0U; + bool can_read_or_write = (file_access_permission_flags_ & + (kReadPermission | kWritePermission)) != 0U; + if (is_invalid || (can_create && can_read_or_write)) { + file_access_permission_flags_ = kInvalidPermission; + return false; + } + + if (file_access_permission_flags_ == kPermissionsNotDefined) + file_access_permission_flags_ = kReadPermission | kWritePermission; + return true; +} + +bool FileBrowserHandler::CanRead() const { + DCHECK(!(file_access_permission_flags_ & kInvalidPermission)); + return (file_access_permission_flags_ & kReadPermission) != 0; +} + +bool FileBrowserHandler::CanWrite() const { + DCHECK(!(file_access_permission_flags_ & kInvalidPermission)); + return (file_access_permission_flags_ & kWritePermission) != 0; +} + +bool FileBrowserHandler::HasCreateAccessPermission() const { + DCHECK(!(file_access_permission_flags_ & kInvalidPermission)); + return (file_access_permission_flags_ & kCreatePermission) != 0; +} + +// static +FileBrowserHandler::List* +FileBrowserHandler::GetHandlers(const extensions::Extension* extension) { + FileBrowserHandlerInfo* info = static_cast<FileBrowserHandlerInfo*>( + extension->GetManifestData(keys::kFileBrowserHandlers)); + if (info) + return &info->file_browser_handlers; + return NULL; +} + +std::string* FileBrowserHandler::g_test_extension_id_ = NULL; + +FileBrowserHandlerParser::FileBrowserHandlerParser() { +} + +FileBrowserHandlerParser::~FileBrowserHandlerParser() { +} + +namespace { + +FileBrowserHandler* LoadFileBrowserHandler( + const std::string& extension_id, + const DictionaryValue* file_browser_handler, + string16* error) { + scoped_ptr<FileBrowserHandler> result(new FileBrowserHandler()); + result->set_extension_id(extension_id); + + std::string handler_id; + // Read the file action |id| (mandatory). + if (!file_browser_handler->HasKey(keys::kPageActionId) || + !file_browser_handler->GetString(keys::kPageActionId, &handler_id)) { + *error = ASCIIToUTF16(errors::kInvalidPageActionId); + return NULL; + } + result->set_id(handler_id); + + // Read the page action title from |default_title| (mandatory). + std::string title; + if (!file_browser_handler->HasKey(keys::kPageActionDefaultTitle) || + !file_browser_handler->GetString(keys::kPageActionDefaultTitle, &title)) { + *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); + return NULL; + } + result->set_title(title); + + // Initialize access permissions (optional). + const ListValue* access_list_value = NULL; + if (file_browser_handler->HasKey(keys::kFileAccessList)) { + if (!file_browser_handler->GetList(keys::kFileAccessList, + &access_list_value) || + access_list_value->empty()) { + *error = ASCIIToUTF16(errors::kInvalidFileAccessList); + return NULL; + } + for (size_t i = 0; i < access_list_value->GetSize(); ++i) { + std::string access; + if (!access_list_value->GetString(i, &access) || + result->AddFileAccessPermission(access)) { + *error = extensions::ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidFileAccessValue, base::IntToString(i)); + return NULL; + } + } + } + if (!result->ValidateFileAccessPermissions()) { + *error = ASCIIToUTF16(errors::kInvalidFileAccessList); + return NULL; + } + + // Initialize file filters (mandatory, unless "create" access is specified, + // in which case is ignored). + if (!result->HasCreateAccessPermission()) { + const ListValue* file_filters = NULL; + if (!file_browser_handler->HasKey(keys::kFileFilters) || + !file_browser_handler->GetList(keys::kFileFilters, &file_filters) || + file_filters->empty()) { + *error = ASCIIToUTF16(errors::kInvalidFileFiltersList); + return NULL; + } + for (size_t i = 0; i < file_filters->GetSize(); ++i) { + std::string filter; + if (!file_filters->GetString(i, &filter)) { + *error = extensions::ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidFileFilterValue, base::IntToString(i)); + return NULL; + } + StringToLowerASCII(&filter); + if (!StartsWithASCII(filter, + std::string(chrome::kFileSystemScheme) + ':', + true)) { + *error = extensions::ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidURLPatternError, filter); + return NULL; + } + // The user inputs filesystem:*; we don't actually implement scheme + // wildcards in URLPattern, so transform to what will match correctly. + filter.replace(0, 11, "chrome-extension://*/"); + URLPattern pattern(URLPattern::SCHEME_EXTENSION); + if (pattern.Parse(filter) != URLPattern::PARSE_SUCCESS) { + *error = extensions::ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidURLPatternError, filter); + return NULL; + } + std::string path = pattern.path(); + bool allowed = path == "/*" || path == "/*.*" || + (path.compare(0, 3, "/*.") == 0 && + path.find_first_of('*', 3) == std::string::npos); + if (!allowed) { + *error = extensions::ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidURLPatternError, filter); + return NULL; + } + result->AddPattern(pattern); + } + + // Initialize MIME type filters (optional). + // NOTE: This is only used by QuickOffice extension to register MIME types + // it can handle by directly downloading them. It will *not* be used in File + // Manager UI. This is why file filters are mandatory even when MIME type + // filters are specified. + const ListValue* mime_type_filters = NULL; + if (file_browser_handler->HasKey(keys::kMIMETypes)) { + if (!FileBrowserHandler::ExtensionWhitelistedForMIMETypes(extension_id)) { + *error = ASCIIToUTF16( + errors::kNoPermissionForFileBrowserHandlerMIMETypes); + return NULL; + } + + if (!file_browser_handler->GetList(keys::kMIMETypes, + &mime_type_filters)) { + *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandlerMIMETypes); + return NULL; + } + + for (size_t i = 0; i < mime_type_filters->GetSize(); ++i) { + std::string filter; + if (!mime_type_filters->GetString(i, &filter)) { + *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandlerMIMETypes); + return NULL; + } + result->AddMIMEType(filter); + } + } + } + + std::string default_icon; + // Read the file browser action |default_icon| (optional). + if (file_browser_handler->HasKey(keys::kPageActionDefaultIcon)) { + if (!file_browser_handler->GetString( + keys::kPageActionDefaultIcon, &default_icon) || + default_icon.empty()) { + *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); + return NULL; + } + result->set_icon_path(default_icon); + } + + return result.release(); +} + +// Loads FileBrowserHandlers from |extension_actions| into a list in |result|. +bool LoadFileBrowserHandlers( + const std::string& extension_id, + const ListValue* extension_actions, + FileBrowserHandler::List* result, + string16* error) { + for (ListValue::const_iterator iter = extension_actions->begin(); + iter != extension_actions->end(); + ++iter) { + if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) { + *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler); + return false; + } + scoped_ptr<FileBrowserHandler> action( + LoadFileBrowserHandler( + extension_id, reinterpret_cast<DictionaryValue*>(*iter), error)); + if (!action.get()) + return false; // Failed to parse file browser action definition. + result->push_back(linked_ptr<FileBrowserHandler>(action.release())); + } + return true; +} + +} // namespace + +bool FileBrowserHandlerParser::Parse(const base::Value* value, + extensions::Extension* extension, + string16* error) { + const ListValue* file_browser_handlers_value = NULL; + if (!value->GetAsList(&file_browser_handlers_value)) { + *error = ASCIIToUTF16(errors::kInvalidFileBrowserHandler); + return false; + } + scoped_ptr<FileBrowserHandlerInfo> info(new FileBrowserHandlerInfo); + if (!LoadFileBrowserHandlers(extension->id(), + file_browser_handlers_value, + &info->file_browser_handlers, + error)) { + return false; // Failed to parse file browser actions definition. + } + + extension->SetManifestData(keys::kFileBrowserHandlers, info.release()); + return true; +} diff --git a/chrome/browser/chromeos/extensions/file_browser_handler.h b/chrome/browser/chromeos/extensions/file_browser_handler.h new file mode 100644 index 0000000..4dfbd69 --- /dev/null +++ b/chrome/browser/chromeos/extensions/file_browser_handler.h @@ -0,0 +1,124 @@ +// 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 CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_HANDLER_H_ + +#include <set> +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/manifest_handler.h" +#include "extensions/common/url_pattern.h" +#include "extensions/common/url_pattern_set.h" +#include "googleurl/src/gurl.h" + +class URLPattern; + +// FileBrowserHandler encapsulates the state of a file browser action. +class FileBrowserHandler { + public: + typedef std::vector<linked_ptr<FileBrowserHandler> > List; + + // Returns true iff the extension with id |extension_id| is allowed to use + // MIME type filters. + static bool ExtensionWhitelistedForMIMETypes(const std::string& extension_id); + + // Returns list of extensions' ids that are allowed to use MIME type filters. + static std::vector<std::string> GetMIMETypeWhitelist(); + + // Whitelists the extension to use MIME type filters for a test. + // |extension_id| should be owned by the test code. + static void set_extension_whitelisted_for_test(std::string* extension_id) { + g_test_extension_id_ = extension_id; + } + + FileBrowserHandler(); + ~FileBrowserHandler(); + + // extension id + std::string extension_id() const { return extension_id_; } + void set_extension_id(const std::string& extension_id) { + extension_id_ = extension_id; + } + + // action id + const std::string& id() const { return id_; } + void set_id(const std::string& id) { id_ = id; } + + // default title + const std::string& title() const { return title_; } + void set_title(const std::string& title) { title_ = title; } + + // File schema URL patterns. + const extensions::URLPatternSet& file_url_patterns() const { + return url_set_; + } + void AddPattern(const URLPattern& pattern); + bool MatchesURL(const GURL& url) const; + void ClearPatterns(); + + // Adds a MIME type filter to the handler. + void AddMIMEType(const std::string& mime_type); + // Tests if the handler has registered a filter for the MIME type. + bool CanHandleMIMEType(const std::string& mime_type) const; + + // Action icon path. + const std::string icon_path() const { return default_icon_path_; } + void set_icon_path(const std::string& path) { + default_icon_path_ = path; + } + + // File access permissions. + // Adjusts file_access_permission_flags_ to allow specified permission. + bool AddFileAccessPermission(const std::string& permission_str); + // Checks that specified file access permissions are valid (all set + // permissions are valid and there is no other permission specified with + // "create") + // If no access permissions were set, initialize them to default value. + bool ValidateFileAccessPermissions(); + // Checks if handler has read access. + bool CanRead() const; + // Checks if handler has write access. + bool CanWrite() const; + // Checks if handler has "create" access specified. + bool HasCreateAccessPermission() const; + + // Returns the file browser handlers associated with the |extension|. + static List* GetHandlers(const extensions::Extension* extension); + + private: + // The id of the extension that will be whitelisted to use MIME type filters + // during tests. + static std::string* g_test_extension_id_; + + // The id for the extension this action belongs to (as defined in the + // extension manifest). + std::string extension_id_; + std::string title_; + std::string default_icon_path_; + // The id for the FileBrowserHandler, for example: "PdfFileAction". + std::string id_; + unsigned int file_access_permission_flags_; + + // A list of file filters. + extensions::URLPatternSet url_set_; + // A list of MIME type filters. + std::set<std::string> mime_type_set_; +}; + +// Parses the "file_browser_handlers" extension manifest key. +class FileBrowserHandlerParser : public extensions::ManifestHandler { + public: + FileBrowserHandlerParser(); + virtual ~FileBrowserHandlerParser(); + + virtual bool Parse(const base::Value* value, + extensions::Extension* extension, + string16* error) OVERRIDE; +}; + +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_HANDLER_H_ diff --git a/chrome/browser/chromeos/extensions/file_browser_manifest_unittest.cc b/chrome/browser/chromeos/extensions/file_browser_manifest_unittest.cc new file mode 100644 index 0000000..58d8314 --- /dev/null +++ b/chrome/browser/chromeos/extensions/file_browser_manifest_unittest.cc @@ -0,0 +1,212 @@ +// 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 "base/string_number_conversions.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" +#include "chrome/common/extensions/extension_builder.h" +#include "chrome/common/extensions/extension_manifest_constants.h" +#include "chrome/common/extensions/manifest_handler.h" +#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h" +#include "chrome/common/extensions/value_builder.h" +#include "extensions/common/error_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace errors = extension_manifest_errors; + +using extensions::DictionaryBuilder; +using extensions::Extension; +using extensions::ExtensionBuilder; +using extensions::ListBuilder; + +namespace { + +class FileBrowserHandlerManifestTest : public ExtensionManifestTest { + virtual void SetUp() OVERRIDE { + ExtensionManifestTest::SetUp(); + extensions::ManifestHandler::Register( + extension_manifest_keys::kFileBrowserHandlers, + new FileBrowserHandlerParser); + } +}; + +TEST_F(FileBrowserHandlerManifestTest, InvalidFileBrowserHandlers) { + Testcase testcases[] = { + Testcase("filebrowser_invalid_access_permission.json", + extensions::ErrorUtils::FormatErrorMessage( + errors::kInvalidFileAccessValue, base::IntToString(1))), + Testcase("filebrowser_invalid_access_permission_list.json", + errors::kInvalidFileAccessList), + Testcase("filebrowser_invalid_empty_access_permission_list.json", + errors::kInvalidFileAccessList), + Testcase("filebrowser_invalid_actions_1.json", + errors::kInvalidFileBrowserHandler), + Testcase("filebrowser_invalid_actions_2.json", + errors::kInvalidFileBrowserHandler), + Testcase("filebrowser_invalid_action_id.json", + errors::kInvalidPageActionId), + Testcase("filebrowser_invalid_action_title.json", + errors::kInvalidPageActionDefaultTitle), + Testcase("filebrowser_invalid_file_filters_1.json", + errors::kInvalidFileFiltersList), + Testcase("filebrowser_invalid_file_filters_2.json", + extensions::ErrorUtils::FormatErrorMessage( + errors::kInvalidFileFilterValue, base::IntToString(0))), + Testcase("filebrowser_invalid_file_filters_url.json", + extensions::ErrorUtils::FormatErrorMessage( + errors::kInvalidURLPatternError, "http:*.html")) + }; + RunTestcases(testcases, arraysize(testcases), EXPECT_TYPE_ERROR); +} + +TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandler) { + scoped_refptr<const Extension> extension = + ExtensionBuilder() + .SetManifest(DictionaryBuilder() + .Set("name", "file browser handler test") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("file_browser_handlers", ListBuilder() + .Append(DictionaryBuilder() + .Set("id", "ExtremelyCoolAction") + .Set("default_title", "Be Amazed") + .Set("default_icon", "icon.png") + .Set("file_filters", ListBuilder() + .Append("filesystem:*.txt"))))) + .Build(); + + ASSERT_TRUE(extension.get()); + FileBrowserHandler::List* handlers = + FileBrowserHandler::GetHandlers(extension); + ASSERT_TRUE(handlers != NULL); + ASSERT_EQ(handlers->size(), 1U); + const FileBrowserHandler* action = handlers->at(0).get(); + + EXPECT_EQ(action->id(), "ExtremelyCoolAction"); + EXPECT_EQ(action->title(), "Be Amazed"); + EXPECT_EQ(action->icon_path(), "icon.png"); + const extensions::URLPatternSet& patterns = action->file_url_patterns(); + ASSERT_EQ(patterns.patterns().size(), 1U); + EXPECT_TRUE(action->MatchesURL( + GURL("filesystem:chrome-extension://foo/local/test.txt"))); + EXPECT_FALSE(action->HasCreateAccessPermission()); + EXPECT_TRUE(action->CanRead()); + EXPECT_TRUE(action->CanWrite()); + EXPECT_FALSE(action->CanHandleMIMEType("plain/text")); +} + +TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerMIMETypes) { + scoped_refptr<const Extension> extension = + ExtensionBuilder() + .SetID(extension_misc::kQuickOfficeExtensionId) + .SetManifest(DictionaryBuilder() + .Set("name", "file browser handler test") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("file_browser_handlers", ListBuilder() + .Append(DictionaryBuilder() + .Set("id", "ID") + .Set("default_title", "Default title") + .Set("default_icon", "icon.png") + .Set("file_filters", ListBuilder() + .Append("filesystem:*.txt")) + .Set("mime_types", ListBuilder() + .Append("plain/text"))))) + .Build(); + + ASSERT_TRUE(extension.get()); + FileBrowserHandler::List* handlers = + FileBrowserHandler::GetHandlers(extension); + ASSERT_TRUE(handlers != NULL); + ASSERT_EQ(handlers->size(), 1U); + const FileBrowserHandler* action = handlers->at(0).get(); + + EXPECT_FALSE(action->CanHandleMIMEType("plain/html")); + EXPECT_TRUE(action->CanHandleMIMEType("plain/text")); + + const extensions::URLPatternSet& patterns = action->file_url_patterns(); + ASSERT_EQ(patterns.patterns().size(), 1U); + EXPECT_TRUE(action->MatchesURL( + GURL("filesystem:chrome-extension://foo/local/test.txt"))); +} + +TEST_F(FileBrowserHandlerManifestTest, + FileBrowserHandlerMIMETypesNotWhitelisted) { + scoped_ptr<DictionaryValue> manifest_value = + DictionaryBuilder() + .Set("name", "MIME types test") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("file_browser_handlers", ListBuilder() + .Append(DictionaryBuilder() + .Set("id", "ID") + .Set("default_title", "Default title") + .Set("default_icon", "icon.png") + .Set("file_filters", ListBuilder() + .Append("filesystem:*.txt")) + .Set("mime_types", ListBuilder() + .Append("plain/text")))) + .Build(); + + LoadAndExpectError(Manifest(manifest_value.get(), "MIME types test"), + errors::kNoPermissionForFileBrowserHandlerMIMETypes); +} + +TEST_F(FileBrowserHandlerManifestTest, ValidFileBrowserHandlerWithCreate) { + scoped_refptr<const Extension> extension = + ExtensionBuilder() + .SetManifest(DictionaryBuilder() + .Set("name", "file browser handler test create") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("file_browser_handlers", ListBuilder() + .Append(DictionaryBuilder() + .Set("id", "ID") + .Set("default_title", "Default title") + .Set("default_icon", "icon.png") + .Set("file_filters", ListBuilder() + .Append("filesystem:*.txt")) + .Set("file_access", ListBuilder() + .Append("create"))))) + .Build(); + + ASSERT_TRUE(extension.get()); + FileBrowserHandler::List* handlers = + FileBrowserHandler::GetHandlers(extension); + ASSERT_TRUE(handlers != NULL); + ASSERT_EQ(handlers->size(), 1U); + const FileBrowserHandler* action = handlers->at(0).get(); + const extensions::URLPatternSet& patterns = action->file_url_patterns(); + + EXPECT_EQ(patterns.patterns().size(), 0U); + EXPECT_TRUE(action->HasCreateAccessPermission()); + EXPECT_FALSE(action->CanRead()); + EXPECT_FALSE(action->CanWrite()); +} + +TEST_F(FileBrowserHandlerManifestTest, FileManagerURLOverride) { + scoped_ptr<DictionaryValue> manifest_value = + DictionaryBuilder() + .Set("name", "override_files") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("chrome_url_overrides", DictionaryBuilder() + .Set("files", "main.html")) + .Build(); + + // Non component extensions can't ovverride chrome://files/ URL. + LoadAndExpectError(Manifest(manifest_value.get(), "override_files"), + errors::kInvalidChromeURLOverrides); + + // A component extention can override chrome://files/ URL. + std::string error; + LoadExtension(Manifest(manifest_value.get(), "override_files"), + &error, Extension::COMPONENT, Extension::NO_FLAGS); +#if defined(FILE_MANAGER_EXTENSION) + EXPECT_EQ("", error); +#else + EXPECT_EQ(std::string(errors::kInvalidChromeURLOverrides), error); +#endif +} + +} // namespace diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_browser_private_api.cc index 96e665f..e75c81c 100644 --- a/chrome/browser/chromeos/extensions/file_browser_private_api.cc +++ b/chrome/browser/chromeos/extensions/file_browser_private_api.cc @@ -32,12 +32,15 @@ #include "chrome/browser/chromeos/drive/drive_file_system_util.h" #include "chrome/browser/chromeos/drive/drive_system_service.h" #include "chrome/browser/chromeos/drive/drive_webapps_registry.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" +#include "chrome/browser/chromeos/extensions/file_browser_private_api_factory.h" #include "chrome/browser/chromeos/extensions/file_handler_util.h" #include "chrome/browser/chromeos/extensions/file_manager_util.h" #include "chrome/browser/chromeos/extensions/zip_file_creator.h" #include "chrome/browser/chromeos/system/statistics_provider.h" #include "chrome/browser/extensions/app_file_handler_util.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/extensions/extension_function_registry.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" @@ -56,7 +59,7 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_icon_set.h" -#include "chrome/common/extensions/file_browser_handler.h" +#include "chrome/common/extensions/extension_manifest_constants.h" #include "chrome/common/pref_names.h" #include "chromeos/disks/disk_mount_manager.h" #include "content/public/browser/child_process_security_policy.h" @@ -530,6 +533,65 @@ class RequestLocalFileSystemFunction::LocalFileSystemCallbackDispatcher { DISALLOW_COPY_AND_ASSIGN(LocalFileSystemCallbackDispatcher); }; +FileBrowserPrivateAPI::FileBrowserPrivateAPI(Profile* profile) + : event_router_(make_scoped_refptr(new FileBrowserEventRouter(profile))) { + extensions::ManifestHandler::Register( + extension_manifest_keys::kFileBrowserHandlers, + new FileBrowserHandlerParser); + + ExtensionFunctionRegistry* registry = + ExtensionFunctionRegistry::GetInstance(); + registry->RegisterFunction<CancelFileDialogFunction>(); + registry->RegisterFunction<ExecuteTasksFileBrowserFunction>(); + registry->RegisterFunction<SetDefaultTaskFileBrowserFunction>(); + registry->RegisterFunction<FileDialogStringsFunction>(); + registry->RegisterFunction<GetFileTasksFileBrowserFunction>(); + registry->RegisterFunction<GetVolumeMetadataFunction>(); + registry->RegisterFunction<RequestLocalFileSystemFunction>(); + registry->RegisterFunction<AddFileWatchBrowserFunction>(); + registry->RegisterFunction<RemoveFileWatchBrowserFunction>(); + registry->RegisterFunction<SelectFileFunction>(); + registry->RegisterFunction<SelectFilesFunction>(); + registry->RegisterFunction<AddMountFunction>(); + registry->RegisterFunction<RemoveMountFunction>(); + registry->RegisterFunction<GetMountPointsFunction>(); + registry->RegisterFunction<GetSizeStatsFunction>(); + registry->RegisterFunction<FormatDeviceFunction>(); + registry->RegisterFunction<ViewFilesFunction>(); + registry->RegisterFunction<ToggleFullscreenFunction>(); + registry->RegisterFunction<IsFullscreenFunction>(); + registry->RegisterFunction<GetDriveFilePropertiesFunction>(); + registry->RegisterFunction<PinDriveFileFunction>(); + registry->RegisterFunction<GetFileLocationsFunction>(); + registry->RegisterFunction<GetDriveFilesFunction>(); + registry->RegisterFunction<GetFileTransfersFunction>(); + registry->RegisterFunction<CancelFileTransfersFunction>(); + registry->RegisterFunction<TransferFileFunction>(); + registry->RegisterFunction<GetPreferencesFunction>(); + registry->RegisterFunction<SetPreferencesFunction>(); + registry->RegisterFunction<SearchDriveFunction>(); + registry->RegisterFunction<ClearDriveCacheFunction>(); + registry->RegisterFunction<ReloadDriveFunction>(); + registry->RegisterFunction<GetNetworkConnectionStateFunction>(); + registry->RegisterFunction<RequestDirectoryRefreshFunction>(); + registry->RegisterFunction<SetLastModifiedFunction>(); + registry->RegisterFunction<ZipSelectionFunction>(); + + event_router_->ObserveFileSystemEvents(); +} + +FileBrowserPrivateAPI::~FileBrowserPrivateAPI() { +} + +void FileBrowserPrivateAPI::Shutdown() { + event_router_->Shutdown(); +} + +// static +FileBrowserPrivateAPI* FileBrowserPrivateAPI::Get(Profile* profile) { + return FileBrowserPrivateAPIFactory::GetForProfile(profile); +} + void RequestLocalFileSystemFunction::RequestOnFileThread( scoped_refptr<fileapi::FileSystemContext> file_system_context, const GURL& source_url, @@ -608,7 +670,7 @@ bool FileWatchBrowserFunctionBase::RunImpl() { base::Bind( &FileWatchBrowserFunctionBase::RunFileWatchOperationOnFileThread, this, - FileBrowserEventRouterFactory::GetForProfile(profile_), + FileBrowserPrivateAPI::Get(profile_)->event_router(), file_watch_url, extension_id())); @@ -1428,7 +1490,7 @@ bool AddMountFunction::RunImpl() { const std::string& drive_path = drive::util::GetDriveMountPointPathAsString(); SetResult(new base::StringValue(drive_path)); - FileBrowserEventRouterFactory::GetForProfile(profile_)-> + FileBrowserPrivateAPI::Get(profile_)->event_router()-> MountDrive(base::Bind(&AddMountFunction::SendResponse, this, success)); diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api.h b/chrome/browser/chromeos/extensions/file_browser_private_api.h index be0d43d..eadc92c 100644 --- a/chrome/browser/chromeos/extensions/file_browser_private_api.h +++ b/chrome/browser/chromeos/extensions/file_browser_private_api.h @@ -10,7 +10,6 @@ #include <string> #include <vector> -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/platform_file.h" #include "chrome/browser/chromeos/drive/drive_file_error.h" @@ -18,9 +17,15 @@ #include "chrome/browser/chromeos/extensions/zip_file_creator.h" #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/profile_keyed_service.h" #include "googleurl/src/url_util.h" class GURL; +class Profile; + +namespace base { +class Value; +} namespace fileapi { class FileSystemContext; @@ -37,6 +42,26 @@ namespace ui { struct SelectedFileInfo; } +// Manages and registers the fileBrowserPrivate API with the extension system. +class FileBrowserPrivateAPI : public ProfileKeyedService { + public: + explicit FileBrowserPrivateAPI(Profile* profile); + virtual ~FileBrowserPrivateAPI(); + + // ProfileKeyedService overrides. + virtual void Shutdown() OVERRIDE; + + // Convenience function to return the FileBrowserPrivateAPI for a Profile. + static FileBrowserPrivateAPI* Get(Profile* profile); + + scoped_refptr<FileBrowserEventRouter> event_router() { + return event_router_; + } + + private: + scoped_refptr<FileBrowserEventRouter> event_router_; +}; + // Implements the chrome.fileBrowserPrivate.requestLocalFileSystem method. class RequestLocalFileSystemFunction : public AsyncExtensionFunction { public: diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api_factory.cc b/chrome/browser/chromeos/extensions/file_browser_private_api_factory.cc new file mode 100644 index 0000000..ce6e337 --- /dev/null +++ b/chrome/browser/chromeos/extensions/file_browser_private_api_factory.cc @@ -0,0 +1,55 @@ +// 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 "chrome/browser/chromeos/extensions/file_browser_private_api_factory.h" + +#include "chrome/browser/chromeos/drive/drive_system_service.h" +#include "chrome/browser/chromeos/extensions/file_browser_private_api.h" +#include "chrome/browser/extensions/extension_system_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_dependency_manager.h" + +// static +FileBrowserPrivateAPI* +FileBrowserPrivateAPIFactory::GetForProfile(Profile* profile) { + return static_cast<FileBrowserPrivateAPI*>( + GetInstance()->GetServiceForProfile(profile, true)); +} + +// static +FileBrowserPrivateAPIFactory* +FileBrowserPrivateAPIFactory::GetInstance() { + return Singleton<FileBrowserPrivateAPIFactory>::get(); +} + +FileBrowserPrivateAPIFactory::FileBrowserPrivateAPIFactory() + : ProfileKeyedServiceFactory( + "FileBrowserPrivateAPI", + ProfileDependencyManager::GetInstance()) { + DependsOn(drive::DriveSystemServiceFactory::GetInstance()); + DependsOn(extensions::ExtensionSystemFactory::GetInstance()); +} + +FileBrowserPrivateAPIFactory::~FileBrowserPrivateAPIFactory() { +} + +ProfileKeyedService* +FileBrowserPrivateAPIFactory::BuildServiceInstanceFor(Profile* profile) const { + return new FileBrowserPrivateAPI(profile); +} + +bool FileBrowserPrivateAPIFactory::ServiceHasOwnInstanceInIncognito() const { + // Explicitly and always allow this router in guest login mode. See + // chrome/browser/profiles/profile_keyed_base_factory.h comment + // for the details. + return true; +} + +bool FileBrowserPrivateAPIFactory::ServiceIsCreatedWithProfile() const { + return true; +} + +bool FileBrowserPrivateAPIFactory::ServiceIsNULLWhileTesting() const { + return true; +} diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api_factory.h b/chrome/browser/chromeos/extensions/file_browser_private_api_factory.h new file mode 100644 index 0000000..b7ed1ac --- /dev/null +++ b/chrome/browser/chromeos/extensions/file_browser_private_api_factory.h @@ -0,0 +1,40 @@ +// 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 CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_PRIVATE_API_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_PRIVATE_API_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" + +class FileBrowserPrivateAPI; +class Profile; + +class FileBrowserPrivateAPIFactory : public ProfileKeyedServiceFactory { + public: + // Returns the FileBrowserPrivateAPI for |profile|, creating it if + // it is not yet created. + static FileBrowserPrivateAPI* GetForProfile(Profile* profile); + + // Returns the FileBrowserPrivateAPIFactory instance. + static FileBrowserPrivateAPIFactory* GetInstance(); + + protected: + // ProfileKeyedBaseFactory overrides: + virtual bool ServiceHasOwnInstanceInIncognito() const OVERRIDE; + virtual bool ServiceIsCreatedWithProfile() const OVERRIDE; + virtual bool ServiceIsNULLWhileTesting() const OVERRIDE; + + private: + friend struct DefaultSingletonTraits<FileBrowserPrivateAPIFactory>; + + FileBrowserPrivateAPIFactory(); + virtual ~FileBrowserPrivateAPIFactory(); + + // ProfileKeyedServiceFactory: + virtual ProfileKeyedService* BuildServiceInstanceFor(Profile* profile) + const OVERRIDE; +}; + +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_BROWSER_PRIVATE_API_FACTORY_H_ diff --git a/chrome/browser/chromeos/extensions/file_browser_resource_throttle.cc b/chrome/browser/chromeos/extensions/file_browser_resource_throttle.cc index 7649929..f7aecc7 100644 --- a/chrome/browser/chromeos/extensions/file_browser_resource_throttle.cc +++ b/chrome/browser/chromeos/extensions/file_browser_resource_throttle.cc @@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/values.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" #include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/browser/extensions/extension_system.h" @@ -15,7 +16,6 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_set.h" -#include "chrome/common/extensions/file_browser_handler.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" @@ -37,12 +37,13 @@ const char* const kOnExecuteContentHandlerEvent = // |extension| must not be NULL. bool CanHandleMimeType(const Extension* extension, const std::string& mime_type) { - if (!extension->file_browser_handlers()) + FileBrowserHandler::List* handlers = + FileBrowserHandler::GetHandlers(extension); + if (!handlers) return false; - for (Extension::FileBrowserHandlerList::const_iterator handler = - extension->file_browser_handlers()->begin(); - handler != extension->file_browser_handlers()->end(); + for (FileBrowserHandler::List::const_iterator handler = handlers->begin(); + handler != handlers->end(); ++handler) { if ((*handler)->CanHandleMIMEType(mime_type)) { return true; diff --git a/chrome/browser/chromeos/extensions/file_browser_resource_throttle_browsertest.cc b/chrome/browser/chromeos/extensions/file_browser_resource_throttle_browsertest.cc index bd24d9f..bcd4488 100644 --- a/chrome/browser/chromeos/extensions/file_browser_resource_throttle_browsertest.cc +++ b/chrome/browser/chromeos/extensions/file_browser_resource_throttle_browsertest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/message_loop.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" #include "chrome/browser/chromeos/extensions/file_browser_resource_throttle.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/extensions/event_router.h" @@ -13,7 +14,6 @@ #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.cc" -#include "chrome/common/extensions/file_browser_handler.h" #include "chrome/common/pref_names.cc" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/download_item.h" @@ -194,8 +194,9 @@ class FileBrowserResourceThrottleExtensionApiTest : public ExtensionApiTest { if (!extension) return NULL; - if (!extension->file_browser_handlers() || - extension->file_browser_handlers()->size() == 0u) { + FileBrowserHandler::List* handlers = + FileBrowserHandler::GetHandlers(extension); + if (!handlers || handlers->size() == 0u) { message_ = "No file browser handlers defined."; return NULL; } @@ -209,7 +210,7 @@ class FileBrowserResourceThrottleExtensionApiTest : public ExtensionApiTest { // that is not white-listed to handle MIME types with its file browser // handlers. FileBrowserHandler* file_browser_handler = const_cast<FileBrowserHandler*>( - extension->file_browser_handlers()->at(0).get()); + handlers->at(0).get()); file_browser_handler->AddMIMEType("application/msword"); file_browser_handler->AddMIMEType("plain/text"); diff --git a/chrome/browser/chromeos/extensions/file_browser_resource_throttle_unittest.cc b/chrome/browser/chromeos/extensions/file_browser_resource_throttle_unittest.cc index 7456c46..8cfe5b7 100644 --- a/chrome/browser/chromeos/extensions/file_browser_resource_throttle_unittest.cc +++ b/chrome/browser/chromeos/extensions/file_browser_resource_throttle_unittest.cc @@ -3,12 +3,14 @@ // found in the LICENSE file. #include "base/message_loop.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" #include "chrome/browser/chromeos/extensions/file_browser_resource_throttle.h" #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_builder.h" #include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/extensions/file_browser_handler.h" +#include "chrome/common/extensions/extension_manifest_constants.h" +#include "chrome/common/extensions/manifest_handler.h" #include "chrome/common/extensions/value_builder.h" #include "content/public/browser/resource_controller.h" #include "content/public/test/test_browser_thread.h" @@ -65,7 +67,10 @@ class FileBrowserResourceThrottleTest : public testing::Test { virtual ~FileBrowserResourceThrottleTest() {} virtual void SetUp() { - // Extension info map must be created before |CreateAndIstallTestExtension| + extensions::ManifestHandler::Register( + extension_manifest_keys::kFileBrowserHandlers, + new FileBrowserHandlerParser); + // Extension info map must be created before |CreateAndInstallTestExtension| // is called (the method will add created extension to the info map). extension_info_map_ = new ExtensionInfoMap(); CreateAndInstallTestExtension(); diff --git a/chrome/browser/chromeos/extensions/file_handler_util.cc b/chrome/browser/chromeos/extensions/file_handler_util.cc index 9e94e65..386d896 100644 --- a/chrome/browser/chromeos/extensions/file_handler_util.cc +++ b/chrome/browser/chromeos/extensions/file_handler_util.cc @@ -13,6 +13,7 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/chromeos/drive/drive_file_system_util.h" #include "chrome/browser/chromeos/drive/drive_task_executor.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" #include "chrome/browser/chromeos/extensions/file_manager_util.h" #include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_host.h" @@ -28,7 +29,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/host_desktop.h" -#include "chrome/common/extensions/file_browser_handler.h" #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" @@ -121,9 +121,11 @@ bool MatchesAllURLs(const FileBrowserHandler* handler) { const FileBrowserHandler* FindFileBrowserHandler(const Extension* extension, const std::string& action_id) { - for (Extension::FileBrowserHandlerList::const_iterator action_iter = - extension->file_browser_handlers()->begin(); - action_iter != extension->file_browser_handlers()->end(); + FileBrowserHandler::List* handler_list = + FileBrowserHandler::GetHandlers(extension); + for (FileBrowserHandler::List::const_iterator action_iter = + handler_list->begin(); + action_iter != handler_list->end(); ++action_iter) { if (action_iter->get()->id() == action_id) return action_iter->get(); @@ -174,12 +176,14 @@ bool GetFileBrowserHandlers(Profile* profile, if (profile->IsOffTheRecord() && !service->IsIncognitoEnabled(extension->id())) continue; - if (!extension->file_browser_handlers()) - continue; - for (Extension::FileBrowserHandlerList::const_iterator action_iter = - extension->file_browser_handlers()->begin(); - action_iter != extension->file_browser_handlers()->end(); + FileBrowserHandler::List* handler_list = + FileBrowserHandler::GetHandlers(extension); + if (!handler_list) + continue; + for (FileBrowserHandler::List::const_iterator action_iter = + handler_list->begin(); + action_iter != handler_list->end(); ++action_iter) { const FileBrowserHandler* action = action_iter->get(); if (!action->MatchesURL(lowercase_url)) diff --git a/chrome/browser/chromeos/extensions/file_handler_util.h b/chrome/browser/chromeos/extensions/file_handler_util.h index 69fd2e7..c92a9fc 100644 --- a/chrome/browser/chromeos/extensions/file_handler_util.h +++ b/chrome/browser/chromeos/extensions/file_handler_util.h @@ -11,10 +11,10 @@ #include "base/callback.h" #include "base/platform_file.h" #include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/file_browser_handler.h" #include "extensions/common/url_pattern_set.h" class Browser; +class FileBrowserHandler; class GURL; class Profile; diff --git a/chrome/browser/chromeos/extensions/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager_util.cc index ffc8d9b..f3501c1 100644 --- a/chrome/browser/chromeos/extensions/file_manager_util.cc +++ b/chrome/browser/chromeos/extensions/file_manager_util.cc @@ -19,6 +19,7 @@ #include "chrome/browser/chromeos/drive/drive_file_system.h" #include "chrome/browser/chromeos/drive/drive_file_system_util.h" #include "chrome/browser/chromeos/drive/drive_system_service.h" +#include "chrome/browser/chromeos/extensions/file_browser_handler.h" #include "chrome/browser/chromeos/extensions/file_handler_util.h" #include "chrome/browser/chromeos/media/media_player.h" #include "chrome/browser/extensions/crx_installer.h" @@ -39,7 +40,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/file_browser_handler.h" #include "chrome/common/url_constants.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/plugin_service.h" diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc index af31e83..699ec62 100644 --- a/chrome/browser/chromeos/login/login_utils_browsertest.cc +++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc @@ -39,6 +39,8 @@ #include "chromeos/dbus/mock_cryptohome_client.h" #include "chromeos/dbus/mock_dbus_thread_manager.h" #include "chromeos/dbus/mock_session_manager_client.h" +#include "chromeos/disks/disk_mount_manager.h" +#include "chromeos/disks/mock_disk_mount_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_utils.h" @@ -189,8 +191,9 @@ class LoginUtilsTest : public testing::Test, // which is part of io_thread_state_. DBusThreadManager::InitializeForTesting(&mock_dbus_thread_manager_); - input_method::InitializeForTesting( - &mock_input_method_manager_); + input_method::InitializeForTesting(&mock_input_method_manager_); + disks::DiskMountManager::InitializeForTesting(&mock_disk_mount_manager_); + mock_disk_mount_manager_.SetupDefaultReplies(); // Likewise, SessionManagerClient should also be initialized before // io_thread_state_. @@ -473,6 +476,7 @@ class LoginUtilsTest : public testing::Test, MockDBusThreadManager mock_dbus_thread_manager_; input_method::MockInputMethodManager mock_input_method_manager_; + disks::MockDiskMountManager mock_disk_mount_manager_; net::TestURLFetcherFactory test_url_fetcher_factory_; cryptohome::MockAsyncMethodCaller* mock_async_method_caller_; |