diff options
Diffstat (limited to 'chromium/extensions/browser/value_store/legacy_value_store_factory.cc')
-rw-r--r-- | chromium/extensions/browser/value_store/legacy_value_store_factory.cc | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/chromium/extensions/browser/value_store/legacy_value_store_factory.cc b/chromium/extensions/browser/value_store/legacy_value_store_factory.cc new file mode 100644 index 00000000000..bafb93ee2a3 --- /dev/null +++ b/chromium/extensions/browser/value_store/legacy_value_store_factory.cc @@ -0,0 +1,264 @@ +// Copyright 2016 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 "extensions/browser/value_store/legacy_value_store_factory.h" + +#include <string> + +#include "base/files/file_enumerator.h" +#include "base/files/file_util.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/browser/value_store/leveldb_value_store.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" + +using base::AutoLock; +using content::BrowserThread; + +namespace { + +// Statistics are logged to UMA with these strings as part of histogram name. +// They can all be found under Extensions.Database.Open.<client>. Changing this +// needs to synchronize with histograms.xml, AND will also become incompatible +// with older browsers still reporting the previous values. +const char kSettingsDatabaseUMAClientName[] = "Settings"; +const char kRulesDatabaseUMAClientName[] = "Rules"; +const char kStateDatabaseUMAClientName[] = "State"; + +bool ValidDBExists(const base::FilePath& path) { + // TODO(cmumford): Enhance to detect if dir contains valid database. + return base::DirectoryExists(path); +} + +} // namespace + +namespace extensions { + +// +// ModelSettings +// +LegacyValueStoreFactory::ModelSettings::ModelSettings( + const base::FilePath& data_path) + : data_path_(data_path) {} + +base::FilePath LegacyValueStoreFactory::ModelSettings::GetDBPath( + const ExtensionId& extension_id) const { + return data_path_.AppendASCII(extension_id); +} + +bool LegacyValueStoreFactory::ModelSettings::DeleteData( + const ExtensionId& extension_id) { + return base::DeleteFile(GetDBPath(extension_id), true /* recursive */); +} + +bool LegacyValueStoreFactory::ModelSettings::DataExists( + const ExtensionId& extension_id) const { + return ValidDBExists(GetDBPath(extension_id)); +} + +std::set<ExtensionId> +LegacyValueStoreFactory::ModelSettings::GetKnownExtensionIDs() const { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + std::set<ExtensionId> result; + + // Leveldb databases are directories inside |base_path_|. + base::FileEnumerator extension_dirs(data_path_, false, + base::FileEnumerator::DIRECTORIES); + while (!extension_dirs.Next().empty()) { + base::FilePath extension_dir = extension_dirs.GetInfo().GetName(); + DCHECK(!extension_dir.IsAbsolute()); + // Extension ID's are 'a'..'p', so any directory within this folder will + // either be ASCII, or created by some other application and safe to ignore. + std::string maybe_as_ascii(extension_dir.MaybeAsASCII()); + if (!maybe_as_ascii.empty()) { + result.insert(maybe_as_ascii); + } + } + + return result; +} + +// +// SettingsRoot +// + +LegacyValueStoreFactory::SettingsRoot::SettingsRoot( + const base::FilePath& base_path, + const std::string& extension_dirname, + const std::string& app_dirname) { + if (!extension_dirname.empty()) + extensions_.reset( + new ModelSettings(base_path.AppendASCII(extension_dirname))); + + if (!app_dirname.empty()) + apps_.reset(new ModelSettings(base_path.AppendASCII(app_dirname))); +} + +LegacyValueStoreFactory::SettingsRoot::~SettingsRoot() = default; + +const LegacyValueStoreFactory::ModelSettings* +LegacyValueStoreFactory::SettingsRoot::GetModel(ModelType model_type) const { + switch (model_type) { + case ValueStoreFactory::ModelType::APP: + DCHECK(apps_ != nullptr); + return apps_.get(); + case ValueStoreFactory::ModelType::EXTENSION: + DCHECK(extensions_ != nullptr); + return extensions_.get(); + } + NOTREACHED(); + return nullptr; +} + +LegacyValueStoreFactory::ModelSettings* +LegacyValueStoreFactory::SettingsRoot::GetModel(ModelType model_type) { + switch (model_type) { + case ValueStoreFactory::ModelType::APP: + DCHECK(apps_ != nullptr); + return apps_.get(); + case ValueStoreFactory::ModelType::EXTENSION: + DCHECK(extensions_ != nullptr); + return extensions_.get(); + } + NOTREACHED(); + return nullptr; +} + +std::set<ExtensionId> +LegacyValueStoreFactory::SettingsRoot::GetKnownExtensionIDs( + ModelType model_type) const { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + switch (model_type) { + case ValueStoreFactory::ModelType::APP: + DCHECK(apps_ != nullptr); + return apps_->GetKnownExtensionIDs(); + case ValueStoreFactory::ModelType::EXTENSION: + DCHECK(extensions_ != nullptr); + return extensions_->GetKnownExtensionIDs(); + } + NOTREACHED(); + return std::set<ExtensionId>(); +} + +// +// LegacyValueStoreFactory +// + +LegacyValueStoreFactory::LegacyValueStoreFactory( + const base::FilePath& profile_path) + : profile_path_(profile_path), + local_settings_(profile_path, + kLocalExtensionSettingsDirectoryName, + kLocalAppSettingsDirectoryName), + sync_settings_(profile_path, + kSyncExtensionSettingsDirectoryName, + kSyncAppSettingsDirectoryName), + // Currently no such thing as a managed app - only an extension. + managed_settings_(profile_path, kManagedSettingsDirectoryName, "") {} + +LegacyValueStoreFactory::~LegacyValueStoreFactory() = default; + +bool LegacyValueStoreFactory::RulesDBExists() const { + return ValidDBExists(GetRulesDBPath()); +} + +bool LegacyValueStoreFactory::StateDBExists() const { + return ValidDBExists(GetStateDBPath()); +} + +scoped_ptr<ValueStore> LegacyValueStoreFactory::CreateRulesStore() { + return make_scoped_ptr( + new LeveldbValueStore(kRulesDatabaseUMAClientName, GetRulesDBPath())); +} + +scoped_ptr<ValueStore> LegacyValueStoreFactory::CreateStateStore() { + return make_scoped_ptr( + new LeveldbValueStore(kStateDatabaseUMAClientName, GetStateDBPath())); +} + +scoped_ptr<ValueStore> LegacyValueStoreFactory::CreateSettingsStore( + settings_namespace::Namespace settings_namespace, + ModelType model_type, + const ExtensionId& extension_id) { + const ModelSettings* settings_root = + GetSettingsRoot(settings_namespace).GetModel(model_type); + DCHECK(settings_root != nullptr); + return make_scoped_ptr(new LeveldbValueStore( + kSettingsDatabaseUMAClientName, settings_root->GetDBPath(extension_id))); +} + +void LegacyValueStoreFactory::DeleteSettings( + settings_namespace::Namespace settings_namespace, + ModelType model_type, + const ExtensionId& extension_id) { + // TODO(cmumford): Verify that we always need to be called on FILE thread. + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + ModelSettings* model_settings = + GetSettingsRoot(settings_namespace).GetModel(model_type); + if (model_settings == nullptr) { + NOTREACHED(); + return; + } + model_settings->DeleteData(extension_id); +} + +bool LegacyValueStoreFactory::HasSettings( + settings_namespace::Namespace settings_namespace, + ModelType model_type, + const ExtensionId& extension_id) { + const ModelSettings* model_settings = + GetSettingsRoot(settings_namespace).GetModel(model_type); + if (model_settings == nullptr) + return false; + return model_settings->DataExists(extension_id); +} + +std::set<ExtensionId> LegacyValueStoreFactory::GetKnownExtensionIDs( + settings_namespace::Namespace settings_type, + ModelType model_type) const { + return GetSettingsRoot(settings_type).GetKnownExtensionIDs(model_type); +} + +const LegacyValueStoreFactory::SettingsRoot& +LegacyValueStoreFactory::GetSettingsRoot( + settings_namespace::Namespace settings_namespace) const { + switch (settings_namespace) { + case settings_namespace::LOCAL: + return local_settings_; + case settings_namespace::SYNC: + return sync_settings_; + case settings_namespace::MANAGED: + return managed_settings_; + case settings_namespace::INVALID: + break; + } + NOTREACHED(); + return local_settings_; +} + +LegacyValueStoreFactory::SettingsRoot& LegacyValueStoreFactory::GetSettingsRoot( + settings_namespace::Namespace settings_namespace) { + switch (settings_namespace) { + case settings_namespace::LOCAL: + return local_settings_; + case settings_namespace::SYNC: + return sync_settings_; + case settings_namespace::MANAGED: + return managed_settings_; + case settings_namespace::INVALID: + break; + } + NOTREACHED(); + return local_settings_; +} + +base::FilePath LegacyValueStoreFactory::GetRulesDBPath() const { + return profile_path_.AppendASCII(kRulesStoreName); +} + +base::FilePath LegacyValueStoreFactory::GetStateDBPath() const { + return profile_path_.AppendASCII(kStateStoreName); +} + +} // namespace extensions |