Compare commits

...

3 Commits

Author SHA1 Message Date
Marshall Greenblatt 002f4b5b4a tools: Don't write args.gn if unchanged (see #3681, see #3685)
Now that args.gn is an input to the make_config_header target we
don't want to invalidate the build unnecessarily by modifying the
file if the contents are unchanged.
2024-05-03 15:38:10 -04:00
Marshall Greenblatt 17a1fd62ec tests: Remove extension tests (see #3685)
The Alloy extension API is deprecated and these tests have not been
supported for some time.
2024-05-03 15:23:35 -04:00
Marshall Greenblatt ca636bb96e chrome: Support CefResourceBundleHandler (see #3685) 2024-05-03 12:51:09 -04:00
46 changed files with 181 additions and 4171 deletions

View File

@ -1973,13 +1973,6 @@ if (is_mac) {
]
}
bundle_data("cefclient_resources_bundle_data_extensions_set_page_color") {
sources = gypi_paths2.cefclient_sources_resources_extensions_set_page_color
outputs = [
"{{bundle_resources_dir}}/extensions/set_page_color/{{source_file_part}}",
]
}
bundle_data("cefclient_resources_bundle_data_english") {
sources = [
"tests/cefclient/resources/mac/English.lproj/InfoPlist.strings",
@ -2029,7 +2022,6 @@ if (is_mac) {
gypi_paths2.cefclient_sources_mac
deps = [
":cefclient_resources_bundle_data",
":cefclient_resources_bundle_data_extensions_set_page_color",
":cefclient_resources_bundle_data_english",
":cefclient_xibs",
]
@ -2219,11 +2211,6 @@ if (is_mac) {
gypi_paths2.cefclient_sources_resources
outputs = [ "${root_out_dir}/cefclient_files/{{source_file_part}}" ]
}
copy("copy_cefclient_files_extensions_set_page_color") {
sources = gypi_paths2.cefclient_sources_resources_extensions_set_page_color
outputs = [ "${root_out_dir}/cefclient_files/extensions/set_page_color/{{source_file_part}}" ]
}
}
executable("cefclient") {
@ -2294,7 +2281,6 @@ if (is_mac) {
deps += [
":copy_cefclient_files",
":copy_cefclient_files_extensions_set_page_color",
]
libs = [

View File

@ -167,8 +167,6 @@
'shared_sources_browser': [
'tests/shared/browser/client_app_browser.cc',
'tests/shared/browser/client_app_browser.h',
'tests/shared/browser/extension_util.cc',
'tests/shared/browser/extension_util.h',
'tests/shared/browser/file_util.cc',
'tests/shared/browser/file_util.h',
'tests/shared/browser/geometry_util.cc',
@ -338,13 +336,6 @@
'tests/cefclient/resources/window.html',
'tests/cefclient/resources/xmlhttprequest.html',
],
'cefclient_sources_resources_extensions_set_page_color': [
'tests/cefclient/resources/extensions/set_page_color/icon.png',
'tests/cefclient/resources/extensions/set_page_color/manifest.json',
'tests/cefclient/resources/extensions/set_page_color/popup.html',
'tests/cefclient/resources/extensions/set_page_color/popup.js',
'tests/cefclient/resources/extensions/set_page_color/README.md',
],
'cefclient_sources_win': [
'tests/cefclient/browser/browser_window_osr_win.cc',
'tests/cefclient/browser/browser_window_osr_win.h',
@ -491,13 +482,6 @@
'tests/ceftests/dom_unittest.cc',
'tests/ceftests/download_unittest.cc',
'tests/ceftests/draggable_regions_unittest.cc',
'tests/ceftests/extensions/background_unittest.cc',
'tests/ceftests/extensions/chrome_alarms_unittest.cc',
'tests/ceftests/extensions/chrome_storage_unittest.cc',
'tests/ceftests/extensions/chrome_tabs_unittest.cc',
'tests/ceftests/extensions/extension_test_handler.cc',
'tests/ceftests/extensions/extension_test_handler.h',
'tests/ceftests/extensions/view_unittest.cc',
'tests/ceftests/file_util_unittest.cc',
'tests/ceftests/frame_handler_unittest.cc',
'tests/ceftests/frame_unittest.cc',

View File

@ -12,6 +12,7 @@
#include "cef/libcef/common/app_manager.h"
#include "cef/libcef/common/chrome/chrome_content_client_cef.h"
#include "cef/libcef/common/main_runner_handler.h"
#include "cef/libcef/common/resource_bundle_delegate.h"
#include "cef/libcef/common/task_runner_manager.h"
#include "chrome/app/chrome_main_delegate.h"
@ -71,6 +72,11 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
scoped_refptr<base::SingleThreadTaskRunner> GetRenderTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> GetWebWorkerTaskRunner() override;
// ChromeMainDelegate overrides.
ui::ResourceBundle::Delegate* GetResourceBundleDelegate() override {
return &resource_bundle_delegate_;
}
private:
ChromeContentBrowserClientCef* content_browser_client() const;
ChromeContentRendererClientCef* content_renderer_client() const;
@ -81,6 +87,8 @@ class ChromeMainDelegateCef : public ChromeMainDelegate,
// We use this instead of ChromeMainDelegate::chrome_content_client_.
ChromeContentClientCef chrome_content_client_cef_;
CefResourceBundleDelegate resource_bundle_delegate_;
};
#endif // CEF_LIBCEF_COMMON_CHROME_CHROME_MAIN_DELEGATE_CEF_

View File

@ -1,24 +1,42 @@
#include "cef/libcef/common/resource_bundle_delegate.h"
#include "cef/libcef/common/app_manager.h"
#include "cef/libcef/features/runtime.h"
CefResourceBundleDelegate::CefResourceBundleDelegate() {
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
// Alloy bootstrap explicitly enables pack file loading in
// AlloyMainDelegate::InitializeResourceBundle, and it is otherwise disabled
// by default. Chrome bootstrap does not support this.
allow_pack_file_load_ = cef::IsChromeRuntimeEnabled();
#endif
}
base::FilePath CefResourceBundleDelegate::GetPathForResourcePack(
const base::FilePath& pack_path,
ui::ResourceScaleFactor scale_factor) {
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
// Only allow the cef pack file to load.
if (!pack_loading_disabled_ && allow_pack_file_load_) {
return pack_path;
}
return base::FilePath();
#else
return pack_path;
#endif
}
base::FilePath CefResourceBundleDelegate::GetPathForLocalePack(
const base::FilePath& pack_path,
const std::string& locale) {
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
if (!pack_loading_disabled_) {
return pack_path;
}
return base::FilePath();
#else
return pack_path;
#endif
}
gfx::Image CefResourceBundleDelegate::GetImageNamed(int resource_id) {
@ -63,7 +81,13 @@ bool CefResourceBundleDelegate::GetRawDataResource(
}
}
return (pack_loading_disabled_ || !value->empty());
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
if (pack_loading_disabled_) {
return true;
}
#endif
return !value->empty();
}
bool CefResourceBundleDelegate::GetLocalizedString(
@ -81,5 +105,11 @@ bool CefResourceBundleDelegate::GetLocalizedString(
}
}
return (pack_loading_disabled_ || !value->empty());
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
if (pack_loading_disabled_) {
return true;
}
#endif
return !value->empty();
}

View File

@ -7,18 +7,23 @@
#define CEF_LIBCEF_COMMON_RESOURCE_BUNDLE_DELEGATE_H_
#pragma once
#include "cef/libcef/features/features.h"
#include "ui/base/resource/resource_bundle.h"
class AlloyContentClient;
class CefResourceBundleDelegate : public ui::ResourceBundle::Delegate {
public:
CefResourceBundleDelegate() = default;
CefResourceBundleDelegate();
CefResourceBundleDelegate(const CefResourceBundleDelegate&) = delete;
CefResourceBundleDelegate& operator=(const CefResourceBundleDelegate&) =
delete;
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
void set_pack_loading_disabled(bool val) { pack_loading_disabled_ = val; }
bool pack_loading_disabled() const { return pack_loading_disabled_; }
void set_allow_pack_file_load(bool val) { allow_pack_file_load_ = val; }
bool allow_pack_file_load() const { return allow_pack_file_load_; }
#endif
private:
// ui::ResourceBundle::Delegate methods.
@ -38,9 +43,11 @@ class CefResourceBundleDelegate : public ui::ResourceBundle::Delegate {
std::string_view* value) const override;
bool GetLocalizedString(int message_id, std::u16string* value) const override;
#if BUILDFLAG(ENABLE_ALLOY_BOOTSTRAP)
private:
bool pack_loading_disabled_ = false;
bool allow_pack_file_load_ = false;
bool allow_pack_file_load_;
#endif
};
#endif // CEF_LIBCEF_COMMON_RESOURCE_BUNDLE_DELEGATE_H_

View File

@ -217,6 +217,9 @@ patches = [
#
# Apply dynamic light/dark theme changes to web content.
# https://issues.chromium.org/issues/332328864#comment3
#
# Pass ui::ResourceBundle::Delegate to InitSharedInstanceWithLocale.
# https://github.com/chromiumembedded/cef/issues/3685
'name': 'chrome_runtime',
},
{
@ -735,6 +738,9 @@ patches = [
#
# mac: Add fallback for unsupported --lang values.
# https://github.com/chromiumembedded/cef/issues/3653
#
# Pass ui::ResourceBundle::Delegate to InitSharedInstanceWithLocale.
# https://github.com/chromiumembedded/cef/issues/3685
'name': 'mac_chrome_locale_3623'
},
{

View File

@ -1,5 +1,5 @@
diff --git chrome/app/chrome_main_delegate.cc chrome/app/chrome_main_delegate.cc
index c09a805c4ed7b..de89b16690593 100644
index c09a805c4ed7b..3db1403d60ed5 100644
--- chrome/app/chrome_main_delegate.cc
+++ chrome/app/chrome_main_delegate.cc
@@ -37,6 +37,7 @@
@ -40,7 +40,17 @@ index c09a805c4ed7b..de89b16690593 100644
// In the case the process is not the singleton process, the uninstall tasks
// need to be executed here. A window will be displayed asking to close all
// running instances.
@@ -1069,7 +1077,8 @@ std::optional<int> ChromeMainDelegate::PostEarlyInitialization(
@@ -1050,7 +1058,8 @@ std::optional<int> ChromeMainDelegate::PostEarlyInitialization(
// Initializes the resource bundle and determines the locale.
std::string actual_locale = LoadLocalState(
- chrome_feature_list_creator, invoked_in_browser->is_running_test);
+ chrome_feature_list_creator, GetResourceBundleDelegate(),
+ invoked_in_browser->is_running_test);
chrome_feature_list_creator->SetApplicationLocale(actual_locale);
chrome_feature_list_creator->OverrideCachedUIStrings();
@@ -1069,7 +1078,8 @@ std::optional<int> ChromeMainDelegate::PostEarlyInitialization(
if (base::FeatureList::IsEnabled(
features::kWriteBasicSystemProfileToPersistentHistogramsFile)) {
@ -50,7 +60,7 @@ index c09a805c4ed7b..de89b16690593 100644
#if BUILDFLAG(IS_ANDROID)
record =
base::FeatureList::IsEnabled(chrome::android::kUmaBackgroundSessions);
@@ -1505,6 +1514,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
@@ -1505,6 +1515,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
@ -58,7 +68,7 @@ index c09a805c4ed7b..de89b16690593 100644
crash_reporter::InitializeCrashKeys();
#if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -1523,6 +1533,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
@@ -1523,6 +1534,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
InitMacCrashReporter(command_line, process_type);
SetUpInstallerPreferences(command_line);
#endif
@ -66,7 +76,17 @@ index c09a805c4ed7b..de89b16690593 100644
#if BUILDFLAG(IS_WIN)
child_process_logging::Init();
@@ -1733,6 +1744,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
@@ -1703,7 +1715,8 @@ void ChromeMainDelegate::PreSandboxStartup() {
#else
const std::string loaded_locale =
ui::ResourceBundle::InitSharedInstanceWithLocale(
- locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+ locale, GetResourceBundleDelegate(),
+ ui::ResourceBundle::LOAD_COMMON_RESOURCES);
base::FilePath resources_pack_path;
base::PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
@@ -1733,6 +1746,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
}
@ -74,7 +94,7 @@ index c09a805c4ed7b..de89b16690593 100644
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
// Zygote needs to call InitCrashReporter() in RunZygote().
if (process_type != switches::kZygoteProcess) {
@@ -1768,6 +1780,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
@@ -1768,6 +1782,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
// After all the platform Breakpads have been initialized, store the command
// line for crash reporting.
crash_keys::SetCrashKeysFromCommandLine(command_line);
@ -82,7 +102,7 @@ index c09a805c4ed7b..de89b16690593 100644
#if BUILDFLAG(ENABLE_PDF)
MaybePatchGdiGetFontData();
@@ -1893,6 +1906,7 @@ void ChromeMainDelegate::ZygoteForked() {
@@ -1893,6 +1908,7 @@ void ChromeMainDelegate::ZygoteForked() {
SetUpProfilingShutdownHandler();
}
@ -90,7 +110,7 @@ index c09a805c4ed7b..de89b16690593 100644
// Needs to be called after we have chrome::DIR_USER_DATA. BrowserMain sets
// this up for the browser process in a different manner.
const base::CommandLine* command_line =
@@ -1905,6 +1919,7 @@ void ChromeMainDelegate::ZygoteForked() {
@@ -1905,6 +1921,7 @@ void ChromeMainDelegate::ZygoteForked() {
// Reset the command line for the newly spawned process.
crash_keys::SetCrashKeysFromCommandLine(*command_line);
@ -98,7 +118,7 @@ index c09a805c4ed7b..de89b16690593 100644
}
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -2001,6 +2016,7 @@ void ChromeMainDelegate::InitializeMemorySystem() {
@@ -2001,6 +2018,7 @@ void ChromeMainDelegate::InitializeMemorySystem() {
const bool is_browser_process = process_type.empty();
const bool gwp_asan_boost_sampling = is_browser_process || IsCanaryDev();
@ -106,7 +126,7 @@ index c09a805c4ed7b..de89b16690593 100644
memory_system::Initializer()
.SetGwpAsanParameters(gwp_asan_boost_sampling, process_type)
.SetProfilingClientParameters(chrome::GetChannel(),
@@ -2010,5 +2026,5 @@ void ChromeMainDelegate::InitializeMemorySystem() {
@@ -2010,5 +2028,5 @@ void ChromeMainDelegate::InitializeMemorySystem() {
memory_system::DispatcherParameters::
AllocationTraceRecorderInclusion::kDynamic,
process_type)
@ -114,10 +134,18 @@ index c09a805c4ed7b..de89b16690593 100644
+ .Initialize(*memory_system_);
}
diff --git chrome/app/chrome_main_delegate.h chrome/app/chrome_main_delegate.h
index 3553377e96017..5207128b768f2 100644
index 3553377e96017..9f6edc70ef1d4 100644
--- chrome/app/chrome_main_delegate.h
+++ chrome/app/chrome_main_delegate.h
@@ -49,6 +49,8 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
@@ -16,6 +16,7 @@
#include "chrome/common/chrome_content_client.h"
#include "components/memory_system/memory_system.h"
#include "content/public/app/content_main_delegate.h"
+#include "ui/base/resource/resource_bundle.h"
namespace base {
class CommandLine;
@@ -49,6 +50,8 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
~ChromeMainDelegate() override;
@ -126,7 +154,17 @@ index 3553377e96017..5207128b768f2 100644
protected:
// content::ContentMainDelegate:
std::optional<int> BasicStartupComplete() override;
@@ -98,7 +100,7 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
@@ -92,13 +95,17 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
void InitializeMemorySystem();
+ virtual ui::ResourceBundle::Delegate* GetResourceBundleDelegate() {
+ return nullptr;
+ }
+
std::unique_ptr<ChromeContentBrowserClient> chrome_content_browser_client_;
std::unique_ptr<ChromeContentUtilityClient> chrome_content_utility_client_;
std::unique_ptr<tracing::TracingSamplerProfiler> tracing_sampler_profiler_;
ChromeContentClient chrome_content_client_;

View File

@ -1,8 +1,21 @@
diff --git chrome/browser/chrome_resource_bundle_helper.cc chrome/browser/chrome_resource_bundle_helper.cc
index 0cfc966050b60..8268a8b1f4fcb 100644
index 0cfc966050b60..bbc20cffaee1a 100644
--- chrome/browser/chrome_resource_bundle_helper.cc
+++ chrome/browser/chrome_resource_bundle_helper.cc
@@ -82,16 +82,8 @@ std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
@@ -68,8 +68,10 @@ extern void InitializeLocalState(
// Initializes the shared instance of ResourceBundle and returns the application
// locale. An empty |actual_locale| value indicates failure.
-std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
- bool is_running_tests) {
+std::string InitResourceBundleAndDetermineLocale(
+ PrefService* local_state,
+ ui::ResourceBundle::Delegate* resource_bundle_delegate,
+ bool is_running_tests) {
#if BUILDFLAG(IS_ANDROID)
// In order for SetLoadSecondaryLocalePaks() to work ResourceBundle must
// not have been created yet.
@@ -82,16 +84,8 @@ std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
.empty());
#endif
@ -20,6 +33,52 @@ index 0cfc966050b60..8268a8b1f4fcb 100644
#if BUILDFLAG(IS_CHROMEOS_ASH)
ui::ResourceBundle::SetLottieParsingFunctions(
@@ -103,7 +97,8 @@ std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
// On a POSIX OS other than ChromeOS, the parameter that is passed to the
// method InitSharedInstance is ignored.
std::string actual_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
- preferred_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
+ preferred_locale, resource_bundle_delegate,
+ ui::ResourceBundle::LOAD_COMMON_RESOURCES);
CHECK(!actual_locale.empty())
<< "Locale could not be found for " << preferred_locale;
@@ -155,6 +150,7 @@ std::string InitResourceBundleAndDetermineLocale(PrefService* local_state,
std::string LoadLocalState(
ChromeFeatureListCreator* chrome_feature_list_creator,
+ ui::ResourceBundle::Delegate* resource_bundle_delegate,
bool is_running_tests) {
base::FilePath user_data_dir;
if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
@@ -166,5 +162,6 @@ std::string LoadLocalState(
new ChromeCommandLinePrefStore(base::CommandLine::ForCurrentProcess()));
return InitResourceBundleAndDetermineLocale(
- chrome_feature_list_creator->local_state(), is_running_tests);
+ chrome_feature_list_creator->local_state(), resource_bundle_delegate,
+ is_running_tests);
}
diff --git chrome/browser/chrome_resource_bundle_helper.h chrome/browser/chrome_resource_bundle_helper.h
index 0b22e445bc3ff..1d7c6b319ba4b 100644
--- chrome/browser/chrome_resource_bundle_helper.h
+++ chrome/browser/chrome_resource_bundle_helper.h
@@ -7,12 +7,15 @@
#include <string>
+#include "ui/base/resource/resource_bundle.h"
+
class ChromeFeatureListCreator;
// Loads the local state, and returns the application locale. An empty return
// value indicates the ResouceBundle couldn't be loaded.
std::string LoadLocalState(
ChromeFeatureListCreator* chrome_feature_list_creator,
+ ui::ResourceBundle::Delegate* resource_bundle_delegate,
bool is_running_tests);
#endif // CHROME_BROWSER_CHROME_RESOURCE_BUNDLE_HELPER_H_
diff --git components/language/core/browser/locale_util.cc components/language/core/browser/locale_util.cc
index aa43742055b04..e84f21ab963cc 100644
--- components/language/core/browser/locale_util.cc

View File

@ -83,7 +83,6 @@
'shared_sources_resources',
'cefclient_bundle_resources_mac:MAC',
'cefclient_sources_resources',
'cefclient_sources_resources_extensions_set_page_color',
],
}}

View File

@ -23,7 +23,6 @@
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/root_window_manager.h"
#include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/extension_util.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/binary_value_utils.h"
#include "tests/shared/common/client_switches.h"
@ -1015,21 +1014,6 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
SetOfflineState(browser, true);
}
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
if (use_alloy_style_ && browser->GetHost()->GetExtension()) {
// Browsers hosting extension apps should auto-resize.
browser->GetHost()->SetAutoResizeEnabled(true, CefSize(20, 20),
CefSize(1000, 1000));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
if (extension_util::IsInternalExtension(extension->GetPath())) {
// Register the internal handler for extension resources.
extension_util::AddInternalExtensionToResourceManager(
extension, GetResourceManager());
}
}
#endif
NotifyBrowserCreated(browser);
}

View File

@ -70,11 +70,6 @@
#define IDS_WINDOW_ICON_2X_PNG 1025
#define IDS_XMLHTTPREQUEST_HTML 1026
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031
#define IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML 1032
#define IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS 1033
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED

View File

@ -17,14 +17,6 @@ int GetResourceId(const char* resource_name) {
{"binding.html", IDS_BINDING_HTML},
{"dialogs.html", IDS_DIALOGS_HTML},
{"draggable.html", IDS_DRAGGABLE_HTML},
{"extensions/set_page_color/icon.png",
IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG},
{"extensions/set_page_color/manifest.json",
IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON},
{"extensions/set_page_color/popup.html",
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML},
{"extensions/set_page_color/popup.js",
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS},
{"hang.html", IDS_HANG_HTML},
{"ipc_performance.html", IDS_IPC_PERFORMANCE_HTML},
{"localstorage.html", IDS_LOCALSTORAGE_HTML},

View File

@ -29,20 +29,4 @@ scoped_refptr<RootWindow> RootWindow::GetForBrowser(int browser_id) {
browser_id);
}
void RootWindow::OnExtensionsChanged(const ExtensionSet& extensions) {
REQUIRE_MAIN_THREAD();
DCHECK(delegate_);
DCHECK(!WithExtension());
if (extensions.empty()) {
return;
}
ExtensionSet::const_iterator it = extensions.begin();
for (; it != extensions.end(); ++it) {
delegate_->CreateExtensionWindow(*it, CefRect(), nullptr, base::DoNothing(),
WithWindowlessRendering());
}
}
} // namespace client

View File

@ -24,9 +24,6 @@ namespace client {
enum class WindowType {
NORMAL,
// The window is hosting an extension app.
EXTENSION,
// The window is a modal dialog.
DIALOG,
@ -92,8 +89,6 @@ struct RootWindowConfig {
std::string url;
};
typedef std::set<CefRefPtr<CefExtension>> ExtensionSet;
// Represents a top-level native window in the browser process. While references
// to this object are thread-safe the methods must be called on the main thread
// unless otherwise indicated.
@ -135,18 +130,6 @@ class RootWindow
// Called when the RootWindow is activated (becomes the foreground window).
virtual void OnRootWindowActivated(RootWindow* root_window) = 0;
// Called when the browser is created for the RootWindow.
virtual void OnBrowserCreated(RootWindow* root_window,
CefRefPtr<CefBrowser> browser) = 0;
// Create a window for |extension|. |source_bounds| are the bounds of the
// UI element, like a button, that triggered the extension.
virtual void CreateExtensionWindow(CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback,
bool with_osr) = 0;
protected:
virtual ~Delegate() = default;
};
@ -228,13 +211,6 @@ class RootWindow
// Returns true if this window is using windowless rendering (osr).
virtual bool WithWindowlessRendering() const = 0;
// Returns true if this window is hosting an extension app.
virtual bool WithExtension() const = 0;
// Called when the set of loaded extensions changes. The default
// implementation will create a single window instance for each extension.
virtual void OnExtensionsChanged(const ExtensionSet& extensions);
protected:
// Allow deletion via scoped_refptr only.
friend struct DeleteOnMainThread;

View File

@ -85,7 +85,6 @@ RootWindowGtk::RootWindowGtk(bool use_alloy_style)
with_controls_(false),
always_on_top_(false),
with_osr_(false),
with_extension_(false),
is_popup_(false),
initialized_(false),
window_(nullptr),
@ -119,7 +118,6 @@ void RootWindowGtk::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
always_on_top_ = config->always_on_top;
with_osr_ = config->with_osr;
with_extension_ = config->window_type == WindowType::EXTENSION;
start_rect_ = config->bounds;
CreateBrowserWindow(config->url);
@ -279,11 +277,6 @@ bool RootWindowGtk::WithWindowlessRendering() const {
return with_osr_;
}
bool RootWindowGtk::WithExtension() const {
REQUIRE_MAIN_THREAD();
return with_extension_;
}
void RootWindowGtk::CreateBrowserWindow(const std::string& startup_url) {
if (with_osr_) {
OsrRendererSettings settings = {};
@ -460,8 +453,6 @@ void RootWindowGtk::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
if (is_popup_) {
CreateRootWindow(CefBrowserSettings(), false);
}
delegate_->OnBrowserCreated(this, browser);
}
void RootWindowGtk::OnBrowserWindowClosing() {

View File

@ -45,7 +45,6 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
CefRefPtr<CefBrowser> GetBrowser() const override;
ClientWindowHandle GetWindowHandle() const override;
bool WithWindowlessRendering() const override;
bool WithExtension() const override;
private:
void CreateBrowserWindow(const std::string& startup_url);
@ -129,7 +128,6 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
bool with_controls_;
bool always_on_top_;
bool with_osr_;
bool with_extension_;
bool is_popup_;
CefRect start_rect_;
std::unique_ptr<BrowserWindow> browser_window_;

View File

@ -48,7 +48,6 @@ class RootWindowMac : public RootWindow, public BrowserWindow::Delegate {
CefRefPtr<CefBrowser> GetBrowser() const override;
ClientWindowHandle GetWindowHandle() const override;
bool WithWindowlessRendering() const override;
bool WithExtension() const override;
// BrowserWindow::Delegate methods.
bool UseAlloyStyle() const override { return IsAlloyStyle(); }

View File

@ -218,7 +218,6 @@ class RootWindowMacImpl
CefRefPtr<CefBrowser> GetBrowser() const;
ClientWindowHandle GetWindowHandle() const;
bool WithWindowlessRendering() const;
bool WithExtension() const;
// BrowserWindow::Delegate methods.
void OnBrowserCreated(CefRefPtr<CefBrowser> browser);
@ -237,7 +236,6 @@ class RootWindowMacImpl
RootWindowMac& root_window_;
bool with_controls_ = false;
bool with_osr_ = false;
bool with_extension_ = false;
bool is_popup_ = false;
CefRect initial_bounds_;
cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL;
@ -279,7 +277,6 @@ void RootWindowMacImpl::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
with_osr_ = config->with_osr;
with_extension_ = config->window_type == WindowType::EXTENSION;
if (!config->bounds.IsEmpty()) {
// Initial state was specified via the config object.
@ -460,11 +457,6 @@ bool RootWindowMacImpl::WithWindowlessRendering() const {
return with_osr_;
}
bool RootWindowMacImpl::WithExtension() const {
REQUIRE_MAIN_THREAD();
return with_extension_;
}
void RootWindowMacImpl::OnNativeWindowClosed() {
window_ = nil;
window_destroyed_ = true;
@ -650,8 +642,6 @@ void RootWindowMacImpl::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
if (is_popup_) {
CreateRootWindow(CefBrowserSettings(), false);
}
root_window_.delegate_->OnBrowserCreated(&root_window_, browser);
}
void RootWindowMacImpl::OnBrowserWindowDestroyed() {
@ -841,10 +831,6 @@ bool RootWindowMac::WithWindowlessRendering() const {
return impl_->WithWindowlessRendering();
}
bool RootWindowMac::WithExtension() const {
return impl_->WithExtension();
}
void RootWindowMac::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
impl_->OnBrowserCreated(browser);
}

View File

@ -13,7 +13,6 @@
#include "tests/cefclient/browser/default_client_handler.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/extension_util.h"
#include "tests/shared/browser/file_util.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/client_switches.h"
@ -22,8 +21,7 @@ namespace client {
namespace {
class ClientRequestContextHandler : public CefRequestContextHandler,
public CefExtensionHandler {
class ClientRequestContextHandler : public CefRequestContextHandler {
public:
using CreateCallback = RootWindow::Delegate::RequestContextCallback;
@ -35,38 +33,6 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
CefRefPtr<CefRequestContext> request_context) override {
CEF_REQUIRE_UI_THREAD();
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
const auto main_context = MainContext::Get();
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (!main_context->UseChromeBootstrap() &&
command_line->HasSwitch(switches::kLoadExtension)) {
// Alloy implementation for loading extensions. Chrome runtime handles
// this internally.
if (main_context->GetRootWindowManager()->request_context_per_browser()) {
// The example extension loading implementation requires all browsers to
// share the same request context.
LOG(ERROR)
<< "Cannot mix --load-extension and --request-context-per-browser";
} else {
// Load one or more extension paths specified on the command-line and
// delimited with semicolon.
const std::string& extension_path =
command_line->GetSwitchValue(switches::kLoadExtension);
if (!extension_path.empty()) {
std::string part;
std::istringstream f(extension_path);
while (getline(f, part, ';')) {
if (!part.empty()) {
extension_util::LoadExtension(request_context, part, this);
}
}
}
}
}
#endif // !defined(DISABLE_ALLOY_BOOTSTRAP)
// Allow the startup URL to create popups that bypass the popup blocker.
// For example, via Tests > New Popup from the top menu. This applies for
// for the Chrome runtime only.
@ -83,31 +49,6 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
}
}
// CefExtensionHandler methods:
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) override {
CEF_REQUIRE_UI_THREAD();
MainContext::Get()->GetRootWindowManager()->AddExtension(extension);
}
CefRefPtr<CefBrowser> GetActiveBrowser(CefRefPtr<CefExtension> extension,
CefRefPtr<CefBrowser> browser,
bool include_incognito) override {
CEF_REQUIRE_UI_THREAD();
// Return the browser for the active/foreground window.
CefRefPtr<CefBrowser> active_browser =
MainContext::Get()->GetRootWindowManager()->GetActiveBrowser();
if (!active_browser) {
LOG(WARNING)
<< "No active browser available for extension "
<< browser->GetHost()->GetExtension()->GetIdentifier().ToString();
} else {
// The active browser should not be hosting an extension.
DCHECK(!active_browser->GetHost()->GetExtension());
}
return active_browser;
}
private:
CreateCallback create_callback_;
@ -227,59 +168,6 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
return root_window;
}
scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsExtension(
CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback,
bool with_controls,
bool with_osr) {
const std::string& extension_url = extension_util::GetExtensionURL(extension);
if (extension_url.empty()) {
NOTREACHED() << "Extension cannot be loaded directly.";
return nullptr;
}
// Create an initially hidden browser window that loads the extension URL.
// We'll show the window when the desired size becomes available via
// ClientHandler::OnAutoResize.
auto config = std::make_unique<RootWindowConfig>();
config->window_type = WindowType::EXTENSION;
config->with_controls = with_controls;
config->with_osr = with_osr;
config->initially_hidden = true;
config->source_bounds = source_bounds;
config->parent_window = parent_window;
config->close_callback = std::move(close_callback);
config->url = extension_url;
return CreateRootWindow(std::move(config));
}
bool RootWindowManager::HasRootWindowAsExtension(
CefRefPtr<CefExtension> extension) {
REQUIRE_MAIN_THREAD();
for (auto root_window : root_windows_) {
if (!root_window->WithExtension()) {
continue;
}
CefRefPtr<CefBrowser> browser = root_window->GetBrowser();
if (!browser) {
continue;
}
CefRefPtr<CefExtension> browser_extension =
browser->GetHost()->GetExtension();
DCHECK(browser_extension);
if (browser_extension->GetIdentifier() == extension->GetIdentifier()) {
return true;
}
}
return false;
}
scoped_refptr<RootWindow> RootWindowManager::GetWindowForBrowser(
int browser_id) const {
REQUIRE_MAIN_THREAD();
@ -298,11 +186,6 @@ scoped_refptr<RootWindow> RootWindowManager::GetActiveRootWindow() const {
return active_root_window_;
}
CefRefPtr<CefBrowser> RootWindowManager::GetActiveBrowser() const {
base::AutoLock lock_scope(active_browser_lock_);
return active_browser_;
}
void RootWindowManager::CloseAllWindows(bool force) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
// Execute this method on the main thread.
@ -324,31 +207,6 @@ void RootWindowManager::CloseAllWindows(bool force) {
}
}
void RootWindowManager::AddExtension(CefRefPtr<CefExtension> extension) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
// Execute this method on the main thread.
MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::AddExtension,
base::Unretained(this), extension));
return;
}
// Don't track extensions that can't be loaded directly.
if (extension_util::GetExtensionURL(extension).empty()) {
return;
}
// Don't add the same extension multiple times.
ExtensionSet::const_iterator it = extensions_.begin();
for (; it != extensions_.end(); ++it) {
if ((*it)->GetIdentifier() == extension->GetIdentifier()) {
return;
}
}
extensions_.insert(extension);
NotifyExtensionsChanged();
}
void RootWindowManager::OnRootWindowCreated(
scoped_refptr<RootWindow> root_window) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
@ -359,24 +217,10 @@ void RootWindowManager::OnRootWindowCreated(
}
root_windows_.insert(root_window);
if (!root_window->WithExtension()) {
root_window->OnExtensionsChanged(extensions_);
if (root_windows_.size() == 1U) {
// The first non-extension root window should be considered the active
// window.
OnRootWindowActivated(root_window.get());
}
}
}
void RootWindowManager::NotifyExtensionsChanged() {
REQUIRE_MAIN_THREAD();
for (auto root_window : root_windows_) {
if (!root_window->WithExtension()) {
root_window->OnExtensionsChanged(extensions_);
}
if (root_windows_.size() == 1U) {
// The first root window should be considered the active window.
OnRootWindowActivated(root_window.get());
}
}
@ -482,9 +326,6 @@ void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) {
if (root_window == active_root_window_) {
active_root_window_ = nullptr;
base::AutoLock lock_scope(active_browser_lock_);
active_browser_ = nullptr;
}
if (terminate_when_all_windows_closed_ && root_windows_.empty()) {
@ -497,47 +338,11 @@ void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) {
void RootWindowManager::OnRootWindowActivated(RootWindow* root_window) {
REQUIRE_MAIN_THREAD();
if (root_window->WithExtension()) {
// We don't want extension apps to become the active RootWindow.
return;
}
if (root_window == active_root_window_) {
return;
}
active_root_window_ = root_window;
{
base::AutoLock lock_scope(active_browser_lock_);
// May be nullptr at this point, in which case we'll make the association in
// OnBrowserCreated.
active_browser_ = active_root_window_->GetBrowser();
}
}
void RootWindowManager::OnBrowserCreated(RootWindow* root_window,
CefRefPtr<CefBrowser> browser) {
REQUIRE_MAIN_THREAD();
if (root_window == active_root_window_) {
base::AutoLock lock_scope(active_browser_lock_);
active_browser_ = browser;
}
}
void RootWindowManager::CreateExtensionWindow(
CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback,
bool with_osr) {
REQUIRE_MAIN_THREAD();
if (!HasRootWindowAsExtension(extension)) {
CreateRootWindowAsExtension(extension, source_bounds, parent_window,
std::move(close_callback), false, with_osr);
}
}
void RootWindowManager::CleanupOnUIThread() {

View File

@ -46,22 +46,6 @@ class RootWindowManager : public RootWindow::Delegate {
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings);
// Create a new top-level native window to host |extension|.
// If |with_controls| is true the window will show controls.
// If |with_osr| is true the window will use off-screen rendering.
// This method can be called from anywhere.
scoped_refptr<RootWindow> CreateRootWindowAsExtension(
CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback,
bool with_controls,
bool with_osr);
// Returns true if a window hosting |extension| currently exists. Must be
// called on the main thread.
bool HasRootWindowAsExtension(CefRefPtr<CefExtension> extension);
// Returns the RootWindow associated with the specified browser ID. Must be
// called on the main thread.
scoped_refptr<RootWindow> GetWindowForBrowser(int browser_id) const;
@ -70,18 +54,10 @@ class RootWindowManager : public RootWindow::Delegate {
// Must be called on the main thread.
scoped_refptr<RootWindow> GetActiveRootWindow() const;
// Returns the currently active/foreground browser. May return nullptr. Safe
// to call from any thread.
CefRefPtr<CefBrowser> GetActiveBrowser() const;
// Close all existing windows. If |force| is true onunload handlers will not
// be executed.
void CloseAllWindows(bool force);
// Manage the set of loaded extensions. RootWindows will be notified via the
// OnExtensionsChanged method.
void AddExtension(CefRefPtr<CefExtension> extension);
bool request_context_per_browser() const {
return request_context_per_browser_;
}
@ -93,7 +69,6 @@ class RootWindowManager : public RootWindow::Delegate {
~RootWindowManager() override;
void OnRootWindowCreated(scoped_refptr<RootWindow> root_window);
void NotifyExtensionsChanged();
// RootWindow::Delegate methods.
CefRefPtr<CefRequestContext> GetRequestContext() override;
@ -103,13 +78,6 @@ class RootWindowManager : public RootWindow::Delegate {
void OnExit(RootWindow* root_window) override;
void OnRootWindowDestroyed(RootWindow* root_window) override;
void OnRootWindowActivated(RootWindow* root_window) override;
void OnBrowserCreated(RootWindow* root_window,
CefRefPtr<CefBrowser> browser) override;
void CreateExtensionWindow(CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback,
bool with_osr) override;
// |callback| may be nullptr. Must be called on the main thread.
CefRefPtr<CefRequestContext> CreateRequestContext(
@ -129,19 +97,11 @@ class RootWindowManager : public RootWindow::Delegate {
// thread.
scoped_refptr<RootWindow> active_root_window_;
// The currently active/foreground browser. Access is protected by
// |active_browser_lock_;
mutable base::Lock active_browser_lock_;
CefRefPtr<CefBrowser> active_browser_;
// Singleton window used as the temporary parent for popup browsers.
std::unique_ptr<TempWindow> temp_window_;
CefRefPtr<CefRequestContext> shared_request_context_;
// Loaded extensions. Only accessed on the main thread.
ExtensionSet extensions_;
scoped_refptr<ImageCache> image_cache_;
DISALLOW_COPY_AND_ASSIGN(RootWindowManager);

View File

@ -194,32 +194,11 @@ ClientWindowHandle RootWindowViews::GetWindowHandle() const {
#endif
}
bool RootWindowViews::WithExtension() const {
DCHECK(initialized_);
return config_->window_type == WindowType::EXTENSION;
}
bool RootWindowViews::WithControls() {
DCHECK(initialized_);
return config_->with_controls;
}
void RootWindowViews::OnExtensionsChanged(const ExtensionSet& extensions) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
CefPostTask(TID_UI, base::BindOnce(&RootWindowViews::OnExtensionsChanged,
this, extensions));
return;
}
if (window_) {
window_->OnExtensionsChanged(extensions);
} else {
// Window may not exist yet for popups.
pending_extensions_ = extensions;
}
}
bool RootWindowViews::InitiallyHidden() {
CEF_REQUIRE_UI_THREAD();
#if defined(OS_MAC)
@ -256,11 +235,6 @@ void RootWindowViews::OnViewsWindowCreated(CefRefPtr<ViewsWindow> window) {
DCHECK(!window_);
window_ = window;
window_->SetAlwaysOnTop(config_->always_on_top);
if (!pending_extensions_.empty()) {
window_->OnExtensionsChanged(pending_extensions_);
pending_extensions_.clear();
}
}
void RootWindowViews::OnViewsWindowClosing(CefRefPtr<ViewsWindow> window) {
@ -312,22 +286,6 @@ ViewsWindow::Delegate* RootWindowViews::GetDelegateForPopup(
return root_window;
}
void RootWindowViews::CreateExtensionWindow(CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
// Execute this method on the main thread.
MAIN_POST_CLOSURE(base::BindOnce(&RootWindowViews::CreateExtensionWindow,
this, extension, source_bounds,
parent_window, std::move(close_callback)));
return;
}
delegate_->CreateExtensionWindow(extension, source_bounds, parent_window,
std::move(close_callback), false);
}
void RootWindowViews::OnTest(int test_id) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
// Execute this method on the main thread.
@ -352,7 +310,6 @@ void RootWindowViews::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_MAIN_THREAD();
DCHECK(!browser_);
browser_ = browser;
delegate_->OnBrowserCreated(this, browser);
}
void RootWindowViews::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {

View File

@ -51,8 +51,6 @@ class RootWindowViews : public RootWindow,
CefRefPtr<CefBrowser> GetBrowser() const override;
ClientWindowHandle GetWindowHandle() const override;
bool WithWindowlessRendering() const override { return false; }
bool WithExtension() const override;
void OnExtensionsChanged(const ExtensionSet& extensions) override;
// ViewsWindow::Delegate methods:
bool WithControls() override;
@ -67,10 +65,6 @@ class RootWindowViews : public RootWindow,
void OnViewsWindowActivated(CefRefPtr<ViewsWindow> window) override;
ViewsWindow::Delegate* GetDelegateForPopup(
CefRefPtr<CefClient> client) override;
void CreateExtensionWindow(CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback) override;
void OnTest(int test_id) override;
void OnExit() override;
@ -122,7 +116,6 @@ class RootWindowViews : public RootWindow,
cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL;
bool position_on_resize_ = false;
CefRefPtr<ViewsWindow> window_;
ExtensionSet pending_extensions_;
scoped_refptr<ImageCache> image_cache_;
DISALLOW_COPY_AND_ASSIGN(RootWindowViews);

View File

@ -135,7 +135,6 @@ void RootWindowWin::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
always_on_top_ = config->always_on_top;
with_osr_ = config->with_osr;
with_extension_ = config->window_type == WindowType::EXTENSION;
CreateBrowserWindow(config->url);
@ -316,11 +315,6 @@ bool RootWindowWin::WithWindowlessRendering() const {
return with_osr_;
}
bool RootWindowWin::WithExtension() const {
REQUIRE_MAIN_THREAD();
return with_extension_;
}
void RootWindowWin::CreateBrowserWindow(const std::string& startup_url) {
if (with_osr_) {
OsrRendererSettings settings = {};
@ -1071,8 +1065,6 @@ void RootWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
// Make sure the browser is sized correctly.
OnSize(false);
}
delegate_->OnBrowserCreated(this, browser);
}
void RootWindowWin::OnBrowserWindowDestroyed() {

View File

@ -47,7 +47,6 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
CefRefPtr<CefBrowser> GetBrowser() const override;
ClientWindowHandle GetWindowHandle() const override;
bool WithWindowlessRendering() const override;
bool WithExtension() const override;
private:
void ContinueInitOnUIThread(std::unique_ptr<RootWindowConfig> config,
@ -122,7 +121,6 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
bool with_controls_ = false;
bool always_on_top_ = false;
bool with_osr_ = false;
bool with_extension_ = false;
bool is_popup_ = false;
CefRect initial_bounds_;
cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL;

View File

@ -823,15 +823,6 @@ void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager,
}
void Alert(CefRefPtr<CefBrowser> browser, const std::string& message) {
if (browser->GetHost()->GetExtension()) {
// Alerts originating from extension hosts should instead be displayed in
// the active browser.
browser = MainContext::Get()->GetRootWindowManager()->GetActiveBrowser();
if (!browser) {
return;
}
}
// Escape special characters in the message.
std::string msg = AsciiStrReplace(message, "\\", "\\\\");
msg = AsciiStrReplace(msg, "'", "\\'");

View File

@ -15,7 +15,6 @@
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/views_style.h"
#include "tests/shared/browser/extension_util.h"
#include "tests/shared/common/client_switches.h"
#if !defined(OS_WIN)
@ -28,8 +27,6 @@ namespace client {
namespace {
const char kDefaultExtensionIcon[] = "window_icon";
// Default window size.
constexpr int kDefaultWidth = 800;
constexpr int kDefaultHeight = 600;
@ -53,10 +50,6 @@ enum ControlIds {
// Reserved range of top menu button IDs.
ID_TOP_MENU_FIRST,
ID_TOP_MENU_LAST = ID_TOP_MENU_FIRST + 10,
// Reserved range of extension button IDs.
ID_EXTENSION_BUTTON_FIRST,
ID_EXTENSION_BUTTON_LAST = ID_EXTENSION_BUTTON_FIRST + 10,
};
typedef std::vector<CefRefPtr<CefLabelButton>> LabelButtons;
@ -389,40 +382,6 @@ void ViewsWindow::OnBeforeContextMenu(CefRefPtr<CefMenuModel> model) {
views_style::ApplyTo(model);
}
void ViewsWindow::OnExtensionsChanged(const ExtensionSet& extensions) {
CEF_REQUIRE_UI_THREAD();
if (extensions.empty()) {
if (!extensions_.empty()) {
extensions_.clear();
UpdateExtensionControls();
}
return;
}
ImageCache::ImageInfoSet image_set;
ExtensionSet::const_iterator it = extensions.begin();
for (; it != extensions.end(); ++it) {
CefRefPtr<CefExtension> extension = *it;
bool internal = false;
const std::string& icon_path =
extension_util::GetExtensionIconPath(extension, &internal);
if (!icon_path.empty()) {
// Load the extension icon.
image_set.push_back(
ImageCache::ImageInfo::Create1x(icon_path, icon_path, internal));
} else {
// Get a nullptr image and use the default icon.
image_set.push_back(ImageCache::ImageInfo::Empty());
}
}
delegate_->GetImageCache()->LoadImages(
image_set,
base::BindOnce(&ViewsWindow::OnExtensionIconsLoaded, this, extensions));
}
// static
bool ViewsWindow::SupportsWindowRestore(WindowType type) {
// Only support window restore with normal windows.
@ -587,26 +546,8 @@ void ViewsWindow::OnMenuButtonPressed(
CefRefPtr<CefMenuButtonPressedLock> button_pressed_lock) {
CEF_REQUIRE_UI_THREAD();
const int id = menu_button->GetID();
if (id >= ID_EXTENSION_BUTTON_FIRST && id <= ID_EXTENSION_BUTTON_LAST) {
const size_t extension_idx = id - ID_EXTENSION_BUTTON_FIRST;
if (extension_idx >= extensions_.size()) {
LOG(ERROR) << "Invalid extension index " << extension_idx;
return;
}
// Keep the button pressed until the extension window is closed.
extension_button_pressed_lock_ = button_pressed_lock;
// Create a window for the extension.
delegate_->CreateExtensionWindow(
extensions_[extension_idx].extension_, menu_button->GetBoundsInScreen(),
window_, base::BindOnce(&ViewsWindow::OnExtensionWindowClosed, this));
return;
}
DCHECK(with_controls_ || with_overlay_controls_);
DCHECK_EQ(ID_MENU_BUTTON, id);
DCHECK_EQ(ID_MENU_BUTTON, menu_button->GetID());
const auto button_bounds = menu_button->GetBoundsInScreen();
@ -780,10 +721,8 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
// Add the BrowserView as the only child of the Window.
window_->AddChildView(browser_view_);
if (type_ != WindowType::EXTENSION) {
// Choose a reasonable minimum window size.
minimum_window_size_ = CefSize(100, 100);
}
// Choose a reasonable minimum window size.
minimum_window_size_ = CefSize(100, 100);
}
if (!delegate_->InitiallyHidden()) {
@ -811,7 +750,6 @@ void ViewsWindow::OnWindowDestroyed(CefRefPtr<CefWindow> window) {
menu_bar_->Reset();
menu_bar_ = nullptr;
}
extensions_panel_ = nullptr;
menu_button_ = nullptr;
window_ = nullptr;
}
@ -872,15 +810,7 @@ CefRefPtr<CefWindow> ViewsWindow::GetParentWindow(CefRefPtr<CefWindow> window,
bool* is_menu,
bool* can_activate_menu) {
CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefWindow> parent_window = delegate_->GetParentWindow();
if (parent_window) {
// Extension windows behave as a menu and allow activation.
if (type_ == WindowType::EXTENSION) {
*is_menu = true;
*can_activate_menu = true;
}
}
return parent_window;
return delegate_->GetParentWindow();
}
bool ViewsWindow::IsWindowModalDialog(CefRefPtr<CefWindow> window) {
@ -965,18 +895,7 @@ bool ViewsWindow::OnKeyEvent(CefRefPtr<CefWindow> window,
const CefKeyEvent& event) {
CEF_REQUIRE_UI_THREAD();
if (!window_) {
return false;
}
if (type_ == WindowType::EXTENSION && event.type == KEYEVENT_RAWKEYDOWN &&
event.windows_key_code == VK_ESCAPE) {
// Close the extension window on escape.
Close(false);
return true;
}
if (!with_controls_) {
if (!window_ || !with_controls_) {
return false;
}
@ -1048,16 +967,6 @@ void ViewsWindow::OnFocus(CefRefPtr<CefView> view) {
}
}
void ViewsWindow::OnBlur(CefRefPtr<CefView> view) {
CEF_REQUIRE_UI_THREAD();
const int view_id = view->GetID();
if (view_id == ID_BROWSER_VIEW && type_ == WindowType::EXTENSION) {
// Close windows hosting extensions when the browser loses focus.
Close(false);
}
}
void ViewsWindow::OnWindowChanged(CefRefPtr<CefView> view, bool added) {
const int view_id = view->GetID();
if (view_id != ID_BROWSER_VIEW) {
@ -1158,7 +1067,7 @@ ViewsWindow::ViewsWindow(WindowType type,
accepts_first_mouse_ = command_line->HasSwitch(switches::kAcceptsFirstMouse);
// Without a window frame.
frameless_ = hide_frame || type_ == WindowType::EXTENSION;
frameless_ = hide_frame;
// With an overlay that mimics window controls.
with_overlay_controls_ = hide_frame && !hide_overlays && !with_controls_;
@ -1322,11 +1231,6 @@ void ViewsWindow::AddControls() {
panel->AddChildView(browse_button);
}
panel->AddChildView(location_bar_);
UpdateExtensionControls();
DCHECK(extensions_panel_);
panel->AddChildView(extensions_panel_);
panel->AddChildView(menu_button_);
// Allow |location| to grow and fill any remaining space.
@ -1435,88 +1339,6 @@ void ViewsWindow::ShowTopControls(bool show) {
}
}
void ViewsWindow::UpdateExtensionControls() {
CEF_REQUIRE_UI_THREAD();
if (!window_ || !with_controls_) {
return;
}
if (!extensions_panel_) {
extensions_panel_ = CefPanel::CreatePanel(this);
// Use a horizontal box layout for |panel|.
CefBoxLayoutSettings panel_layout_settings;
panel_layout_settings.horizontal = true;
CefRefPtr<CefBoxLayout> panel_layout =
extensions_panel_->SetToBoxLayout(panel_layout_settings);
} else {
extensions_panel_->RemoveAllChildViews();
}
if (extensions_.size() >
ID_EXTENSION_BUTTON_LAST - ID_EXTENSION_BUTTON_FIRST) {
LOG(WARNING) << "Too many extensions loaded. Some will be ignored.";
}
ExtensionInfoSet::const_iterator it = extensions_.begin();
for (int id = ID_EXTENSION_BUTTON_FIRST;
it != extensions_.end() && id <= ID_EXTENSION_BUTTON_LAST; ++id, ++it) {
CefRefPtr<CefMenuButton> button =
CefMenuButton::CreateMenuButton(this, CefString());
button->SetID(id);
button->SetImage(CEF_BUTTON_STATE_NORMAL, (*it).image_);
button->SetInkDropEnabled(true);
// Override the default minimum size.
button->SetMinimumSize(CefSize(0, 0));
extensions_panel_->AddChildView(button);
}
CefRefPtr<CefView> parent_view = extensions_panel_->GetParentView();
if (parent_view) {
parent_view->InvalidateLayout();
}
}
void ViewsWindow::OnExtensionIconsLoaded(const ExtensionSet& extensions,
const ImageCache::ImageSet& images) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
CefPostTask(TID_UI, base::BindOnce(&ViewsWindow::OnExtensionIconsLoaded,
this, extensions, images));
return;
}
DCHECK_EQ(extensions.size(), images.size());
extensions_.clear();
ExtensionSet::const_iterator it1 = extensions.begin();
ImageCache::ImageSet::const_iterator it2 = images.begin();
for (; it1 != extensions.end() && it2 != images.end(); ++it1, ++it2) {
CefRefPtr<CefImage> icon = *it2;
if (!icon) {
icon = delegate_->GetImageCache()->GetCachedImage(kDefaultExtensionIcon);
}
extensions_.emplace_back(*it1, icon);
}
UpdateExtensionControls();
}
void ViewsWindow::OnExtensionWindowClosed() {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
CefPostTask(TID_UI,
base::BindOnce(&ViewsWindow::OnExtensionWindowClosed, this));
return;
}
// Restore the button state.
extension_button_pressed_lock_ = nullptr;
}
#if !defined(OS_MAC)
void ViewsWindow::NudgeWindow() {
NOTIMPLEMENTED();

View File

@ -31,8 +31,6 @@
namespace client {
typedef std::set<CefRefPtr<CefExtension>> ExtensionSet;
// Implements a CefWindow that hosts a single CefBrowserView and optional
// Views-hosted controls. All methods must be called on the browser process UI
// thread.
@ -84,13 +82,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
// Return the Delegate for the popup window controlled by |client|.
virtual Delegate* GetDelegateForPopup(CefRefPtr<CefClient> client) = 0;
// Create a window for |extension|. |source_bounds| are the bounds of the
// UI element, like a button, that triggered the extension.
virtual void CreateExtensionWindow(CefRefPtr<CefExtension> extension,
const CefRect& source_bounds,
CefRefPtr<CefWindow> parent_window,
base::OnceClosure close_callback) = 0;
// Called to execute a test. See resource.h for |test_id| values.
virtual void OnTest(int test_id) = 0;
@ -130,7 +121,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
void TakeFocus(bool next);
void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model);
void OnExtensionsChanged(const ExtensionSet& extensions);
static bool SupportsWindowRestore(WindowType type);
bool SupportsWindowRestore() const;
@ -207,7 +197,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
CefSize GetPreferredSize(CefRefPtr<CefView> view) override;
CefSize GetMinimumSize(CefRefPtr<CefView> view) override;
void OnFocus(CefRefPtr<CefView> view) override;
void OnBlur(CefRefPtr<CefView> view) override;
void OnWindowChanged(CefRefPtr<CefView> view, bool added) override;
void OnLayoutChanged(CefRefPtr<CefView> view,
const CefRect& new_bounds) override;
@ -254,13 +243,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
// Show/hide top controls on the Window.
void ShowTopControls(bool show);
// Update extension controls on the Window.
void UpdateExtensionControls();
void OnExtensionIconsLoaded(const ExtensionSet& extensions,
const ImageCache::ImageSet& images);
void OnExtensionWindowClosed();
void NudgeWindow();
const WindowType type_;
@ -306,20 +288,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool can_go_back_ = false;
bool can_go_forward_ = false;
// Structure representing an extension.
struct ExtensionInfo {
ExtensionInfo(CefRefPtr<CefExtension> extension, CefRefPtr<CefImage> image)
: extension_(extension), image_(image) {}
CefRefPtr<CefExtension> extension_;
CefRefPtr<CefImage> image_;
};
typedef std::vector<ExtensionInfo> ExtensionInfoSet;
ExtensionInfoSet extensions_;
CefRefPtr<CefPanel> extensions_panel_;
CefRefPtr<CefMenuButtonPressedLock> extension_button_pressed_lock_;
IMPLEMENT_REFCOUNTING(ViewsWindow);
DISALLOW_COPY_AND_ASSIGN(ViewsWindow);
};

View File

@ -1,17 +0,0 @@
# Color Extension
Demonstrates basic extension app loading and integration by using a popup to change the page color.
## Usage
Run `cefclient --load-extension=set_page_color`.
When using the Views framework (`--use-views`) an extension icon will be added to the control bar and clicking the icon will open the extension window. When not using the Views framework an extension window will be opened automatically on application start.
## Implementation
Based on the [set_page_color](https://developer.chrome.com/extensions/samples#search:browser%20action%20with%20a%20popup) example extension.
Calls:
* [tabs.executeScript](https://developer.chrome.com/extensions/tabs#method-executeScript)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

View File

@ -1,14 +0,0 @@
{
"name": "A browser action with a popup that changes the page color",
"description": "Change the current page color",
"version": "1.0",
"permissions": [
"tabs", "http://*/*", "https://*/*"
],
"browser_action": {
"default_title": "Set this page's color.",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"manifest_version": 2
}

View File

@ -1,55 +0,0 @@
<!doctype html>
<html>
<head>
<title>Set Page Color Popup</title>
<style>
body {
overflow: hidden;
margin: 0px;
padding: 0px;
background: white;
}
div:first-child {
margin-top: 0px;
}
div {
cursor: pointer;
text-align: center;
padding: 1px 3px;
font-family: sans-serif;
font-size: 0.8em;
width: 100px;
margin-top: 1px;
background: #cccccc;
}
div:hover {
background: #aaaaaa;
}
#red {
border: 1px solid red;
color: red;
}
#blue {
border: 1px solid blue;
color: blue;
}
#green {
border: 1px solid green;
color: green;
}
#yellow {
border: 1px solid yellow;
color: yellow;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<div id="red">red</div>
<div id="blue">blue</div>
<div id="green">green</div>
<div id="yellow">yellow</div>
</body>
</html>

View File

@ -1,16 +0,0 @@
// 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.
function click(e) {
chrome.tabs.executeScript(null,
{code:"document.body.style.backgroundColor='" + e.target.id + "'"});
}
document.addEventListener('DOMContentLoaded', function () {
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', click);
}
});

View File

@ -57,11 +57,6 @@ IDS_WINDOW_ICON_1X_PNG BINARY "..\\..\\..\\shared\\resources\\window_icon.1x.png
IDS_WINDOW_ICON_2X_PNG BINARY "..\\..\\..\\shared\\resources\\window_icon.2x.png"
IDS_XMLHTTPREQUEST_HTML BINARY "..\\xmlhttprequest.html"
IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG BINARY "..\\extensions\\set_page_color\\icon.png"
IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON BINARY "..\\extensions\\set_page_color\\manifest.json"
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML BINARY "..\\extensions\\set_page_color\\popup.html"
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS BINARY "..\\extensions\\set_page_color\\popup.js"
/////////////////////////////////////////////////////////////////////////////
//
// Icon

View File

@ -1,293 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/ceftests/extensions/extension_test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/extension_util.h"
using client::ClientAppBrowser;
namespace {
const char kExtensionPath[] = "background-extension";
const char kBackgroundScript[] = "background.js";
// HTML file created internally to load the background script.
const char kGeneratedBackgroundPage[] = "_generated_background_page.html";
// Test load/unload of an extension with a background script.
class BackgroundLoadUnloadTestHandler : public ExtensionTestHandler {
public:
explicit BackgroundLoadUnloadTestHandler(
RequestContextType request_context_type)
: ExtensionTestHandler(request_context_type) {
// Only creating the extension browser.
set_create_main_browser(false);
}
// CefExtensionHandler methods:
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension);
EXPECT_TRUE(extension->IsLoaded());
EXPECT_TRUE(extension->GetLoaderContext());
EXPECT_TRUE(
loader_request_context()->IsSame(extension->GetLoaderContext()));
VerifyExtension(extension);
EXPECT_FALSE(got_loaded_);
got_loaded_.yes();
EXPECT_FALSE(extension_);
extension_ = extension;
background_page_url_ = GetExtensionURL(extension, kGeneratedBackgroundPage);
// Add extension resources.
script_url_ = GetExtensionURL(extension, kBackgroundScript);
AddResource(script_url_, GetMessageJS("extension_onload"),
"text/javascript");
}
void OnExtensionUnloaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension);
EXPECT_FALSE(extension->IsLoaded());
EXPECT_FALSE(extension->GetLoaderContext());
EXPECT_FALSE(got_unloaded_);
got_unloaded_.yes();
EXPECT_TRUE(extension_);
EXPECT_TRUE(extension_->IsSame(extension));
// The extension should no longer be registered with the context.
if (loader_request_context()) {
VerifyExtensionInContext(extension, loader_request_context(), false,
true);
}
if (request_context() && !request_context_same_loader()) {
VerifyExtensionInContext(extension, request_context(), false, false);
}
extension_ = nullptr;
// Execute asynchronously so call stacks have a chance to unwind.
// Will close the browser windows.
CefPostTask(
TID_UI,
base::BindOnce(&BackgroundLoadUnloadTestHandler::DestroyTest, this));
}
bool OnBeforeBackgroundBrowser(CefRefPtr<CefExtension> extension,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension);
EXPECT_TRUE(extension->IsLoaded());
EXPECT_TRUE(extension->GetLoaderContext());
EXPECT_TRUE(
loader_request_context()->IsSame(extension->GetLoaderContext()));
VerifyExtension(extension);
const std::string& background_page_url =
GetExtensionURL(extension, kGeneratedBackgroundPage);
EXPECT_STREQ(background_page_url.c_str(), url.ToString().c_str());
EXPECT_FALSE(client);
client = this;
// Allow the browser creation.
return false;
}
// CefLoadHandler methods:
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
EXPECT_TRUE(browser->GetHost()->IsBackgroundHost());
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
if (isLoading) {
EXPECT_FALSE(extension_browser_);
extension_browser_ = browser;
} else {
EXPECT_TRUE(browser->IsSame(extension_browser_));
const std::string& url = browser->GetMainFrame()->GetURL();
EXPECT_STREQ(background_page_url_.c_str(), url.c_str());
EXPECT_FALSE(got_load_done_);
got_load_done_.yes();
TriggerDestroyTestIfDone();
}
}
// CefResourceRequestHandler methods:
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override {
EXPECT_TRUE(browser->GetHost()->IsBackgroundHost());
EXPECT_TRUE(browser->IsSame(extension_browser_));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
const std::string& url = request->GetURL();
if (url == background_page_url_) {
EXPECT_FALSE(got_background_page_url_request_);
got_background_page_url_request_.yes();
} else if (url == script_url_) {
EXPECT_FALSE(got_script_url_request_);
got_script_url_request_.yes();
} else {
EXPECT_TRUE(false); // Not reached.
}
// Handle the resource request.
return RoutingTestHandler::GetResourceHandler(browser, frame, request);
}
CefRefPtr<CefExtension> extension() const { return extension_; }
// Verify |extension| contents.
void VerifyExtension(CefRefPtr<CefExtension> extension) const {
EXPECT_STREQ(("extensions/" + std::string(kExtensionPath)).c_str(),
client::extension_util::GetInternalExtensionResourcePath(
extension->GetPath())
.c_str());
CefRefPtr<CefDictionaryValue> expected_manifest = CreateManifest();
TestDictionaryEqual(expected_manifest, extension->GetManifest());
VerifyExtensionInContext(extension, loader_request_context(), true, true);
if (!request_context_same_loader()) {
VerifyExtensionInContext(extension, request_context(), true, false);
}
}
std::string GetExtensionURL(CefRefPtr<CefExtension> extension,
const std::string& resource_path) const {
const std::string& identifier = extension->GetIdentifier();
const std::string& origin =
client::extension_util::GetExtensionOrigin(identifier);
EXPECT_FALSE(origin.empty());
return origin + resource_path;
}
protected:
void OnLoadExtensions() override {
LoadExtension(kExtensionPath, CreateManifest());
}
bool OnMessage(CefRefPtr<CefBrowser> browser,
const std::string& message) override {
EXPECT_STREQ("extension_onload", message.c_str());
EXPECT_TRUE(browser->GetHost()->IsBackgroundHost());
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_TRUE(browser->GetHost()->IsBackgroundHost());
EXPECT_FALSE(got_body_onload_);
got_body_onload_.yes();
TriggerDestroyTestIfDone();
return true;
}
void OnDestroyTest() override {
extension_browser_ = nullptr;
EXPECT_TRUE(got_loaded_);
EXPECT_TRUE(got_background_page_url_request_);
EXPECT_TRUE(got_script_url_request_);
EXPECT_TRUE(got_body_onload_);
EXPECT_TRUE(got_load_done_);
EXPECT_TRUE(got_unloaded_);
}
// Create a manifest with background script.
CefRefPtr<CefDictionaryValue> CreateManifest() const {
CefRefPtr<CefDictionaryValue> manifest =
CreateDefaultManifest(ApiPermissionsList());
CefRefPtr<CefDictionaryValue> background = CefDictionaryValue::Create();
CefRefPtr<CefListValue> scripts = CefListValue::Create();
scripts->SetString(0, kBackgroundScript);
background->SetList("scripts", scripts);
manifest->SetDictionary("background", background);
return manifest;
}
void TriggerDestroyTestIfDone() {
if (got_body_onload_ && got_load_done_) {
TriggerDestroyTest();
}
}
virtual void TriggerDestroyTest() {
// Execute asynchronously so call stacks have a chance to unwind.
CefPostTask(TID_UI, base::BindOnce(
&BackgroundLoadUnloadTestHandler::UnloadExtension,
this, extension_));
}
CefRefPtr<CefExtension> extension_;
std::string script_url_;
std::string background_page_url_;
CefRefPtr<CefBrowser> extension_browser_;
TrackCallback got_loaded_;
TrackCallback got_background_page_url_request_;
TrackCallback got_script_url_request_;
TrackCallback got_body_onload_;
TrackCallback got_load_done_;
TrackCallback got_unloaded_;
IMPLEMENT_REFCOUNTING(BackgroundLoadUnloadTestHandler);
DISALLOW_COPY_AND_ASSIGN(BackgroundLoadUnloadTestHandler);
};
} // namespace
EXTENSION_TEST_GROUP_ALL(BackgroundLoadUnload, BackgroundLoadUnloadTestHandler)
namespace {
// Same as above but without the unload. Only do this with a custom context to
// avoid poluting the global context.
class BackgroundLoadNoUnloadTestHandler
: public BackgroundLoadUnloadTestHandler {
public:
explicit BackgroundLoadNoUnloadTestHandler(
RequestContextType request_context_type)
: BackgroundLoadUnloadTestHandler(request_context_type) {}
protected:
void TriggerDestroyTest() override {
// Release everything that references the request context. This should
// trigger unload of the extension.
CloseBrowser(extension_browser_, false);
extension_browser_ = nullptr;
ReleaseRequestContexts();
}
};
} // namespace
EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(BackgroundLoadNoUnload,
BackgroundLoadNoUnloadTestHandler)

View File

@ -1,340 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/ceftests/extensions/extension_test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/shared/browser/extension_util.h"
#define ALARMS_TEST_GROUP_ALL(name, test_class) \
EXTENSION_TEST_GROUP_ALL(ChromeAlarms##name, test_class)
#define ALARMS_TEST_GROUP_MINIMAL(name, test_class) \
EXTENSION_TEST_GROUP_MINIMAL(ChromeAlarms##name, test_class)
namespace {
const char kExtensionPath[] = "alarms-extension";
const char kSuccessMessage[] = "success";
// Base class for testing chrome.alarms methods.
// See https://developer.chrome.com/extensions/alarms
class AlarmsTestHandler : public ExtensionTestHandler {
public:
explicit AlarmsTestHandler(RequestContextType request_context_type)
: ExtensionTestHandler(request_context_type) {
// Only creating the extension browser.
set_create_main_browser(false);
}
// CefExtensionHandler methods:
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_FALSE(got_loaded_);
got_loaded_.yes();
// Verify |extension| contents.
EXPECT_FALSE(extension->GetIdentifier().empty());
EXPECT_STREQ(("extensions/" + std::string(kExtensionPath)).c_str(),
client::extension_util::GetInternalExtensionResourcePath(
extension->GetPath())
.c_str());
TestDictionaryEqual(CreateManifest(), extension->GetManifest());
EXPECT_FALSE(extension_);
extension_ = extension;
CreateBrowserForExtension();
}
void OnExtensionUnloaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension_);
EXPECT_TRUE(extension_->IsSame(extension));
EXPECT_FALSE(got_unloaded_);
got_unloaded_.yes();
extension_ = nullptr;
// Execute asynchronously so call stacks have a chance to unwind.
// Will close the browser windows.
CefPostTask(TID_UI, base::BindOnce(&AlarmsTestHandler::DestroyTest, this));
}
// CefLoadHandler methods:
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
if (isLoading) {
EXPECT_FALSE(extension_browser_);
extension_browser_ = browser;
} else {
EXPECT_TRUE(browser->IsSame(extension_browser_));
const std::string& url = browser->GetMainFrame()->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
}
}
// CefResourceRequestHandler methods:
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override {
EXPECT_TRUE(browser->IsSame(extension_browser_));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
const std::string& url = request->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
EXPECT_FALSE(got_url_request_);
got_url_request_.yes();
// Handle the resource request.
return RoutingTestHandler::GetResourceHandler(browser, frame, request);
}
protected:
void OnLoadExtensions() override {
LoadExtension(kExtensionPath, CreateManifest());
}
bool OnMessage(CefRefPtr<CefBrowser> browser,
const std::string& message) override {
if (message == "extension_onload") {
// From body onLoad in the extension browser.
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_FALSE(got_body_onload_);
got_body_onload_.yes();
TriggerAlarmsApiJSFunction();
return true;
}
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_FALSE(got_success_message_);
got_success_message_.yes();
EXPECT_STREQ(kSuccessMessage, message.c_str());
TriggerDestroyTest();
return true;
}
void OnDestroyTest() override {
extension_browser_ = nullptr;
EXPECT_TRUE(got_loaded_);
EXPECT_TRUE(got_url_request_);
EXPECT_TRUE(got_body_onload_);
EXPECT_TRUE(got_trigger_api_function_);
EXPECT_TRUE(got_success_message_);
EXPECT_TRUE(got_unloaded_);
}
// Create a manifest that grants access to the alarms API.
virtual CefRefPtr<CefDictionaryValue> CreateManifest() const {
ApiPermissionsList api_permissions;
api_permissions.push_back("alarms");
return CreateDefaultManifest(api_permissions);
}
// Add resources in the extension browser.
virtual void OnAddExtensionResources(const std::string& origin) {
extension_url_ = origin + "extension.html";
AddResource(extension_url_, GetExtensionHTML(), "text/html");
}
// Returns the chrome.alarms.* JS that is executed in the extension browser
// when the triggerAlarmsApi() JS function is called.
virtual std::string GetAlarmsApiJS() const = 0;
// Returns the JS that will be loaded in the extension browser. This
// implements the triggerAlarmsApi() JS function called from
// TriggerAlarmsApiJSFunction().
virtual std::string GetExtensionJS() const {
return "function triggerAlarmsApi() {" + GetAlarmsApiJS() + "}";
}
// Returns the HTML that will be loaded in the extension browser.
virtual std::string GetExtensionHTML() const {
return "<html><head><script>" + GetExtensionJS() +
"</script></head><body onLoad=" + GetMessageJS("extension_onload") +
">Extension</body></html>";
}
virtual void TriggerDestroyTest() {
// Execute asynchronously so call stacks have a chance to unwind.
CefPostTask(TID_UI, base::BindOnce(&AlarmsTestHandler::UnloadExtension,
this, extension_));
}
CefRefPtr<CefExtension> extension() const { return extension_; }
std::string extension_url() const { return extension_url_; }
CefRefPtr<CefBrowser> extension_browser() const { return extension_browser_; }
bool got_success_message() const { return got_success_message_; }
private:
void CreateBrowserForExtension() {
const std::string& identifier = extension_->GetIdentifier();
EXPECT_FALSE(identifier.empty());
const std::string& origin =
client::extension_util::GetExtensionOrigin(identifier);
EXPECT_FALSE(origin.empty());
// Add extension resources.
OnAddExtensionResources(origin);
// Create a browser to host the extension.
CreateBrowser(extension_url_, request_context());
}
void TriggerAlarmsApiJSFunction() {
EXPECT_FALSE(got_trigger_api_function_);
got_trigger_api_function_.yes();
extension_browser_->GetMainFrame()->ExecuteJavaScript("triggerAlarmsApi();",
extension_url_, 0);
}
CefRefPtr<CefExtension> extension_;
std::string extension_url_;
CefRefPtr<CefBrowser> extension_browser_;
TrackCallback got_loaded_;
TrackCallback got_url_request_;
TrackCallback got_body_onload_;
TrackCallback got_trigger_api_function_;
TrackCallback got_success_message_;
TrackCallback got_unloaded_;
};
} // namespace
namespace {
// Test for chrome.alarms.create(string name, object alarmInfo)
// and chrome.alarms.onAlarm.addListener(function callback)
class CreateAlarmTestHandler : public AlarmsTestHandler {
public:
explicit CreateAlarmTestHandler(RequestContextType request_context_type)
: AlarmsTestHandler(request_context_type) {}
protected:
std::string GetAlarmsApiJS() const override {
return "chrome.alarms.onAlarm.addListener(function (alarm) {" +
GetMessageJS(kSuccessMessage) +
"});"
"chrome.alarms.create(\"test\", {delayInMinutes:0.01})";
}
private:
IMPLEMENT_REFCOUNTING(CreateAlarmTestHandler);
DISALLOW_COPY_AND_ASSIGN(CreateAlarmTestHandler);
};
} // namespace
ALARMS_TEST_GROUP_ALL(CreateAlarm, CreateAlarmTestHandler)
namespace {
// Test for chrome.alarms.get(string name, function callback)
class GetAlarmTestHandler : public AlarmsTestHandler {
public:
explicit GetAlarmTestHandler(RequestContextType request_context_type)
: AlarmsTestHandler(request_context_type) {}
protected:
std::string GetAlarmsApiJS() const override {
return "chrome.alarms.create(\"test\", {delayInMinutes:1});"
"setTimeout(function() {"
"chrome.alarms.get(\"test\", function (alarm) {" +
GetMessageJS(kSuccessMessage) + "})}, 100)";
}
private:
IMPLEMENT_REFCOUNTING(GetAlarmTestHandler);
DISALLOW_COPY_AND_ASSIGN(GetAlarmTestHandler);
};
} // namespace
ALARMS_TEST_GROUP_MINIMAL(GetAlarm, GetAlarmTestHandler)
namespace {
// Test for chrome.alarms.getAll(function callback)
class GetAllAlarmsTestHandler : public AlarmsTestHandler {
public:
explicit GetAllAlarmsTestHandler(RequestContextType request_context_type)
: AlarmsTestHandler(request_context_type) {}
protected:
std::string GetAlarmsApiJS() const override {
return "chrome.alarms.create(\"alarm1\", {delayInMinutes:1});"
"chrome.alarms.create(\"alarm2\", {delayInMinutes:1});"
"setTimeout(function() {"
"chrome.alarms.getAll(function (alarms) {"
"if (alarms.length == 2) {" +
GetMessageJS(kSuccessMessage) + "}})}, 100)";
}
private:
IMPLEMENT_REFCOUNTING(GetAllAlarmsTestHandler);
DISALLOW_COPY_AND_ASSIGN(GetAllAlarmsTestHandler);
};
} // namespace
ALARMS_TEST_GROUP_MINIMAL(GetAllAlarms, GetAllAlarmsTestHandler)
namespace {
// Test for chrome.alarms.clear(string name, function callback)
class ClearAlarmTestHandler : public AlarmsTestHandler {
public:
explicit ClearAlarmTestHandler(RequestContextType request_context_type)
: AlarmsTestHandler(request_context_type) {}
protected:
std::string GetAlarmsApiJS() const override {
return "chrome.alarms.create(\"test\", {delayInMinutes:1});"
"setTimeout(function() {"
"chrome.alarms.clear(\"test\", function (wasCleared) {"
"if (wasCleared) {" +
GetMessageJS(kSuccessMessage) + "}})}, 100)";
}
private:
IMPLEMENT_REFCOUNTING(ClearAlarmTestHandler);
DISALLOW_COPY_AND_ASSIGN(ClearAlarmTestHandler);
};
} // namespace
ALARMS_TEST_GROUP_MINIMAL(ClearAlarm, ClearAlarmTestHandler)
namespace {
// Test for chrome.alarms.clearAll(function callback)
class ClearAllAlarmsTestHandler : public AlarmsTestHandler {
public:
explicit ClearAllAlarmsTestHandler(RequestContextType request_context_type)
: AlarmsTestHandler(request_context_type) {}
protected:
std::string GetAlarmsApiJS() const override {
return "chrome.alarms.create(\"alarm1\", {delayInMinutes:1});"
"chrome.alarms.create(\"alarm2\", {delayInMinutes:1});"
"setTimeout(function() {"
"chrome.alarms.clearAll(function (wasCleared) {"
"if (wasCleared) {" +
GetMessageJS(kSuccessMessage) + "}})}, 100)";
}
private:
IMPLEMENT_REFCOUNTING(ClearAllAlarmsTestHandler);
DISALLOW_COPY_AND_ASSIGN(ClearAllAlarmsTestHandler);
};
} // namespace
ALARMS_TEST_GROUP_MINIMAL(ClearAllAlarms, ClearAllAlarmsTestHandler)

View File

@ -1,480 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/ceftests/extensions/extension_test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/shared/browser/extension_util.h"
#define STORAGE_TEST_GROUP_ALL(name, test_class) \
EXTENSION_TEST_GROUP_ALL(ChromeStorage##name, test_class)
#define STORAGE_TEST_GROUP_MINIMAL(name, test_class) \
EXTENSION_TEST_GROUP_MINIMAL(ChromeStorage##name, test_class)
namespace {
const char kExtensionPath[] = "storage-extension";
const char kSuccessMessage[] = "success";
// Base class for testing chrome.storage methods.
// See https://developer.chrome.com/extensions/storage
class StorageTestHandler : public ExtensionTestHandler {
public:
explicit StorageTestHandler(RequestContextType request_context_type)
: ExtensionTestHandler(request_context_type) {
// Only creating the extension browser.
set_create_main_browser(false);
}
// CefExtensionHandler methods:
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_FALSE(got_loaded_);
got_loaded_.yes();
// Verify |extension| contents.
EXPECT_FALSE(extension->GetIdentifier().empty());
EXPECT_STREQ(("extensions/" + std::string(kExtensionPath)).c_str(),
client::extension_util::GetInternalExtensionResourcePath(
extension->GetPath())
.c_str());
TestDictionaryEqual(CreateManifest(), extension->GetManifest());
EXPECT_FALSE(extension_);
extension_ = extension;
CreateBrowserForExtension();
}
void OnExtensionUnloaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension_);
EXPECT_TRUE(extension_->IsSame(extension));
EXPECT_FALSE(got_unloaded_);
got_unloaded_.yes();
extension_ = nullptr;
// Execute asynchronously so call stacks have a chance to unwind.
// Will close the browser windows.
CefPostTask(TID_UI, base::BindOnce(&StorageTestHandler::DestroyTest, this));
}
// CefLoadHandler methods:
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
if (isLoading) {
EXPECT_FALSE(extension_browser_);
extension_browser_ = browser;
} else {
EXPECT_TRUE(browser->IsSame(extension_browser_));
const std::string& url = browser->GetMainFrame()->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
}
}
// CefResourceRequestHandler methods:
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override {
EXPECT_TRUE(browser->IsSame(extension_browser_));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
const std::string& url = request->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
EXPECT_FALSE(got_url_request_);
got_url_request_.yes();
// Handle the resource request.
return RoutingTestHandler::GetResourceHandler(browser, frame, request);
}
protected:
void OnLoadExtensions() override {
LoadExtension(kExtensionPath, CreateManifest());
}
bool OnMessage(CefRefPtr<CefBrowser> browser,
const std::string& message) override {
if (message == "extension_onload") {
// From body onLoad in the extension browser.
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_FALSE(got_body_onload_);
got_body_onload_.yes();
TriggerStorageApiJSFunction();
return true;
}
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_FALSE(got_success_message_);
got_success_message_.yes();
EXPECT_STREQ(kSuccessMessage, message.c_str());
TriggerDestroyTest();
return true;
}
void OnDestroyTest() override {
extension_browser_ = nullptr;
EXPECT_TRUE(got_loaded_);
EXPECT_TRUE(got_url_request_);
EXPECT_TRUE(got_body_onload_);
EXPECT_TRUE(got_trigger_api_function_);
EXPECT_TRUE(got_success_message_);
EXPECT_TRUE(got_unloaded_);
}
// Create a manifest that grants access to the storage API.
virtual CefRefPtr<CefDictionaryValue> CreateManifest() const {
ApiPermissionsList api_permissions;
api_permissions.push_back("storage");
return CreateDefaultManifest(api_permissions);
}
// Add resources in the extension browser.
virtual void OnAddExtensionResources(const std::string& origin) {
extension_url_ = origin + "extension.html";
AddResource(extension_url_, GetExtensionHTML(), "text/html");
}
// Returns the chrome.storage.* JS that is executed in the extension browser
// when the triggerStorageApi() JS function is called.
virtual std::string GetStorageApiJS() const = 0;
// Returns the JS that will be loaded in the extension browser. This
// implements the triggerStorageApi() JS function called from
// TriggerStorageApiJSFunction().
virtual std::string GetExtensionJS() const {
return "function triggerStorageApi() {" + GetStorageApiJS() + "}";
}
// Returns the HTML that will be loaded in the extension browser.
virtual std::string GetExtensionHTML() const {
return "<html><head><script>" + GetExtensionJS() +
"</script></head><body onLoad=" + GetMessageJS("extension_onload") +
">Extension</body></html>";
}
virtual void TriggerDestroyTest() {
// Execute asynchronously so call stacks have a chance to unwind.
CefPostTask(TID_UI, base::BindOnce(&StorageTestHandler::UnloadExtension,
this, extension_));
}
CefRefPtr<CefExtension> extension() const { return extension_; }
std::string extension_url() const { return extension_url_; }
CefRefPtr<CefBrowser> extension_browser() const { return extension_browser_; }
bool got_success_message() const { return got_success_message_; }
private:
void CreateBrowserForExtension() {
const std::string& identifier = extension_->GetIdentifier();
EXPECT_FALSE(identifier.empty());
const std::string& origin =
client::extension_util::GetExtensionOrigin(identifier);
EXPECT_FALSE(origin.empty());
// Add extension resources.
OnAddExtensionResources(origin);
// Create a browser to host the extension.
CreateBrowser(extension_url_, request_context());
}
void TriggerStorageApiJSFunction() {
EXPECT_FALSE(got_trigger_api_function_);
got_trigger_api_function_.yes();
extension_browser_->GetMainFrame()->ExecuteJavaScript(
"triggerStorageApi();", extension_url_, 0);
}
CefRefPtr<CefExtension> extension_;
std::string extension_url_;
CefRefPtr<CefBrowser> extension_browser_;
TrackCallback got_loaded_;
TrackCallback got_url_request_;
TrackCallback got_body_onload_;
TrackCallback got_trigger_api_function_;
TrackCallback got_success_message_;
TrackCallback got_unloaded_;
};
} // namespace
namespace {
// Test for chrome.storage.local.set(object items, function callback)
// and for chrome.storage.local.get(string or array of string or object keys,
// function callback)
class LocalStorageTestHandler : public StorageTestHandler {
public:
explicit LocalStorageTestHandler(RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.local.set({\"local_key_1\": \"local_value_1\"}, "
"function() {"
"chrome.storage.local.get(\"local_key_1\", function (items) {"
"if(items[\"local_key_1\"] == \"local_value_1\") {" +
GetMessageJS(kSuccessMessage) +
"}});"
"});";
}
private:
IMPLEMENT_REFCOUNTING(LocalStorageTestHandler);
DISALLOW_COPY_AND_ASSIGN(LocalStorageTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_ALL(LocalStorage, LocalStorageTestHandler)
namespace {
// Test for chrome.storage.local.getBytesInUse(string or array of string keys,
// function callback)
class LocalStorageGetBytesInUseTestHandler : public StorageTestHandler {
public:
explicit LocalStorageGetBytesInUseTestHandler(
RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.local.set({\"local_key_2\": \"local_value_2\"}, "
"function() {"
"chrome.storage.local.getBytesInUse(\"local_key_2\", function "
"(bytesInUse) {"
"if (bytesInUse == 26) {" +
GetMessageJS(kSuccessMessage) +
"}});"
"});";
}
private:
IMPLEMENT_REFCOUNTING(LocalStorageGetBytesInUseTestHandler);
DISALLOW_COPY_AND_ASSIGN(LocalStorageGetBytesInUseTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(LocalStorageGetBytesInUse,
LocalStorageGetBytesInUseTestHandler)
namespace {
// Test for chrome.storage.local.remove(string or array of string keys, function
// callback)
class LocalStorageRemoveTestHandler : public StorageTestHandler {
public:
explicit LocalStorageRemoveTestHandler(
RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.local.set({\"local_key_3\": \"local_value_3\"}, "
"function() {"
"chrome.storage.local.remove(\"local_key_3\", function () {"
"chrome.storage.local.get(\"local_key_3\", function(items) {"
"if (items[\"local_key_3\"] == undefined) {" +
GetMessageJS(kSuccessMessage) +
"}})})"
"});";
}
private:
IMPLEMENT_REFCOUNTING(LocalStorageRemoveTestHandler);
DISALLOW_COPY_AND_ASSIGN(LocalStorageRemoveTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(LocalStorageRemove, LocalStorageRemoveTestHandler)
namespace {
// Test for chrome.storage.local.clear(function callback)
class LocalStorageClearTestHandler : public StorageTestHandler {
public:
explicit LocalStorageClearTestHandler(RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "var value1Cleared = false;"
"var value2Cleared = false;"
"function checkCleared() {"
"if (value1Cleared && value2Cleared) {" +
GetMessageJS(kSuccessMessage) +
"}}"
"chrome.storage.local.set({\"local_key_4\": \"local_value_4\","
"\"local_key_5\": \"local_value_5\"}, function() {"
"chrome.storage.local.clear(function () {"
"chrome.storage.local.get(\"local_key_4\", function(items) {"
"if (items[\"local_key_4\"] == undefined) {"
"value1Cleared = true;"
"checkCleared();"
"}});"
"chrome.storage.local.get(\"local_key_5\", function(items) {"
"if (items[\"local_key_5\"] == undefined) {"
"value2Cleared = true;"
"checkCleared();"
"}});"
"})});";
}
private:
IMPLEMENT_REFCOUNTING(LocalStorageClearTestHandler);
DISALLOW_COPY_AND_ASSIGN(LocalStorageClearTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(LocalStorageClear, LocalStorageClearTestHandler)
namespace {
// Test for chrome.storage.sync.set(object items, function callback)
// and for chrome.storage.sync.get(string or array of string or object keys,
// function callback)
class SyncStorageTestHandler : public StorageTestHandler {
public:
explicit SyncStorageTestHandler(RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.sync.set({\"sync_key_1\": \"sync_value_1\"}, "
"function() {"
"chrome.storage.sync.get(\"sync_key_1\", function (items) {"
"if (items[\"sync_key_1\"] == \"sync_value_1\") {" +
GetMessageJS(kSuccessMessage) +
"}});"
"});";
}
private:
IMPLEMENT_REFCOUNTING(SyncStorageTestHandler);
DISALLOW_COPY_AND_ASSIGN(SyncStorageTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_ALL(SyncStorage, SyncStorageTestHandler)
namespace {
// Test for chrome.storage.sync.getBytesInUse(string or array of string keys,
// function callback)
class SyncStorageGetBytesInUseTestHandler : public StorageTestHandler {
public:
explicit SyncStorageGetBytesInUseTestHandler(
RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.sync.set({\"sync_key_2\": \"sync_value_2\"}, "
"function() {"
"chrome.storage.sync.getBytesInUse(\"sync_key_2\", function "
"(bytesInUse) {"
"if (bytesInUse == 24) {" +
GetMessageJS(kSuccessMessage) +
"}});"
"});";
}
private:
IMPLEMENT_REFCOUNTING(SyncStorageGetBytesInUseTestHandler);
DISALLOW_COPY_AND_ASSIGN(SyncStorageGetBytesInUseTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(SyncStorageGetBytesInUse,
SyncStorageGetBytesInUseTestHandler)
namespace {
// Test for chrome.storage.sync.remove(string or array of string keys, function
// callback)
class SyncStorageRemoveTestHandler : public StorageTestHandler {
public:
explicit SyncStorageRemoveTestHandler(RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "chrome.storage.sync.set({\"sync_key_3\": \"sync_value_3\"}, "
"function() {"
"chrome.storage.sync.remove(\"sync_key_3\", function () {"
"chrome.storage.sync.get(\"sync_key_3\", function(items) {"
"if (items[\"sync_key_3\"] == undefined) {" +
GetMessageJS(kSuccessMessage) +
"}})})"
"});";
}
private:
IMPLEMENT_REFCOUNTING(SyncStorageRemoveTestHandler);
DISALLOW_COPY_AND_ASSIGN(SyncStorageRemoveTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(SyncStorageRemove, SyncStorageRemoveTestHandler)
namespace {
// Test for chrome.storage.sync.clear(function callback)
class SyncStorageClearTestHandler : public StorageTestHandler {
public:
explicit SyncStorageClearTestHandler(RequestContextType request_context_type)
: StorageTestHandler(request_context_type) {}
protected:
std::string GetStorageApiJS() const override {
return "var value1Cleared = false;"
"var value2Cleared = false;"
"function checkCleared() {"
"if (value1Cleared && value2Cleared) {" +
GetMessageJS(kSuccessMessage) +
"}}"
"chrome.storage.sync.set({\"sync_key_4\": \"sync_value_4\","
"\"sync_key_5\": \"sync_value_5\"}, function() {"
"chrome.storage.sync.clear(function () {"
"chrome.storage.sync.get(\"sync_key_4\", function(items) {"
"if (items[\"sync_key_4\"] == undefined) {"
"value1Cleared = true;"
"checkCleared();"
"}});"
"chrome.storage.sync.get(\"sync_key_5\", function(items) {"
"if (items[\"sync_key_5\"] == undefined) {"
"value2Cleared = true;"
"checkCleared();"
"}});"
"})});";
}
private:
IMPLEMENT_REFCOUNTING(SyncStorageClearTestHandler);
DISALLOW_COPY_AND_ASSIGN(SyncStorageClearTestHandler);
};
} // namespace
STORAGE_TEST_GROUP_MINIMAL(SyncStorageClear, SyncStorageClearTestHandler)

File diff suppressed because it is too large Load Diff

View File

@ -1,240 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/ceftests/extensions/extension_test_handler.h"
#include "include/cef_request_context_handler.h"
#include "tests/ceftests/test_suite.h"
#include "tests/ceftests/test_util.h"
ExtensionTestHandler::ExtensionTestHandler(
RequestContextType request_context_type)
: request_context_type_(request_context_type) {
// Verify supported flag combinations.
if (request_context_on_disk()) {
EXPECT_TRUE(request_context_is_custom());
}
if (request_context_load_with_handler()) {
EXPECT_FALSE(request_context_load_without_handler());
}
if (request_context_load_without_handler()) {
EXPECT_TRUE(request_context_with_handler());
EXPECT_FALSE(request_context_load_with_handler());
}
}
ExtensionTestHandler::~ExtensionTestHandler() {
if (!request_context_temp_dir_.IsEmpty()) {
// Temporary directory will be deleted on shutdown.
request_context_temp_dir_.Take();
}
}
void ExtensionTestHandler::RunTest() {
if (create_main_browser_) {
OnAddMainBrowserResources();
}
CefRefPtr<CefRequestContextHandler> rc_handler;
if (request_context_with_handler()) {
class Handler : public CefRequestContextHandler {
public:
explicit Handler(ExtensionTestHandler* test_handler)
: test_handler_(test_handler) {}
void OnRequestContextInitialized(
CefRefPtr<CefRequestContext> request_context) override {
if (test_handler_->create_main_browser()) {
// Load extensions after the RequestContext has been initialized by
// creation of the main browser.
test_handler_->OnLoadExtensions();
}
}
private:
ExtensionTestHandler* test_handler_;
IMPLEMENT_REFCOUNTING(Handler);
};
rc_handler = new Handler(this);
}
if (request_context_is_custom()) {
CefRequestContextSettings settings;
if (request_context_on_disk()) {
// Create a new temporary directory.
EXPECT_TRUE(request_context_temp_dir_.CreateUniqueTempDirUnderPath(
CefTestSuite::GetInstance()->root_cache_path()));
CefString(&settings.cache_path) = request_context_temp_dir_.GetPath();
}
request_context_ = CefRequestContext::CreateContext(settings, rc_handler);
} else {
request_context_ = CefRequestContext::CreateContext(
CefRequestContext::GetGlobalContext(), rc_handler);
}
if (request_context_load_with_handler()) {
class Handler : public CefRequestContextHandler {
public:
Handler() = default;
private:
IMPLEMENT_REFCOUNTING(Handler);
};
loader_request_context_ =
CefRequestContext::CreateContext(request_context_, new Handler());
} else if (request_context_load_without_handler()) {
loader_request_context_ =
CefRequestContext::CreateContext(request_context_, nullptr);
} else {
loader_request_context_ = request_context_;
}
if (create_main_browser_) {
OnCreateMainBrowser();
} else {
// Creation of the extension browser will trigger initialization of the
// RequestContext, so just load the extensions now.
OnLoadExtensions();
}
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
void ExtensionTestHandler::DestroyTest() {
OnDestroyTest();
ReleaseRequestContexts();
RoutingTestHandler::DestroyTest();
}
void ExtensionTestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
RoutingTestHandler::OnAfterCreated(browser);
if (create_main_browser() && !request_context_with_handler() &&
GetBrowserId() == browser->GetIdentifier()) {
// When the RequestContext doesn't have a handler we won't get a
// notification for RequestContext initialization. Instead use main browser
// creation to indicate that the RequestContext has been initialized.
OnLoadExtensions();
}
}
void ExtensionTestHandler::OnExtensionLoadFailed(cef_errorcode_t result) {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(false); // Not reached.
}
// CefMessageRouterBrowserSide::Handler methods:
bool ExtensionTestHandler::OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64_t query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) {
if (OnMessage(browser, request)) {
return true;
}
EXPECT_FALSE(true) << "Unexpected message: " << request.ToString();
return false;
}
// static
CefRefPtr<CefDictionaryValue> ExtensionTestHandler::CreateDefaultManifest(
const std::vector<std::string>& api_permissions) {
CefRefPtr<CefDictionaryValue> manifest = CefDictionaryValue::Create();
manifest->SetString("name", "An extension");
manifest->SetString("description", "An extension description");
manifest->SetString("version", "1.0");
manifest->SetInt("manifest_version", 2);
CefRefPtr<CefListValue> permissions = CefListValue::Create();
permissions->SetSize(api_permissions.size() + 2);
size_t idx = 0;
for (; idx < api_permissions.size(); ++idx) {
permissions->SetString(idx, api_permissions[idx]);
}
// Allow access to all http/https origins.
permissions->SetString(idx++, "http://*/*");
permissions->SetString(idx++, "https://*/*");
manifest->SetList("permissions", permissions);
return manifest;
}
// static
std::string ExtensionTestHandler::GetMessageJS(const std::string& message) {
EXPECT_TRUE(!message.empty());
return "window.testQuery({request:'" + message + "'});";
}
// static
void ExtensionTestHandler::VerifyExtensionInContext(
CefRefPtr<CefExtension> extension,
CefRefPtr<CefRequestContext> context,
bool has_access,
bool is_loader) {
const CefString& extension_id = extension->GetIdentifier();
EXPECT_FALSE(extension_id.empty());
if (has_access) {
EXPECT_TRUE(context->DidLoadExtension(extension_id));
EXPECT_TRUE(context->HasExtension(extension_id));
} else {
EXPECT_FALSE(context->DidLoadExtension(extension_id));
EXPECT_FALSE(context->HasExtension(extension_id));
}
CefRefPtr<CefExtension> extension2 = context->GetExtension(extension_id);
if (has_access) {
EXPECT_TRUE(extension2);
EXPECT_TRUE(extension->IsSame(extension2));
TestDictionaryEqual(extension->GetManifest(), extension2->GetManifest());
} else {
EXPECT_FALSE(extension2);
}
std::vector<CefString> extension_ids;
EXPECT_TRUE(context->GetExtensions(extension_ids));
// Should be our test extension and possibly the builtin PDF extension if it
// has finished loading (our extension may load first if the call to
// LoadExtension initializes the request context).
bool has_extension = false;
for (const auto& i : extension_ids) {
if (i == extension_id) {
has_extension = true;
break;
}
}
if (has_access) {
EXPECT_TRUE(has_extension);
} else {
EXPECT_FALSE(has_extension);
}
}
void ExtensionTestHandler::LoadExtension(
const std::string& extension_path,
CefRefPtr<CefDictionaryValue> manifest) {
EXPECT_TRUE(!extension_path.empty());
loader_request_context_->LoadExtension(extension_path, manifest, this);
}
void ExtensionTestHandler::UnloadExtension(CefRefPtr<CefExtension> extension) {
EXPECT_TRUE(extension);
extension->Unload();
EXPECT_FALSE(extension->IsLoaded());
EXPECT_FALSE(extension->GetLoaderContext());
}
void ExtensionTestHandler::ReleaseRequestContexts() {
request_context_ = nullptr;
loader_request_context_ = nullptr;
}

View File

@ -1,238 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_
#define CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_
#pragma once
#include <vector>
#include "include/cef_extension_handler.h"
#include "include/cef_values.h"
#include "include/wrapper/cef_scoped_temp_dir.h"
#include "tests/ceftests/routing_test_handler.h"
#include "tests/gtest/include/gtest/gtest.h"
class ExtensionTestHandler : public RoutingTestHandler,
public CefExtensionHandler {
public:
// All tests must be able to run with all RequestContext combinations. See the
// EXTENSION_TEST_GROUP_* macros below.
enum RequestContextType {
// If set create a custom context. Otherwise, use the global context.
RC_TYPE_FLAG_CUSTOM = 1 << 0,
// If set store data on disk. Otherwise, store data in memory.
// Requires RC_TYPE_FLAG_CUSTOM.
RC_TYPE_FLAG_ON_DISK = 1 << 1,
// If set use a handler. Otherwise, don't.
RC_TYPE_FLAG_WITH_HANDLER = 1 << 2,
// If set load extensions with a different context that shares the same
// storage but specifies a different handler.
// Excludes RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER.
RC_TYPE_FLAG_LOAD_WITH_HANDLER = 1 << 3,
// If set load extensions with a different context that shares the same
// storage but doesn't specify a handler.
// Requires RC_TYPE_FLAG_WITH_HANDLER.
// Excludes RC_TYPE_FLAG_LOAD_WITH_HANDLER.
RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER = 1 << 4,
};
explicit ExtensionTestHandler(RequestContextType request_context_type);
~ExtensionTestHandler() override;
// TestHandler methods:
void RunTest() override;
void DestroyTest() override;
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
// CefExtensionHandler methods:
void OnExtensionLoadFailed(cef_errorcode_t result) override;
// CefMessageRouterBrowserSide::Handler methods:
bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64_t query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) override;
CefRefPtr<CefRequestContext> request_context() const {
return request_context_;
}
CefRefPtr<CefRequestContext> loader_request_context() const {
return loader_request_context_;
}
bool request_context_is_custom() const {
return !!(request_context_type_ & RC_TYPE_FLAG_CUSTOM);
}
bool request_context_on_disk() const {
return !!(request_context_type_ & RC_TYPE_FLAG_ON_DISK);
}
bool request_context_with_handler() const {
return !!(request_context_type_ & RC_TYPE_FLAG_WITH_HANDLER);
}
bool request_context_load_with_handler() const {
return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITH_HANDLER);
}
bool request_context_load_without_handler() const {
return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER);
}
bool request_context_same_loader() const {
return !(request_context_load_with_handler() ||
request_context_load_without_handler());
}
protected:
// Returns the default extension manifest.
typedef std::vector<std::string> ApiPermissionsList;
static CefRefPtr<CefDictionaryValue> CreateDefaultManifest(
const ApiPermissionsList& api_permissions);
// Returns the JS code that, when executed, will deliver |message| to the
// OnMessage callback.
static std::string GetMessageJS(const std::string& message);
// Run checks on the state of |extension| in |context|. If |has_access| is
// true then |context| is expected to have access to |extension|. If
// |is_loader| is true then |context| is expected to have loaded |extension|.
static void VerifyExtensionInContext(CefRefPtr<CefExtension> extension,
CefRefPtr<CefRequestContext> context,
bool has_access,
bool is_loader);
// Helper for loading/unloading an extension.
void LoadExtension(const std::string& extension_path,
CefRefPtr<CefDictionaryValue> manifest);
void UnloadExtension(CefRefPtr<CefExtension> extension);
// Release request contexts. This is normally called from DestroyTest().
void ReleaseRequestContexts();
void set_create_main_browser(bool val) { create_main_browser_ = val; }
bool create_main_browser() const { return create_main_browser_; }
// Called when its time to add resources for the main browser if
// |create_main_browser_| is true.
virtual void OnAddMainBrowserResources() {}
// Called when its time to create the main browser if
// |create_main_browser_| is true.
virtual void OnCreateMainBrowser() {}
// Called when its time to load extensions.
virtual void OnLoadExtensions() = 0;
// Called when |browser| receives |message|. Return true if the message is
// handled. The JS code that sends messages is created by GetMessageJS().
virtual bool OnMessage(CefRefPtr<CefBrowser> browser,
const std::string& message) = 0;
// Called to perform verification on test destruction.
virtual void OnDestroyTest() = 0;
private:
const RequestContextType request_context_type_;
CefScopedTempDir request_context_temp_dir_;
// Context used when creating browsers.
CefRefPtr<CefRequestContext> request_context_;
// Context used when loading extensions.
CefRefPtr<CefRequestContext> loader_request_context_;
// If true expect creation of a main browser. Default is true.
bool create_main_browser_ = true;
DISALLOW_COPY_AND_ASSIGN(ExtensionTestHandler);
};
// Helper for implementing an extension test.
#define EXTENSION_TEST(name, test_class, rc_type) \
TEST(ExtensionTest, name) { \
CefRefPtr<test_class> handler = new test_class( \
static_cast<ExtensionTestHandler::RequestContextType>(rc_type)); \
handler->ExecuteTest(); \
ReleaseAndWaitForDestructor(handler); \
}
// Helper for implementing extension tests that include all RequestContext
// combinations. When two or more extension tests significantly overlap in
// tested functionality the first test should use the ALL macro and the others
// should use the MINIMAL macro.
#define EXTENSION_TEST_GROUP_ALL(name, test_class) \
EXTENSION_TEST(name##RCGlobal, test_class, 0) \
EXTENSION_TEST(name##RCGlobalLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \
EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithoutHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \
EXTENSION_TEST(name##RCCustomInMemory, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \
EXTENSION_TEST(name##RCCustomInMemoryLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithoutHandler, \
test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \
EXTENSION_TEST(name##RCCustomOnDisk, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK) \
EXTENSION_TEST(name##RCCustomOnDiskLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomOnDiskWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \
EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithoutHandler, \
test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \
ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER)
#define EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \
EXTENSION_TEST(name##RCGlobal, test_class, 0) \
EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER)
#define EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class) \
EXTENSION_TEST(name##RCCustomInMemory, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \
EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \
ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \
ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER)
// Helper for implementing extension tests that include a minimal set of
// RequestContext combinations. This mostly just verifies that the test runs
// and doesn't leak state information in the context.
#define EXTENSION_TEST_GROUP_MINIMAL(name, test_class) \
EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \
EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class)
#endif // CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_

View File

@ -1,244 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/ceftests/extensions/extension_test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/shared/browser/extension_util.h"
namespace {
const char kExtensionPath[] = "view-extension";
// Test extension load/unload.
class ViewLoadUnloadTestHandler : public ExtensionTestHandler {
public:
explicit ViewLoadUnloadTestHandler(RequestContextType request_context_type)
: ExtensionTestHandler(request_context_type) {
// Only creating the extension browser.
set_create_main_browser(false);
}
// CefExtensionHandler methods:
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension);
EXPECT_TRUE(extension->IsLoaded());
EXPECT_TRUE(extension->GetLoaderContext());
EXPECT_TRUE(
loader_request_context()->IsSame(extension->GetLoaderContext()));
VerifyExtension(extension);
EXPECT_FALSE(got_loaded_);
got_loaded_.yes();
EXPECT_FALSE(extension_);
extension_ = extension;
CreateBrowserForExtension();
}
void OnExtensionUnloaded(CefRefPtr<CefExtension> extension) override {
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
EXPECT_TRUE(extension);
EXPECT_FALSE(extension->IsLoaded());
EXPECT_FALSE(extension->GetLoaderContext());
EXPECT_FALSE(got_unloaded_);
got_unloaded_.yes();
EXPECT_TRUE(extension_);
EXPECT_TRUE(extension_->IsSame(extension));
// The extension should no longer be registered with the context.
if (loader_request_context()) {
VerifyExtensionInContext(extension, loader_request_context(), false,
true);
}
if (request_context() && !request_context_same_loader()) {
VerifyExtensionInContext(extension, request_context(), false, false);
}
extension_ = nullptr;
// Execute asynchronously so call stacks have a chance to unwind.
// Will close the browser windows.
CefPostTask(TID_UI,
base::BindOnce(&ViewLoadUnloadTestHandler::DestroyTest, this));
}
// CefLoadHandler methods:
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
EXPECT_FALSE(browser->GetHost()->IsBackgroundHost());
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
if (isLoading) {
EXPECT_FALSE(extension_browser_);
extension_browser_ = browser;
} else {
EXPECT_TRUE(browser->IsSame(extension_browser_));
const std::string& url = browser->GetMainFrame()->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
EXPECT_FALSE(got_load_done_);
got_load_done_.yes();
TriggerDestroyTestIfDone();
}
}
// CefResourceRequestHandler methods:
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override {
EXPECT_FALSE(browser->GetHost()->IsBackgroundHost());
EXPECT_TRUE(browser->IsSame(extension_browser_));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
const std::string& url = request->GetURL();
EXPECT_STREQ(extension_url_.c_str(), url.c_str());
EXPECT_FALSE(got_url_request_);
got_url_request_.yes();
// Handle the resource request.
return RoutingTestHandler::GetResourceHandler(browser, frame, request);
}
protected:
void OnLoadExtensions() override {
LoadExtension(kExtensionPath, CreateManifest());
}
bool OnMessage(CefRefPtr<CefBrowser> browser,
const std::string& message) override {
EXPECT_FALSE(browser->GetHost()->IsBackgroundHost());
EXPECT_STREQ("extension_onload", message.c_str());
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
EXPECT_TRUE(extension);
EXPECT_TRUE(extension_->IsSame(extension));
EXPECT_TRUE(browser->IsSame(extension_browser_));
EXPECT_FALSE(got_body_onload_);
got_body_onload_.yes();
TriggerDestroyTestIfDone();
return true;
}
void OnDestroyTest() override {
extension_browser_ = nullptr;
EXPECT_TRUE(got_loaded_);
EXPECT_TRUE(got_url_request_);
EXPECT_TRUE(got_body_onload_);
EXPECT_TRUE(got_load_done_);
EXPECT_TRUE(got_unloaded_);
}
// Create the default manifest.
CefRefPtr<CefDictionaryValue> CreateManifest() const {
return CreateDefaultManifest(ApiPermissionsList());
}
// Verify |extension| contents.
void VerifyExtension(CefRefPtr<CefExtension> extension) const {
EXPECT_STREQ(("extensions/" + std::string(kExtensionPath)).c_str(),
client::extension_util::GetInternalExtensionResourcePath(
extension->GetPath())
.c_str());
CefRefPtr<CefDictionaryValue> expected_manifest = CreateManifest();
TestDictionaryEqual(expected_manifest, extension->GetManifest());
VerifyExtensionInContext(extension, loader_request_context(), true, true);
if (!request_context_same_loader()) {
VerifyExtensionInContext(extension, request_context(), true, false);
}
}
void CreateBrowserForExtension() {
const std::string& identifier = extension_->GetIdentifier();
EXPECT_FALSE(identifier.empty());
const std::string& origin =
client::extension_util::GetExtensionOrigin(identifier);
EXPECT_FALSE(origin.empty());
// Add extension resources.
extension_url_ = origin + "extension.html";
AddResource(extension_url_,
"<html><body onLoad=" + GetMessageJS("extension_onload") +
">Extension</body></html>",
"text/html");
// Create a browser to host the extension.
CreateBrowser(extension_url_, request_context());
}
void TriggerDestroyTestIfDone() {
if (got_body_onload_ && got_load_done_) {
TriggerDestroyTest();
}
}
virtual void TriggerDestroyTest() {
// Execute asynchronously so call stacks have a chance to unwind.
CefPostTask(TID_UI,
base::BindOnce(&ViewLoadUnloadTestHandler::UnloadExtension,
this, extension_));
}
CefRefPtr<CefExtension> extension_;
std::string extension_url_;
CefRefPtr<CefBrowser> extension_browser_;
TrackCallback got_loaded_;
TrackCallback got_url_request_;
TrackCallback got_body_onload_;
TrackCallback got_load_done_;
TrackCallback got_unloaded_;
IMPLEMENT_REFCOUNTING(ViewLoadUnloadTestHandler);
DISALLOW_COPY_AND_ASSIGN(ViewLoadUnloadTestHandler);
};
} // namespace
EXTENSION_TEST_GROUP_ALL(ViewLoadUnload, ViewLoadUnloadTestHandler)
namespace {
// Same as above but without the unload. Only do this with a custom context to
// avoid poluting the global context.
class ViewLoadNoUnloadTestHandler : public ViewLoadUnloadTestHandler {
public:
explicit ViewLoadNoUnloadTestHandler(RequestContextType request_context_type)
: ViewLoadUnloadTestHandler(request_context_type) {}
protected:
void TriggerDestroyTest() override {
// Release everything that references the request context. This should
// trigger unload of the extension.
CloseBrowser(extension_browser_, false);
extension_browser_ = nullptr;
ReleaseRequestContexts();
}
};
} // namespace
EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(ViewLoadNoUnload,
ViewLoadNoUnloadTestHandler)

View File

@ -1,255 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 "tests/shared/browser/extension_util.h"
#include <algorithm>
#include <memory>
#include "include/base/cef_callback.h"
#include "include/cef_parser.h"
#include "include/cef_path_util.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/shared/browser/file_util.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/string_util.h"
namespace client::extension_util {
namespace {
std::string GetResourcesPath() {
CefString resources_dir;
if (CefGetPath(PK_DIR_RESOURCES, resources_dir) && !resources_dir.empty()) {
return resources_dir.ToString() + file_util::kPathSep;
}
return std::string();
}
// Internal extension paths may be prefixed with PK_DIR_RESOURCES and always
// use forward slash as path separator.
std::string GetInternalPath(const std::string& extension_path) {
std::string resources_path_lower = GetResourcesPath();
std::string extension_path_lower = extension_path;
#if defined(OS_WIN)
// Convert to lower-case, since Windows paths are case-insensitive.
resources_path_lower = AsciiStrToLower(resources_path_lower);
extension_path_lower = AsciiStrToLower(extension_path_lower);
#endif
std::string internal_path;
if (!resources_path_lower.empty() &&
extension_path_lower.find(resources_path_lower) == 0U) {
internal_path = extension_path.substr(resources_path_lower.size());
} else {
internal_path = extension_path;
}
#if defined(OS_WIN)
// Normalize path separators.
std::replace(internal_path.begin(), internal_path.end(), '\\', '/');
#endif
return internal_path;
}
using ManifestCallback =
base::OnceCallback<void(CefRefPtr<CefDictionaryValue> /*manifest*/)>;
void RunManifestCallback(ManifestCallback callback,
CefRefPtr<CefDictionaryValue> manifest) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the browser UI thread.
CefPostTask(TID_UI, base::BindOnce(std::move(callback), manifest));
return;
}
std::move(callback).Run(manifest);
}
// Asynchronously reads the manifest and executes |callback| on the UI thread.
void GetInternalManifest(const std::string& extension_path,
ManifestCallback callback) {
if (!CefCurrentlyOn(TID_FILE_USER_BLOCKING)) {
// Execute on the browser FILE thread.
CefPostTask(TID_FILE_USER_BLOCKING,
base::BindOnce(GetInternalManifest, extension_path,
std::move(callback)));
return;
}
const std::string& manifest_path = GetInternalExtensionResourcePath(
file_util::JoinPath(extension_path, "manifest.json"));
std::string manifest_contents;
if (!LoadBinaryResource(manifest_path.c_str(), manifest_contents) ||
manifest_contents.empty()) {
LOG(ERROR) << "Failed to load manifest from " << manifest_path;
RunManifestCallback(std::move(callback), nullptr);
return;
}
CefString error_msg;
CefRefPtr<CefValue> value =
CefParseJSONAndReturnError(manifest_contents, JSON_PARSER_RFC, error_msg);
if (!value || value->GetType() != VTYPE_DICTIONARY) {
if (error_msg.empty()) {
error_msg = "Incorrectly formatted dictionary contents.";
}
LOG(ERROR) << "Failed to parse manifest from " << manifest_path << "; "
<< error_msg.ToString();
RunManifestCallback(std::move(callback), nullptr);
return;
}
RunManifestCallback(std::move(callback), value->GetDictionary());
}
void LoadExtensionWithManifest(CefRefPtr<CefRequestContext> request_context,
const std::string& extension_path,
CefRefPtr<CefExtensionHandler> handler,
CefRefPtr<CefDictionaryValue> manifest) {
CEF_REQUIRE_UI_THREAD();
// Load the extension internally. Resource requests will be handled via
// AddInternalExtensionToResourceManager.
request_context->LoadExtension(extension_path, manifest, handler);
}
} // namespace
bool IsInternalExtension(const std::string& extension_path) {
// List of internally handled extensions.
static const char* extensions[] = {"set_page_color"};
const std::string& internal_path = GetInternalPath(extension_path);
for (auto& i : extensions) {
// Exact match or first directory component.
const std::string& extension = i;
if (internal_path == extension ||
internal_path.find(extension + '/') == 0) {
return true;
}
}
return false;
}
std::string GetInternalExtensionResourcePath(
const std::string& extension_path) {
return "extensions/" + GetInternalPath(extension_path);
}
std::string GetExtensionResourcePath(const std::string& extension_path,
bool* internal) {
const bool is_internal = IsInternalExtension(extension_path);
if (internal) {
*internal = is_internal;
}
if (is_internal) {
return GetInternalExtensionResourcePath(extension_path);
}
return extension_path;
}
bool GetExtensionResourceContents(const std::string& extension_path,
std::string& contents) {
CEF_REQUIRE_FILE_USER_BLOCKING_THREAD();
if (IsInternalExtension(extension_path)) {
const std::string& contents_path =
GetInternalExtensionResourcePath(extension_path);
return LoadBinaryResource(contents_path.c_str(), contents);
}
return file_util::ReadFileToString(extension_path, &contents);
}
void LoadExtension(CefRefPtr<CefRequestContext> request_context,
const std::string& extension_path,
CefRefPtr<CefExtensionHandler> handler) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the browser UI thread.
CefPostTask(TID_UI, base::BindOnce(LoadExtension, request_context,
extension_path, handler));
return;
}
if (IsInternalExtension(extension_path)) {
// Read the extension manifest and load asynchronously.
GetInternalManifest(
extension_path,
base::BindOnce(LoadExtensionWithManifest, request_context,
extension_path, handler));
} else {
// Load the extension from disk.
request_context->LoadExtension(extension_path, nullptr, handler);
}
}
void AddInternalExtensionToResourceManager(
CefRefPtr<CefExtension> extension,
CefRefPtr<CefResourceManager> resource_manager) {
DCHECK(IsInternalExtension(extension->GetPath()));
if (!CefCurrentlyOn(TID_IO)) {
// Execute on the browser IO thread.
CefPostTask(TID_IO, base::BindOnce(AddInternalExtensionToResourceManager,
extension, resource_manager));
return;
}
const std::string& origin = GetExtensionOrigin(extension->GetIdentifier());
const std::string& resource_path =
GetInternalExtensionResourcePath(extension->GetPath());
// Add provider for bundled resource files.
#if defined(OS_WIN)
// Read resources from the binary.
resource_manager->AddProvider(
CreateBinaryResourceProvider(origin, resource_path), 50, std::string());
#elif defined(OS_POSIX)
// Read resources from a directory on disk.
std::string resource_dir;
if (GetResourceDir(resource_dir)) {
resource_dir += "/" + resource_path;
resource_manager->AddDirectoryProvider(origin, resource_dir, 50,
std::string());
}
#endif
}
std::string GetExtensionOrigin(const std::string& extension_id) {
return "chrome-extension://" + extension_id + "/";
}
std::string GetExtensionURL(CefRefPtr<CefExtension> extension) {
CefRefPtr<CefDictionaryValue> browser_action =
extension->GetManifest()->GetDictionary("browser_action");
if (browser_action) {
const std::string& default_popup =
browser_action->GetString("default_popup");
if (!default_popup.empty()) {
return GetExtensionOrigin(extension->GetIdentifier()) + default_popup;
}
}
return std::string();
}
std::string GetExtensionIconPath(CefRefPtr<CefExtension> extension,
bool* internal) {
CefRefPtr<CefDictionaryValue> browser_action =
extension->GetManifest()->GetDictionary("browser_action");
if (browser_action) {
const std::string& default_icon = browser_action->GetString("default_icon");
if (!default_icon.empty()) {
return GetExtensionResourcePath(
file_util::JoinPath(extension->GetPath(), default_icon), internal);
}
}
return std::string();
}
} // namespace client::extension_util

View File

@ -1,78 +0,0 @@
// Copyright (c) 2017 The Chromium Embedded Framework 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 CEF_TESTS_CEFCLIENT_BROWSER_EXTENSION_UTIL_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_EXTENSION_UTIL_H_
#pragma once
#include <string>
#include "include/cef_extension.h"
#include "include/cef_extension_handler.h"
#include "include/wrapper/cef_resource_manager.h"
namespace client::extension_util {
// Returns true if |extension_path| can be handled internally via
// LoadBinaryResource. This checks a hard-coded list of allowed extension path
// components.
bool IsInternalExtension(const std::string& extension_path);
// Returns the path relative to the resource directory after removing the
// PK_DIR_RESOURCES prefix. This will be the relative path expected by
// LoadBinaryResource (uses '/' as path separator on all platforms). Only call
// this method for internal extensions, either when IsInternalExtension returns
// true or when the extension is handled internally through some means other
// than LoadBinaryResource. Use GetExtensionResourcePath instead if you are
// unsure whether the extension is internal or external.
std::string GetInternalExtensionResourcePath(const std::string& extension_path);
// Returns the resource path for |extension_path|. For external extensions this
// will be the full file path on disk. For internal extensions this will be the
// relative path expected by LoadBinaryResource (uses '/' as path separator on
// all platforms). Internal extensions must be on the hard-coded list enforced
// by IsInternalExtension. If |internal| is non-nullptr it will be set to true
// if the extension is handled internally.
std::string GetExtensionResourcePath(const std::string& extension_path,
bool* internal);
// Read the contents of |extension_path| into |contents|. For external
// extensions this will read the file from disk. For internal extensions this
// will call LoadBinaryResource. Internal extensions must be on the hard-coded
// list enforced by IsInternalExtension. Returns true on success. Must be
// called on the FILE thread.
bool GetExtensionResourceContents(const std::string& extension_path,
std::string& contents);
// Load |extension_path| in |request_context|. May be an internal or external
// extension. Internal extensions must be on the hard-coded list enforced by
// IsInternalExtension.
void LoadExtension(CefRefPtr<CefRequestContext> request_context,
const std::string& extension_path,
CefRefPtr<CefExtensionHandler> handler);
// Register an internal handler for extension resources. Internal extensions
// must be on the hard-coded list enforced by IsInternalExtension.
void AddInternalExtensionToResourceManager(
CefRefPtr<CefExtension> extension,
CefRefPtr<CefResourceManager> resource_manager);
// Returns the URL origin for |extension_id|.
std::string GetExtensionOrigin(const std::string& extension_id);
// Parse browser_action manifest values as defined at
// https://developer.chrome.com/extensions/browserAction
// Look for a browser_action.default_popup manifest value.
std::string GetExtensionURL(CefRefPtr<CefExtension> extension);
// Look for a browser_action.default_icon manifest value and return the resource
// path. If |internal| is non-nullptr it will be set to true if the extension is
// handled internally.
std::string GetExtensionIconPath(CefRefPtr<CefExtension> extension,
bool* internal);
} // namespace client::extension_util
#endif // CEF_TESTS_CEFCLIENT_BROWSER_EXTENSION_UTIL_H_

View File

@ -43,9 +43,6 @@ const char kAlwaysOnTop[] = "always-on-top";
const char kHideTopMenu[] = "hide-top-menu";
const char kSslClientCertificate[] = "ssl-client-certificate";
const char kCRLSetsPath[] = "crl-sets-path";
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
const char kLoadExtension[] = "load-extension";
#endif
const char kNoActivate[] = "no-activate";
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
const char kEnableChromeRuntime[] = "enable-chrome-runtime";

View File

@ -37,9 +37,6 @@ extern const char kAlwaysOnTop[];
extern const char kHideTopMenu[];
extern const char kSslClientCertificate[];
extern const char kCRLSetsPath[];
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
extern const char kLoadExtension[];
#endif
extern const char kNoActivate[];
#if !defined(DISABLE_ALLOY_BOOTSTRAP)
extern const char kEnableChromeRuntime[];

View File

@ -5,7 +5,7 @@
from __future__ import absolute_import
from __future__ import print_function
from file_util import make_dir, write_file
from file_util import make_dir, write_file_if_changed
from gclient_util import *
from gn_args import GetAllPlatformConfigs, GetConfigFileContents
import issue_1999
@ -140,7 +140,7 @@ for dir, config in configs.items():
make_dir(out_path, False)
args_gn_path = os.path.join(out_path, 'args.gn')
args_gn_contents = GetConfigFileContents(config)
write_file(args_gn_path, args_gn_contents)
write_file_if_changed(args_gn_path, args_gn_contents)
# Generate the Ninja config.
cmd = ['gn', 'gen', os.path.join('out', dir)]

View File

@ -822,8 +822,6 @@ if mode == 'standard':
'tests/cefclient/', cefclient_dir, options.quiet)
transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_resources'], \
'tests/cefclient/', cefclient_dir, options.quiet)
transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_resources_extensions_set_page_color'], \
'tests/cefclient/', cefclient_dir, options.quiet)
# transfer common cefsimple files
transfer_gypi_files(cef_dir, cef_paths2['cefsimple_sources_common'], \