Add initial WebUI support (issue #2037)

- Visit chrome://webui-hosts for the list of supported hosts.
This commit is contained in:
Marshall Greenblatt 2016-11-07 14:14:09 -05:00
parent 659e5af870
commit 18763fde50
25 changed files with 962 additions and 262 deletions

View File

@ -946,6 +946,7 @@ template("cef_pak_scaled") {
repack("pak_${target_name}") {
# Each input pak file should also have a deps line for completeness.
# Add associated .h files in the make_pack_header("resources") target.
sources = [
"$root_gen_dir/blink/public/resources/blink_image_resources_${percent}_percent.pak",
"$root_gen_dir/chrome/renderer_resources_${percent}_percent.pak",
@ -993,6 +994,8 @@ cef_pak_scaled("200_percent") {
# Generate devtools_resources.pak.
repack("pak_devtools") {
# Each input pak file should also have a deps line for completeness.
# Add associated .h files in the make_pack_header("resources") target.
sources = [
"$root_gen_dir/blink/devtools_resources.pak",
]
@ -1010,6 +1013,7 @@ repack("pak_devtools") {
# Generate cef_extensions.pak.
repack("pak_extensions") {
# Each input pak file should also have a deps line for completeness.
# Add associated .h files in the make_pack_header("resources") target.
sources = [
"$root_gen_dir/chrome/component_extension_resources.pak",
"$root_gen_dir/extensions/extensions_renderer_resources.pak",
@ -1069,12 +1073,15 @@ grit("cef_resources") {
# Generate cef.pak.
repack("pak") {
# Each input pak file should also have a deps line for completeness.
# Add associated .h files in the make_pack_header("resources") target.
sources = [
"$root_gen_dir/blink/public/resources/blink_resources.pak",
"$root_gen_dir/chrome/browser_resources.pak",
"$root_gen_dir/chrome/net_internals_resources.pak",
"$root_gen_dir/chrome/common_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/cef/cef_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/net/net_resources.pak",
]
@ -1085,9 +1092,11 @@ repack("pak") {
public_deps = [
"//third_party/WebKit/public:resources_grit",
"//chrome/browser:resources",
"//chrome/browser/resources:net_internals_resources",
"//chrome/common:resources",
"//components/resources:components_resources",
":cef_resources",
"//content/browser/tracing:resources",
"//content:resources",
"//net:net_resources",
]
@ -1127,11 +1136,16 @@ make_pack_header("resources") {
header = "$root_out_dir/includes/include/cef_pack_resources.h"
inputs = [
"$root_gen_dir/blink/grit/devtools_resources.h",
"$root_gen_dir/blink/public/resources/grit/blink_image_resources.h",
"$root_gen_dir/blink/public/resources/grit/blink_resources.h",
"$root_gen_dir/cef/grit/cef_resources.h",
"$root_gen_dir/chrome/grit/browser_resources.h",
"$root_gen_dir/chrome/grit/common_resources.h",
"$root_gen_dir/chrome/grit/component_extension_resources.h",
"$root_gen_dir/chrome/grit/net_internals_resources.h",
"$root_gen_dir/chrome/grit/renderer_resources.h",
"$root_gen_dir/components/grit/components_resources.h",
"$root_gen_dir/content/browser/tracing/grit/tracing_resources.h",
"$root_gen_dir/content/grit/content_resources.h",
"$root_gen_dir/extensions/grit/extensions_browser_resources.h",
"$root_gen_dir/extensions/grit/extensions_renderer_resources.h",
@ -1148,6 +1162,7 @@ make_pack_header("strings") {
header = "$root_out_dir/includes/include/cef_pack_strings.h"
inputs = [
"$root_gen_dir/cef/grit/cef_strings.h",
"$root_gen_dir/chrome/grit/chromium_strings.h",
"$root_gen_dir/chrome/grit/generated_resources.h",
"$root_gen_dir/chrome/grit/locale_settings.h",
"$root_gen_dir/chrome/grit/platform_locale_settings.h",
@ -1396,6 +1411,7 @@ cef_unittests_sources = [
"tests/unittests/v8_unittest.cc",
"tests/unittests/values_unittest.cc",
"tests/unittests/version_unittest.cc",
"tests/unittests/webui_unittest.cc",
"tests/unittests/xml_reader_unittest.cc",
"tests/unittests/zip_reader_unittest.cc",
]

View File

@ -27,8 +27,10 @@ template("_repack_one_locale") {
visibility = invoker.visibility
# Each input pak file should also have a deps line for completeness.
# Add associated .h files in the make_pack_header("strings") target.
sources = [
"${root_gen_dir}/cef/cef_strings_${locale}.pak",
"${root_gen_dir}/chrome/chromium_strings_${locale}.pak",
"${root_gen_dir}/chrome/generated_resources_${locale}.pak",
"${root_gen_dir}/chrome/locale_settings_${locale}.pak",
"${root_gen_dir}/chrome/platform_locale_settings_${locale}.pak",
@ -45,6 +47,7 @@ template("_repack_one_locale") {
# listed both here and in the libcef_static target.
public_deps = [
":cef_strings",
"//chrome/app:chromium_strings",
"//chrome/app:generated_resources",
"//chrome/app/resources:locale_settings",
"//chrome/app/resources:platform_locale_settings",

View File

@ -17,6 +17,7 @@
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/streams/stream_context.h"
#include "content/browser/webui/url_data_manager.h"
#include "content/public/browser/storage_partition.h"
namespace {
@ -47,6 +48,10 @@ bool ShouldProxyUserData(const void* key) {
if (key == kFontFamilyCacheKey)
return true;
// If this value is not proxied WebUI will fail to load.
if (key == content::URLDataManager::GetUserDataKey())
return true;
return false;
}
@ -69,6 +74,14 @@ CefBrowserContextProxy::~CefBrowserContextProxy() {
parent_->RemoveProxy(this);
}
void CefBrowserContextProxy::Initialize() {
CefBrowserContext::Initialize();
// This object's CefResourceContext needs to proxy some UserData requests to
// the parent object's CefResourceContext.
resource_context()->set_parent(parent_->resource_context());
}
base::SupportsUserData::Data*
CefBrowserContextProxy::GetUserData(const void* key) const {
if (ShouldProxyUserData(key))

View File

@ -23,6 +23,9 @@ class CefBrowserContextProxy : public CefBrowserContext {
CefBrowserContextProxy(CefRefPtr<CefRequestContextHandler> handler,
scoped_refptr<CefBrowserContextImpl> parent);
// Must be called immediately after this object is created.
void Initialize() override;
// SupportsUserData methods.
Data* GetUserData(const void* key) const override;
void SetUserData(const void* key, Data* data) override;

View File

@ -17,6 +17,7 @@
#include "libcef/browser/extensions/browser_context_keyed_service_factories.h"
#include "libcef/browser/extensions/extensions_browser_client.h"
#include "libcef/browser/extensions/extension_system_factory.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_client.h"
#include "libcef/common/extensions/extensions_util.h"
@ -27,10 +28,8 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/content_switches.h"
#include "device/geolocation/access_token_store.h"
#include "device/geolocation/geolocation_delegate.h"
@ -141,11 +140,6 @@ void CefBrowserMainParts::ToolkitInitialized() {
}
void CefBrowserMainParts::PostMainMessageLoopStart() {
// Don't use the default WebUI controller factory because is conflicts with
// CEF's internal handling of "chrome://tracing".
content::WebUIControllerFactory::UnregisterFactoryForTesting(
content::ContentWebUIControllerFactory::GetInstance());
#if defined(OS_LINUX)
printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&CefPrintDialogLinux::CreatePrintDialog);
@ -202,6 +196,8 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
device::GeolocationProvider::SetGeolocationDelegate(
new CefGeolocationDelegate(
global_browser_context_->request_context().get()));
scheme::RegisterWebUIControllerFactory();
}
void CefBrowserMainParts::PostMainMessageLoopRun() {

View File

@ -11,25 +11,46 @@
#include "libcef/common/cef_switches.h"
#include "base/command_line.h"
#include "chrome/browser/net/chrome_net_log_helper.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "components/net_log/chrome_net_log.h"
#include "content/public/common/content_switches.h"
#include "ui/message_center/message_center.h"
ChromeBrowserProcessStub::ChromeBrowserProcessStub()
: initialized_(false),
context_initialized_(false),
shutdown_(false),
locale_("en-US") {
chrome::SetBrowserContextIncognitoHelper(this);
}
ChromeBrowserProcessStub::~ChromeBrowserProcessStub() {
DCHECK(!initialized_ || shutdown_);
DCHECK((!initialized_ && !context_initialized_) || shutdown_);
g_browser_process = NULL;
chrome::SetBrowserContextIncognitoHelper(nullptr);
}
void ChromeBrowserProcessStub::Initialize() {
CEF_REQUIRE_UIT();
void ChromeBrowserProcessStub::Initialize(
const base::CommandLine& command_line) {
DCHECK(!initialized_);
DCHECK(!context_initialized_);
DCHECK(!shutdown_);
base::FilePath net_log_path;
if (command_line.HasSwitch(switches::kLogNetLog))
net_log_path = command_line.GetSwitchValuePath(switches::kLogNetLog);
net_log_.reset(new net_log::ChromeNetLog(
net_log_path, GetNetCaptureModeFromCommandLine(command_line),
command_line.GetCommandLineString(), std::string()));
initialized_ = true;
}
void ChromeBrowserProcessStub::OnContextInitialized() {
CEF_REQUIRE_UIT();
DCHECK(initialized_);
DCHECK(!context_initialized_);
DCHECK(!shutdown_);
// Must be created after the NotificationService.
@ -37,12 +58,13 @@ void ChromeBrowserProcessStub::Initialize() {
profile_manager_.reset(new ChromeProfileManagerStub());
event_router_forwarder_ = new extensions::EventRouterForwarder();
initialized_ = true;
context_initialized_ = true;
}
void ChromeBrowserProcessStub::Shutdown() {
CEF_REQUIRE_UIT();
DCHECK(initialized_);
DCHECK(context_initialized_);
DCHECK(!shutdown_);
// Wait for the pending print jobs to finish. Don't do this later, since
@ -58,146 +80,149 @@ void ChromeBrowserProcessStub::Shutdown() {
}
void ChromeBrowserProcessStub::ResourceDispatcherHostCreated() {
NOTIMPLEMENTED();
NOTREACHED();
};
void ChromeBrowserProcessStub::EndSession() {
NOTIMPLEMENTED();
NOTREACHED();
};
metrics_services_manager::MetricsServicesManager*
ChromeBrowserProcessStub::GetMetricsServicesManager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
metrics::MetricsService* ChromeBrowserProcessStub::metrics_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
rappor::RapporService* ChromeBrowserProcessStub::rappor_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
IOThread* ChromeBrowserProcessStub::io_thread() {
NOTIMPLEMENTED();
return NULL;
}
WatchDogThread* ChromeBrowserProcessStub::watchdog_thread() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
ProfileManager* ChromeBrowserProcessStub::profile_manager() {
DCHECK(context_initialized_);
return profile_manager_.get();
}
PrefService* ChromeBrowserProcessStub::local_state() {
NOTIMPLEMENTED();
return NULL;
DCHECK(context_initialized_);
return profile_manager_->GetLastUsedProfile(
profile_manager_->user_data_dir())->GetPrefs();
}
net::URLRequestContextGetter*
ChromeBrowserProcessStub::system_request_context() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
variations::VariationsService*
ChromeBrowserProcessStub::variations_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
BrowserProcessPlatformPart* ChromeBrowserProcessStub::platform_part() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
extensions::EventRouterForwarder*
ChromeBrowserProcessStub::extension_event_router_forwarder() {
DCHECK(context_initialized_);
return event_router_forwarder_.get();
}
NotificationUIManager* ChromeBrowserProcessStub::notification_ui_manager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
NotificationPlatformBridge*
ChromeBrowserProcessStub::notification_platform_bridge() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
message_center::MessageCenter* ChromeBrowserProcessStub::message_center() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
policy::BrowserPolicyConnector*
ChromeBrowserProcessStub::browser_policy_connector() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
policy::PolicyService* ChromeBrowserProcessStub::policy_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
IconManager* ChromeBrowserProcessStub::icon_manager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
GpuModeManager* ChromeBrowserProcessStub::gpu_mode_manager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
GpuProfileCache* ChromeBrowserProcessStub::gpu_profile_cache() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
void ChromeBrowserProcessStub::CreateDevToolsHttpProtocolHandler(
const std::string& ip,
uint16_t port) {
NOTIMPLEMENTED();
NOTREACHED();
}
void ChromeBrowserProcessStub::CreateDevToolsAutoOpener() {
NOTIMPLEMENTED();
NOTREACHED();
}
bool ChromeBrowserProcessStub::IsShuttingDown() {
NOTIMPLEMENTED();
NOTREACHED();
return false;
}
printing::PrintJobManager* ChromeBrowserProcessStub::print_job_manager() {
DCHECK(context_initialized_);
return print_job_manager_.get();
}
printing::PrintPreviewDialogController*
ChromeBrowserProcessStub::print_preview_dialog_controller() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
printing::BackgroundPrintingManager*
ChromeBrowserProcessStub::background_printing_manager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
IntranetRedirectDetector*
ChromeBrowserProcessStub::intranet_redirect_detector() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
@ -211,45 +236,45 @@ void ChromeBrowserProcessStub::SetApplicationLocale(const std::string& locale) {
}
DownloadStatusUpdater* ChromeBrowserProcessStub::download_status_updater() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
DownloadRequestLimiter* ChromeBrowserProcessStub::download_request_limiter() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
BackgroundModeManager* ChromeBrowserProcessStub::background_mode_manager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
void ChromeBrowserProcessStub::set_background_mode_manager_for_test(
std::unique_ptr<BackgroundModeManager> manager) {
NOTIMPLEMENTED();
NOTREACHED();
}
StatusTray* ChromeBrowserProcessStub::status_tray() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
safe_browsing::SafeBrowsingService*
ChromeBrowserProcessStub::safe_browsing_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
safe_browsing::ClientSideDetectionService*
ChromeBrowserProcessStub::safe_browsing_detection_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
subresource_filter::RulesetService*
ChromeBrowserProcessStub::subresource_filter_ruleset_service() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
@ -259,75 +284,75 @@ void ChromeBrowserProcessStub::StartAutoupdateTimer() {
#endif
net_log::ChromeNetLog* ChromeBrowserProcessStub::net_log() {
NOTIMPLEMENTED();
return NULL;
DCHECK(initialized_);
return net_log_.get();
}
component_updater::ComponentUpdateService*
ChromeBrowserProcessStub::component_updater() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
CRLSetFetcher* ChromeBrowserProcessStub::crl_set_fetcher() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
component_updater::PnaclComponentInstaller*
ChromeBrowserProcessStub::pnacl_component_installer() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
component_updater::SupervisedUserWhitelistInstaller*
ChromeBrowserProcessStub::supervised_user_whitelist_installer() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
MediaFileSystemRegistry*
ChromeBrowserProcessStub::media_file_system_registry() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
bool ChromeBrowserProcessStub::created_local_state() const {
NOTIMPLEMENTED();
NOTREACHED();
return false;
}
#if defined(ENABLE_WEBRTC)
WebRtcLogUploader* ChromeBrowserProcessStub::webrtc_log_uploader() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
#endif
network_time::NetworkTimeTracker*
ChromeBrowserProcessStub::network_time_tracker() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
gcm::GCMDriver* ChromeBrowserProcessStub::gcm_driver() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
shell_integration::DefaultWebClientState
ChromeBrowserProcessStub::CachedDefaultWebClientState() {
NOTIMPLEMENTED();
NOTREACHED();
return shell_integration::UNKNOWN_DEFAULT;
}
memory::TabManager* ChromeBrowserProcessStub::GetTabManager() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
PhysicalWebDataSource* ChromeBrowserProcessStub::GetPhysicalWebDataSource() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}

View File

@ -33,7 +33,8 @@ class ChromeBrowserProcessStub : public BrowserProcess,
ChromeBrowserProcessStub();
~ChromeBrowserProcessStub() override;
void Initialize();
void Initialize(const base::CommandLine& command_line);
void OnContextInitialized();
void Shutdown();
// BrowserProcess implementation.
@ -117,12 +118,14 @@ class ChromeBrowserProcessStub : public BrowserProcess,
private:
bool initialized_;
bool context_initialized_;
bool shutdown_;
std::string locale_;
std::unique_ptr<printing::PrintJobManager> print_job_manager_;
std::unique_ptr<ChromeProfileManagerStub> profile_manager_;
scoped_refptr<extensions::EventRouterForwarder> event_router_forwarder_;
std::unique_ptr<net_log::ChromeNetLog> net_log_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProcessStub);
};

View File

@ -6,6 +6,25 @@
#include "libcef/browser/chrome_profile_manager_stub.h"
#include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/content_browser_client.h"
namespace {
// Return the active browser context. This is primarily called from Chrome code
// that handles WebUI views and wishes to associate the view's data with a
// particular context (profile). Chrome stores multiple profiles in sub-
// directories of |user_data_dir| and then uses ProfileManager to track which
// profile (sub-directory name) was last active.
//
// TODO(cef): To most closely match Chrome behavior this should return the
// context for the currently active browser (e.g. the browser with input focus).
// Return the main context for now since we don't currently have a good way to
// determine that.
CefBrowserContextImpl* GetActiveBrowserContext() {
return CefContentBrowserClient::Get()->browser_context().get();
}
} // namespace
ChromeProfileManagerStub::ChromeProfileManagerStub()
: ProfileManager(base::FilePath()) {
@ -18,7 +37,15 @@ Profile* ChromeProfileManagerStub::GetProfile(
const base::FilePath& profile_dir) {
scoped_refptr<CefBrowserContextImpl> browser_context =
CefBrowserContextImpl::GetForCachePath(profile_dir);
DCHECK(browser_context);
if (!browser_context) {
// ProfileManager makes assumptions about profile directory paths that do
// not match CEF usage. For example, the default Chrome profile name is
// "Default" so it will append that sub-directory name to an empty
// |user_data_dir| value and then call this method. Use the active context
// in cases such as this where we don't understand what ProfileManager is
// asking for.
browser_context = GetActiveBrowserContext();
}
return browser_context.get();
}
@ -29,3 +56,10 @@ bool ChromeProfileManagerStub::IsValidProfile(const void* profile) {
reinterpret_cast<content::BrowserContext*>(
const_cast<void*>(profile))).get();
}
Profile* ChromeProfileManagerStub::GetLastUsedProfile(
const base::FilePath& user_data_dir) {
// Override this method to avoid having to register prefs::kProfileLastUsed,
// usage of which doesn't make sense for CEF.
return GetActiveBrowserContext();
}

View File

@ -18,6 +18,7 @@ class ChromeProfileManagerStub : public ProfileManager {
Profile* GetProfile(const base::FilePath& profile_dir) override;
bool IsValidProfile(const void* profile) override;
Profile* GetLastUsedProfile(const base::FilePath& user_data_dir) override;
private:
DISALLOW_COPY_AND_ASSIGN(ChromeProfileManagerStub);

View File

@ -5,38 +5,38 @@
#include "libcef/browser/chrome_profile_stub.h"
ChromeProfileStub::ChromeProfileStub(){
ChromeProfileStub::ChromeProfileStub() {
}
ChromeProfileStub::~ChromeProfileStub() {
}
scoped_refptr<base::SequencedTaskRunner> ChromeProfileStub::GetIOTaskRunner() {
NOTIMPLEMENTED();
NOTREACHED();
return scoped_refptr<base::SequencedTaskRunner>();
}
std::string ChromeProfileStub::GetProfileUserName() const {
NOTIMPLEMENTED();
NOTREACHED();
return std::string();
}
Profile::ProfileType ChromeProfileStub::GetProfileType() const {
NOTIMPLEMENTED();
NOTREACHED();
return REGULAR_PROFILE;
}
Profile* ChromeProfileStub::GetOffTheRecordProfile() {
NOTIMPLEMENTED();
NOTREACHED();
return NULL;
}
void ChromeProfileStub::DestroyOffTheRecordProfile() {
NOTIMPLEMENTED();
NOTREACHED();
}
bool ChromeProfileStub::HasOffTheRecordProfile() {
NOTIMPLEMENTED();
NOTREACHED();
return false;
}
@ -44,100 +44,100 @@ Profile* ChromeProfileStub::GetOriginalProfile() {
return this;
}
bool ChromeProfileStub::IsSupervised() const {
bool ChromeProfileStub::IsSupervised() const {
return false;
}
bool ChromeProfileStub::IsChild() const {
NOTIMPLEMENTED();
bool ChromeProfileStub::IsChild() const {
return false;
}
bool ChromeProfileStub::IsLegacySupervised() const {
NOTIMPLEMENTED();
bool ChromeProfileStub::IsLegacySupervised() const {
NOTREACHED();
return false;
}
ExtensionSpecialStoragePolicy*
ChromeProfileStub::GetExtensionSpecialStoragePolicy() {
NOTIMPLEMENTED();
ChromeProfileStub::GetExtensionSpecialStoragePolicy() {
NOTREACHED();
return NULL;
}
PrefService* ChromeProfileStub::GetOffTheRecordPrefs() {
NOTIMPLEMENTED();
PrefService* ChromeProfileStub::GetOffTheRecordPrefs() {
NOTREACHED();
return NULL;
}
net::URLRequestContextGetter*
ChromeProfileStub::GetRequestContextForExtensions() {
NOTIMPLEMENTED();
ChromeProfileStub::GetRequestContextForExtensions() {
// TODO(cef): Consider creating a separate context for extensions to match
// Chrome behavior.
return GetRequestContext();
}
net::SSLConfigService* ChromeProfileStub::GetSSLConfigService() {
NOTREACHED();
return NULL;
}
net::SSLConfigService* ChromeProfileStub::GetSSLConfigService() {
NOTIMPLEMENTED();
return NULL;
}
bool ChromeProfileStub::IsSameProfile(Profile* profile) {
NOTIMPLEMENTED();
bool ChromeProfileStub::IsSameProfile(Profile* profile) {
NOTREACHED();
return false;
}
base::Time ChromeProfileStub::GetStartTime() const {
NOTIMPLEMENTED();
base::Time ChromeProfileStub::GetStartTime() const {
NOTREACHED();
return base::Time();
}
base::FilePath ChromeProfileStub::last_selected_directory() {
NOTIMPLEMENTED();
base::FilePath ChromeProfileStub::last_selected_directory() {
NOTREACHED();
return base::FilePath();
}
void ChromeProfileStub::set_last_selected_directory(
const base::FilePath& path) {
NOTIMPLEMENTED();
const base::FilePath& path) {
NOTREACHED();
}
PrefProxyConfigTracker* ChromeProfileStub::GetProxyConfigTracker() {
NOTIMPLEMENTED();
PrefProxyConfigTracker* ChromeProfileStub::GetProxyConfigTracker() {
NOTREACHED();
return NULL;
}
chrome_browser_net::Predictor* ChromeProfileStub::GetNetworkPredictor() {
NOTIMPLEMENTED();
chrome_browser_net::Predictor* ChromeProfileStub::GetNetworkPredictor() {
NOTREACHED();
return NULL;
}
DevToolsNetworkControllerHandle*
ChromeProfileStub::GetDevToolsNetworkControllerHandle() {
NOTIMPLEMENTED();
ChromeProfileStub::GetDevToolsNetworkControllerHandle() {
NOTREACHED();
return NULL;
}
void ChromeProfileStub::ClearNetworkingHistorySince(
base::Time time,
const base::Closure& completion) {
NOTIMPLEMENTED();
const base::Closure& completion) {
NOTREACHED();
}
GURL ChromeProfileStub::GetHomePage() {
NOTIMPLEMENTED();
GURL ChromeProfileStub::GetHomePage() {
NOTREACHED();
return GURL();
}
bool ChromeProfileStub::WasCreatedByVersionOrLater(
const std::string& version) {
NOTIMPLEMENTED();
const std::string& version) {
NOTREACHED();
return false;
}
void ChromeProfileStub::SetExitType(ExitType exit_type) {
NOTIMPLEMENTED();
NOTREACHED();
}
Profile::ExitType ChromeProfileStub::GetLastSessionExitType() {
NOTIMPLEMENTED();
NOTREACHED();
return EXIT_NORMAL;
}

View File

@ -48,7 +48,6 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/plugin_service_impl.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_url_handler.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/navigation_handle.h"
@ -848,9 +847,7 @@ void CefContentBrowserClient::OverrideWebkitPrefs(
void CefContentBrowserClient::BrowserURLHandlerCreated(
content::BrowserURLHandler* handler) {
// Used to redirect about: URLs to chrome: URLs.
handler->AddHandlerPair(&scheme::WillHandleBrowserAboutURL,
content::BrowserURLHandler::null_handler());
scheme::BrowserURLHandlerCreated(handler);
}
std::string CefContentBrowserClient::GetDefaultDownloadName() {

View File

@ -307,6 +307,9 @@ bool CefContext::Initialize(const CefMainArgs& args,
if (exit_code >= 0)
return false;
static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Initialize(
*base::CommandLine::ForCurrentProcess());
// Run the process. Results in a call to CefMainDelegate::RunProcess() which
// will create the browser runner and message loop without blocking.
exit_code = main_runner_->Run();
@ -389,7 +392,8 @@ void CefContext::PopulateRequestContextSettings(
void CefContext::OnContextInitialized() {
CEF_REQUIRE_UIT();
static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Initialize();
static_cast<ChromeBrowserProcessStub*>(g_browser_process)->
OnContextInitialized();
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
CefWidevineLoader::GetInstance()->OnContextInitialized();

View File

@ -5,6 +5,7 @@
#include "libcef/browser/net/chrome_scheme_handler.h"
#include <algorithm>
#include <map>
#include <string>
#include <utility>
@ -19,6 +20,7 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
@ -27,16 +29,15 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "cef/grit/cef_resources.h"
#include "components/grit/components_resources.h"
#include "content/browser/net/view_http_cache_job_factory.h"
#include "content/browser/net/view_blob_internals_job_factory.h"
#include "chrome/browser/browser_about_handler.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/url_constants.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/public/browser/browser_url_handler.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "ipc/ipc_channel.h"
#include "net/url_request/url_request.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/resources/grit/webui_resources.h"
#include "ui/resources/grit/webui_resources_map.h"
#include "v8/include/v8.h"
namespace scheme {
@ -45,38 +46,282 @@ const char kChromeURL[] = "chrome://";
namespace {
const char kChromeCreditsDomain[] = "credits";
const char kChromeLicenseDomain[] = "license";
const char kChromeResourcesDomain[] = "resources";
const char kChromeVersionDomain[] = "version";
const char kChromeUILicenseHost[] = "license";
const char kChromeUIWebUIHostsHost[] = "webui-hosts";
enum ChromeDomain {
CHROME_UNKNOWN = 0,
CHROME_CREDITS,
CHROME_LICENSE,
CHROME_RESOURCES,
CHROME_VERSION,
// Chrome hosts implemented by WebUI.
// Some WebUI handlers have Chrome dependencies that may fail in CEF without
// additional changes. Do not add new hosts to this list without also manually
// testing all related functionality in CEF.
const char* kAllowedWebUIHosts[] = {
content::kChromeUIAppCacheInternalsHost,
content::kChromeUIAccessibilityHost,
content::kChromeUIBlobInternalsHost,
chrome::kChromeUICreditsHost,
content::kChromeUIGpuHost,
content::kChromeUIHistogramHost,
content::kChromeUIIndexedDBInternalsHost,
content::kChromeUIMediaInternalsHost,
chrome::kChromeUINetExportHost,
chrome::kChromeUINetInternalsHost,
content::kChromeUINetworkErrorHost,
content::kChromeUINetworkErrorsListingHost,
content::kChromeUINetworkViewCacheHost,
content::kChromeUIResourcesHost,
content::kChromeUIServiceWorkerInternalsHost,
chrome::kChromeUISystemInfoHost,
content::kChromeUITracingHost,
content::kChromeUIWebRTCInternalsHost,
};
ChromeDomain GetChromeDomain(const std::string& domain_name) {
static struct {
const char* name;
ChromeDomain domain;
} domains[] = {
{ kChromeCreditsDomain, CHROME_CREDITS },
{ kChromeLicenseDomain, CHROME_LICENSE },
{ kChromeResourcesDomain, CHROME_RESOURCES },
{ kChromeVersionDomain, CHROME_VERSION },
};
enum ChromeHostId {
CHROME_UNKNOWN = 0,
CHROME_LICENSE,
CHROME_VERSION,
CHROME_WEBUI_HOSTS,
};
for (size_t i = 0; i < sizeof(domains) / sizeof(domains[0]); ++i) {
if (base::EqualsCaseInsensitiveASCII(domains[i].name, domain_name.c_str()))
return domains[i].domain;
// Chrome hosts implemented by CEF.
const struct {
const char* host;
ChromeHostId host_id;
} kAllowedCefHosts[] = {
{ kChromeUILicenseHost, CHROME_LICENSE },
{ chrome::kChromeUIVersionHost, CHROME_VERSION },
{ kChromeUIWebUIHostsHost, CHROME_WEBUI_HOSTS },
};
ChromeHostId GetChromeHostId(const std::string& host) {
for (size_t i = 0;
i < sizeof(kAllowedCefHosts) / sizeof(kAllowedCefHosts[0]); ++i) {
if (base::EqualsCaseInsensitiveASCII(kAllowedCefHosts[i].host,
host.c_str())) {
return kAllowedCefHosts[i].host_id;
}
}
return CHROME_UNKNOWN;
}
void GetAllowedHosts(std::vector<std::string>* hosts) {
for (size_t i = 0;
i < sizeof(kAllowedCefHosts) / sizeof(kAllowedCefHosts[0]); ++i) {
hosts->push_back(kAllowedCefHosts[i].host);
}
for (size_t i = 0;
i < sizeof(kAllowedWebUIHosts) / sizeof(kAllowedWebUIHosts[0]); ++i) {
hosts->push_back(kAllowedWebUIHosts[i]);
}
}
// Intercepts all WebUI calls and either blocks them or forwards them to the
// Content or Chrome WebUI factory as appropriate.
class CefWebUIControllerFactory : public content::WebUIControllerFactory {
public:
// Returns true if WebUI is allowed to handle the specified |url|.
static bool AllowWebUIForURL(const GURL& url) {
if (!url.SchemeIs(content::kChromeUIScheme))
return false;
for (size_t i = 0;
i < sizeof(kAllowedWebUIHosts) / sizeof(kAllowedWebUIHosts[0]); ++i) {
if (base::EqualsCaseInsensitiveASCII(kAllowedWebUIHosts[i],
url.host().c_str())) {
return true;
}
}
return false;
}
content::WebUIController* CreateWebUIControllerForURL(
content::WebUI* web_ui,
const GURL& url) const override {
content::WebUIController* controller = nullptr;
if (!AllowWebUIForURL(url))
return controller;
controller = content::ContentWebUIControllerFactory::GetInstance()->
CreateWebUIControllerForURL(web_ui, url);
if (controller != nullptr)
return controller;
controller = ChromeWebUIControllerFactory::GetInstance()->
CreateWebUIControllerForURL(web_ui, url);
if (controller != nullptr)
return controller;
return nullptr;
}
content::WebUI::TypeID GetWebUIType(content::BrowserContext* browser_context,
const GURL& url) const override {
content::WebUI::TypeID type = content::WebUI::kNoWebUI;
if (!AllowWebUIForURL(url))
return type;
type = content::ContentWebUIControllerFactory::GetInstance()->GetWebUIType(
browser_context, url);
if (type != content::WebUI::kNoWebUI)
return type;
type = ChromeWebUIControllerFactory::GetInstance()->GetWebUIType(
browser_context, url);
if (type != content::WebUI::kNoWebUI)
return type;
return content::WebUI::kNoWebUI;
}
bool UseWebUIForURL(content::BrowserContext* browser_context,
const GURL& url) const override {
if (!AllowWebUIForURL(url))
return false;
if (content::ContentWebUIControllerFactory::GetInstance()->UseWebUIForURL(
browser_context, url) ||
ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
browser_context, url)) {
return true;
}
return false;
}
bool UseWebUIBindingsForURL(content::BrowserContext* browser_context,
const GURL& url) const override {
if (!AllowWebUIForURL(url))
return false;
if (content::ContentWebUIControllerFactory::GetInstance()->
UseWebUIBindingsForURL(browser_context, url) ||
ChromeWebUIControllerFactory::GetInstance()->UseWebUIBindingsForURL(
browser_context, url)) {
return true;
}
return false;
}
static void BrowserURLHandlerCreated(content::BrowserURLHandler* handler) {
// about: handler. Must come before chrome: handler, since it will
// rewrite about: urls to chrome: URLs and then expect chrome: to
// actually handle them. Also relies on a preliminary fixup phase.
handler->SetFixupHandler(&FixupBrowserAboutURL);
handler->AddHandlerPair(&WillHandleBrowserAboutURL,
content::BrowserURLHandler::null_handler());
// chrome: & friends.
handler->AddHandlerPair(&HandleWebUI, &HandleWebUIReverse);
}
static CefWebUIControllerFactory* GetInstance();
protected:
CefWebUIControllerFactory() {}
~CefWebUIControllerFactory() override {}
private:
friend struct base::DefaultLazyInstanceTraits<CefWebUIControllerFactory>;
// From chrome/browser/chrome_content_browser_client.cc
// Returns a copy of the given url with its host set to given host and path
// set to given path. Other parts of the url will be the same.
static GURL ReplaceURLHostAndPath(const GURL& url,
const std::string& host,
const std::string& path) {
url::Replacements<char> replacements;
replacements.SetHost(host.c_str(), url::Component(0, host.length()));
replacements.SetPath(path.c_str(), url::Component(0, path.length()));
return url.ReplaceComponents(replacements);
}
// Maps "foo://bar/baz/" to "foo://chrome/bar/baz/".
static GURL AddUberHost(const GURL& url) {
const std::string uber_host = chrome::kChromeUIUberHost;
std::string new_path;
url.host_piece().AppendToString(&new_path);
url.path_piece().AppendToString(&new_path);
return ReplaceURLHostAndPath(url, uber_host, new_path);
}
// If url->host() is "chrome" and url->path() has characters other than the
// first slash, changes the url from "foo://chrome/bar/" to "foo://bar/" and
// returns true. Otherwise returns false.
static bool RemoveUberHost(GURL* url) {
if (url->host() != chrome::kChromeUIUberHost)
return false;
if (url->path().empty() || url->path() == "/")
return false;
const std::string old_path = url->path();
const std::string::size_type separator = old_path.find('/', 1);
std::string new_host;
std::string new_path;
if (separator == std::string::npos) {
new_host = old_path.substr(1);
} else {
new_host = old_path.substr(1, separator - 1);
new_path = old_path.substr(separator);
}
// Do not allow URLs with paths empty before the first slash since we can't
// have an empty host. (e.g "foo://chrome//")
if (new_host.empty())
return false;
*url = ReplaceURLHostAndPath(*url, new_host, new_path);
DCHECK(url->is_valid());
return true;
}
// Handles rewriting Web UI URLs.
static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context) {
// Do not handle special URLs such as "about:foo"
if (!url->host().empty()) {
const GURL chrome_url = AddUberHost(*url);
// Handle valid "chrome://chrome/foo" URLs so the reverse handler will
// be called.
if (GetInstance()->UseWebUIForURL(browser_context, chrome_url))
return true;
}
if (!GetInstance()->UseWebUIForURL(browser_context, *url))
return false;
return true;
}
// Reverse URL handler for Web UI. Maps "chrome://chrome/foo/" to
// "chrome://foo/".
static bool HandleWebUIReverse(GURL* url,
content::BrowserContext* browser_context) {
if (!url->is_valid() || !url->SchemeIs(content::kChromeUIScheme))
return false;
return RemoveUberHost(url);
}
DISALLOW_COPY_AND_ASSIGN(CefWebUIControllerFactory);
};
base::LazyInstance<CefWebUIControllerFactory>::Leaky
g_web_ui_controller_factory = LAZY_INSTANCE_INITIALIZER;
// static
CefWebUIControllerFactory* CefWebUIControllerFactory::GetInstance() {
return &g_web_ui_controller_factory.Get();
}
std::string GetOSType() {
#if defined(OS_WIN)
return "Windows";
@ -186,49 +431,6 @@ class TemplateParser {
std::string ident_end_;
};
// From content/browser/webui/shared_resources_data_source.cc.
using ResourcesMap = base::hash_map<std::string, int>;
// TODO(rkc): Once we have a separate source for apps, remove '*/apps/' aliases.
const char* const kPathAliases[][2] = {
{"../../../third_party/polymer/v1_0/components-chromium/", "polymer/v1_0/"},
{"../../../third_party/web-animations-js/sources/",
"polymer/v1_0/web-animations-js/"},
{"../../views/resources/default_100_percent/common/", "images/apps/"},
{"../../views/resources/default_200_percent/common/", "images/2x/apps/"},
{"../../webui/resources/cr_elements/", "cr_elements/"}};
void AddResource(const std::string& path,
int resource_id,
ResourcesMap* resources_map) {
if (!resources_map->insert(std::make_pair(path, resource_id)).second)
NOTREACHED() << "Redefinition of '" << path << "'";
}
const ResourcesMap* CreateResourcesMap() {
ResourcesMap* result = new ResourcesMap();
for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
const std::string resource_name = kWebuiResources[i].name;
const int resource_id = kWebuiResources[i].value;
AddResource(resource_name, resource_id, result);
for (const char* const (&alias)[2] : kPathAliases) {
if (base::StartsWith(resource_name, alias[0],
base::CompareCase::SENSITIVE)) {
AddResource(alias[1] + resource_name.substr(strlen(alias[0])),
resource_id, result);
}
}
}
return result;
}
const ResourcesMap& GetResourcesMap() {
// This pointer will be intentionally leaked on shutdown.
static const ResourcesMap* resources_map = CreateResourcesMap();
return *resources_map;
}
class Delegate : public InternalHandlerDelegate {
public:
Delegate() {}
@ -243,49 +445,33 @@ class Delegate : public InternalHandlerDelegate {
bool handled = false;
ChromeDomain domain = GetChromeDomain(url.host());
switch (domain) {
case CHROME_CREDITS:
handled = OnCredits(path, action);
break;
ChromeHostId host_id = GetChromeHostId(url.host());
switch (host_id) {
case CHROME_LICENSE:
handled = OnLicense(action);
break;
case CHROME_RESOURCES:
handled = OnResources(path, action);
break;
case CHROME_VERSION:
handled = OnVersion(browser, action);
break;
case CHROME_WEBUI_HOSTS:
handled = OnWebUIHosts(action);
break;
default:
break;
}
if (!handled && domain != CHROME_VERSION) {
if (!handled && host_id != CHROME_VERSION) {
LOG(INFO) << "Reguest for unknown chrome resource: " <<
url.spec().c_str();
if (domain != CHROME_RESOURCES) {
action->redirect_url =
GURL(std::string(kChromeURL) + kChromeVersionDomain);
return true;
}
action->redirect_url =
GURL(std::string(kChromeURL) + chrome::kChromeUIVersionHost);
return true;
}
return handled;
}
bool OnCredits(const std::string& path, Action* action) {
if (path == "credits.js") {
action->resource_id = IDR_ABOUT_UI_CREDITS_JS;
} else {
action->mime_type = "text/html";
action->resource_id = IDR_ABOUT_UI_CREDITS_HTML;
action->encoding = Action::ENCODING_BROTLI;
}
return true;
}
bool OnLicense(Action* action) {
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
IDR_CEF_LICENSE_TXT, ui::SCALE_FACTOR_NONE);
@ -305,33 +491,6 @@ class Delegate : public InternalHandlerDelegate {
return true;
}
bool OnResources(const std::string& path, Action* action) {
// Implementation based on SharedResourcesDataSource::StartDataRequest.
const ResourcesMap& resources_map = GetResourcesMap();
auto it = resources_map.find(path);
int resource_id = (it != resources_map.end()) ? it->second : -1;
if (resource_id == -1) {
NOTREACHED() << "Failed to find resource id for " << path;
return false;
}
if (resource_id == IDR_WEBUI_CSS_TEXT_DEFAULTS ||
resource_id == IDR_WEBUI_CSS_TEXT_DEFAULTS_MD) {
const std::string& css = resource_id == IDR_WEBUI_CSS_TEXT_DEFAULTS ?
webui::GetWebUiCssTextDefaults() : webui::GetWebUiCssTextDefaultsMd();
DCHECK(!css.empty());
action->mime_type = "text/css";
action->stream = CefStreamReader::CreateForData(
const_cast<char*>(css.c_str()), css.length());
action->stream_size = css.length();
} else {
action->resource_id = resource_id;
}
return true;
}
bool OnVersion(CefRefPtr<CefBrowser> browser,
Action* action) {
base::StringPiece piece = CefContentClient::Get()->GetDataResource(
@ -370,6 +529,29 @@ class Delegate : public InternalHandlerDelegate {
return true;
}
bool OnWebUIHosts(Action* action) {
std::string html = "<html>\n<head><title>WebUI Hosts</title></head>\n"
"<body bgcolor=\"white\"><h3>WebUI Hosts</h3>\n<ul>\n";
std::vector<std::string> hosts;
GetAllowedHosts(&hosts);
std::sort(hosts.begin(), hosts.end());
for (size_t i = 0U; i < hosts.size(); ++i) {
html += "<li><a href=\"chrome://" + hosts[i] + "\">chrome://" +
hosts[i] + "</a></li>\n";
}
html += "</ul></body>\n</html>";
action->mime_type = "text/html";
action->stream = CefStreamReader::CreateForData(
const_cast<char*>(html.c_str()), html.length());
action->stream_size = html.length();
return true;
}
};
void DidFinishChromeVersionLoad(CefRefPtr<CefFrame> frame) {
@ -422,14 +604,8 @@ class ChromeProtocolHandlerWrapper :
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
// Keep synchronized with the checks in
// ChromeProtocolHandler::MaybeCreateJob.
if (content::ViewHttpCacheJobFactory::IsSupportedURL(request->url()) ||
(request->url().SchemeIs(content::kChromeUIScheme) &&
request->url().host() == content::kChromeUIAppCacheInternalsHost) ||
content::ViewBlobInternalsJobFactory::IsSupportedURL(request->url()) ||
(request->url().SchemeIs(content::kChromeUIScheme) &&
request->url().host() == content::kChromeUIHistogramHost)) {
// Only allow WebUI to handle chrome:// URLs whitelisted by CEF.
if (CefWebUIControllerFactory::AllowWebUIForURL(request->url())) {
return chrome_protocol_handler_->MaybeCreateJob(request,
network_delegate);
}
@ -453,22 +629,23 @@ void RegisterChromeHandler(CefURLRequestManager* request_manager) {
CreateInternalHandlerFactory(base::WrapUnique(new Delegate())));
}
bool WillHandleBrowserAboutURL(GURL* url,
content::BrowserContext* browser_context) {
std::string text = url->possibly_invalid_spec();
if (text.find("about:") == 0 && text != "about:blank" && text.length() > 6) {
// Redirect about: URLs to chrome://
*url = GURL(kChromeURL + text.substr(6));
}
void RegisterWebUIControllerFactory() {
// Channel all WebUI handling through CefWebUIControllerFactory.
content::WebUIControllerFactory::UnregisterFactoryForTesting(
content::ContentWebUIControllerFactory::GetInstance());
// Allow the redirection to proceed.
return false;
content::WebUIControllerFactory::RegisterFactory(
CefWebUIControllerFactory::GetInstance());
}
void BrowserURLHandlerCreated(content::BrowserURLHandler* handler) {
CefWebUIControllerFactory::BrowserURLHandlerCreated(handler);
}
void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,
const GURL& validated_url) {
ChromeDomain domain = GetChromeDomain(validated_url.host());
switch (domain) {
ChromeHostId host_id = GetChromeHostId(validated_url.host());
switch (host_id) {
case CHROME_VERSION:
DidFinishChromeVersionLoad(frame);
default:

View File

@ -20,7 +20,7 @@ class ListValue;
}
namespace content {
class BrowserContext;
class BrowserURLHandler;
}
class CefURLRequestManager;
@ -32,9 +32,11 @@ extern const char kChromeURL[];
// Register the chrome scheme handler.
void RegisterChromeHandler(CefURLRequestManager* request_manager);
// Used to redirect about: URLs to chrome: URLs.
bool WillHandleBrowserAboutURL(GURL* url,
content::BrowserContext* browser_context);
// Register the WebUI controller factory.
void RegisterWebUIControllerFactory();
// Register the WebUI handler.
void BrowserURLHandlerCreated(content::BrowserURLHandler* handler);
// Used to fire any asynchronous content updates.
void DidFinishChromeLoad(CefRefPtr<CefFrame> frame,

View File

@ -25,8 +25,10 @@
#include "base/threading/thread_restrictions.h"
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/common/pref_names.h"
#include "components/net_log/chrome_net_log.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
@ -114,12 +116,14 @@ CefURLRequestContextGetterImpl::CefURLRequestContextGetterImpl(
std::unique_ptr<net::ProxyConfigService> proxy_config_service,
content::URLRequestInterceptorScopedVector request_interceptors)
: settings_(settings),
net_log_(g_browser_process->net_log()),
io_task_runner_(std::move(io_task_runner)),
file_task_runner_(std::move(file_task_runner)),
proxy_config_service_(std::move(proxy_config_service)),
request_interceptors_(std::move(request_interceptors)) {
// Must first be created on the UI thread.
CEF_REQUIRE_UIT();
DCHECK(net_log_);
std::swap(protocol_handlers_, *protocol_handlers);
@ -197,6 +201,8 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
cache_path = base::FilePath(CefString(&settings_.cache_path));
url_request_context_.reset(new CefURLRequestContextImpl());
url_request_context_->set_net_log(net_log_);
storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get()));
@ -214,7 +220,8 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
storage_->set_http_user_agent_settings(base::WrapUnique(
new CefHttpUserAgentSettings(accept_language)));
storage_->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL));
storage_->set_host_resolver(
net::HostResolver::CreateDefaultResolver(net_log_));
storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
storage_->set_transport_security_state(
base::WrapUnique(new net::TransportSecurityState));
@ -231,7 +238,7 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
std::unique_ptr<net::ProxyService> system_proxy_service =
ProxyServiceFactory::CreateProxyService(
NULL,
net_log_,
url_request_context_.get(),
url_request_context_->network_delegate(),
std::move(proxy_config_service_),
@ -299,6 +306,7 @@ net::URLRequestContext* CefURLRequestContextGetterImpl::GetURLRequestContext() {
url_request_context_->http_server_properties();
network_session_params.ignore_certificate_errors =
settings_.ignore_certificate_errors ? true : false;
network_session_params.net_log = net_log_;
storage_->set_http_network_session(
base::WrapUnique(new net::HttpNetworkSession(network_session_params)));

View File

@ -91,6 +91,8 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter {
const CefRequestContextSettings settings_;
net::NetLog* net_log_; // Guaranteed to outlive this object.
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;

View File

@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/net/prediction_options.h"
#include "chrome/browser/prefs/command_line_pref_store.h"
#include "chrome/browser/supervised_user/supervised_user_pref_store.h"
#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
@ -172,6 +173,7 @@ std::unique_ptr<PrefService> CreatePrefService(
renderer_prefs::RegisterProfilePrefs(registry.get());
update_client::RegisterPrefs(registry.get());
content_settings::CookieSettings::RegisterProfilePrefs(registry.get());
chrome_browser_net::RegisterPredictionOptionsProfilePrefs(registry.get());
// Print preferences.
registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
@ -227,6 +229,10 @@ std::unique_ptr<PrefService> CreatePrefService(
registry->RegisterDictionaryPref(prefs::kCurrentThemeTints);
registry->RegisterDictionaryPref(prefs::kCurrentThemeDisplayProperties);
// Browser UI preferences.
// Based on chrome/browser/ui/browser_ui_prefs.cc RegisterBrowserPrefs.
registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
if (command_line->HasSwitch(switches::kEnablePreferenceTesting)) {
// Preferences used with unit tests.
registry->RegisterBooleanPref("test.bool", true);

View File

@ -8,6 +8,7 @@
#include "libcef/browser/thread_util.h"
#include "base/logging.h"
#include "content/browser/resource_context_impl.h"
#include "content/public/browser/browser_thread.h"
#if defined(USE_NSS_CERTS)
@ -22,11 +23,24 @@
#include "net/ssl/client_cert_store_mac.h"
#endif
namespace {
bool ShouldProxyUserData(const void* key) {
// If this value is not proxied WebUI will fail to load.
if (key == content::GetURLDataManagerBackendUserDataKey())
return true;
return false;
}
} // namespace
CefResourceContext::CefResourceContext(
bool is_off_the_record,
extensions::InfoMap* extension_info_map,
CefRefPtr<CefRequestContextHandler> handler)
: is_off_the_record_(is_off_the_record),
: parent_(nullptr),
is_off_the_record_(is_off_the_record),
extension_info_map_(extension_info_map),
handler_(handler) {
}
@ -45,6 +59,27 @@ CefResourceContext::~CefResourceContext() {
}
}
base::SupportsUserData::Data* CefResourceContext::GetUserData(const void* key)
const {
if (parent_ && ShouldProxyUserData(key))
return parent_->GetUserData(key);
return content::ResourceContext::GetUserData(key);
}
void CefResourceContext::SetUserData(const void* key, Data* data) {
if (parent_ && ShouldProxyUserData(key))
parent_->SetUserData(key, data);
else
content::ResourceContext::SetUserData(key, data);
}
void CefResourceContext::RemoveUserData(const void* key) {
if (parent_ && ShouldProxyUserData(key))
parent_->RemoveUserData(key);
else
content::ResourceContext::RemoveUserData(key);
}
net::HostResolver* CefResourceContext::GetHostResolver() {
CHECK(getter_.get());
return getter_->GetHostResolver();
@ -80,6 +115,12 @@ void CefResourceContext::set_url_request_context_getter(
getter_ = getter;
}
void CefResourceContext::set_parent(CefResourceContext* parent) {
DCHECK(!parent_);
DCHECK(parent);
parent_ = parent;
}
void CefResourceContext::AddPluginLoadDecision(
int render_process_id,
const base::FilePath& plugin_path,

View File

@ -30,6 +30,11 @@ class CefResourceContext : public content::ResourceContext {
CefRefPtr<CefRequestContextHandler> handler);
~CefResourceContext() override;
// SupportsUserData implementation.
Data* GetUserData(const void* key) const override;
void SetUserData(const void* key, Data* data) override;
void RemoveUserData(const void* key) override;
// ResourceContext implementation.
net::HostResolver* GetHostResolver() override;
net::URLRequestContext* GetRequestContext() override;
@ -37,6 +42,7 @@ class CefResourceContext : public content::ResourceContext {
std::unique_ptr<net::ClientCertStore> CreateClientCertStore();
void set_url_request_context_getter(CefURLRequestContextGetter* getter);
void set_parent(CefResourceContext* parent);
// Remember the plugin load decision for plugin status requests that arrive
// via CefPluginServiceFilter::IsPluginAvailable.
@ -64,6 +70,11 @@ class CefResourceContext : public content::ResourceContext {
private:
scoped_refptr<CefURLRequestContextGetter> getter_;
// Non-NULL when this object is owned by a CefBrowserContextProxy. |parent_|
// is guaranteed to outlive this object because CefBrowserContextProxy has a
// refptr to the CefBrowserContextImpl that owns |parent_|.
CefResourceContext* parent_;
// Only accessed on the IO thread.
bool is_off_the_record_;
scoped_refptr<extensions::InfoMap> extension_info_map_;

View File

@ -286,6 +286,16 @@ base::StringPiece CefContentClient::GetDataResource(
return value;
}
base::RefCountedMemory* CefContentClient::GetDataResourceBytes(
int resource_id) const {
base::RefCountedMemory* value =
ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id);
if (!value)
LOG(ERROR) << "No data resource bytes available for id " << resource_id;
return value;
}
gfx::Image& CefContentClient::GetNativeImageNamed(int resource_id) const {
gfx::Image& value =
ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);

View File

@ -42,6 +42,8 @@ class CefContentClient : public content::ContentClient,
base::StringPiece GetDataResource(
int resource_id,
ui::ScaleFactor scale_factor) const override;
base::RefCountedMemory* GetDataResourceBytes(
int resource_id) const override;
gfx::Image& GetNativeImageNamed(int resource_id) const override;
struct SchemeInfo {

View File

@ -274,4 +274,12 @@ patches = [
'name': 'webview_plugin_2020',
'path': '../',
},
{
# Support WebUI by:
# (a) Exposing required UserData keys;
# (b) Removing dependency on non-NULL IOThread* object.
# https://bitbucket.org/chromiumembedded/cef/issues/2037
'name': 'webui_2037',
'path': '../',
},
]

View File

@ -63,7 +63,7 @@ index 4b43013..169ca47 100644
content::BrowserContext* GetBrowserContextRedirectedInIncognito(
content::BrowserContext* context);
diff --git chrome/browser/profiles/profile_manager.h chrome/browser/profiles/profile_manager.h
index ba156c5..b7f41d3 100644
index ba156c5..0ed578b 100644
--- chrome/browser/profiles/profile_manager.h
+++ chrome/browser/profiles/profile_manager.h
@@ -89,7 +89,7 @@ class ProfileManager : public base::NonThreadSafe,
@ -84,3 +84,12 @@ index ba156c5..b7f41d3 100644
// Returns the directory where the first created profile is stored,
// relative to the user data directory currently in use.
@@ -126,7 +126,7 @@ class ProfileManager : public base::NonThreadSafe,
// Get the Profile last used (the Profile to which owns the most recently
// focused window) with this Chrome build. If no signed profile has been
// stored in Local State, hand back the Default profile.
- Profile* GetLastUsedProfile(const base::FilePath& user_data_dir);
+ virtual Profile* GetLastUsedProfile(const base::FilePath& user_data_dir);
// Get the path of the last used profile, or if that's undefined, the default
// profile.

View File

@ -0,0 +1,117 @@
diff --git chrome/browser/ui/webui/net_internals/net_internals_ui.cc chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 92fa2f1..cc3f54a 100644
--- chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -689,9 +689,17 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady(
PrePopulateEventList();
- // Register with network stack to observe events.
- io_thread_->net_log()->DeprecatedAddObserver(
- this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
+ net::NetLog* net_log = nullptr;
+ if (io_thread_)
+ net_log = io_thread_->net_log();
+ else
+ net_log = g_browser_process->net_log();
+
+ if (net_log) {
+ // Register with network stack to observe events.
+ net_log->DeprecatedAddObserver(
+ this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
+ }
}
void NetInternalsMessageHandler::IOThreadImpl::OnGetNetInfo(
@@ -869,21 +877,8 @@ void NetInternalsMessageHandler::IOThreadImpl::OnHSTSDelete(
void NetInternalsMessageHandler::IOThreadImpl::OnGetSessionNetworkStats(
const base::ListValue* list) {
DCHECK(!list);
- net::URLRequestContext* context =
- main_context_getter_->GetURLRequestContext();
- net::HttpNetworkSession* http_network_session =
- GetHttpNetworkSession(context);
std::unique_ptr<base::Value> network_info;
- if (http_network_session) {
- // TODO(mmenke): This cast is ugly. Can we get rid of it, or, better,
- // remove DRP data from net-internals entirely?
- data_reduction_proxy::DataReductionProxyNetworkDelegate* net_delegate =
- static_cast<data_reduction_proxy::DataReductionProxyNetworkDelegate*>(
- context->network_delegate());
- if (net_delegate)
- network_info = net_delegate->SessionNetworkStatsInfoToValue();
- }
SendJavascriptCommand("receivedSessionNetworkStats", std::move(network_info));
}
@@ -1149,8 +1144,10 @@ void NetInternalsMessageHandler::IOThreadImpl::PrePopulateEventList() {
std::set<net::URLRequestContext*> contexts;
for (const auto& getter : context_getters_)
contexts.insert(getter->GetURLRequestContext());
- contexts.insert(io_thread_->globals()->proxy_script_fetcher_context.get());
- contexts.insert(io_thread_->globals()->system_request_context.get());
+ if (io_thread_) {
+ contexts.insert(io_thread_->globals()->proxy_script_fetcher_context.get());
+ contexts.insert(io_thread_->globals()->system_request_context.get());
+ }
// Add entries for ongoing network objects.
CreateNetLogEntriesForActiveObjects(contexts, this);
diff --git content/browser/resource_context_impl.cc content/browser/resource_context_impl.cc
index 22c12ee..57031f3 100644
--- content/browser/resource_context_impl.cc
+++ content/browser/resource_context_impl.cc
@@ -84,6 +84,10 @@ URLDataManagerBackend* GetURLDataManagerForResourceContext(
context->GetUserData(kURLDataManagerBackendKeyName));
}
+const void* GetURLDataManagerBackendUserDataKey() {
+ return kURLDataManagerBackendKeyName;
+}
+
void InitializeResourceContext(BrowserContext* browser_context) {
ResourceContext* resource_context = browser_context->GetResourceContext();
diff --git content/browser/resource_context_impl.h content/browser/resource_context_impl.h
index 903cc54..56ee4ea 100644
--- content/browser/resource_context_impl.h
+++ content/browser/resource_context_impl.h
@@ -28,6 +28,8 @@ CONTENT_EXPORT StreamContext* GetStreamContextForResourceContext(
URLDataManagerBackend* GetURLDataManagerForResourceContext(
ResourceContext* context);
+const void* GetURLDataManagerBackendUserDataKey();
+
// Initialize the above data on the ResourceContext from a given BrowserContext.
CONTENT_EXPORT void InitializeResourceContext(BrowserContext* browser_context);
diff --git content/browser/webui/url_data_manager.cc content/browser/webui/url_data_manager.cc
index a9ec107..4a215ca 100644
--- content/browser/webui/url_data_manager.cc
+++ content/browser/webui/url_data_manager.cc
@@ -123,6 +123,11 @@ void URLDataManager::AddWebUIDataSource(BrowserContext* browser_context,
}
// static
+const void* URLDataManager::GetUserDataKey() {
+ return kURLDataManagerKeyName;
+}
+
+// static
bool URLDataManager::IsScheduledForDeletion(
const URLDataSourceImpl* data_source) {
base::AutoLock lock(g_delete_lock.Get());
diff --git content/browser/webui/url_data_manager.h content/browser/webui/url_data_manager.h
index 8eca18c..97fc80ea 100644
--- content/browser/webui/url_data_manager.h
+++ content/browser/webui/url_data_manager.h
@@ -55,6 +55,8 @@ class CONTENT_EXPORT URLDataManager : public base::SupportsUserData::Data {
static void AddWebUIDataSource(BrowserContext* browser_context,
WebUIDataSource* source);
+ static const void* GetUserDataKey();
+
private:
friend class URLDataSourceImpl;
friend struct DeleteURLDataSource;

View File

@ -0,0 +1,212 @@
// Copyright 2016 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 "include/base/cef_bind.h"
#include "include/cef_callback.h"
#include "include/cef_parser.h"
#include "include/wrapper/cef_closure_task.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "tests/unittests/test_handler.h"
namespace {
typedef std::vector<std::string> UrlList;
class WebUITestHandler : public TestHandler {
public:
explicit WebUITestHandler(const UrlList& url_list)
: url_list_(url_list),
url_index_(0U),
expected_error_code_(ERR_NONE) {
CHECK(!url_list_.empty());
}
void set_expected_url(const std::string& expected_url) {
expected_url_ = expected_url;
}
void set_expected_error_code(int error_code) {
expected_error_code_ = error_code;
}
void RunTest() override {
// Create the browser.
CreateBrowser(url_list_[0]);
// Time out the test after a reasonable period of time.
SetTestTimeout((int(url_list_.size() / 5U) + 1) * 5000);
}
void NextNav() {
base::Closure next_action;
if (++url_index_ == url_list_.size()) {
next_action = base::Bind(&WebUITestHandler::DestroyTest, this);
} else {
next_action = base::Bind(&WebUITestHandler::LoadURL, this,
url_list_[url_index_]);
}
// Wait a bit for the WebUI content to finish loading before performing the
// next action.
CefPostDelayedTask(TID_UI, next_action, 200);
}
void LoadURL(const std::string& url) {
GetBrowser()->GetMainFrame()->LoadURL(url);
}
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
if (!isLoading) {
// Verify that we navigated to the expected URL.
std::string expected_url = expected_url_;
if (expected_url.empty())
expected_url = url_list_[url_index_];
EXPECT_STREQ(expected_url.c_str(),
browser->GetMainFrame()->GetURL().ToString().c_str());
NextNav();
}
}
void OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& errorText,
const CefString& failedUrl) override {
got_load_error_.yes();
EXPECT_EQ(expected_error_code_, errorCode) <<
"failedUrl = " << failedUrl.ToString();
}
void DestroyTest() override {
if (expected_error_code_ == ERR_NONE)
EXPECT_FALSE(got_load_error_);
else
EXPECT_TRUE(got_load_error_);
TestHandler::DestroyTest();
}
UrlList url_list_;
size_t url_index_;
std::string expected_url_;
int expected_error_code_;
TrackCallback got_load_error_;
IMPLEMENT_REFCOUNTING(WebUITestHandler);
};
} // namespace
// Test hosts with special behaviors.
// Non-existing URLs should redirect to chrome://version/.
TEST(WebUITest, doesnotexist) {
UrlList url_list;
url_list.push_back("chrome://doesnotexist/");
CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
handler->set_expected_url("chrome://version/");
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// about:* URIs should redirect to chrome://*.
TEST(WebUITest, about) {
UrlList url_list;
url_list.push_back("about:license");
CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
handler->set_expected_url("chrome://license/");
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// chrome://network-error/X should generate network error X.
TEST(WebUITest, network_error) {
UrlList url_list;
// -310 is ERR_TOO_MANY_REDIRECTS
url_list.push_back("chrome://network-error/-310");
CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
handler->set_expected_url("data:text/html,chromewebdata");
handler->set_expected_error_code(ERR_TOO_MANY_REDIRECTS);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Test hosts with a single URL.
namespace {
void RunWebUITest(const UrlList& url_list) {
CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
void RunWebUITest(const std::string& url) {
UrlList url_list;
url_list.push_back(url);
RunWebUITest(url_list);
}
} // namespace
#define WEBUI_TEST(name) \
TEST(WebUITest, name) { \
std::string name_str = #name; \
std::replace(name_str.begin(), name_str.end(), '_', '-'); \
RunWebUITest("chrome://" + name_str + "/"); \
}
WEBUI_TEST(appcache_internals);
WEBUI_TEST(accessibility);
WEBUI_TEST(blob_internals);
WEBUI_TEST(credits);
WEBUI_TEST(gpu);
WEBUI_TEST(histograms);
WEBUI_TEST(indexeddb_internals);
WEBUI_TEST(license);
WEBUI_TEST(media_internals);
WEBUI_TEST(net_export);
WEBUI_TEST(network_errors);
WEBUI_TEST(serviceworker_internals);
WEBUI_TEST(system);
WEBUI_TEST(tracing);
WEBUI_TEST(version);
WEBUI_TEST(view_http_cache);
WEBUI_TEST(webrtc_internals);
WEBUI_TEST(webui_hosts);
// Test hosts with multiple URLs.
TEST(WebUITest, net_internals) {
UrlList url_list;
url_list.push_back("chrome://net-internals/#capture");
url_list.push_back("chrome://net-internals/#export");
url_list.push_back("chrome://net-internals/#import");
url_list.push_back("chrome://net-internals/#proxy");
url_list.push_back("chrome://net-internals/#events");
url_list.push_back("chrome://net-internals/#timeline");
url_list.push_back("chrome://net-internals/#dns");
url_list.push_back("chrome://net-internals/#sockets");
url_list.push_back("chrome://net-internals/#alt-svc");
url_list.push_back("chrome://net-internals/#http2");
url_list.push_back("chrome://net-internals/#quic");
url_list.push_back("chrome://net-internals/#sdch");
url_list.push_back("chrome://net-internals/#httpCache");
url_list.push_back("chrome://net-internals/#modules");
url_list.push_back("chrome://net-internals/#hsts");
url_list.push_back("chrome://net-internals/#bandwidth");
url_list.push_back("chrome://net-internals/#prerender");
RunWebUITest(url_list);
}