This source file includes following definitions.
- incognito_enabled
- Equals
- GetInstance
- SetupIfNecessary
- InstallExtension
- UninstallExtension
- GetInstalledExtensionNames
- EnableExtension
- DisableExtension
- IsExtensionEnabled
- IncognitoEnableExtension
- IncognitoDisableExtension
- IsIncognitoEnabled
- IsExtensionPendingInstallForSync
- InstallExtensionsPendingForSync
- GetExtensionStates
- ExtensionStatesMatch
- SetupProfile
- NameToPublicKey
- CreateExtension
- GetExtension
#include "chrome/browser/sync/test/integration/sync_extension_helper.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/pending_extension_info.h"
#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/id_util.h"
#include "extensions/common/manifest_constants.h"
#include "sync/api/string_ordinal.h"
#include "testing/gtest/include/gtest/gtest.h"
using extensions::Extension;
using extensions::ExtensionRegistry;
using extensions::Manifest;
SyncExtensionHelper::ExtensionState::ExtensionState()
: enabled_state(ENABLED), incognito_enabled(false) {}
SyncExtensionHelper::ExtensionState::~ExtensionState() {}
bool SyncExtensionHelper::ExtensionState::Equals(
const SyncExtensionHelper::ExtensionState &other) const {
return ((enabled_state == other.enabled_state) &&
(incognito_enabled == other.incognito_enabled));
}
SyncExtensionHelper* SyncExtensionHelper::GetInstance() {
SyncExtensionHelper* instance = Singleton<SyncExtensionHelper>::get();
instance->SetupIfNecessary(sync_datatype_helper::test());
return instance;
}
SyncExtensionHelper::SyncExtensionHelper() : setup_completed_(false) {}
SyncExtensionHelper::~SyncExtensionHelper() {}
void SyncExtensionHelper::SetupIfNecessary(SyncTest* test) {
if (setup_completed_)
return;
for (int i = 0; i < test->num_clients(); ++i) {
SetupProfile(test->GetProfile(i));
}
SetupProfile(test->verifier());
setup_completed_ = true;
}
std::string SyncExtensionHelper::InstallExtension(
Profile* profile, const std::string& name, Manifest::Type type) {
scoped_refptr<Extension> extension = GetExtension(profile, name, type);
if (!extension.get()) {
NOTREACHED() << "Could not install extension " << name;
return std::string();
}
extensions::ExtensionSystem::Get(profile)
->extension_service()
->OnExtensionInstalled(extension.get(),
syncer::StringOrdinal(),
false ,
extensions::NOT_BLACKLISTED,
false );
return extension->id();
}
void SyncExtensionHelper::UninstallExtension(
Profile* profile, const std::string& name) {
ExtensionService::UninstallExtensionHelper(
extensions::ExtensionSystem::Get(profile)->extension_service(),
extensions::id_util::GenerateId(name));
}
std::vector<std::string> SyncExtensionHelper::GetInstalledExtensionNames(
Profile* profile) const {
std::vector<std::string> names;
scoped_ptr<const extensions::ExtensionSet> extensions(
extensions::ExtensionRegistry::Get(profile)
->GenerateInstalledExtensionsSet());
for (extensions::ExtensionSet::const_iterator it = extensions->begin();
it != extensions->end(); ++it) {
names.push_back((*it)->name());
}
return names;
}
void SyncExtensionHelper::EnableExtension(Profile* profile,
const std::string& name) {
extensions::ExtensionSystem::Get(profile)
->extension_service()
->EnableExtension(extensions::id_util::GenerateId(name));
}
void SyncExtensionHelper::DisableExtension(Profile* profile,
const std::string& name) {
extensions::ExtensionSystem::Get(profile)
->extension_service()
->DisableExtension(extensions::id_util::GenerateId(name),
Extension::DISABLE_USER_ACTION);
}
bool SyncExtensionHelper::IsExtensionEnabled(
Profile* profile, const std::string& name) const {
return extensions::ExtensionSystem::Get(profile)
->extension_service()
->IsExtensionEnabled(extensions::id_util::GenerateId(name));
}
void SyncExtensionHelper::IncognitoEnableExtension(
Profile* profile, const std::string& name) {
extensions::util::SetIsIncognitoEnabled(
extensions::id_util::GenerateId(name), profile, true);
}
void SyncExtensionHelper::IncognitoDisableExtension(
Profile* profile, const std::string& name) {
extensions::util::SetIsIncognitoEnabled(
extensions::id_util::GenerateId(name), profile, false);
}
bool SyncExtensionHelper::IsIncognitoEnabled(
Profile* profile, const std::string& name) const {
return extensions::util::IsIncognitoEnabled(
extensions::id_util::GenerateId(name), profile);
}
bool SyncExtensionHelper::IsExtensionPendingInstallForSync(
Profile* profile, const std::string& id) const {
const extensions::PendingExtensionManager* pending_extension_manager =
extensions::ExtensionSystem::Get(profile)
->extension_service()
->pending_extension_manager();
const extensions::PendingExtensionInfo* info =
pending_extension_manager->GetById(id);
if (!info)
return false;
return info->is_from_sync();
}
void SyncExtensionHelper::InstallExtensionsPendingForSync(Profile* profile) {
const extensions::PendingExtensionManager* pending_extension_manager =
extensions::ExtensionSystem::Get(profile)
->extension_service()
->pending_extension_manager();
std::list<std::string> pending_crx_ids;
pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_crx_ids);
std::list<std::string>::const_iterator iter;
const extensions::PendingExtensionInfo* info = NULL;
for (iter = pending_crx_ids.begin(); iter != pending_crx_ids.end(); ++iter) {
ASSERT_TRUE((info = pending_extension_manager->GetById(*iter)));
if (!info->is_from_sync())
continue;
StringMap::const_iterator iter2 = id_to_name_.find(*iter);
if (iter2 == id_to_name_.end()) {
ADD_FAILURE() << "Could not get name for id " << *iter
<< " (profile = " << profile->GetDebugName() << ")";
continue;
}
TypeMap::const_iterator iter3 = id_to_type_.find(*iter);
if (iter3 == id_to_type_.end()) {
ADD_FAILURE() << "Could not get type for id " << *iter
<< " (profile = " << profile->GetDebugName() << ")";
}
InstallExtension(profile, iter2->second, iter3->second);
}
}
SyncExtensionHelper::ExtensionStateMap
SyncExtensionHelper::GetExtensionStates(Profile* profile) {
const std::string& profile_debug_name = profile->GetDebugName();
ExtensionStateMap extension_state_map;
scoped_ptr<const extensions::ExtensionSet> extensions(
extensions::ExtensionRegistry::Get(profile)
->GenerateInstalledExtensionsSet());
ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
for (extensions::ExtensionSet::const_iterator it = extensions->begin();
it != extensions->end(); ++it) {
const std::string& id = (*it)->id();
extension_state_map[id].enabled_state =
extension_service->IsExtensionEnabled(id) ?
ExtensionState::ENABLED :
ExtensionState::DISABLED;
extension_state_map[id].incognito_enabled =
extensions::util::IsIncognitoEnabled(id, profile);
DVLOG(2) << "Extension " << (*it)->id() << " in profile "
<< profile_debug_name << " is "
<< (extension_service->IsExtensionEnabled(id) ?
"enabled" : "disabled");
}
const extensions::PendingExtensionManager* pending_extension_manager =
extension_service->pending_extension_manager();
std::list<std::string> pending_crx_ids;
pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_crx_ids);
std::list<std::string>::const_iterator id;
for (id = pending_crx_ids.begin(); id != pending_crx_ids.end(); ++id) {
extension_state_map[*id].enabled_state = ExtensionState::PENDING;
extension_state_map[*id].incognito_enabled =
extensions::util::IsIncognitoEnabled(*id, profile);
DVLOG(2) << "Extension " << *id << " in profile "
<< profile_debug_name << " is pending";
}
return extension_state_map;
}
bool SyncExtensionHelper::ExtensionStatesMatch(
Profile* profile1, Profile* profile2) {
const ExtensionStateMap& state_map1 = GetExtensionStates(profile1);
const ExtensionStateMap& state_map2 = GetExtensionStates(profile2);
if (state_map1.size() != state_map2.size()) {
DVLOG(1) << "Number of extensions for profile " << profile1->GetDebugName()
<< " does not match profile " << profile2->GetDebugName();
return false;
}
ExtensionStateMap::const_iterator it1 = state_map1.begin();
ExtensionStateMap::const_iterator it2 = state_map2.begin();
while (it1 != state_map1.end()) {
if (it1->first != it2->first) {
DVLOG(1) << "Extensions for profile " << profile1->GetDebugName()
<< " do not match profile " << profile2->GetDebugName();
return false;
} else if (!it1->second.Equals(it2->second)) {
DVLOG(1) << "Extension states for profile " << profile1->GetDebugName()
<< " do not match profile " << profile2->GetDebugName();
return false;
}
++it1;
++it2;
}
return true;
}
void SyncExtensionHelper::SetupProfile(Profile* profile) {
extensions::ExtensionSystem::Get(profile)->InitForRegularProfile(true);
profile_extensions_.insert(make_pair(profile, ExtensionNameMap()));
}
namespace {
std::string NameToPublicKey(const std::string& name) {
std::string public_key;
std::string pem;
EXPECT_TRUE(Extension::ProducePEM(name, &pem) &&
Extension::FormatPEMForFileOutput(pem, &public_key,
true ));
return public_key;
}
scoped_refptr<Extension> CreateExtension(const base::FilePath& base_dir,
const std::string& name,
Manifest::Type type) {
base::DictionaryValue source;
source.SetString(extensions::manifest_keys::kName, name);
const std::string& public_key = NameToPublicKey(name);
source.SetString(extensions::manifest_keys::kPublicKey, public_key);
source.SetString(extensions::manifest_keys::kVersion, "0.0.0.0");
switch (type) {
case Manifest::TYPE_EXTENSION:
break;
case Manifest::TYPE_THEME:
source.Set(extensions::manifest_keys::kTheme,
new base::DictionaryValue());
break;
case Manifest::TYPE_HOSTED_APP:
case Manifest::TYPE_LEGACY_PACKAGED_APP:
source.Set(extensions::manifest_keys::kApp, new base::DictionaryValue());
source.SetString(extensions::manifest_keys::kLaunchWebURL,
"http://www.example.com");
break;
case Manifest::TYPE_PLATFORM_APP: {
source.Set(extensions::manifest_keys::kApp, new base::DictionaryValue());
source.Set(extensions::manifest_keys::kPlatformAppBackground,
new base::DictionaryValue());
base::ListValue* scripts = new base::ListValue();
scripts->AppendString("main.js");
source.Set(extensions::manifest_keys::kPlatformAppBackgroundScripts,
scripts);
break;
}
default:
ADD_FAILURE();
return NULL;
}
const base::FilePath sub_dir = base::FilePath().AppendASCII(name);
base::FilePath extension_dir;
if (!base::PathExists(base_dir) &&
!base::CreateDirectory(base_dir)) {
ADD_FAILURE();
return NULL;
}
if (!base::CreateTemporaryDirInDir(base_dir, sub_dir.value(),
&extension_dir)) {
ADD_FAILURE();
return NULL;
}
std::string error;
scoped_refptr<Extension> extension =
Extension::Create(extension_dir, Manifest::INTERNAL, source,
Extension::NO_FLAGS, &error);
if (!error.empty()) {
ADD_FAILURE() << error;
return NULL;
}
if (!extension.get()) {
ADD_FAILURE();
return NULL;
}
if (extension->name() != name) {
EXPECT_EQ(name, extension->name());
return NULL;
}
if (extension->GetType() != type) {
EXPECT_EQ(type, extension->GetType());
return NULL;
}
return extension;
}
}
scoped_refptr<Extension> SyncExtensionHelper::GetExtension(
Profile* profile, const std::string& name, Manifest::Type type) {
if (name.empty()) {
ADD_FAILURE();
return NULL;
}
ProfileExtensionNameMap::iterator it = profile_extensions_.find(profile);
if (it == profile_extensions_.end()) {
ADD_FAILURE();
return NULL;
}
ExtensionNameMap::const_iterator it2 = it->second.find(name);
if (it2 != it->second.end()) {
return it2->second;
}
scoped_refptr<Extension> extension =
CreateExtension(extensions::ExtensionSystem::Get(profile)
->extension_service()
->install_directory(),
name,
type);
if (!extension.get()) {
ADD_FAILURE();
return NULL;
}
const std::string& expected_id = extensions::id_util::GenerateId(name);
if (extension->id() != expected_id) {
EXPECT_EQ(expected_id, extension->id());
return NULL;
}
DVLOG(2) << "created extension with name = "
<< name << ", id = " << expected_id;
(it->second)[name] = extension;
id_to_name_[expected_id] = name;
id_to_type_[expected_id] = type;
return extension;
}