| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/browser/test_extensions_browser_client.h" |
| |
| #include "base/command_line.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "components/update_client/configurator.h" |
| #include "components/update_client/test_configurator.h" |
| #include "content/public/browser/browser_context.h" |
| #include "extensions/browser/extension_host_delegate.h" |
| #include "extensions/browser/kiosk/kiosk_delegate.h" |
| #include "extensions/browser/safe_browsing_delegate.h" |
| #include "extensions/browser/test_runtime_api_delegate.h" |
| #include "extensions/browser/updater/null_extension_cache.h" |
| #include "extensions/buildflags/buildflags.h" |
| #include "extensions/common/extension_id.h" |
| #include "extensions/common/switches.h" |
| #include "extensions/common/url_pattern_set.h" |
| #include "services/network/public/mojom/url_loader.mojom.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| #include "chromeos/ash/components/login/login_state/login_state.h" |
| #endif |
| |
| using content::BrowserContext; |
| |
| namespace extensions { |
| namespace { |
| |
| // An ExtensionManagementClient that returns safe/null defaults. |
| class TestExtensionManagementClient : public ExtensionManagementClient { |
| public: |
| explicit TestExtensionManagementClient() = default; |
| TestExtensionManagementClient(const TestExtensionManagementClient&) = delete; |
| TestExtensionManagementClient& operator=( |
| const TestExtensionManagementClient&) = delete; |
| ~TestExtensionManagementClient() override = default; |
| |
| // ExtensionManagementClient: |
| bool UpdatesFromWebstore(const Extension& extension) override { return true; } |
| bool IsInstallationExplicitlyAllowed(const ExtensionId& id) override { |
| return false; |
| } |
| bool IsForceInstalledInLowTrustEnvironment( |
| const Extension& extension) override { |
| return false; |
| } |
| const URLPatternSet& GetPolicyBlockedHosts( |
| const Extension* extension) override { |
| return URLPatternSet::Empty(); |
| } |
| const URLPatternSet& GetPolicyAllowedHosts( |
| const Extension* extension) override { |
| return URLPatternSet::Empty(); |
| } |
| bool UsesDefaultPolicyHostRestrictions(const Extension* extension) override { |
| return false; |
| } |
| bool BlocklistedByDefault() const override { return false; } |
| GURL GetEffectiveUpdateURL(const Extension& extension) override { return {}; } |
| |
| bool IsAllowedManifestType(Manifest::Type manifest_type, |
| const std::string& extension_id) const override { |
| return false; |
| } |
| ManagedInstallationMode GetInstallationMode( |
| const Extension* extension) override { |
| return ManagedInstallationMode::kBlocked; |
| } |
| ManagedInstallationMode GetInstallationMode( |
| const ExtensionId& extension_id, |
| const std::string& update_url) override { |
| return ManagedInstallationMode::kBlocked; |
| } |
| const std::string BlockedInstallMessage(const ExtensionId& id) override { |
| return std::string(); |
| } |
| bool IsPermissionSetAllowed(const Extension* extension, |
| const PermissionSet& perms) override { |
| return false; |
| } |
| bool IsPermissionSetAllowed(const ExtensionId& extension_id, |
| const std::string& update_url, |
| const PermissionSet& perms) override { |
| return false; |
| } |
| bool IsInstallationExplicitlyBlocked(const ExtensionId& id) override { |
| return false; |
| } |
| }; |
| |
| // A KioskDelegate that returns safe/null defaults. |
| class TestKioskDelegate : public KioskDelegate { |
| public: |
| TestKioskDelegate() = default; |
| TestKioskDelegate(const TestKioskDelegate&) = delete; |
| TestKioskDelegate& operator=(const TestKioskDelegate&) = delete; |
| ~TestKioskDelegate() override = default; |
| |
| // KioskDelegate: |
| bool IsAutoLaunchedKioskApp(const ExtensionId& id) const override { |
| return false; |
| } |
| }; |
| |
| } // namespace |
| |
| TestExtensionsBrowserClient::TestExtensionsBrowserClient( |
| BrowserContext* main_context) |
| : extension_cache_(std::make_unique<NullExtensionCache>()), |
| safe_browsing_delegate_(std::make_unique<SafeBrowsingDelegate>()), |
| extension_management_client_( |
| std::make_unique<TestExtensionManagementClient>()), |
| kiosk_delegate_(std::make_unique<TestKioskDelegate>()) { |
| if (main_context) { |
| SetMainContext(main_context); |
| } |
| } |
| |
| TestExtensionsBrowserClient::TestExtensionsBrowserClient() |
| : TestExtensionsBrowserClient(nullptr) {} |
| |
| TestExtensionsBrowserClient::~TestExtensionsBrowserClient() = default; |
| |
| void TestExtensionsBrowserClient::SetUpdateClientFactory( |
| base::RepeatingCallback<update_client::UpdateClient*(void)> factory) { |
| update_client_factory_ = std::move(factory); |
| } |
| |
| void TestExtensionsBrowserClient::SetMainContext( |
| content::BrowserContext* main_context) { |
| DCHECK(!main_context_); |
| DCHECK(main_context); |
| DCHECK(!main_context->IsOffTheRecord()); |
| main_context_ = main_context; |
| } |
| |
| void TestExtensionsBrowserClient::SetIncognitoContext(BrowserContext* context) { |
| // If a context is provided it must be off-the-record. |
| DCHECK(!context || context->IsOffTheRecord()); |
| incognito_context_ = context; |
| } |
| |
| bool TestExtensionsBrowserClient::IsShuttingDown() { return false; } |
| |
| bool TestExtensionsBrowserClient::AreExtensionsDisabled( |
| const base::CommandLine& command_line, |
| BrowserContext* context) { |
| return command_line.HasSwitch(switches::kDisableExtensions); |
| } |
| |
| bool TestExtensionsBrowserClient::IsValidContext(void* context) { |
| return context == main_context_ || |
| (incognito_context_ && context == incognito_context_); |
| } |
| |
| bool TestExtensionsBrowserClient::IsSameContext(BrowserContext* first, |
| BrowserContext* second) { |
| DCHECK(first); |
| DCHECK(second); |
| return first == second || |
| (first == main_context_ && second == incognito_context_) || |
| (first == incognito_context_ && second == main_context_); |
| } |
| |
| bool TestExtensionsBrowserClient::HasOffTheRecordContext( |
| BrowserContext* context) { |
| return context == main_context_ && incognito_context_ != nullptr; |
| } |
| |
| BrowserContext* TestExtensionsBrowserClient::GetOffTheRecordContext( |
| BrowserContext* context) { |
| if (context == main_context_) { |
| return incognito_context_; |
| } |
| return nullptr; |
| } |
| |
| BrowserContext* TestExtensionsBrowserClient::GetOriginalContext( |
| BrowserContext* context) { |
| return main_context_; |
| } |
| |
| content::BrowserContext* |
| TestExtensionsBrowserClient::GetContextRedirectedToOriginal( |
| content::BrowserContext* context) { |
| return GetOriginalContext(context); |
| } |
| |
| content::BrowserContext* |
| TestExtensionsBrowserClient::GetContextRedirectedToOriginalWithoutAshInternals( |
| content::BrowserContext* context) { |
| return GetOriginalContext(context); |
| } |
| |
| content::BrowserContext* TestExtensionsBrowserClient::GetContextOwnInstance( |
| content::BrowserContext* context) { |
| return context; |
| } |
| |
| content::BrowserContext* TestExtensionsBrowserClient::GetContextForOriginalOnly( |
| content::BrowserContext* context) { |
| // Default implementation of |
| // `BrowserContextKeyedServiceFactory::GetBrowserContextToUse()`. |
| return context->IsOffTheRecord() ? nullptr : context; |
| } |
| |
| bool TestExtensionsBrowserClient::AreExtensionsDisabledForContext( |
| content::BrowserContext* context) { |
| return false; |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| bool TestExtensionsBrowserClient::IsActiveContext( |
| content::BrowserContext* browser_context) const { |
| return true; |
| } |
| |
| std::string TestExtensionsBrowserClient::GetUserIdHashFromContext( |
| content::BrowserContext* context) { |
| if (context != main_context_ || !ash::LoginState::IsInitialized()) { |
| return ""; |
| } |
| return ash::LoginState::Get()->primary_user_hash(); |
| } |
| #endif |
| |
| bool TestExtensionsBrowserClient::IsGuestSession( |
| BrowserContext* context) const { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::IsExtensionIncognitoEnabled( |
| const ExtensionId& extension_id, |
| content::BrowserContext* context) const { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::IsExtensionIncognitoEnabled( |
| const Extension* extension, |
| content::BrowserContext* context) const { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::CanExtensionCrossIncognito( |
| const extensions::Extension* extension, |
| content::BrowserContext* context) const { |
| return false; |
| } |
| |
| base::FilePath TestExtensionsBrowserClient::GetBundleResourcePath( |
| const network::ResourceRequest& request, |
| const base::FilePath& extension_resources_path, |
| int* resource_id) const { |
| *resource_id = 0; |
| return base::FilePath(); |
| } |
| |
| void TestExtensionsBrowserClient::LoadResourceFromResourceBundle( |
| const network::ResourceRequest& request, |
| mojo::PendingReceiver<network::mojom::URLLoader> loader, |
| const base::FilePath& resource_relative_path, |
| int resource_id, |
| scoped_refptr<net::HttpResponseHeaders> headers, |
| mojo::PendingRemote<network::mojom::URLLoaderClient> client) { |
| // Should not be called because GetBundleResourcePath() returned empty path. |
| NOTREACHED() << "Resource is not from a bundle."; |
| } |
| |
| bool TestExtensionsBrowserClient::AllowCrossRendererResourceLoad( |
| const network::ResourceRequest& request, |
| network::mojom::RequestDestination destination, |
| ui::PageTransition page_transition, |
| content::ChildProcessId child_id, |
| bool is_incognito, |
| const Extension* extension, |
| const ExtensionSet& extensions, |
| const ProcessMap& process_map, |
| const GURL& upstream_url) { |
| return false; |
| } |
| |
| void TestExtensionsBrowserClient::GetEarlyExtensionPrefsObservers( |
| content::BrowserContext* context, |
| std::vector<EarlyExtensionPrefsObserver*>* observers) const {} |
| |
| ProcessManagerDelegate* TestExtensionsBrowserClient::GetProcessManagerDelegate() |
| const { |
| return process_manager_delegate_; |
| } |
| |
| mojo::PendingRemote<network::mojom::URLLoaderFactory> |
| TestExtensionsBrowserClient::GetControlledFrameEmbedderURLLoader( |
| const url::Origin& app_origin, |
| content::FrameTreeNodeId frame_tree_node_id, |
| content::BrowserContext* browser_context) { |
| return mojo::PendingRemote<network::mojom::URLLoaderFactory>(); |
| } |
| |
| std::unique_ptr<ExtensionHostDelegate> |
| TestExtensionsBrowserClient::CreateExtensionHostDelegate() { |
| return nullptr; |
| } |
| |
| bool TestExtensionsBrowserClient::DidVersionUpdate(BrowserContext* context) { |
| return false; |
| } |
| |
| void TestExtensionsBrowserClient::PermitExternalProtocolHandler() { |
| } |
| |
| bool TestExtensionsBrowserClient::IsInDemoMode() { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::IsScreensaverInDemoMode( |
| const std::string& app_id) { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::IsRunningInForcedAppMode() { return false; } |
| |
| bool TestExtensionsBrowserClient::IsAppModeForcedForApp( |
| const ExtensionId& extension_id) { |
| return false; |
| } |
| |
| bool TestExtensionsBrowserClient::IsLoggedInAsPublicAccount() { |
| return false; |
| } |
| |
| ExtensionSystemProvider* |
| TestExtensionsBrowserClient::GetExtensionSystemFactory() { |
| DCHECK(extension_system_factory_); |
| return extension_system_factory_; |
| } |
| |
| void TestExtensionsBrowserClient::RegisterBrowserInterfaceBindersForFrame( |
| mojo::BinderMapWithContext<content::RenderFrameHost*>* binder_map, |
| content::RenderFrameHost* render_frame_host, |
| const Extension* extension) const {} |
| |
| std::unique_ptr<RuntimeAPIDelegate> |
| TestExtensionsBrowserClient::CreateRuntimeAPIDelegate( |
| content::BrowserContext* context) const { |
| return std::unique_ptr<RuntimeAPIDelegate>(new TestRuntimeAPIDelegate()); |
| } |
| |
| const ComponentExtensionResourceManager* |
| TestExtensionsBrowserClient::GetComponentExtensionResourceManager() { |
| return nullptr; |
| } |
| |
| void TestExtensionsBrowserClient::BroadcastEventToRenderers( |
| events::HistogramValue histogram_value, |
| const std::string& event_name, |
| base::ListValue args, |
| bool dispatch_to_off_the_record_profiles) {} |
| |
| ExtensionCache* TestExtensionsBrowserClient::GetExtensionCache() { |
| return extension_cache_.get(); |
| } |
| |
| bool TestExtensionsBrowserClient::IsBackgroundUpdateAllowed() { |
| return true; |
| } |
| |
| bool TestExtensionsBrowserClient::IsMinBrowserVersionSupported( |
| const std::string& min_version) { |
| return true; |
| } |
| |
| void TestExtensionsBrowserClient::CreateExtensionWebContentsObserver( |
| content::WebContents* web_contents) {} |
| |
| ExtensionWebContentsObserver* |
| TestExtensionsBrowserClient::GetExtensionWebContentsObserver( |
| content::WebContents* web_contents) { |
| return nullptr; |
| } |
| |
| KioskDelegate* TestExtensionsBrowserClient::GetKioskDelegate() { |
| return kiosk_delegate_.get(); |
| } |
| |
| SafeBrowsingDelegate* TestExtensionsBrowserClient::GetSafeBrowsingDelegate() { |
| return safe_browsing_delegate_.get(); |
| } |
| |
| UserScriptListener* TestExtensionsBrowserClient::GetUserScriptListener() { |
| return user_script_listener_; |
| } |
| |
| scoped_refptr<update_client::UpdateClient> |
| TestExtensionsBrowserClient::CreateUpdateClient( |
| scoped_refptr<update_client::Configurator> /*configurator*/) { |
| return update_client_factory_.is_null() |
| ? nullptr |
| : base::WrapRefCounted(update_client_factory_.Run()); |
| } |
| |
| scoped_refptr<update_client::Configurator> |
| TestExtensionsBrowserClient::CreateUpdateClientConfigurator( |
| content::BrowserContext* context) { |
| return base::MakeRefCounted<update_client::TestConfigurator>(nullptr); |
| } |
| |
| std::string TestExtensionsBrowserClient::GetApplicationLocale() { |
| return l10n_util::GetApplicationLocale(std::string()); |
| } |
| |
| ExtensionManagementClient* |
| TestExtensionsBrowserClient::GetExtensionManagementClient( |
| content::BrowserContext* context) { |
| return extension_management_client_.get(); |
| } |
| |
| bool TestExtensionsBrowserClient::IsTelemetryLoggingEnabled( |
| content::BrowserContext* context) { |
| return telemetry_logging_enabled_; |
| } |
| |
| void TestExtensionsBrowserClient::SetTelemetryLoggingEnabled(bool enabled) { |
| telemetry_logging_enabled_ = enabled; |
| } |
| |
| } // namespace extensions |