blob: 68f41d24cc352b11e25362414f15c3d198ce7570 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/test_extension_system.h"
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/blocklist.h"
#include "chrome/browser/extensions/chrome_app_sorting.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/cws_info_service.h"
#include "chrome/browser/extensions/cws_info_service_factory.h"
#include "chrome/browser/extensions/extension_management.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "components/prefs/pref_service.h"
#include "components/services/unzip/content/unzip_service.h"
#include "components/services/unzip/in_process_unzipper.h"
#include "components/value_store/test_value_store_factory.h"
#include "components/value_store/testing_value_store.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/quota_service.h"
#include "extensions/browser/state_store.h"
#include "extensions/browser/user_script_manager.h"
#include "services/data_decoder/data_decoder_service.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager.h"
#endif
using content::BrowserThread;
namespace extensions {
namespace {
// A fake CWSInfoService for tests that utilize the test extension system and
// service infrastructure but do not depend on the actual functionality of the
// service.
class FakeCWSInfoService : public CWSInfoService {
public:
explicit FakeCWSInfoService(Profile* profile) {}
explicit FakeCWSInfoService(const CWSInfoService&) = delete;
FakeCWSInfoService& operator=(const CWSInfoService&) = delete;
~FakeCWSInfoService() override = default;
// CWSInfoServiceInterface:
std::optional<bool> IsLiveInCWS(const Extension& extension) const override;
std::optional<CWSInfo> GetCWSInfo(const Extension& extension) const override;
void CheckAndMaybeFetchInfo() override {}
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
// KeyedService:
// Ensure that the keyed service shutdown is a no-op.
void Shutdown() override {}
};
std::optional<bool> FakeCWSInfoService::IsLiveInCWS(
const Extension& extension) const {
return true;
}
std::optional<CWSInfoServiceInterface::CWSInfo> FakeCWSInfoService::GetCWSInfo(
const Extension& extension) const {
return CWSInfoServiceInterface::CWSInfo();
}
std::unique_ptr<KeyedService> BuildFakeCWSService(
content::BrowserContext* context) {
return std::make_unique<FakeCWSInfoService>(
Profile::FromBrowserContext(context));
}
} // namespace
TestExtensionSystem::TestExtensionSystem(Profile* profile)
: profile_(profile),
store_factory_(new value_store::TestValueStoreFactory()),
state_store_(new StateStore(profile_,
store_factory_,
StateStore::BackendType::RULES,
false)),
quota_service_(new QuotaService()),
app_sorting_(new ChromeAppSorting(profile_)) {}
TestExtensionSystem::~TestExtensionSystem() = default;
void TestExtensionSystem::Shutdown() {
if (extension_service_)
extension_service_->Shutdown();
in_process_data_decoder_.reset();
}
ExtensionService* TestExtensionSystem::CreateExtensionService(
const base::CommandLine* command_line,
const base::FilePath& install_directory,
bool autoupdate_enabled,
bool extensions_enabled) {
return CreateExtensionService(command_line, install_directory,
base::FilePath(), autoupdate_enabled,
extensions_enabled);
}
ExtensionService* TestExtensionSystem::CreateExtensionService(
const base::CommandLine* command_line,
const base::FilePath& install_directory,
const base::FilePath& unpacked_install_directory,
bool autoupdate_enabled,
bool extensions_enabled) {
if (CWSInfoService::Get(profile_) == nullptr) {
Profile* profile = profile_;
#if BUILDFLAG(IS_CHROMEOS_ASH)
// TODO(crbug.com/40891982): Refactor this convenience upstream to test
// callers. Possibly just BuiltInAppTest.BuildGuestMode.
if (profile_->IsGuestSession()) {
profile = profile_->GetOriginalProfile();
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// Associate a dummy CWSInfoService with this profile if necessary.
CWSInfoServiceFactory::GetInstance()->SetTestingFactory(
profile, base::BindRepeating(&BuildFakeCWSService));
}
management_policy_ = std::make_unique<ManagementPolicy>();
management_policy_->RegisterProviders(
ExtensionManagementFactory::GetForBrowserContext(profile_)
->GetProviders());
extension_service_ = std::make_unique<ExtensionService>(
profile_, command_line, install_directory, unpacked_install_directory,
ExtensionPrefs::Get(profile_), Blocklist::Get(profile_),
autoupdate_enabled, extensions_enabled, &ready_);
unzip::SetUnzipperLaunchOverrideForTesting(
base::BindRepeating(&unzip::LaunchInProcessUnzipper));
in_process_data_decoder_ =
std::make_unique<data_decoder::test::InProcessDataDecoder>();
extension_service_->ClearProvidersForTesting();
return extension_service_.get();
}
void TestExtensionSystem::CreateUserScriptManager() {
user_script_manager_ = std::make_unique<UserScriptManager>(profile_);
}
ExtensionService* TestExtensionSystem::extension_service() {
return extension_service_.get();
}
ManagementPolicy* TestExtensionSystem::management_policy() {
return management_policy_.get();
}
void TestExtensionSystem::SetExtensionService(ExtensionService* service) {
extension_service_.reset(service);
}
ServiceWorkerManager* TestExtensionSystem::service_worker_manager() {
return nullptr;
}
UserScriptManager* TestExtensionSystem::user_script_manager() {
return user_script_manager_.get();
}
StateStore* TestExtensionSystem::state_store() {
return state_store_.get();
}
StateStore* TestExtensionSystem::rules_store() {
return state_store_.get();
}
StateStore* TestExtensionSystem::dynamic_user_scripts_store() {
return state_store_.get();
}
scoped_refptr<value_store::ValueStoreFactory>
TestExtensionSystem::store_factory() {
return store_factory_;
}
QuotaService* TestExtensionSystem::quota_service() {
return quota_service_.get();
}
AppSorting* TestExtensionSystem::app_sorting() {
return app_sorting_.get();
}
const base::OneShotEvent& TestExtensionSystem::ready() const {
return ready_;
}
bool TestExtensionSystem::is_ready() const {
return ready_.is_signaled();
}
ContentVerifier* TestExtensionSystem::content_verifier() {
return content_verifier_.get();
}
std::unique_ptr<ExtensionSet> TestExtensionSystem::GetDependentExtensions(
const Extension* extension) {
return extension_service()->shared_module_service()->GetDependentExtensions(
extension);
}
void TestExtensionSystem::InstallUpdate(
const std::string& extension_id,
const std::string& public_key,
const base::FilePath& temp_dir,
bool install_immediately,
InstallUpdateCallback install_update_callback) {
NOTREACHED_IN_MIGRATION();
}
void TestExtensionSystem::PerformActionBasedOnOmahaAttributes(
const std::string& extension_id,
const base::Value::Dict& attributes) {}
bool TestExtensionSystem::FinishDelayedInstallationIfReady(
const std::string& extension_id,
bool install_immediately) {
NOTREACHED_IN_MIGRATION();
return false;
}
value_store::TestingValueStore* TestExtensionSystem::value_store() {
// These tests use TestingValueStore in a way that ensures it only ever mints
// instances of TestingValueStore.
return static_cast<value_store::TestingValueStore*>(
store_factory_->LastCreatedStore());
}
// static
std::unique_ptr<KeyedService> TestExtensionSystem::Build(
content::BrowserContext* profile) {
return base::WrapUnique(
new TestExtensionSystem(static_cast<Profile*>(profile)));
}
void TestExtensionSystem::RecreateAppSorting() {
app_sorting_ = std::make_unique<ChromeAppSorting>(profile_);
}
} // namespace extensions