Compare commits

...

57 Commits

Author SHA1 Message Date
Electron Bot
64c8c27575 Bump v3.0.0-beta.11 2018-09-12 01:08:37 -07:00
trop[bot]
e76a976347 chore: make large beta numbers work when publishing (#14572) 2018-09-12 18:00:08 +10:00
Robo
8d27657fa5 fix: use render client id to track deleted render process hosts (backport: 3-0-x) (#14557)
* fix: use render client id to track deleted render process hosts

* fix: use webContentsId with contextId together (#13749)
2018-09-11 19:56:20 -07:00
John Kleinschmidt
5e81d8dad9 Merge pull request #14558 from electron/rename-appveyor-3-0-x
ci: Rename appveyor-override.yml to appveyor.yml (3-0-x)
2018-09-11 19:52:47 -04:00
John Kleinschmidt
b23acab456 Rename appveyor-override.yml to appveyor.yml 2018-09-11 19:17:50 -04:00
Cheng Zhao
8950caaa85 fix: read ignoreMenuShortcuts per WebContents (#14538) 2018-09-11 17:52:04 +10:00
Alexey Kuzmin
1b920c25af chore: Revert "fix: re-enable power monitor test (#14496)" (#14508)
This reverts commit d36b14a322.
2018-09-10 23:49:25 +10:00
Shelley Vohr
8fd31a3e07 build: [gn] widevine cdm support behind flag (3-0-x) (#14497) 2018-09-07 22:43:39 -07:00
Electron Bot
893f866c05 Bump v3.0.0-beta.10 2018-09-07 21:36:19 -07:00
Shelley Vohr
d36b14a322 fix: re-enable power monitor test (#14496) 2018-09-07 16:24:52 -07:00
John Kleinschmidt
27a33cc1cf Merge pull request #14494 from electron/fix-focus-3-0-x
fix: notify focus change right away rather not on next tick (3-0-x)
2018-09-07 15:31:26 -04:00
John Kleinschmidt
7835bceabd Update to latest libcc for 3-0-x 2018-09-07 14:37:28 -04:00
Nitish Sakhawalkar
af4f08e030 fix: notify focus change right away rather not on next tick (#14453)
* fix: Notify focus change right away, not on next tick

* fix: emit the JS blur/focus events on next tick to avoid race condition

* address feedback from review

* fix: bind deferred Emit() calls to a WeakPtr

This is so that the deferred Emit() calls will be canceled
if the TopLevelWindow is destroyed.

* chore: remove wip/test code cruft

* fix: make linter happy

* Enable disabled tests

* refactor: cleaner impl of EmitEventSoon()

* Revert "Merge branch 'fix-win-focus' of github.com:electron/electron into fix-win-focus"

This reverts commit 90576806eb, reversing
changes made to 9c13e47779.

* Restore 704722c1, which was removed in error.

We apologise again for the fault in the subtitles. Those responsible for sacking the people who have just been sacked have been sacked.
2018-09-07 14:30:41 -04:00
John Kleinschmidt
03dac078d7 Merge pull request #14488 from electron/manage-webview-webcontents-3-0-x
fix: manually manage WebContents of webview when it is detached (3-0-x)
2018-09-07 12:54:06 -04:00
Cheng Zhao
d3d44bdbc6 fix: manually manage WebContents of webview when it is detached 2018-09-07 15:42:58 +09:00
trop[bot]
a370b6982d Macos Window Title And Accessibility Focus Fix - Override accessibility method in atom_ns_window - Add title attribute in accessibilityAttributeValue (#14486) 2018-09-06 18:55:46 -07:00
trop[bot]
03ef5c25f7 fix: don't use deprecated fstatNoException API (#14484) 2018-09-06 13:09:03 -07:00
Roller Bot
3bc6652833 chore: bump libcc (3-0-x) (#14482)
* chore: bump libcc submodule to 61d71f3f150c3ff5025560dee254a53313bfbaf6

* chore: bump libcc in DEPS to 61d71f3f150c3ff5025560dee254a53313bfbaf6
2018-09-06 11:48:45 -07:00
Shelley Vohr
664371245a backport debugger fix (#14481)
* chore: enable debugger api specs (#14475)

* backport base::Value converters
2018-09-06 10:57:41 -07:00
John Kleinschmidt
08270e6817 docs: Specify VS 15.4.5 for 3-0-x (#14476)
Resolves #12898
2018-09-07 00:45:16 +10:00
Electron Bot
8f74a77a64 Bump v3.0.0-beta.9 2018-09-05 17:46:59 -07:00
Shelley Vohr
85c8ada99a deps: roll node to deprecate statsyncnoexception and lstatsyncnoexception (#14467) 2018-09-05 12:06:06 -07:00
Electron Bot
b15a3ee2be Bump v3.0.0-nightly.20180904 2018-09-04 17:16:17 -07:00
Shelley Vohr
7b043ac554 chore: add release-artifact-cleanup script (#14447) 2018-09-04 11:36:48 -07:00
trop[bot]
89a6f1efbb feat: add getUploadProgress API to the net API (#14446) 2018-09-04 12:26:50 -05:00
trop[bot]
ce592a5705 feat: allow setting window shape (backport: 3-0-x) (#14445)
* feat: allow setting window shape

This binds Widget::SetShape, an API that already exists in Chromium (for
Windows and Linux). It's a more reliable method of having some parts of
your window be "click-through" than the current `setIgnoreMouseEvents`
API, which messes around with the `WS_EX_LAYERED` window style on
Windows, causing strange bugs and incompatibility with hardware
acceleration.

* update docs
2018-09-04 09:22:11 -07:00
trop[bot]
12087b74e8 feat: allow some features during beta (backport: 3-0-x) (#14449)
* feat: allow all nonbreaking changes during beta

Changes the version policy: currently only nonbreaking bug/security
fixes are allowed during beta. This change would allow all nonbreaking
changes, e.g. new features, during beta.

* refactor: clarify criteria for changes during beta

* Update electron-versioning.md
2018-09-04 11:12:30 -05:00
trop[bot]
d365078022 fix: webview.focus() should move page focus to webview (#14428) 2018-09-03 13:26:41 +10:00
trop[bot]
3dbd84c224 docs: add notes on OOPIF webview's behaviors (#14409) 2018-08-31 14:48:38 -07:00
trop[bot]
2e479ff799 fix: use flexbox to style webview (backport: 3-0-x) (#14408)
* fix: use flexbox to style webview

* docs: remove notes on browserplugin based webview
2018-08-31 14:48:08 -07:00
trop[bot]
a341ae450a fix: allow Tray with title only (without icon) on Mac (#14384) 2018-09-01 08:49:56 +12:00
Roller Bot
0aec308681 chore: bump libcc (3-0-x) (#14391)
* chore: bump libcc submodule to dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e

* chore: bump libcc in DEPS to dc2e7ebd2867d4329ebe7b6849e89cf3dc0afa8e
2018-08-31 10:38:56 -07:00
Samuel Attard
8e9c5b8338 chore: fix bootstrap script on 3-0-x (#14361) 2018-08-29 09:55:54 -07:00
trop[bot]
6bc1e37156 docs: keyboard listeners no longer work on webview (#14372) 2018-08-29 19:26:33 +09:00
Electron Bot
7da7dd85e3 Bump v3.0.0-beta.8 2018-08-28 23:04:31 -07:00
trop[bot]
ccf8a797dc fix: use OS process handle to clear object registry (#14364)
RenderProcessHost switch can happen between ipc calls when
speculative process are invvolved, which will lead to deletion
of entries on current context. Use OS process handles to
uniquely associate a destruction handler for a render process.
2018-08-28 22:55:42 -07:00
Milan Burda
3301e05f33 fix: don't expose desktopCapturer in sandboxed renderers if the feature is disabled (#14345) 2018-08-28 19:51:07 -05:00
trop[bot]
b1c22ba531 fix: emit focus/blur events for webview (backport: 3-0-x) (#14359)
* fix: emit focus/blur events for webview

* test: webview can emit focus event
2018-08-28 13:38:11 -05:00
trop[bot]
873f39b159 fix: crash when tray is destroyed (#14357)
Release the view of status item before destroying it,
gives chance to perform cleanup on the view.
2018-08-28 13:37:38 -05:00
trop[bot]
11864e9e08 fix: create persistent channel ID store when cookie store is persistent (#14358) 2018-08-28 13:37:09 -05:00
trop[bot]
c8a21dbb92 fix: don't crash on tray.setContextMenu(null) (#14331) 2018-08-27 13:27:41 -07:00
trop[bot]
97058837e7 fix: dont parse arguments after a -- in the inspector (#14333) 2018-08-27 14:44:53 -05:00
trop[bot]
ff539c1d61 fix: don't expose view APIs when not enabled (#14321) 2018-08-27 13:00:19 +09:00
trop[bot]
9237d40e09 fix: issue 10962, crash when open devtool (backport: 3-0-x) (#14303)
* fix: crash when opening devtool (#10962)

* fix: fixed linting issues
2018-08-25 12:23:06 -07:00
Shelley Vohr
4721dc0856 fix: opt into location services once device service has been started (backport: 3-0-x) (#14289)
* fix: opt into location services once device service has been started (#14253)

* fix: opt into location services once device service has been started

* refactor: provide fake location provider to mock geolocation reponses

* chore: add spec for navigator.geolocation api using fake location provider

* fix conflict
2018-08-24 08:23:15 -07:00
Electron Bot
1f7fd985dd Bump v3.0.0-nightly.20180823 2018-08-23 21:23:48 -07:00
Roller Bot
d432e420ae chore: bump libcc (3-0-x) (#14280)
* chore: bump libcc submodule to 7165af0ca9863529f28e493568ae3d105eddcdef

* chore: bump libcc in DEPS to 7165af0ca9863529f28e493568ae3d105eddcdef
2018-08-23 21:12:09 -07:00
trop[bot]
635c3f53d8 fix: add method and referrer properties to app login event (backport: 3-0-x) (#14277)
* refactor: remove brightray/network_delegate.{cc|h}

* refactor: respond to http requests through network delegate
2018-08-23 20:47:16 +09:00
trop[bot]
ba703deee2 Print error when removed webview attribute is used (backport: 3-0-x) (#14274)
* chore: print error when removed webview attribute is used

* docs: document removed webview features
2018-08-23 15:42:08 +09:00
Electron Bot
b03178105d Bump v3.0.0-beta.7 2018-08-22 11:13:36 -07:00
Samuel Attard
ef0a6d9a1c fix: inheritance of webPreferences sub properties 2018-08-22 12:19:11 -05:00
trop[bot]
4c7af6a429 fix: notify request context shutdown on IO before cleanup (#14092) 2018-08-22 08:24:56 -07:00
trop[bot]
d1886c5d22 ci: add better logging around request failures for releasing (#14245) 2018-08-21 13:31:44 -07:00
trop[bot]
c558dc2d7d chore: retry for the meta dumper a few times (#14243) 2018-08-21 13:31:13 -07:00
Electron Bot
be68cfd4ea Bump v3.0.0-nightly.20180821 2018-08-21 12:07:19 -07:00
Samuel Attard
115a15c356 Revert "Bump v3.0.0-nightly.20180821"
This reverts commit d4fb904450.
2018-08-21 11:45:21 -07:00
Electron Bot
d4fb904450 Bump v3.0.0-nightly.20180821 2018-08-21 11:16:44 -07:00
115 changed files with 2151 additions and 1368 deletions

View File

@@ -27,6 +27,12 @@ declare_args() {
enable_desktop_capturer = true
enable_run_as_node = true
enable_osr = true
# Provide a fake location provider for mocking
# the geolocation responses. Disable it if you
# need to test with chromium's location provider.
# Should not be enabled for release build.
enable_fake_location_provider = !is_official_build
}
filenames_gypi = exec_script(
@@ -312,6 +318,13 @@ static_library("electron_lib") {
sources = filenames_gypi.lib_sources
set_sources_assignment_filter(sources_assignment_filter)
if (enable_fake_location_provider) {
defines += [
"OVERRIDE_LOCATION_PROVIDER"
]
sources += filenames_gypi.lib_sources_location_provider
}
if (enable_run_as_node) {
sources += [
"atom/app/node_main.cc",

2
DEPS
View File

@@ -2,7 +2,7 @@ vars = {
'chromium_version':
'63.0.3239.150',
'libchromiumcontent_revision':
'92dc0accfae5cd133fa2a6758ae6b3ff4ff7e569',
'61d71f3f150c3ff5025560dee254a53313bfbaf6',
'node_version':
'v9.7.0-33-g538a5023af',
'native_mate_revision':

View File

@@ -20,12 +20,17 @@
#include "content/public/common/user_agent.h"
#include "media/media_features.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE)
#include "base/native_library.h"
#include "base/strings/stringprintf.h"
#include "chrome/common/widevine_cdm_constants.h"
#endif
#include "content/public/common/cdm_info.h"
#include "media/base/video_codecs.h"
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#if defined(ENABLE_PDF_VIEWER)
#include "atom/common/atom_constants.h"
@@ -36,6 +41,67 @@ namespace atom {
namespace {
#if defined(WIDEVINE_CDM_AVAILABLE)
bool IsWidevineAvailable(base::FilePath* adapter_path,
base::FilePath* cdm_path,
std::vector<media::VideoCodec>* codecs_supported) {
static enum {
NOT_CHECKED,
FOUND,
NOT_FOUND,
} widevine_cdm_file_check = NOT_CHECKED;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
*adapter_path = command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
if (!adapter_path->empty()) {
*cdm_path = adapter_path->DirName().AppendASCII(
base::GetNativeLibraryName(kWidevineCdmLibraryName));
if (widevine_cdm_file_check == NOT_CHECKED) {
widevine_cdm_file_check =
(base::PathExists(*adapter_path) && base::PathExists(*cdm_path))
? FOUND
: NOT_FOUND;
}
if (widevine_cdm_file_check == FOUND) {
// Add the supported codecs as if they came from the component manifest.
// This list must match the CDM that is being bundled with Chrome.
codecs_supported->push_back(media::VideoCodec::kCodecVP8);
codecs_supported->push_back(media::VideoCodec::kCodecVP9);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
codecs_supported->push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
return true;
}
}
return false;
}
void AddWidevineAdapterFromCommandLine(
base::CommandLine* command_line,
std::vector<content::PepperPluginInfo>* plugins) {
base::FilePath adapter_path;
base::FilePath cdm_path;
std::vector<media::VideoCodec> video_codecs_supported;
if (IsWidevineAvailable(&adapter_path, &cdm_path, &video_codecs_supported)) {
auto cdm_version_string =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
content::PepperPluginInfo info;
info.is_out_of_process = true;
info.path = adapter_path;
info.name = kWidevineCdmDisplayName;
info.description =
base::StringPrintf("%s (version: %s)", kWidevineCdmDescription,
cdm_version_string.c_str());
info.version = cdm_version_string;
info.permissions = kWidevineCdmPluginPermissions;
content::WebPluginMimeType mime_type(kWidevineCdmPluginMimeType,
kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeTypeDescription);
info.mime_types.push_back(mime_type);
plugins->push_back(info);
}
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#if defined(ENABLE_PEPPER_FLASH)
content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo plugin;
@@ -75,29 +141,23 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
return plugin;
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo widevine_cdm;
widevine_cdm.is_out_of_process = true;
widevine_cdm.path = path;
widevine_cdm.name = kWidevineCdmDisplayName;
widevine_cdm.description =
kWidevineCdmDescription + std::string(" (version: ") + version + ")";
widevine_cdm.version = version;
content::WebPluginMimeType widevine_cdm_mime_type(
kWidevineCdmPluginMimeType, kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeTypeDescription);
void AddPepperFlashFromCommandLine(
base::CommandLine* command_line,
std::vector<content::PepperPluginInfo>* plugins) {
base::FilePath flash_path =
command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
if (flash_path.empty())
return;
widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
widevine_cdm.permissions = kWidevineCdmPluginPermissions;
auto flash_version =
command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
return widevine_cdm;
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#endif // defined(ENABLE_PEPPER_FLASH)
#if defined(ENABLE_PDF_VIEWER)
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
#if defined(ENABLE_PDF_VIEWER)
content::PepperPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
@@ -114,8 +174,8 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
chrome_pdf::PPP_ShutdownModule;
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
plugins->push_back(pdf_info);
}
#endif // defined(ENABLE_PDF_VIEWER)
}
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
const char* separator,
@@ -129,42 +189,6 @@ void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
} // namespace
void AddPepperFlashFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto* command_line = base::CommandLine::ForCurrentProcess();
base::FilePath flash_path =
command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
if (flash_path.empty())
return;
auto flash_version =
command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
void AddWidevineCdmFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto* command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path =
command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
if (widevine_cdm_path.empty())
return;
if (!base::PathExists(widevine_cdm_path))
return;
auto widevine_cdm_version =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
if (widevine_cdm_version.empty())
return;
plugins->push_back(
CreateWidevineCdmInfo(widevine_cdm_path, widevine_cdm_version));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
AtomContentClient::AtomContentClient() {}
AtomContentClient::~AtomContentClient() {}
@@ -200,45 +224,43 @@ void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
void AtomContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
AddPepperFlashFromCommandLine(plugins);
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
AddWidevineCdmFromCommandLine(plugins);
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(ENABLE_PDF_VIEWER)
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
#if defined(ENABLE_PEPPER_FLASH)
AddPepperFlashFromCommandLine(command_line, plugins);
#endif // defined(ENABLE_PEPPER_FLASH)
#if defined(WIDEVINE_CDM_AVAILABLE)
AddWidevineAdapterFromCommandLine(command_line, plugins);
#endif // defined(WIDEVINE_CDM_AVAILABLE)
ComputeBuiltInPlugins(plugins);
#endif // defined(ENABLE_PDF_VIEWER)
}
void AtomContentClient::AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path =
command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
if (widevine_cdm_path.empty())
return;
if (cdms) {
#if defined(WIDEVINE_CDM_AVAILABLE)
base::FilePath adapter_path;
base::FilePath cdm_path;
std::vector<media::VideoCodec> video_codecs_supported;
bool supports_persistent_license = false;
if (IsWidevineAvailable(&adapter_path, &cdm_path,
&video_codecs_supported)) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
auto cdm_version_string =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
// CdmInfo needs |path| to be the actual Widevine library,
// not the adapter, so adjust as necessary. It will be in the
// same directory as the installed adapter.
const base::Version version(cdm_version_string);
DCHECK(version.IsValid());
if (!base::PathExists(widevine_cdm_path))
return;
auto widevine_cdm_version =
command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
if (widevine_cdm_version.empty())
return;
std::vector<media::VideoCodec> supported_video_codecs;
supported_video_codecs.push_back(media::VideoCodec::kCodecVP8);
supported_video_codecs.push_back(media::VideoCodec::kCodecVP9);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
supported_video_codecs.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
content::CdmRegistry::GetInstance()->RegisterCdm(
content::CdmInfo(kWidevineCdmDisplayName, kWidevineCdmGuid,
base::Version(widevine_cdm_version), widevine_cdm_path,
kWidevineCdmFileSystemId, supported_video_codecs, false,
kWidevineKeySystem, false));
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
cdms->push_back(content::CdmInfo(
kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
kWidevineCdmFileSystemId, video_codecs_supported,
supports_persistent_license, kWidevineKeySystem, false));
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
}
}
} // namespace atom

View File

@@ -667,17 +667,17 @@ void App::OnNewWindowForTab() {
}
#endif
void App::OnLogin(LoginHandler* login_handler,
void App::OnLogin(scoped_refptr<LoginHandler> login_handler,
const base::DictionaryValue& request_details) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
bool prevent_default = false;
content::WebContents* web_contents = login_handler->GetWebContents();
if (web_contents) {
prevent_default =
Emit("login", WebContents::CreateFrom(isolate(), web_contents),
request_details, login_handler->auth_info(),
base::Bind(&PassLoginInformation, WrapRefCounted(login_handler)));
prevent_default = Emit(
"login", WebContents::CreateFrom(isolate(), web_contents),
request_details, login_handler->auth_info(),
base::Bind(&PassLoginInformation, base::RetainedRef(login_handler)));
}
// Default behavior is to always cancel the auth.

View File

@@ -98,7 +98,7 @@ class App : public AtomBrowserClient::Delegate,
void OnActivate(bool has_visible_windows) override;
void OnWillFinishLaunching() override;
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
void OnLogin(LoginHandler* login_handler,
void OnLogin(scoped_refptr<LoginHandler> login_handler,
const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
void OnPreMainMessageLoopRun() override;

View File

@@ -5,6 +5,7 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/request_context_delegate.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
@@ -253,9 +254,10 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
auto subscription = browser_context->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
browser_context->set_cookie_change_subscription(std::move(subscription));
cookie_change_subscription_ =
browser_context->GetRequestContextDelegate()
->RegisterCookieChangeCallback(
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
}
Cookies::~Cookies() {}

View File

@@ -9,7 +9,7 @@
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/net/cookie_details.h"
#include "base/callback.h"
#include "base/callback_list.h"
#include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h"
@@ -59,6 +59,8 @@ class Cookies : public mate::TrackableObject<Cookies> {
void OnCookieChanged(const CookieDetails*);
private:
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
cookie_change_subscription_;
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Cookies);

View File

@@ -6,16 +6,13 @@
#include <string>
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
@@ -26,20 +23,22 @@ namespace atom {
namespace api {
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
: web_contents_(web_contents) {
: content::WebContentsObserver(web_contents), web_contents_(web_contents) {
Init(isolate);
}
Debugger::~Debugger() {}
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
std::string detach_reason = "target closed";
Emit("detach", detach_reason);
DCHECK(agent_host == agent_host_);
agent_host_ = nullptr;
ClearPendingRequests();
Emit("detach", "target closed");
}
void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) {
DCHECK(agent_host == agent_host_.get());
DCHECK(agent_host == agent_host_);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
@@ -77,42 +76,52 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
}
}
void Debugger::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) {
if (agent_host_) {
agent_host_->DisconnectWebContents();
auto* web_contents = content::WebContents::FromRenderFrameHost(new_rfh);
agent_host_->ConnectWebContents(web_contents);
}
}
void Debugger::Attach(mate::Arguments* args) {
std::string protocol_version;
args->GetNext(&protocol_version);
if (agent_host_) {
args->ThrowError("Debugger is already attached to the target");
return;
}
if (!protocol_version.empty() &&
!DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) {
args->ThrowError("Requested protocol version is not supported");
return;
}
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_);
if (!agent_host_.get()) {
if (!agent_host_) {
args->ThrowError("No target available");
return;
}
if (agent_host_->IsAttached()) {
args->ThrowError("Another debugger is already attached to this target");
return;
}
agent_host_->AttachClient(this);
}
bool Debugger::IsAttached() {
return agent_host_.get() ? agent_host_->IsAttached() : false;
return agent_host_ && agent_host_->IsAttached();
}
void Debugger::Detach() {
if (!agent_host_.get())
if (!agent_host_)
return;
agent_host_->DetachClient(this);
AgentHostClosed(agent_host_.get());
agent_host_ = nullptr;
}
void Debugger::SendCommand(mate::Arguments* args) {
if (!agent_host_.get())
if (!agent_host_)
return;
std::string method;
@@ -138,6 +147,16 @@ void Debugger::SendCommand(mate::Arguments* args) {
agent_host_->DispatchProtocolMessage(this, json_args);
}
void Debugger::ClearPendingRequests() {
if (pending_requests_.empty())
return;
base::Value error(base::Value::Type::DICTIONARY);
base::Value error_msg("target closed while handling command");
error.SetKey("message", std::move(error_msg));
for (const auto& it : pending_requests_)
it.second.Run(error, base::Value());
}
// static
mate::Handle<Debugger> Debugger::Create(v8::Isolate* isolate,
content::WebContents* web_contents) {

View File

@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/values.h"
#include "content/public/browser/devtools_agent_host_client.h"
#include "content/public/browser/web_contents_observer.h"
#include "native_mate/handle.h"
namespace content {
@@ -28,11 +29,11 @@ namespace atom {
namespace api {
class Debugger : public mate::TrackableObject<Debugger>,
public content::DevToolsAgentHostClient {
public content::DevToolsAgentHostClient,
public content::WebContentsObserver {
public:
using SendCommandCallback =
base::Callback<void(const base::DictionaryValue&,
const base::DictionaryValue&)>;
base::Callback<void(const base::Value&, const base::Value&)>;
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
content::WebContents* web_contents);
@@ -50,6 +51,10 @@ class Debugger : public mate::TrackableObject<Debugger>,
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
const std::string& message) override;
// content::WebContentsObserver:
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
content::RenderFrameHost* new_rfh) override;
private:
using PendingRequestMap = std::map<int, SendCommandCallback>;
@@ -57,6 +62,7 @@ class Debugger : public mate::TrackableObject<Debugger>,
bool IsAttached();
void Detach();
void SendCommand(mate::Arguments* args);
void ClearPendingRequests();
content::WebContents* web_contents_; // Weak Reference.
scoped_refptr<content::DevToolsAgentHost> agent_host_;

View File

@@ -78,13 +78,13 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
return request_job;
}
private:
v8::Isolate* isolate_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
net::URLRequestContextGetter* request_context_;
Protocol::Handler handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);

View File

@@ -244,7 +244,7 @@ class ResolveProxyHelper {
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->url_request_context_getter();
browser_context->GetRequestContext();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy,
base::Unretained(this), context_getter, url));
@@ -453,15 +453,6 @@ void SetDevToolsNetworkEmulationClientIdInIO(
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
}
// Clear protocol handlers in IO thread.
void ClearJobFactoryInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (job_factory)
job_factory->Clear();
}
void DestroyGlobalHandle(v8::Isolate* isolate,
const v8::Global<v8::Value>& global_handle) {
v8::Locker locker(isolate);
@@ -495,10 +486,6 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
}
Session::~Session() {
auto* getter = browser_context_->GetRequestContext();
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::BindOnce(ClearJobFactoryInIO, base::RetainedRef(getter)));
content::BrowserContext::GetDownloadManager(browser_context())
->RemoveObserver(this);
DestroyGlobalHandle(isolate(), cookies_);
@@ -597,10 +584,9 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
devtools_network_emulation_client_id_, std::move(conditions));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&SetDevToolsNetworkEmulationClientIdInIO,
base::RetainedRef(browser_context_->url_request_context_getter()),
devtools_network_emulation_client_id_));
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
base::RetainedRef(browser_context_->GetRequestContext()),
devtools_network_emulation_client_id_));
}
void Session::DisableNetworkEmulation() {
@@ -609,10 +595,9 @@ void Session::DisableNetworkEmulation() {
devtools_network_emulation_client_id_, std::move(conditions));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&SetDevToolsNetworkEmulationClientIdInIO,
base::RetainedRef(browser_context_->url_request_context_getter()),
std::string()));
base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO,
base::RetainedRef(browser_context_->GetRequestContext()),
std::string()));
}
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,

View File

@@ -163,11 +163,11 @@ void TopLevelWindow::OnWindowEndSession() {
}
void TopLevelWindow::OnWindowBlur() {
Emit("blur");
EmitEventSoon("blur");
}
void TopLevelWindow::OnWindowFocus() {
Emit("focus");
EmitEventSoon("focus");
}
void TopLevelWindow::OnWindowShow() {
@@ -571,6 +571,10 @@ double TopLevelWindow::GetOpacity() {
return window_->GetOpacity();
}
void TopLevelWindow::SetShape(const std::vector<gfx::Rect>& rects) {
window_->widget()->SetShape(std::make_unique<std::vector<gfx::Rect>>(rects));
}
void TopLevelWindow::SetRepresentedFilename(const std::string& filename) {
window_->SetRepresentedFilename(filename);
}
@@ -993,6 +997,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("hasShadow", &TopLevelWindow::HasShadow)
.SetMethod("setOpacity", &TopLevelWindow::SetOpacity)
.SetMethod("getOpacity", &TopLevelWindow::GetOpacity)
.SetMethod("setShape", &TopLevelWindow::SetShape)
.SetMethod("setRepresentedFilename",
&TopLevelWindow::SetRepresentedFilename)
.SetMethod("getRepresentedFilename",

View File

@@ -14,6 +14,7 @@
#include "atom/browser/native_window.h"
#include "atom/browser/native_window_observer.h"
#include "atom/common/api/atom_api_native_image.h"
#include "content/public/browser/browser_thread.h"
#include "native_mate/handle.h"
namespace atom {
@@ -146,6 +147,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
bool HasShadow();
void SetOpacity(const double opacity);
double GetOpacity();
void SetShape(const std::vector<gfx::Rect>& rects);
void SetRepresentedFilename(const std::string& filename);
std::string GetRepresentedFilename();
void SetDocumentEdited(bool edited);
@@ -214,6 +216,14 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
// Remove this window from parent window's |child_windows_|.
void RemoveFromParentChildWindows();
template<typename... Args>
void EmitEventSoon(base::StringPiece eventName) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(base::IgnoreResult(&TopLevelWindow::Emit<Args...>),
weak_factory_.GetWeakPtr(), eventName));
}
#if defined(OS_WIN)
typedef std::map<UINT, MessageCallback> MessageCallbackMap;
MessageCallbackMap messages_callback_map_;

View File

@@ -210,7 +210,7 @@ void Tray::PopUpContextMenu(mate::Arguments* args) {
void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
menu_.Reset(isolate, menu.ToV8());
tray_icon_->SetContextMenu(menu->model());
tray_icon_->SetContextMenu(menu.IsEmpty() ? nullptr : menu->model());
}
gfx::Rect Tray::GetBounds() {

View File

@@ -125,6 +125,18 @@ bool URLRequest::ResponseState::Failed() const {
return IsFlagSet(ResponseStateFlags::kFailed);
}
mate::Dictionary URLRequest::GetUploadProgress(v8::Isolate* isolate) {
mate::Dictionary progress = mate::Dictionary::CreateEmpty(isolate);
if (atom_request_) {
progress.Set("active", true);
atom_request_->GetUploadProgress(&progress);
} else {
progress.Set("active", false);
}
return progress;
}
URLRequest::URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) {
InitWith(isolate, wrapper);
}
@@ -183,6 +195,7 @@ void URLRequest::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload)
.SetMethod("followRedirect", &URLRequest::FollowRedirect)
.SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags)
.SetMethod("getUploadProgress", &URLRequest::GetUploadProgress)
.SetProperty("notStarted", &URLRequest::NotStarted)
.SetProperty("finished", &URLRequest::Finished)
// Response APi

View File

@@ -112,6 +112,7 @@ class URLRequest : public mate::EventEmitter<URLRequest> {
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
void OnResponseCompleted();
void OnError(const std::string& error, bool isRequestError);
mate::Dictionary GetUploadProgress(v8::Isolate* isolate);
protected:
explicit URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);

View File

@@ -56,7 +56,6 @@
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/options_switches.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
@@ -483,16 +482,20 @@ WebContents::~WebContents() {
RenderViewDeleted(web_contents()->GetRenderViewHost());
if (type_ == BROWSER_WINDOW && owner_window()) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
if (type_ == WEB_VIEW) {
DestroyWebContents(false /* async */);
} else {
DestroyWebContents(!IsGuest() /* async */);
if (type_ == BROWSER_WINDOW && owner_window()) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
} else {
DestroyWebContents(true /* async */);
}
// The WebContentsDestroyed will not be called automatically because we
// destroy the webContents in the next tick. So we have to manually
// call it here to make sure "destroyed" event is emitted.
WebContentsDestroyed();
}
// The WebContentsDestroyed will not be called automatically because we
// destroy the webContents in the next tick. So we have to manually
// call it here to make sure "destroyed" event is emitted.
WebContentsDestroyed();
}
}
@@ -1039,7 +1042,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
// 2. garbage collection;
// 3. user closes the window of webContents;
// 4. the embedder detaches the frame.
// For webview only #4 will happen, for BrowserWindow both #1 and #3 may
// For webview both #1 and #4 may happen, for BrowserWindow both #1 and #3 may
// happen. The #2 should never happen for webContents, because webview is
// managed by GuestViewManager, and BrowserWindow's webContents is managed
// by api::BrowserWindow.
@@ -1391,7 +1394,9 @@ void WebContents::UnregisterServiceWorker(
}
void WebContents::SetIgnoreMenuShortcuts(bool ignore) {
set_ignore_menu_shortcuts(ignore);
auto* web_preferences = WebContentsPreferences::From(web_contents());
DCHECK(web_preferences);
web_preferences->dict()->SetBoolean("ignoreMenuShortcuts", ignore);
}
void WebContents::SetAudioMuted(bool muted) {
@@ -1722,10 +1727,6 @@ void WebContents::OnCursorChange(const content::WebCursor& cursor) {
}
}
void WebContents::SetSize(v8::Local<v8::Value>) {
// TODO(zcbenz): Remove this method in 4.0.
}
bool WebContents::IsGuest() const {
return type_ == WEB_VIEW;
}
@@ -2022,7 +2023,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("startDrag", &WebContents::StartDrag)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("isGuest", &WebContents::IsGuest)
.SetMethod("attachToIframe", &WebContents::AttachToIframe)
.SetMethod("isOffscreen", &WebContents::IsOffScreen)

View File

@@ -198,7 +198,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
void CapturePage(mate::Arguments* args);
// Methods for creating <webview>.
void SetSize(v8::Local<v8::Value>);
bool IsGuest() const;
void AttachToIframe(content::WebContents* embedder_web_contents,
int embedder_frame_id);

View File

@@ -95,7 +95,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
}
brightray::URLRequestContextGetter* url_request_context_getter =
browser_context_->url_request_context_getter();
browser_context_->GetRequestContext();
if (!url_request_context_getter)
return;
BrowserThread::PostTask(

View File

@@ -17,7 +17,6 @@
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/child_web_contents_tracker.h"
#include "atom/browser/login_handler.h"
#include "atom/browser/native_window.h"
#include "atom/browser/session_preferences.h"
#include "atom/browser/web_contents_permission_helper.h"
@@ -46,6 +45,7 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "device/geolocation/public/cpp/location_provider.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
#include "services/network/public/cpp/resource_request_body.h"
@@ -62,6 +62,10 @@
#include "net/ssl/client_cert_store.h"
#endif
#if defined(OVERRIDE_LOCATION_PROVIDER)
#include "atom/browser/fake_location_provider.h"
#endif // defined(OVERRIDE_LOCATION_PROVIDER)
using content::BrowserThread;
namespace atom {
@@ -341,10 +345,6 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
web_preferences->AppendCommandLineSwitches(command_line);
SessionPreferences::AppendExtraCommandLineSwitches(
web_contents->GetBrowserContext(), command_line);
auto context_id = atom::api::WebContents::GetIDForContents(web_contents);
command_line->AppendSwitchASCII(switches::kContextId,
base::IntToString(context_id));
}
}
@@ -495,17 +495,13 @@ std::unique_ptr<net::ClientCertStore> AtomBrowserClient::CreateClientCertStore(
#endif
}
content::ResourceDispatcherHostLoginDelegate*
AtomBrowserClient::CreateLoginDelegate(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
bool is_main_frame,
const GURL& url,
bool first_auth_attempt,
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
auth_required_callback) {
return new LoginHandler(auth_info, web_contents_getter, url,
auth_required_callback);
std::unique_ptr<device::LocationProvider>
AtomBrowserClient::OverrideSystemLocationProvider() {
#if defined(OVERRIDE_LOCATION_PROVIDER)
return std::make_unique<FakeLocationProvider>();
#else
return nullptr;
#endif
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(

View File

@@ -106,14 +106,8 @@ class AtomBrowserClient : public brightray::BrowserClient,
void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
content::ResourceContext* resource_context) override;
content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
bool is_main_frame,
const GURL& url,
bool first_auth_attempt,
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
auth_required_callback) override;
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider()
override;
// brightray::BrowserClient:
brightray::BrowserMainParts* OverrideCreateBrowserMainParts(

View File

@@ -4,59 +4,30 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_blob_reader.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.h"
#include "atom/browser/atom_permission_manager.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/about_protocol_handler.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/atom_cert_verifier.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/cookie_details.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/browser/request_context_delegate.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "url/url_constants.h"
using content::BrowserThread;
namespace atom {
namespace {
class NoCacheBackend : public net::HttpCache::BackendFactory {
int CreateBackend(net::NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend,
const net::CompletionCallback& callback) override {
return net::ERR_FAILED;
}
};
std::string RemoveWhitespace(const std::string& str) {
std::string trimmed;
if (base::RemoveChars(str, " ", &trimmed))
@@ -70,7 +41,8 @@ std::string RemoveWhitespace(const std::string& str) {
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory,
const base::DictionaryValue& options)
: brightray::BrowserContext(partition, in_memory) {
: brightray::BrowserContext(partition, in_memory),
url_request_context_getter_(nullptr) {
// Construct user agent string.
Browser* browser = Browser::Get();
std::string name = RemoveWhitespace(browser->GetName());
@@ -86,87 +58,24 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
// Read options.
use_cache_ = true;
options.GetBoolean("cache", &use_cache_);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache);
options.GetBoolean("cache", &use_cache);
request_context_delegate_.reset(new RequestContextDelegate(use_cache));
// Initialize Pref Registry in brightray.
InitPrefs();
}
AtomBrowserContext::~AtomBrowserContext() {}
AtomBrowserContext::~AtomBrowserContext() {
url_request_context_getter_->set_delegate(nullptr);
}
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
user_agent_ = user_agent;
}
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
AtomBrowserContext::RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb) {
return cookie_change_sub_list_.Add(cb);
}
std::unique_ptr<net::NetworkDelegate>
AtomBrowserContext::CreateNetworkDelegate() {
return std::make_unique<AtomNetworkDelegate>();
}
std::string AtomBrowserContext::GetUserAgent() {
return user_agent_;
}
std::unique_ptr<net::URLRequestJobFactory>
AtomBrowserContext::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers) {
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
new AtomURLRequestJobFactory);
for (auto& it : *protocol_handlers) {
job_factory->SetProtocolHandler(it.first,
base::WrapUnique(it.second.release()));
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(url::kAboutScheme,
base::WrapUnique(new AboutProtocolHandler));
job_factory->SetProtocolHandler(
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
url::kFileScheme,
base::WrapUnique(
new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
job_factory->SetProtocolHandler(
url::kHttpScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
job_factory->SetProtocolHandler(
url::kHttpsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
job_factory->SetProtocolHandler(
url::kWsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
job_factory->SetProtocolHandler(
url::kWssScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
auto* host_resolver =
url_request_context_getter()->GetURLRequestContext()->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
return std::move(job_factory);
}
net::HttpCache::BackendFactory*
AtomBrowserContext::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache))
return new NoCacheBackend;
else
return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path);
}
content::DownloadManagerDelegate*
AtomBrowserContext::GetDownloadManagerDelegate() {
if (!download_manager_delegate_.get()) {
@@ -189,26 +98,6 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
return permission_manager_.get();
}
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) {
return base::WrapUnique(new AtomCertVerifier(ct_delegate));
}
std::vector<std::string> AtomBrowserContext::GetCookieableSchemes() {
auto default_schemes = brightray::BrowserContext::GetCookieableSchemes();
const auto& standard_schemes = atom::api::GetStandardSchemes();
default_schemes.insert(default_schemes.end(), standard_schemes.begin(),
standard_schemes.end());
return default_schemes;
}
void AtomBrowserContext::NotifyCookieChange(const net::CanonicalCookie& cookie,
bool removed,
net::CookieChangeCause cause) {
CookieDetails cookie_details(&cookie, removed, cause);
cookie_change_sub_list_.Notify(&cookie_details);
}
void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
base::FilePath());
@@ -219,6 +108,16 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
}
std::string AtomBrowserContext::GetUserAgent() const {
return user_agent_;
}
void AtomBrowserContext::OnMainRequestContextCreated(
brightray::URLRequestContextGetter* getter) {
getter->set_delegate(request_context_delegate_.get());
url_request_context_getter_ = getter;
}
AtomBlobReader* AtomBrowserContext::GetBlobReader() {
if (!blob_reader_.get()) {
content::ChromeBlobStorageContext* blob_context =

View File

@@ -8,17 +8,15 @@
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "brightray/browser/browser_context.h"
namespace atom {
class AtomBlobReader;
class AtomDownloadManagerDelegate;
class AtomNetworkDelegate;
class AtomPermissionManager;
class RequestContextDelegate;
class WebViewManager;
struct CookieDetails;
class AtomBrowserContext : public brightray::BrowserContext {
public:
@@ -31,24 +29,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
const base::DictionaryValue& options = base::DictionaryValue());
void SetUserAgent(const std::string& user_agent);
// Register callbacks that needs to notified on any cookie store changes.
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb);
// brightray::URLRequestContextGetter::Delegate:
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
std::string GetUserAgent() override;
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) override;
std::vector<std::string> GetCookieableSchemes() override;
void NotifyCookieChange(const net::CanonicalCookie& cookie,
bool removed,
net::CookieChangeCause cause) override;
AtomBlobReader* GetBlobReader();
// content::BrowserContext:
content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
@@ -57,14 +38,12 @@ class AtomBrowserContext : public brightray::BrowserContext {
// brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
std::string GetUserAgent() const override;
void OnMainRequestContextCreated(
brightray::URLRequestContextGetter* getter) override;
AtomBlobReader* GetBlobReader();
void set_cookie_change_subscription(
std::unique_ptr<
base::CallbackList<void(const CookieDetails*)>::Subscription>
subscription) {
cookie_change_subscription_.swap(subscription);
RequestContextDelegate* GetRequestContextDelegate() const {
return request_context_delegate_.get();
}
protected:
@@ -74,16 +53,14 @@ class AtomBrowserContext : public brightray::BrowserContext {
~AtomBrowserContext() override;
private:
brightray::URLRequestContextGetter* url_request_context_getter_;
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<WebViewManager> guest_manager_;
std::unique_ptr<AtomPermissionManager> permission_manager_;
std::unique_ptr<AtomBlobReader> blob_reader_;
std::unique_ptr<RequestContextDelegate> request_context_delegate_;
std::string user_agent_;
bool use_cache_;
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
cookie_change_subscription_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -237,9 +237,6 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_POSIX)
HandleShutdownSignals();
#endif
// TODO(deepak1556): Enable this optionally based on response
// from AtomPermissionManager.
GetGeolocationControl()->UserDidOptIntoLocationServices();
}
void AtomBrowserMainParts::PostMainMessageLoopRun() {

View File

@@ -54,6 +54,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
// Returns a closure that can be used to remove |callback| from the list.
void RegisterDestructionCallback(base::OnceClosure callback);
// Returns the connection to GeolocationControl which can be
// used to enable the location services once per client.
device::mojom::GeolocationControl* GetGeolocationControl();
Browser* browser() { return browser_.get(); }
protected:
@@ -87,8 +91,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
std::unique_ptr<brightray::ViewsDelegate> views_delegate_;
#endif
device::mojom::GeolocationControl* GetGeolocationControl();
// A fake BrowserProcess object that used to feed the source code from chrome.
std::unique_ptr<BrowserProcess> fake_browser_process_;

View File

@@ -7,6 +7,7 @@
#include <vector>
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/web_contents_preferences.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/permission_type.h"
@@ -43,6 +44,7 @@ class AtomPermissionManager::PendingRequest {
const StatusesCallback& callback)
: render_process_id_(render_frame_host->GetProcess()->GetID()),
callback_(callback),
permissions_(permissions),
results_(permissions.size(), blink::mojom::PermissionStatus::DENIED),
remaining_results_(permissions.size()) {}
@@ -50,6 +52,18 @@ class AtomPermissionManager::PendingRequest {
blink::mojom::PermissionStatus status) {
DCHECK(!IsComplete());
if (status == blink::mojom::PermissionStatus::GRANTED) {
const auto permission = permissions_[permission_id];
if (permission == content::PermissionType::MIDI_SYSEX) {
content::ChildProcessSecurityPolicy::GetInstance()
->GrantSendMidiSysExMessage(render_process_id_);
} else if (permission == content::PermissionType::GEOLOCATION) {
AtomBrowserMainParts::Get()
->GetGeolocationControl()
->UserDidOptIntoLocationServices();
}
}
results_[permission_id] = status;
--remaining_results_;
}
@@ -63,6 +77,7 @@ class AtomPermissionManager::PendingRequest {
private:
int render_process_id_;
const StatusesCallback callback_;
std::vector<content::PermissionType> permissions_;
std::vector<blink::mojom::PermissionStatus> results_;
size_t remaining_results_;
};
@@ -139,6 +154,10 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
content::ChildProcessSecurityPolicy::GetInstance()
->GrantSendMidiSysExMessage(
render_frame_host->GetProcess()->GetID());
} else if (permission == content::PermissionType::GEOLOCATION) {
AtomBrowserMainParts::Get()
->GetGeolocationControl()
->UserDidOptIntoLocationServices();
}
statuses.push_back(blink::mojom::PermissionStatus::GRANTED);
}
@@ -153,10 +172,6 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
for (size_t i = 0; i < permissions.size(); ++i) {
auto permission = permissions[i];
if (permission == content::PermissionType::MIDI_SYSEX) {
content::ChildProcessSecurityPolicy::GetInstance()
->GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID());
}
const auto callback =
base::Bind(&AtomPermissionManager::OnPermissionResponse,
base::Unretained(this), request_id, i);
@@ -186,7 +201,6 @@ void AtomPermissionManager::OnPermissionResponse(
}
}
void AtomPermissionManager::ResetPermission(content::PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {}

View File

@@ -8,6 +8,7 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser_observer.h"
#include "atom/browser/login_handler.h"
#include "atom/browser/native_window.h"
#include "atom/browser/window_list.h"
#include "base/files/file_util.h"
@@ -164,7 +165,7 @@ void Browser::OnAccessibilitySupportChanged() {
}
void Browser::RequestLogin(
LoginHandler* login_handler,
scoped_refptr<LoginHandler> login_handler,
std::unique_ptr<base::DictionaryValue> request_details) {
for (BrowserObserver& observer : observers_)
observer.OnLogin(login_handler, *(request_details.get()));

View File

@@ -33,7 +33,6 @@ class Image;
namespace atom {
class AtomMenuModel;
class LoginHandler;
// This class is used for control application-wide operations.
class Browser : public WindowListObserver {
@@ -229,7 +228,7 @@ class Browser : public WindowListObserver {
void OnAccessibilitySupportChanged();
// Request basic auth login.
void RequestLogin(LoginHandler* login_handler,
void RequestLogin(scoped_refptr<LoginHandler> login_handler,
std::unique_ptr<base::DictionaryValue> request_details);
void PreMainMessageLoopRun();

View File

@@ -7,6 +7,8 @@
#include <string>
#include "atom/browser/login_handler.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
namespace base {
@@ -15,8 +17,6 @@ class DictionaryValue;
namespace atom {
class LoginHandler;
class BrowserObserver {
public:
// The browser is about to close all windows.
@@ -49,7 +49,7 @@ class BrowserObserver {
virtual void OnFinishLaunching(const base::DictionaryValue& launch_info) {}
// The browser requests HTTP login.
virtual void OnLogin(LoginHandler* login_handler,
virtual void OnLogin(scoped_refptr<LoginHandler> login_handler,
const base::DictionaryValue& request_details) {}
// The browser's accessibility suppport has changed.

View File

@@ -62,10 +62,6 @@ class CommonWebContentsDelegate
NativeWindow* owner_window() const { return owner_window_.get(); }
void set_ignore_menu_shortcuts(bool ignore) {
ignore_menu_shortcuts_ = ignore;
}
bool is_html_fullscreen() const { return html_fullscreen_; }
protected:
@@ -157,7 +153,6 @@ class CommonWebContentsDelegate
base::WeakPtr<NativeWindow> owner_window_;
bool offscreen_ = false;
bool ignore_menu_shortcuts_ = false;
// Whether window is fullscreened by HTML5 api.
bool html_fullscreen_ = false;

View File

@@ -6,6 +6,7 @@
#import <Cocoa/Cocoa.h>
#include "atom/browser/web_contents_preferences.h"
#include "brightray/browser/mac/event_dispatching_window.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "ui/events/keycodes/keyboard_codes.h"
@@ -27,15 +28,17 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
if (event.windows_key_code == ui::VKEY_ESCAPE && is_html_fullscreen())
ExitFullscreenModeForTab(source);
if (!ignore_menu_shortcuts_) {
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (auto* web_preferences = WebContentsPreferences::From(source)) {
if (!web_preferences->IsEnabled("ignoreMenuShortcuts", false)) {
// Send the event to the menu before sending it to the window
if (event.os_event.type == NSKeyDown &&
[[NSApp mainMenu] performKeyEquivalent:event.os_event])
return;
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
if (event.os_event.window &&
[event.os_event.window isKindOfClass:[EventDispatchingWindow class]])
[event.os_event.window redispatchKeyEvent:event.os_event];
}
}
}

View File

@@ -6,6 +6,7 @@
#include "atom/browser/api/atom_api_web_contents_view.h"
#include "atom/browser/native_window_views.h"
#include "atom/browser/web_contents_preferences.h"
#include "base/strings/string_util.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "ui/events/keycodes/keyboard_codes.h"
@@ -24,8 +25,12 @@ void CommonWebContentsDelegate::HandleKeyboardEvent(
ExitFullscreenModeForTab(source);
// Let the NativeWindow handle other parts.
if (!ignore_menu_shortcuts_ && owner_window())
owner_window()->HandleKeyboardEvent(source, event);
if (auto* web_preferences = WebContentsPreferences::From(source)) {
if (owner_window() &&
!web_preferences->IsEnabled("ignoreMenuShortcuts", false)) {
owner_window()->HandleKeyboardEvent(source, event);
}
}
}
void CommonWebContentsDelegate::ShowAutofillPopup(

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/fake_location_provider.h"
#include "base/callback.h"
#include "base/time/time.h"
namespace atom {
FakeLocationProvider::FakeLocationProvider() {
position_.latitude = 10;
position_.longitude = -10;
position_.accuracy = 1;
position_.error_code =
device::mojom::Geoposition::ErrorCode::POSITION_UNAVAILABLE;
}
FakeLocationProvider::~FakeLocationProvider() = default;
void FakeLocationProvider::SetUpdateCallback(
const LocationProviderUpdateCallback& callback) {
callback_ = callback;
}
void FakeLocationProvider::StartProvider(bool high_accuracy) {}
void FakeLocationProvider::StopProvider() {}
const device::mojom::Geoposition& FakeLocationProvider::GetPosition() {
return position_;
}
void FakeLocationProvider::OnPermissionGranted() {
if (!callback_.is_null()) {
// Check device::ValidateGeoPosition for range of values.
position_.error_code = device::mojom::Geoposition::ErrorCode::NONE;
position_.timestamp = base::Time::Now();
callback_.Run(this, position_);
}
}
} // namespace atom

View File

@@ -0,0 +1,36 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_
#define ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_
#include "base/macros.h"
#include "device/geolocation/public/cpp/location_provider.h"
#include "services/device/public/mojom/geoposition.mojom.h"
namespace atom {
class FakeLocationProvider : public device::LocationProvider {
public:
FakeLocationProvider();
~FakeLocationProvider() override;
// LocationProvider Implementation:
void SetUpdateCallback(
const LocationProviderUpdateCallback& callback) override;
void StartProvider(bool high_accuracy) override;
void StopProvider() override;
const device::mojom::Geoposition& GetPosition() override;
void OnPermissionGranted() override;
private:
device::mojom::Geoposition position_;
LocationProviderUpdateCallback callback_;
DISALLOW_COPY_AND_ASSIGN(FakeLocationProvider);
};
} // namespace atom
#endif // ATOM_BROWSER_FAKE_LOCATION_PROVIDER_H_

View File

@@ -5,6 +5,7 @@
#include "atom/browser/login_handler.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
@@ -15,78 +16,75 @@ using content::BrowserThread;
namespace atom {
LoginHandler::LoginHandler(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
const GURL& url,
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
auth_required_callback)
: auth_info_(auth_info),
web_contents_getter_(web_contents_getter),
auth_required_callback_(auth_required_callback) {
// Fill request details on IO thread.
// TODO(deepak1556): Fill in method and referrer details to
// avoid breaking the app login event.
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const net::NetworkDelegate::AuthCallback& callback,
net::AuthCredentials* credentials,
const content::ResourceRequestInfo* resource_request_info)
: credentials_(credentials),
auth_info_(auth_info),
auth_callback_(std::move(callback)),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<base::DictionaryValue> request_details(
new base::DictionaryValue);
request_details->SetKey("url", base::Value(url.spec()));
FillRequestDetails(request_details.get(), request);
web_contents_getter_ =
resource_request_info->GetWebContentsGetterForRequest();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&Browser::RequestLogin, base::Unretained(Browser::Get()),
base::RetainedRef(WrapRefCounted(this)),
std::move(request_details)));
base::RetainedRef(this), std::move(request_details)));
}
LoginHandler::~LoginHandler() {}
void LoginHandler::Login(const base::string16& username,
const base::string16& password) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&LoginHandler::DoLogin, weak_factory_.GetWeakPtr(),
username, password));
}
void LoginHandler::CancelAuth() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&LoginHandler::DoCancelAuth, weak_factory_.GetWeakPtr()));
}
void LoginHandler::NotifyRequestDestroyed() {
auth_callback_.Reset();
credentials_ = nullptr;
weak_factory_.InvalidateWeakPtrs();
}
content::WebContents* LoginHandler::GetWebContents() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return web_contents_getter_.Run();
}
void LoginHandler::Login(const base::string16& username,
const base::string16& password) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (TestAndSetAuthHandled())
return;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&LoginHandler::DoLogin, this, username, password));
}
void LoginHandler::CancelAuth() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (TestAndSetAuthHandled())
return;
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::BindOnce(&LoginHandler::DoCancelAuth, this));
}
void LoginHandler::OnRequestCancelled() {
TestAndSetAuthHandled();
auth_required_callback_.Reset();
}
// Marks authentication as handled and returns the previous handled state.
bool LoginHandler::TestAndSetAuthHandled() {
base::AutoLock lock(handled_auth_lock_);
bool was_handled = handled_auth_;
handled_auth_ = true;
return was_handled;
}
void LoginHandler::DoCancelAuth() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!auth_required_callback_.is_null())
std::move(auth_required_callback_).Run(base::nullopt);
if (!auth_callback_.is_null())
std::move(auth_callback_)
.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);
}
void LoginHandler::DoLogin(const base::string16& username,
const base::string16& password) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!auth_required_callback_.is_null()) {
std::move(auth_required_callback_)
.Run(net::AuthCredentials(username, password));
if (!auth_callback_.is_null()) {
credentials_->Set(username, password);
std::move(auth_callback_)
.Run(net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
}
}

View File

@@ -6,72 +6,65 @@
#define ATOM_BROWSER_LOGIN_HANDLER_H_
#include "base/callback.h"
#include "base/optional.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "net/base/network_delegate.h"
namespace content {
class WebContents;
}
namespace net {
class AuthChallengeInfo;
class AuthCredentials;
} // namespace net
namespace atom {
// Handles the HTTP basic auth, must be created on IO thread.
class LoginHandler : public content::ResourceDispatcherHostLoginDelegate {
class LoginHandler : public base::RefCountedThreadSafe<LoginHandler> {
public:
LoginHandler(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
const GURL& url,
const base::Callback<void(const base::Optional<net::AuthCredentials>&)>&
auth_required_callback);
LoginHandler(net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const net::NetworkDelegate::AuthCallback& callback,
net::AuthCredentials* credentials,
const content::ResourceRequestInfo* resource_request_info);
// The auth is cancelled, must be called on UI thread.
void CancelAuth();
// The URLRequest associated with the auth is destroyed.
void NotifyRequestDestroyed();
// Login with |username| and |password|, must be called on UI thread.
void Login(const base::string16& username, const base::string16& password);
// Returns the WebContents associated with the request, must be called on UI
// thread.
content::WebContents* GetWebContents() const;
// The auth is cancelled, must be called on UI thread.
void CancelAuth();
// Login with |username| and |password|, must be called on UI thread.
void Login(const base::string16& username, const base::string16& password);
const net::AuthChallengeInfo* auth_info() const { return auth_info_.get(); }
protected:
~LoginHandler() override;
// content::ResourceDispatcherHostLoginDelegate:
void OnRequestCancelled() override;
const net::AuthChallengeInfo* auth_info() const { return &auth_info_; }
private:
friend class base::RefCountedThreadSafe<LoginHandler>;
friend class base::DeleteHelper<LoginHandler>;
~LoginHandler();
// Must be called on IO thread.
void DoCancelAuth();
void DoLogin(const base::string16& username, const base::string16& password);
// Marks authentication as handled and returns the previous handled
// state.
bool TestAndSetAuthHandled();
// True if we've handled auth (Login or CancelAuth has been called).
bool handled_auth_ = false;
mutable base::Lock handled_auth_lock_;
// Credentials to be used for the auth.
net::AuthCredentials* credentials_;
// Who/where/what asked for the authentication.
scoped_refptr<net::AuthChallengeInfo> auth_info_;
const net::AuthChallengeInfo& auth_info_;
// WebContents associated with the login request.
content::ResourceRequestInfo::WebContentsGetter web_contents_getter_;
base::Callback<void(const base::Optional<net::AuthCredentials>&)>
auth_required_callback_;
// Called with preferred value of net::NetworkDelegate::AuthRequiredResponse.
net::NetworkDelegate::AuthCallback auth_callback_;
base::WeakPtrFactory<LoginHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(LoginHandler);
};

View File

@@ -1104,12 +1104,10 @@ void NativeWindowViews::OnWidgetActivationChanged(views::Widget* changed_widget,
if (changed_widget != widget())
return;
// Post the notification to next tick.
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(active ? &NativeWindow::NotifyWindowFocus
: &NativeWindow::NotifyWindowBlur,
GetWeakPtr()));
if (active)
NativeWindow::NotifyWindowFocus();
else
NativeWindow::NotifyWindowBlur();
// Hide menu bar when window is blured.
if (!active && IsMenuBarAutoHide() && IsMenuBarVisible())

View File

@@ -7,11 +7,17 @@
#include <utility>
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/login_handler.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_request_info.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
#include "services/network/throttling/throttling_network_transaction.h"
@@ -231,7 +237,15 @@ AtomNetworkDelegate::ResponseListenerInfo::ResponseListenerInfo(
AtomNetworkDelegate::ResponseListenerInfo::ResponseListenerInfo() = default;
AtomNetworkDelegate::ResponseListenerInfo::~ResponseListenerInfo() = default;
AtomNetworkDelegate::AtomNetworkDelegate() {}
AtomNetworkDelegate::AtomNetworkDelegate() {
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kIgnoreConnectionsLimit)) {
std::string value =
command_line->GetSwitchValueASCII(switches::kIgnoreConnectionsLimit);
ignore_connections_limit_domains_ = base::SplitString(
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
}
AtomNetworkDelegate::~AtomNetworkDelegate() {}
@@ -262,9 +276,17 @@ int AtomNetworkDelegate::OnBeforeURLRequest(
net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) {
if (!base::ContainsKey(response_listeners_, kOnBeforeRequest))
return brightray::NetworkDelegate::OnBeforeURLRequest(request, callback,
new_url);
if (!base::ContainsKey(response_listeners_, kOnBeforeRequest)) {
for (const auto& domain : ignore_connections_limit_domains_) {
if (request->url().DomainIs(domain)) {
// Allow unlimited concurrent connections.
request->SetPriority(net::MAXIMUM_PRIORITY);
request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS);
break;
}
}
return net::OK;
}
return HandleResponseEvent(kOnBeforeRequest, request, callback, new_url);
}
@@ -278,8 +300,7 @@ int AtomNetworkDelegate::OnBeforeStartTransaction(
kDevToolsEmulateNetworkConditionsClientId,
client_id_);
if (!base::ContainsKey(response_listeners_, kOnBeforeSendHeaders))
return brightray::NetworkDelegate::OnBeforeStartTransaction(
request, callback, headers);
return net::OK;
return HandleResponseEvent(kOnBeforeSendHeaders, request, callback, headers,
*headers);
@@ -288,10 +309,8 @@ int AtomNetworkDelegate::OnBeforeStartTransaction(
void AtomNetworkDelegate::OnStartTransaction(
net::URLRequest* request,
const net::HttpRequestHeaders& headers) {
if (!base::ContainsKey(simple_listeners_, kOnSendHeaders)) {
brightray::NetworkDelegate::OnStartTransaction(request, headers);
if (!base::ContainsKey(simple_listeners_, kOnSendHeaders))
return;
}
HandleSimpleEvent(kOnSendHeaders, request, headers);
}
@@ -303,8 +322,7 @@ int AtomNetworkDelegate::OnHeadersReceived(
scoped_refptr<net::HttpResponseHeaders>* override,
GURL* allowed) {
if (!base::ContainsKey(response_listeners_, kOnHeadersReceived))
return brightray::NetworkDelegate::OnHeadersReceived(
request, callback, original, override, allowed);
return net::OK;
return HandleResponseEvent(
kOnHeadersReceived, request, callback,
@@ -313,10 +331,8 @@ int AtomNetworkDelegate::OnHeadersReceived(
void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) {
if (!base::ContainsKey(simple_listeners_, kOnBeforeRedirect)) {
brightray::NetworkDelegate::OnBeforeRedirect(request, new_location);
if (!base::ContainsKey(simple_listeners_, kOnBeforeRedirect))
return;
}
HandleSimpleEvent(kOnBeforeRedirect, request, new_location,
request->response_headers(), request->GetSocketAddress(),
@@ -325,10 +341,8 @@ void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
void AtomNetworkDelegate::OnResponseStarted(net::URLRequest* request,
int net_error) {
if (!base::ContainsKey(simple_listeners_, kOnResponseStarted)) {
brightray::NetworkDelegate::OnResponseStarted(request, net_error);
if (!base::ContainsKey(simple_listeners_, kOnResponseStarted))
return;
}
if (request->status().status() != net::URLRequestStatus::SUCCESS)
return;
@@ -346,33 +360,109 @@ void AtomNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
// Error event.
OnErrorOccurred(request, started);
return;
} else if (request->response_headers() &&
net::HttpResponseHeaders::IsRedirectResponseCode(
request->response_headers()->response_code())) {
}
if (request->response_headers() &&
net::HttpResponseHeaders::IsRedirectResponseCode(
request->response_headers()->response_code())) {
// Redirect event.
brightray::NetworkDelegate::OnCompleted(request, started);
return;
}
if (!base::ContainsKey(simple_listeners_, kOnCompleted)) {
brightray::NetworkDelegate::OnCompleted(request, started);
if (!base::ContainsKey(simple_listeners_, kOnCompleted))
return;
}
HandleSimpleEvent(kOnCompleted, request, request->response_headers(),
request->was_cached());
}
void AtomNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
const auto& it = login_handler_map_.find(request->identifier());
if (it != login_handler_map_.end()) {
it->second->NotifyRequestDestroyed();
it->second = nullptr;
login_handler_map_.erase(it);
}
callbacks_.erase(request->identifier());
}
net::NetworkDelegate::AuthRequiredResponse AtomNetworkDelegate::OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) {
auto* resource_request_info =
content::ResourceRequestInfo::ForRequest(request);
if (!resource_request_info)
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
login_handler_map_.emplace(
request->identifier(),
new LoginHandler(request, auth_info, std::move(callback), credentials,
resource_request_info));
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
}
bool AtomNetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) {
return true;
}
bool AtomNetworkDelegate::OnCanSetCookie(
const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) {
return true;
}
bool AtomNetworkDelegate::OnCanAccessFile(
const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const {
return true;
}
bool AtomNetworkDelegate::OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const {
return false;
}
bool AtomNetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
return true;
}
bool AtomNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const {
return false;
}
// TODO(deepak1556) : Enable after hooking into the reporting service
// https://crbug.com/704259
bool AtomNetworkDelegate::OnCanQueueReportingReport(
const url::Origin& origin) const {
return false;
}
void AtomNetworkDelegate::OnCanSendReportingReports(
std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {}
bool AtomNetworkDelegate::OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
bool AtomNetworkDelegate::OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
void AtomNetworkDelegate::OnErrorOccurred(net::URLRequest* request,
bool started) {
if (!base::ContainsKey(simple_listeners_, kOnErrorOccurred)) {
brightray::NetworkDelegate::OnCompleted(request, started);
if (!base::ContainsKey(simple_listeners_, kOnErrorOccurred))
return;
}
HandleSimpleEvent(kOnErrorOccurred, request, request->was_cached(),
request->status());

View File

@@ -8,14 +8,14 @@
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/synchronization/lock.h"
#include "base/values.h"
#include "brightray/browser/network_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "extensions/common/url_pattern.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
@@ -27,7 +27,9 @@ using URLPatterns = std::set<URLPattern>;
const char* ResourceTypeToString(content::ResourceType type);
class AtomNetworkDelegate : public brightray::NetworkDelegate {
class LoginHandler;
class AtomNetworkDelegate : public net::NetworkDelegate {
public:
using ResponseCallback = base::Callback<void(const base::DictionaryValue&)>;
using SimpleListener = base::Callback<void(const base::DictionaryValue&)>;
@@ -86,6 +88,10 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
int OnBeforeStartTransaction(net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) override;
void OnBeforeSendHeaders(net::URLRequest* request,
const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info,
net::HttpRequestHeaders* headers) override {}
void OnStartTransaction(net::URLRequest* request,
const net::HttpRequestHeaders& headers) override;
int OnHeadersReceived(
@@ -97,8 +103,43 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
void OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_read) override {}
void OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) override {}
void OnCompleted(net::URLRequest* request, bool started) override;
void OnURLRequestDestroyed(net::URLRequest* request) override;
void OnPACScriptError(int line_number, const base::string16& error) override {
}
AuthRequiredResponse OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) override;
bool OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) override;
bool OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) override;
bool OnCanAccessFile(const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const override;
bool OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const override;
bool OnAreExperimentalCookieFeaturesEnabled() const override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const override;
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
void OnCanSendReportingReports(std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)>
result_callback) const override;
bool OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
bool OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
private:
void OnErrorOccurred(net::URLRequest* request, bool started);
@@ -124,9 +165,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
T out,
const base::DictionaryValue& response);
std::map<uint64_t, scoped_refptr<LoginHandler>> login_handler_map_;
std::map<SimpleEvent, SimpleListenerInfo> simple_listeners_;
std::map<ResponseEvent, ResponseListenerInfo> response_listeners_;
std::map<uint64_t, net::CompletionCallback> callbacks_;
std::vector<std::string> ignore_connections_limit_domains_;
// Client id for devtools network emulation.
std::string client_id_;

View File

@@ -70,11 +70,8 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
return nullptr;
}
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter(
browser_context->url_request_context_getter());
browser_context->GetRequestContext());
DCHECK(request_context_getter);
if (!request_context_getter) {
return nullptr;
}
scoped_refptr<AtomURLRequest> atom_url_request(new AtomURLRequest(delegate));
if (content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
@@ -504,4 +501,16 @@ void AtomURLRequest::InformDelegateErrorOccured(const std::string& error,
delegate_->OnError(error, isRequestError);
}
void AtomURLRequest::GetUploadProgress(mate::Dictionary* progress) const {
net::UploadProgress upload_progress;
if (request_) {
progress->Set("started", true);
upload_progress = request_->GetUploadProgress();
} else {
progress->Set("started", false);
}
progress->Set("current", upload_progress.position());
progress->Set("total", upload_progress.size());
}
} // namespace atom

View File

@@ -43,6 +43,7 @@ class AtomURLRequest : public base::RefCountedThreadSafe<AtomURLRequest>,
void PassLoginInformation(const base::string16& username,
const base::string16& password) const;
void SetLoadFlags(int flags) const;
void GetUploadProgress(mate::Dictionary* progress) const;
protected:
// Overrides of net::URLRequest::Delegate

View File

@@ -9,6 +9,7 @@
#include "atom/browser/api/atom_api_session.h"
#include "atom/browser/atom_browser_context.h"
#include "base/guid.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "native_mate/dictionary.h"
@@ -93,16 +94,15 @@ void URLRequestFetchJob::BeforeStartInUI(v8::Isolate* isolate,
if (options.Get("session", &val)) {
if (val->IsNull()) {
// We have to create the URLRequestContextGetter on UI thread.
url_request_context_getter_ = new brightray::URLRequestContextGetter(
this, nullptr, base::FilePath(), true,
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), nullptr,
content::URLRequestInterceptorScopedVector());
custom_browser_context_ =
AtomBrowserContext::From(base::GenerateGUID(), true);
url_request_context_getter_ =
custom_browser_context_->GetRequestContext();
} else {
mate::Handle<api::Session> session;
if (mate::ConvertFromV8(isolate, val, &session) && !session.IsEmpty()) {
AtomBrowserContext* browser_context = session->browser_context();
url_request_context_getter_ =
browser_context->url_request_context_getter();
url_request_context_getter_ = browser_context->GetRequestContext();
}
}
}

View File

@@ -8,16 +8,17 @@
#include <string>
#include "atom/browser/net/js_asker.h"
#include "brightray/browser/url_request_context_getter.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_read_observer.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
namespace atom {
class AtomBrowserContext;
class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
public net::URLFetcherDelegate,
public brightray::URLRequestContextGetter::Delegate {
public net::URLFetcherDelegate {
public:
URLRequestFetchJob(net::URLRequest*, net::NetworkDelegate*);
~URLRequestFetchJob() override;
@@ -51,6 +52,7 @@ class URLRequestFetchJob : public JsAsker<net::URLRequestJob>,
void ClearPendingBuffer();
void ClearWriteBuffer();
scoped_refptr<AtomBrowserContext> custom_browser_context_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
std::unique_ptr<net::URLFetcher> fetcher_;
std::unique_ptr<net::HttpResponseInfo> response_info_;

View File

@@ -4,6 +4,8 @@
#include "atom/browser/node_debugger.h"
#include <string>
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "libplatform/libplatform.h"
@@ -25,10 +27,15 @@ void NodeDebugger::Start(node::MultiIsolatePlatform* platform) {
node::DebugOptions options;
for (auto& arg : base::CommandLine::ForCurrentProcess()->argv()) {
#if defined(OS_WIN)
options.ParseOption("Electron", base::UTF16ToUTF8(arg));
const std::string nice_arg = base::UTF16ToUTF8(arg);
#else
options.ParseOption("Electron", arg);
const std::string& nice_arg = arg;
#endif
// Stop handling arguments after a "--" to be consistent with Chromium
if (nice_arg == "--")
break;
options.ParseOption("Electron", nice_arg);
}
// Set process._debugWaitConnect if --inspect-brk was specified to stop

View File

@@ -0,0 +1,163 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/request_context_delegate.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/net/about_protocol_handler.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/atom_cert_verifier.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/cookie_details.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/common/options_switches.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/ftp_protocol_handler.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "url/url_constants.h"
using content::BrowserThread;
namespace atom {
namespace {
class NoCacheBackend : public net::HttpCache::BackendFactory {
int CreateBackend(net::NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend,
const net::CompletionCallback& callback) override {
return net::ERR_FAILED;
}
};
} // namespace
RequestContextDelegate::RequestContextDelegate(bool use_cache)
: use_cache_(use_cache), weak_factory_(this) {}
RequestContextDelegate::~RequestContextDelegate() {}
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RequestContextDelegate::RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return cookie_change_sub_list_.Add(cb);
}
void RequestContextDelegate::NotifyCookieChange(
const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CookieDetails cookie_details(
&cookie, !(cause == net::CookieChangeCause::INSERTED), cause);
cookie_change_sub_list_.Notify(&cookie_details);
}
std::unique_ptr<net::NetworkDelegate>
RequestContextDelegate::CreateNetworkDelegate() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::make_unique<AtomNetworkDelegate>();
}
std::unique_ptr<net::URLRequestJobFactory>
RequestContextDelegate::CreateURLRequestJobFactory(
net::URLRequestContext* url_request_context,
content::ProtocolHandlerMap* protocol_handlers) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<AtomURLRequestJobFactory> job_factory(
new AtomURLRequestJobFactory);
for (auto& it : *protocol_handlers) {
job_factory->SetProtocolHandler(it.first,
base::WrapUnique(it.second.release()));
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(url::kAboutScheme,
base::WrapUnique(new AboutProtocolHandler));
job_factory->SetProtocolHandler(
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
url::kFileScheme,
base::WrapUnique(
new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
job_factory->SetProtocolHandler(
url::kHttpScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
job_factory->SetProtocolHandler(
url::kHttpsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
job_factory->SetProtocolHandler(
url::kWsScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
job_factory->SetProtocolHandler(
url::kWssScheme,
base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
auto* host_resolver = url_request_context->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
return std::move(job_factory);
}
net::HttpCache::BackendFactory*
RequestContextDelegate::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!use_cache_) {
return new NoCacheBackend;
} else {
int max_size = 0;
base::StringToInt(
command_line->GetSwitchValueASCII(switches::kDiskCacheSize), &max_size);
base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
return new net::HttpCache::DefaultBackend(
net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
}
}
std::unique_ptr<net::CertVerifier> RequestContextDelegate::CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::make_unique<AtomCertVerifier>(ct_delegate);
}
void RequestContextDelegate::GetCookieableSchemes(
std::vector<std::string>* cookie_schemes) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
const auto& standard_schemes = atom::api::GetStandardSchemes();
cookie_schemes->insert(cookie_schemes->end(), standard_schemes.begin(),
standard_schemes.end());
}
void RequestContextDelegate::OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindRepeating(&RequestContextDelegate::NotifyCookieChange,
weak_factory_.GetWeakPtr(), cookie, cause));
}
} // namespace atom

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
#define ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "brightray/browser/url_request_context_getter.h"
namespace atom {
struct CookieDetails;
class RequestContextDelegate
: public brightray::URLRequestContextGetter::Delegate {
public:
explicit RequestContextDelegate(bool use_cache);
~RequestContextDelegate() override;
// Register callbacks that needs to notified on any cookie store changes.
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
RegisterCookieChangeCallback(
const base::Callback<void(const CookieDetails*)>& cb);
protected:
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
net::URLRequestContext* url_request_context,
content::ProtocolHandlerMap* protocol_handlers) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) override;
void GetCookieableSchemes(std::vector<std::string>* cookie_schemes) override;
void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) override;
private:
void NotifyCookieChange(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause);
base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
bool use_cache_ = true;
base::WeakPtrFactory<RequestContextDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RequestContextDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_

View File

@@ -56,8 +56,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,0,0,6
PRODUCTVERSION 3,0,0,6
FILEVERSION 3,0,0,11
PRODUCTVERSION 3,0,0,11
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L

View File

@@ -7,6 +7,7 @@
#include "brightray/browser/mac/event_dispatching_window.h"
#include "ui/views/cocoa/native_widget_mac_nswindow.h"
#include "ui/views/widget/native_widget_mac.h"
namespace atom {
@@ -40,6 +41,7 @@ class ScopedDisableResize {
- (id)initWithShell:(atom::NativeWindowMac*)shell
styleMask:(NSUInteger)styleMask;
- (atom::NativeWindowMac*)shell;
- (id)accessibilityFocusedUIElement;
- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect;
- (void)enableWindowButtonsOffset;
- (void)toggleFullScreenMode:(id)sender;

View File

@@ -7,6 +7,8 @@
#include "atom/browser/native_window_mac.h"
#include "atom/browser/ui/cocoa/atom_preview_item.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "atom/browser/ui/cocoa/root_view_mac.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/base/cocoa/window_size_constants.h"
namespace atom {
@@ -39,6 +41,13 @@ bool ScopedDisableResize::disable_resize_ = false;
return shell_;
}
- (id)accessibilityFocusedUIElement {
views::Widget* widget = shell_->widget();
id superFocus = [super accessibilityFocusedUIElement];
if (!widget || shell_->IsFocused())
return superFocus;
return nil;
}
- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect {
return [super contentRectForFrameRect:frameRect];
}
@@ -91,6 +100,10 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqual:NSAccessibilityTitleAttribute])
return base::SysUTF8ToNSString(shell_->GetTitle());
if ([attribute isEqual:NSAccessibilityEnabledAttribute])
return [NSNumber numberWithBool:YES];
if (![attribute isEqualToString:@"AXChildren"])
return [super accessibilityAttributeValue:attribute];

View File

@@ -41,9 +41,15 @@ const CGFloat kVerticalTitleMargin = 2;
@implementation StatusItemView
- (id)initWithImage:(NSImage*)image icon:(atom::TrayIconCocoa*)icon {
image_.reset([image copy]);
- (void)dealloc {
trayIcon_ = nil;
menuController_ = nil;
[super dealloc];
}
- (id)initWithIcon:(atom::TrayIconCocoa*)icon {
trayIcon_ = icon;
menuController_ = nil;
highlight_mode_ = atom::TrayIcon::HighlightMode::SELECTION;
ignoreDoubleClickEvents_ = NO;
forceHighlight_ = NO;
@@ -89,6 +95,7 @@ const CGFloat kVerticalTitleMargin = 2;
trackingArea_.reset();
}
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
[statusItem_ setView:nil];
statusItem_.reset();
}
@@ -156,6 +163,8 @@ const CGFloat kVerticalTitleMargin = 2;
// The width of the icon.
- (CGFloat)iconWidth {
if (!image_ && title_)
return kHorizontalMargin;
CGFloat thickness = [[NSStatusBar systemStatusBar] thickness];
CGFloat imageHeight = [image_ size].height;
CGFloat imageWidth = [image_ size].width;
@@ -424,7 +433,9 @@ const CGFloat kVerticalTitleMargin = 2;
namespace atom {
TrayIconCocoa::TrayIconCocoa() {}
TrayIconCocoa::TrayIconCocoa() {
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
}
TrayIconCocoa::~TrayIconCocoa() {
[status_item_view_ removeItem];
@@ -433,12 +444,7 @@ TrayIconCocoa::~TrayIconCocoa() {
}
void TrayIconCocoa::SetImage(const gfx::Image& image) {
if (status_item_view_) {
[status_item_view_ setImage:image.AsNSImage()];
} else {
status_item_view_.reset(
[[StatusItemView alloc] initWithImage:image.AsNSImage() icon:this]);
}
[status_item_view_ setImage:image.IsEmpty() ? nil : image.AsNSImage()];
}
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
@@ -474,11 +480,18 @@ void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
// Substribe to MenuClosed event.
if (menu_model_)
menu_model_->RemoveObserver(this);
menu_model->AddObserver(this);
// Create native menu.
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
useDefaultAccelerator:NO]);
menu_model_ = menu_model;
if (menu_model) {
menu_model->AddObserver(this);
// Create native menu.
menu_.reset([[AtomMenuController alloc] initWithModel:menu_model
useDefaultAccelerator:NO]);
} else {
menu_.reset();
}
[status_item_view_ setMenuController:menu_.get()];
}

View File

@@ -31,6 +31,22 @@ bool IsPDFViewerEnabled() {
#endif
}
bool IsFakeLocationProviderEnabled() {
#if defined(OVERRIDE_LOCATION_PROVIDER)
return true;
#else
return false;
#endif
}
bool IsViewApiEnabled() {
#if defined(ENABLE_VIEW_API)
return true;
#else
return false;
#endif
}
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
@@ -39,6 +55,9 @@ void Initialize(v8::Local<v8::Object> exports,
dict.SetMethod("isDesktopCapturerEnabled", &IsDesktopCapturerEnabled);
dict.SetMethod("isOffscreenRenderingEnabled", &IsOffscreenRenderingEnabled);
dict.SetMethod("isPDFViewerEnabled", &IsPDFViewerEnabled);
dict.SetMethod("isFakeLocationProviderEnabled",
&IsFakeLocationProviderEnabled);
dict.SetMethod("isViewApiEnabled", &IsViewApiEnabled);
}
} // namespace

View File

@@ -8,7 +8,7 @@
#define ATOM_MAJOR_VERSION 3
#define ATOM_MINOR_VERSION 0
#define ATOM_PATCH_VERSION 0
#define ATOM_PRE_RELEASE_VERSION -beta.6
#define ATOM_PRE_RELEASE_VERSION -beta.11
#ifndef ATOM_STRINGIFY
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)

View File

@@ -30,6 +30,25 @@ v8::Local<v8::Value> Converter<base::DictionaryValue>::ToV8(
return converter.ToV8Value(&val, isolate->GetCurrentContext());
}
bool Converter<base::Value>::FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::Value* out) {
atom::V8ValueConverter converter;
std::unique_ptr<base::Value> value(
converter.FromV8Value(val, isolate->GetCurrentContext()));
if (value) {
*out = value->Clone();
return true;
} else {
return false;
}
}
v8::Local<v8::Value> Converter<base::Value>::ToV8(v8::Isolate* isolate,
const base::Value& val) {
atom::V8ValueConverter converter;
return converter.ToV8Value(&val, isolate->GetCurrentContext());
}
bool Converter<base::ListValue>::FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::ListValue* out) {

View File

@@ -10,6 +10,7 @@
namespace base {
class DictionaryValue;
class ListValue;
class Value;
} // namespace base
namespace mate {
@@ -23,6 +24,15 @@ struct Converter<base::DictionaryValue> {
const base::DictionaryValue& val);
};
template <>
struct Converter<base::Value> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
base::Value* out);
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const base::Value& val);
};
template <>
struct Converter<base::ListValue> {
static bool FromV8(v8::Isolate* isolate,

View File

@@ -211,6 +211,7 @@ void NodeBindings::Initialize() {
// Init node.
// (we assume node::Init would not modify the parameters under embedded mode).
// NOTE: If you change this line, please ping @codebytere or @MarshallOfSound
node::Init(nullptr, nullptr, nullptr, nullptr);
#if defined(OS_WIN)

View File

@@ -189,9 +189,6 @@ const char kAppUserModelId[] = "app-user-model-id";
// The application path
const char kAppPath[] = "app-path";
// The context ID for this process
const char kContextId[] = "context-id";
// The command line switch versions of the options.
const char kBackgroundColor[] = "background-color";
const char kPreloadScript[] = "preload";
@@ -215,6 +212,12 @@ const char kWidevineCdmPath[] = "widevine-cdm-path";
// Widevine CDM version.
const char kWidevineCdmVersion[] = "widevine-cdm-version";
// Forces the maximum disk space to be used by the disk cache, in bytes.
const char kDiskCacheSize[] = "disk-cache-size";
// Ignore the limit of 6 connections per host.
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
} // namespace switches
} // namespace atom

View File

@@ -93,7 +93,6 @@ extern const char kRegisterServiceWorkerSchemes[];
extern const char kSecureSchemes[];
extern const char kAppUserModelId[];
extern const char kAppPath[];
extern const char kContextId[];
extern const char kBackgroundColor[];
extern const char kPreloadScript[];
@@ -112,6 +111,9 @@ extern const char kWebviewTag[];
extern const char kWidevineCdmPath[];
extern const char kWidevineCdmVersion[];
extern const char kDiskCacheSize[];
extern const char kIgnoreConnectionsLimit[];
} // namespace switches
} // namespace atom

View File

@@ -16,14 +16,13 @@
#include "atom/renderer/content_settings_observer.h"
#include "atom/renderer/preferences_manager.h"
#include "base/command_line.h"
#include "base/process/process_handle.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "chrome/renderer/media/chrome_key_systems.h"
#include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/printing/print_web_view_helper.h"
#include "chrome/renderer/tts_dispatcher.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "native_mate/dictionary.h"
@@ -47,14 +46,6 @@
#include "atom/common/atom_constants.h"
#endif // defined(ENABLE_PDF_VIEWER)
// This is defined in later versions of Chromium, remove this if you see
// compiler complaining duplicate defines.
#if defined(OS_WIN) || defined(OS_FUCHSIA)
#define CrPRIdPid "ld"
#else
#define CrPRIdPid "d"
#endif
namespace atom {
namespace {
@@ -68,8 +59,8 @@ v8::Local<v8::Value> GetRenderProcessPreferences(
return v8::Null(isolate);
}
std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::vector<std::string> ParseSchemesCLISwitch(base::CommandLine* command_line,
const char* switch_name) {
std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name);
return base::SplitString(custom_schemes, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
@@ -79,12 +70,20 @@ std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
RendererClientBase::RendererClientBase() {
// Parse --standard-schemes=scheme1,scheme2
auto* command_line = base::CommandLine::ForCurrentProcess();
std::vector<std::string> standard_schemes_list =
ParseSchemesCLISwitch(switches::kStandardSchemes);
ParseSchemesCLISwitch(command_line, switches::kStandardSchemes);
for (const std::string& scheme : standard_schemes_list)
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kContextIsolation);
// We rely on the unique process host id which is notified to the
// renderer process via command line switch from the content layer,
// if this switch is removed from the content layer for some reason,
// we should define our own.
DCHECK(command_line->HasSwitch(::switches::kRendererClientId));
renderer_client_id_ =
command_line->GetSwitchValueASCII(::switches::kRendererClientId);
}
RendererClientBase::~RendererClientBase() {}
@@ -92,9 +91,9 @@ RendererClientBase::~RendererClientBase() {}
void RendererClientBase::DidCreateScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) {
// global.setHidden("contextId", `${processId}-${++nextContextId}`)
std::string context_id = base::StringPrintf(
"%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_);
// global.setHidden("contextId", `${processHostId}-${++next_context_id_}`)
auto context_id = base::StringPrintf(
"%s-%" PRId64, renderer_client_id_.c_str(), ++next_context_id_);
v8::Isolate* isolate = context->GetIsolate();
v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId");
v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key);
@@ -112,6 +111,8 @@ void RendererClientBase::AddRenderBindings(
}
void RendererClientBase::RenderThreadStarted() {
auto* command_line = base::CommandLine::ForCurrentProcess();
blink::WebCustomElement::AddEmbedderCustomElementName("webview");
blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
@@ -133,7 +134,7 @@ void RendererClientBase::RenderThreadStarted() {
// Parse --secure-schemes=scheme1,scheme2
std::vector<std::string> secure_schemes_list =
ParseSchemesCLISwitch(switches::kSecureSchemes);
ParseSchemesCLISwitch(command_line, switches::kSecureSchemes);
for (const std::string& scheme : secure_schemes_list)
blink::SchemeRegistry::RegisterURLSchemeAsSecure(
WTF::String::FromUTF8(scheme.data(), scheme.length()));
@@ -147,7 +148,6 @@ void RendererClientBase::RenderThreadStarted() {
#if defined(OS_WIN)
// Set ApplicationUserModelID in renderer process.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::string16 app_id =
command_line->GetSwitchValueNative(switches::kAppUserModelId);
if (!app_id.empty()) {
@@ -221,7 +221,17 @@ bool RendererClientBase::OverrideCreatePlugin(
void RendererClientBase::AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
AddChromeKeySystems(key_systems);
#if defined(WIDEVINE_CDM_AVAILABLE)
key_systems_provider_.AddSupportedKeySystems(key_systems);
#endif
}
bool RendererClientBase::IsKeySystemsUpdateNeeded() {
#if defined(WIDEVINE_CDM_AVAILABLE)
return key_systems_provider_.IsKeySystemsUpdateNeeded();
#else
return false;
#endif
}
v8::Local<v8::Context> RendererClientBase::GetContext(

View File

@@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include "chrome/renderer/media/chrome_key_systems_provider.h"
#include "content/public/renderer/content_renderer_client.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -50,12 +51,16 @@ class RendererClientBase : public content::ContentRendererClient {
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
override;
bool IsKeySystemsUpdateNeeded() override;
private:
std::unique_ptr<PreferencesManager> preferences_manager_;
ChromeKeySystemsProvider key_systems_provider_;
bool isolated_world_;
std::string renderer_client_id_;
// An increasing ID used for indentifying an V8 context in this process.
int next_context_id_ = 0;
int64_t next_context_id_ = 0;
};
} // namespace atom

View File

@@ -36,6 +36,7 @@ static_library("brightray") {
"//components/prefs",
"//content/public/browser",
"//content/shell:resources",
"//net:extras",
"//net:net_with_v8",
"//skia",
"//ui/views",

View File

@@ -112,6 +112,7 @@
'libraries': [
# Following libraries are always linked statically.
'<(libchromiumcontent_dir)/libbase_static.a',
'<(libchromiumcontent_dir)/libextras.a',
'<(libchromiumcontent_dir)/libgtkui.a',
'<(libchromiumcontent_dir)/libhttp_server.a',
'<(libchromiumcontent_dir)/libdevice_service.a',
@@ -206,6 +207,7 @@
'libraries': [
# Following libraries are always linked statically.
'<(libchromiumcontent_dir)/libbase_static.a',
'<(libchromiumcontent_dir)/libextras.a',
'<(libchromiumcontent_dir)/libhttp_server.a',
'<(libchromiumcontent_dir)/libdevice_service.a',
'<(libchromiumcontent_dir)/libdom_keycode_converter.a',
@@ -342,6 +344,7 @@
'-ldxgi.lib',
# Following libs are always linked statically.
'<(libchromiumcontent_dir)/base_static.lib',
'<(libchromiumcontent_dir)/extras.lib',
'<(libchromiumcontent_dir)/sandbox.lib',
'<(libchromiumcontent_dir)/sandbox_helper_win.lib',
'<(libchromiumcontent_dir)/http_server.lib',

View File

@@ -11,7 +11,6 @@
#include "brightray/browser/brightray_paths.h"
#include "brightray/browser/browser_client.h"
#include "brightray/browser/inspectable_web_contents_impl.h"
#include "brightray/browser/network_delegate.h"
#include "brightray/browser/special_storage_policy.h"
#include "brightray/browser/zoom_level_delegate.h"
#include "brightray/common/application_info.h"
@@ -20,7 +19,6 @@
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/escape.h"
@@ -37,25 +35,10 @@ std::string MakePartitionName(const std::string& input) {
} // namespace
class BrowserContext::ResourceContext : public content::ResourceContext {
public:
ResourceContext() : getter_(nullptr) {}
void set_url_request_context_getter(URLRequestContextGetter* getter) {
getter_ = getter;
}
private:
net::HostResolver* GetHostResolver() override {
return getter_->host_resolver();
}
net::URLRequestContext* GetRequestContext() override {
return getter_->GetURLRequestContext();
}
URLRequestContextGetter* getter_;
};
// static
void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) {
browser_context->OnDestruct();
}
// static
BrowserContext::BrowserContextMap BrowserContext::browser_context_map_;
@@ -72,7 +55,6 @@ scoped_refptr<BrowserContext> BrowserContext::Get(const std::string& partition,
BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
: in_memory_(in_memory),
resource_context_(new ResourceContext),
storage_policy_(new SpecialStoragePolicy),
weak_factory_(this) {
if (!PathService::Get(DIR_USER_DATA, &path_)) {
@@ -88,6 +70,8 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
content::BrowserContext::Initialize(this, path_);
io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr());
browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr();
}
@@ -95,13 +79,14 @@ BrowserContext::~BrowserContext() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
NotifyWillBeDestroyed(this);
ShutdownStoragePartitions();
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
resource_context_.release());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLRequestContextGetter::NotifyContextShutdownOnIO,
base::RetainedRef(url_request_getter_)));
io_handle_->ShutdownOnUIThread();
}
void BrowserContext::OnDestruct() const {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
delete this;
} else {
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
}
}
@@ -135,17 +120,10 @@ URLRequestContextGetter* BrowserContext::GetRequestContext() {
net::URLRequestContextGetter* BrowserContext::CreateRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors) {
DCHECK(!url_request_getter_.get());
url_request_getter_ = new URLRequestContextGetter(
this, static_cast<NetLog*>(BrowserClient::Get()->GetNetLog()), GetPath(),
in_memory_, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
protocol_handlers, std::move(protocol_interceptors));
resource_context_->set_url_request_context_getter(url_request_getter_.get());
return url_request_getter_.get();
}
std::unique_ptr<net::NetworkDelegate> BrowserContext::CreateNetworkDelegate() {
return std::make_unique<NetworkDelegate>();
return io_handle_
->CreateMainRequestContextGetter(protocol_handlers,
std::move(protocol_interceptors))
.get();
}
std::string BrowserContext::GetMediaDeviceIDSalt() {
@@ -171,7 +149,7 @@ bool BrowserContext::IsOffTheRecord() const {
}
content::ResourceContext* BrowserContext::GetResourceContext() {
return resource_context_.get();
return io_handle_->GetResourceContext();
}
content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() {
@@ -214,17 +192,19 @@ BrowserContext::CreateRequestContextForStoragePartition(
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
NOTREACHED();
return nullptr;
}
net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() {
return url_request_getter_.get();
return io_handle_->GetMainRequestContextGetter().get();
}
net::URLRequestContextGetter*
BrowserContext::CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) {
NOTREACHED();
return nullptr;
}

View File

@@ -23,9 +23,15 @@ class SpecialStoragePolicy;
namespace brightray {
class BrowserContext : public base::RefCounted<BrowserContext>,
public content::BrowserContext,
public brightray::URLRequestContextGetter::Delegate {
class BrowserContext;
struct BrowserContextDeleter {
static void Destruct(const BrowserContext* browser_context);
};
class BrowserContext
: public base::RefCountedThreadSafe<BrowserContext, BrowserContextDeleter>,
public content::BrowserContext {
public:
// Get the BrowserContext according to its |partition| and |in_memory|,
// empty pointer when be returned when there is no matching BrowserContext.
@@ -66,14 +72,14 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
const base::FilePath& partition_path,
bool in_memory) override;
std::string GetMediaDeviceIDSalt() override;
URLRequestContextGetter* url_request_context_getter() const {
return url_request_getter_.get();
}
base::FilePath GetPath() const override;
void InitPrefs();
PrefService* prefs() { return prefs_.get(); }
virtual std::string GetUserAgent() const = 0;
virtual void OnMainRequestContextCreated(URLRequestContextGetter* getter) {}
protected:
BrowserContext(const std::string& partition, bool in_memory);
~BrowserContext() override;
@@ -81,16 +87,14 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
// Subclasses should override this to register custom preferences.
virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {}
// URLRequestContextGetter::Delegate:
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
base::FilePath GetPath() const override;
private:
friend class base::RefCounted<BrowserContext>;
class ResourceContext;
friend class base::RefCountedThreadSafe<BrowserContext,
BrowserContextDeleter>;
friend class base::DeleteHelper<BrowserContext>;
friend struct BrowserContextDeleter;
void RegisterInternalPrefs(PrefRegistrySimple* pref_registry);
void OnDestruct() const;
// partition_id => browser_context
struct PartitionKey {
@@ -117,11 +121,12 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
base::FilePath path_;
bool in_memory_;
std::unique_ptr<ResourceContext> resource_context_;
scoped_refptr<URLRequestContextGetter> url_request_getter_;
scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
std::unique_ptr<PrefService> prefs_;
std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_;
// Self-destructing class responsible for creating URLRequestContextGetter
// on the UI thread and deletes itself on the IO thread.
URLRequestContextGetter::Handle* io_handle_;
base::WeakPtrFactory<BrowserContext> weak_factory_;

View File

@@ -484,7 +484,7 @@ void InspectableWebContentsImpl::LoadNetworkResource(
net::URLFetcher* fetcher =
(net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release();
pending_requests_[fetcher] = callback;
fetcher->SetRequestContext(browser_context->url_request_context_getter());
fetcher->SetRequestContext(browser_context->GetRequestContext());
fetcher->SetExtraRequestHeaders(headers);
fetcher->SaveResponseWithWriter(
std::unique_ptr<net::URLFetcherResponseWriter>(
@@ -735,6 +735,8 @@ void InspectableWebContentsImpl::WebContentsDestroyed() {
for (const auto& pair : pending_requests_)
delete pair.first;
pending_requests_.clear();
if (view_ && view_->GetDelegate())
view_->GetDelegate()->DevToolsClosed();
}

View File

@@ -1,161 +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-CHROMIUM file.
#include "brightray/browser/network_delegate.h"
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/strings/string_split.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
namespace brightray {
namespace {
// Ignore the limit of 6 connections per host.
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
} // namespace
NetworkDelegate::NetworkDelegate() {
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kIgnoreConnectionsLimit)) {
std::string value =
command_line->GetSwitchValueASCII(kIgnoreConnectionsLimit);
ignore_connections_limit_domains_ = base::SplitString(
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
}
NetworkDelegate::~NetworkDelegate() {}
int NetworkDelegate::OnBeforeURLRequest(net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) {
for (const auto& domain : ignore_connections_limit_domains_) {
if (request->url().DomainIs(domain)) {
// Allow unlimited concurrent connections.
request->SetPriority(net::MAXIMUM_PRIORITY);
request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS);
break;
}
}
return net::OK;
}
int NetworkDelegate::OnBeforeStartTransaction(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) {
return net::OK;
}
void NetworkDelegate::OnStartTransaction(
net::URLRequest* request,
const net::HttpRequestHeaders& headers) {}
void NetworkDelegate::OnBeforeSendHeaders(
net::URLRequest* request,
const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info,
net::HttpRequestHeaders* headers) {}
int NetworkDelegate::OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) {
return net::OK;
}
void NetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) {}
void NetworkDelegate::OnResponseStarted(net::URLRequest* request,
int net_error) {}
void NetworkDelegate::OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_read) {}
void NetworkDelegate::OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) {}
void NetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {}
void NetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {}
void NetworkDelegate::OnPACScriptError(int line_number,
const base::string16& error) {}
NetworkDelegate::AuthRequiredResponse NetworkDelegate::OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) {
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}
bool NetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) {
return true;
}
bool NetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) {
return true;
}
bool NetworkDelegate::OnCanAccessFile(
const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const {
return true;
}
bool NetworkDelegate::OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const {
return false;
}
bool NetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
return true;
}
bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const {
return false;
}
// TODO(deepak1556) : Enable after hooking into the reporting service
// https://crbug.com/704259
bool NetworkDelegate::OnCanQueueReportingReport(
const url::Origin& origin) const {
return false;
}
void NetworkDelegate::OnCanSendReportingReports(
std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {}
bool NetworkDelegate::OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
bool NetworkDelegate::OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
} // namespace brightray

View File

@@ -1,88 +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-CHROMIUM file.
#ifndef BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
#define BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
#include <set>
#include <string>
#include <vector>
#include "net/base/network_delegate.h"
namespace brightray {
class NetworkDelegate : public net::NetworkDelegate {
public:
NetworkDelegate();
~NetworkDelegate() override;
protected:
int OnBeforeURLRequest(net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) override;
int OnBeforeStartTransaction(net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) override;
void OnBeforeSendHeaders(net::URLRequest* request,
const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info,
net::HttpRequestHeaders* headers) override;
void OnStartTransaction(net::URLRequest* request,
const net::HttpRequestHeaders& headers) override;
int OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) override;
void OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_read) override;
void OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) override;
void OnCompleted(net::URLRequest* request, bool started) override;
void OnURLRequestDestroyed(net::URLRequest* request) override;
void OnPACScriptError(int line_number, const base::string16& error) override;
AuthRequiredResponse OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) override;
bool OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) override;
bool OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) override;
bool OnCanAccessFile(const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const override;
bool OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const override;
bool OnAreExperimentalCookieFeaturesEnabled() const override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const override;
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
void OnCanSendReportingReports(std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)>
result_callback) const override;
bool OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
bool OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
private:
std::vector<std::string> ignore_connections_limit_domains_;
DISALLOW_COPY_AND_ASSIGN(NetworkDelegate);
};
} // namespace brightray
#endif // BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_

View File

@@ -12,14 +12,15 @@
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "brightray/browser/browser_client.h"
#include "brightray/browser/browser_context.h"
#include "brightray/browser/net/require_ct_delegate.h"
#include "brightray/browser/net_log.h"
#include "brightray/browser/network_delegate.h"
#include "brightray/common/switches.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "content/public/browser/devtools_network_transaction_factory.h"
#include "content/public/browser/resource_context.h"
#include "net/base/host_mapping_rules.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_known_logs.h"
@@ -29,6 +30,7 @@
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/extras/sqlite/sqlite_channel_id_store.h"
#include "net/http/http_auth_filter.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
@@ -58,83 +60,107 @@ using content::BrowserThread;
namespace brightray {
std::string URLRequestContextGetter::Delegate::GetUserAgent() {
return base::EmptyString();
}
class ResourceContext : public content::ResourceContext {
public:
ResourceContext() = default;
~ResourceContext() override = default;
std::unique_ptr<net::NetworkDelegate>
URLRequestContextGetter::Delegate::CreateNetworkDelegate() {
return nullptr;
}
std::unique_ptr<net::URLRequestJobFactory>
URLRequestContextGetter::Delegate::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers) {
std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory(
new net::URLRequestJobFactoryImpl);
for (auto& it : *protocol_handlers) {
job_factory->SetProtocolHandler(it.first,
base::WrapUnique(it.second.release()));
net::HostResolver* GetHostResolver() override {
if (request_context_)
return request_context_->host_resolver();
return nullptr;
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
url::kFileScheme,
base::WrapUnique(
new net::FileProtocolHandler(base::CreateTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
net::URLRequestContext* GetRequestContext() override {
return request_context_;
}
return std::move(job_factory);
private:
friend class URLRequestContextGetter;
net::URLRequestContext* request_context_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ResourceContext);
};
URLRequestContextGetter::Handle::Handle(
base::WeakPtr<BrowserContext> browser_context)
: resource_context_(new ResourceContext),
browser_context_(browser_context),
initialized_(false) {}
URLRequestContextGetter::Handle::~Handle() {}
content::ResourceContext* URLRequestContextGetter::Handle::GetResourceContext()
const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
LazyInitialize();
return resource_context_.get();
}
net::HttpCache::BackendFactory*
URLRequestContextGetter::Delegate::CreateHttpCacheBackendFactory(
const base::FilePath& base_path) {
auto* command_line = base::CommandLine::ForCurrentProcess();
int max_size = 0;
base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize),
&max_size);
base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
return new net::HttpCache::DefaultBackend(
net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!main_request_context_getter_.get());
main_request_context_getter_ = new URLRequestContextGetter(
BrowserClient::Get()->GetNetLog(), resource_context_.get(),
browser_context_->IsOffTheRecord(), browser_context_->GetUserAgent(),
browser_context_->GetPath(), protocol_handlers,
std::move(protocol_interceptors));
browser_context_->OnMainRequestContextCreated(
main_request_context_getter_.get());
return main_request_context_getter_;
}
std::unique_ptr<net::CertVerifier>
URLRequestContextGetter::Delegate::CreateCertVerifier(
RequireCTDelegate* ct_delegate) {
return net::CertVerifier::CreateDefault();
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::GetMainRequestContextGetter() const {
return main_request_context_getter_;
}
net::SSLConfigService*
URLRequestContextGetter::Delegate::CreateSSLConfigService() {
return new net::SSLConfigServiceDefaults;
void URLRequestContextGetter::Handle::LazyInitialize() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (initialized_)
return;
initialized_ = true;
content::BrowserContext::EnsureResourceContextInitialized(
browser_context_.get());
}
std::vector<std::string>
URLRequestContextGetter::Delegate::GetCookieableSchemes() {
return {"http", "https", "ws", "wss"};
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (main_request_context_getter_.get()) {
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
base::RetainedRef(main_request_context_getter_),
std::move(resource_context_)));
}
}
if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
delete this;
}
URLRequestContextGetter::URLRequestContextGetter(
Delegate* delegate,
NetLog* net_log,
const base::FilePath& base_path,
ResourceContext* resource_context,
bool in_memory,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const std::string& user_agent,
const base::FilePath& base_path,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors)
: delegate_(delegate),
: job_factory_(nullptr),
delegate_(nullptr),
net_log_(net_log),
resource_context_(resource_context),
protocol_interceptors_(std::move(protocol_interceptors)),
base_path_(base_path),
in_memory_(in_memory),
io_task_runner_(io_task_runner),
protocol_interceptors_(std::move(protocol_interceptors)),
job_factory_(nullptr),
user_agent_(user_agent),
context_shutting_down_(false) {
// Must first be created on the UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -142,48 +168,30 @@ URLRequestContextGetter::URLRequestContextGetter(
if (protocol_handlers)
std::swap(protocol_handlers_, *protocol_handlers);
if (delegate_)
user_agent_ = delegate_->GetUserAgent();
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
proxy_config_service_ =
net::ProxyResolutionService::CreateSystemProxyConfigService(
io_task_runner_);
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
}
URLRequestContextGetter::~URLRequestContextGetter() {}
void URLRequestContextGetter::NotifyContextShutdownOnIO() {
void URLRequestContextGetter::NotifyContextShuttingDown(
std::unique_ptr<ResourceContext> resource_context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
context_shutting_down_ = true;
cookie_change_sub_.reset();
resource_context.reset();
net::URLRequestContextGetter::NotifyContextShuttingDown();
url_request_context_.reset();
storage_.reset();
http_network_session_.reset();
http_auth_preferences_.reset();
host_mapping_rules_.reset();
url_request_context_.reset();
storage_.reset();
ct_delegate_.reset();
net::URLRequestContextGetter::NotifyContextShuttingDown();
}
void URLRequestContextGetter::OnCookieChanged(
const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (!delegate_ || context_shutting_down_)
return;
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(&Delegate::NotifyCookieChange, base::Unretained(delegate_),
cookie, !(cause == net::CookieChangeCause::INSERTED),
cause));
}
net::HostResolver* URLRequestContextGetter::host_resolver() {
return url_request_context_->host_resolver();
}
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
@@ -208,28 +216,46 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
storage_->set_network_delegate(delegate_->CreateNetworkDelegate());
std::unique_ptr<net::CookieStore> cookie_store;
scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
// Create a single task runner to use with the CookieStore and
// ChannelIDStore.
scoped_refptr<base::SequencedTaskRunner> cookie_background_task_runner =
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
auto cookie_path = in_memory_
? base::FilePath()
: base_path_.Append(FILE_PATH_LITERAL("Cookies"));
std::unique_ptr<net::CookieStore> cookie_store =
content::CreateCookieStore(content::CookieStoreConfig(
cookie_path, false, false, nullptr));
storage_->set_cookie_store(std::move(cookie_store));
if (!in_memory_) {
channel_id_db = new net::SQLiteChannelIDStore(
base_path_.Append(FILE_PATH_LITERAL("Origin Bound Certs")),
cookie_background_task_runner);
}
std::unique_ptr<net::ChannelIDService> channel_id_service(
new net::ChannelIDService(
new net::DefaultChannelIDStore(channel_id_db.get())));
content::CookieStoreConfig cookie_config(cookie_path, false, false,
nullptr);
cookie_config.channel_id_service = channel_id_service.get();
cookie_config.background_task_runner = cookie_background_task_runner;
cookie_store = content::CreateCookieStore(cookie_config);
cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID());
// Set custom schemes that can accept cookies.
net::CookieMonster* cookie_monster =
static_cast<net::CookieMonster*>(url_request_context_->cookie_store());
cookie_monster->SetCookieableSchemes(delegate_->GetCookieableSchemes());
static_cast<net::CookieMonster*>(cookie_store.get());
std::vector<std::string> cookie_schemes({"http", "https", "ws", "wss"});
delegate_->GetCookieableSchemes(&cookie_schemes);
cookie_monster->SetCookieableSchemes(cookie_schemes);
// Cookie store will outlive notifier by order of declaration
// in the header.
cookie_change_sub_ =
url_request_context_->cookie_store()
->GetChangeDispatcher()
.AddCallbackForAllChanges(
base::Bind(&URLRequestContextGetter::OnCookieChanged, this));
storage_->set_channel_id_service(std::make_unique<net::ChannelIDService>(
new net::DefaultChannelIDStore(nullptr)));
cookie_store->GetChangeDispatcher().AddCallbackForAllChanges(
base::Bind(&URLRequestContextGetter::OnCookieChanged,
base::RetainedRef(this)));
storage_->set_cookie_store(std::move(cookie_store));
storage_->set_channel_id_service(std::move(channel_id_service));
storage_->set_http_user_agent_settings(
base::WrapUnique(new net::StaticHttpUserAgentSettings(
@@ -307,7 +333,7 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
storage_->set_transport_security_state(std::move(transport_security_state));
storage_->set_cert_verifier(
delegate_->CreateCertVerifier(ct_delegate_.get()));
storage_->set_ssl_config_service(delegate_->CreateSSLConfigService());
storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults());
storage_->set_http_auth_handler_factory(std::move(auth_handler_factory));
std::unique_ptr<net::HttpServerProperties> server_properties(
new net::HttpServerPropertiesImpl);
@@ -360,7 +386,8 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
std::move(backend), false));
std::unique_ptr<net::URLRequestJobFactory> job_factory =
delegate_->CreateURLRequestJobFactory(&protocol_handlers_);
delegate_->CreateURLRequestJobFactory(url_request_context_.get(),
&protocol_handlers_);
job_factory_ = job_factory.get();
// Set up interceptors in the reverse order.
@@ -378,6 +405,9 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
storage_->set_job_factory(std::move(top_job_factory));
}
if (resource_context_)
resource_context_->request_context_ = url_request_context_.get();
return url_request_context_.get();
}
@@ -386,4 +416,11 @@ URLRequestContextGetter::GetNetworkTaskRunner() const {
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
void URLRequestContextGetter::OnCookieChanged(
const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) const {
if (delegate_)
delegate_->OnCookieChanged(cookie, cause);
}
} // namespace brightray

View File

@@ -22,10 +22,6 @@
#include "base/debug/leak_tracker.h"
#endif
namespace base {
class MessageLoop;
}
namespace net {
class HostMappingRules;
class HostResolver;
@@ -38,6 +34,8 @@ class URLRequestJobFactory;
namespace brightray {
class BrowserContext;
class ResourceContext;
class RequireCTDelegate;
class NetLog;
@@ -48,55 +46,76 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
Delegate() {}
virtual ~Delegate() {}
virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate();
virtual std::string GetUserAgent();
virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() = 0;
virtual std::unique_ptr<net::URLRequestJobFactory>
CreateURLRequestJobFactory(content::ProtocolHandlerMap* protocol_handlers);
CreateURLRequestJobFactory(
net::URLRequestContext* url_request_context,
content::ProtocolHandlerMap* protocol_handlers) = 0;
virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path);
const base::FilePath& base_path) = 0;
virtual std::unique_ptr<net::CertVerifier> CreateCertVerifier(
RequireCTDelegate* ct_delegate);
virtual net::SSLConfigService* CreateSSLConfigService();
virtual std::vector<std::string> GetCookieableSchemes();
virtual void NotifyCookieChange(const net::CanonicalCookie& cookie,
bool removed,
net::CookieChangeCause cause) {}
RequireCTDelegate* ct_delegate) = 0;
virtual void GetCookieableSchemes(
std::vector<std::string>* cookie_schemes) {}
virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) {}
};
URLRequestContextGetter(
Delegate* delegate,
NetLog* net_log,
const base::FilePath& base_path,
ResourceContext* resource_context,
bool in_memory,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const std::string& user_agent,
const base::FilePath& base_path,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors);
// net::CookieChangeDispatcher::CookieChangedCallback implementation.
void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause);
// net::URLRequestContextGetter:
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
const override;
net::HostResolver* host_resolver();
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
void NotifyContextShutdownOnIO();
// Discard reference to URLRequestContext and inform observers to
// shutdown. Must be called only on IO thread.
void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>);
private:
friend class BrowserContext;
// Responsible for destroying URLRequestContextGetter
// on the IO thread.
class Handle {
public:
explicit Handle(base::WeakPtr<BrowserContext> browser_context);
~Handle();
scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors);
content::ResourceContext* GetResourceContext() const;
scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter() const;
void ShutdownOnUIThread();
private:
void LazyInitialize() const;
scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
std::unique_ptr<ResourceContext> resource_context_;
base::WeakPtr<BrowserContext> browser_context_;
mutable bool initialized_;
DISALLOW_COPY_AND_ASSIGN(Handle);
};
~URLRequestContextGetter() override;
Delegate* delegate_;
NetLog* net_log_;
base::FilePath base_path_;
bool in_memory_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
std::string user_agent_;
// net::CookieChangeDispatcher::CookieChangedCallback implementation.
void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause) const;
#if DCHECK_IS_ON()
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
@@ -110,11 +129,16 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
std::unique_ptr<net::HttpNetworkSession> http_network_session_;
std::unique_ptr<net::CookieChangeSubscription> cookie_change_sub_;
net::URLRequestJobFactory* job_factory_;
Delegate* delegate_;
NetLog* net_log_;
ResourceContext* resource_context_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector protocol_interceptors_;
net::URLRequestJobFactory* job_factory_; // weak ref
base::FilePath base_path_;
bool in_memory_;
std::string user_agent_;
bool context_shutting_down_;
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);

View File

@@ -50,9 +50,6 @@ const char kAuthServerWhitelist[] = "auth-server-whitelist";
const char kAuthNegotiateDelegateWhitelist[] =
"auth-negotiate-delegate-whitelist";
// Forces the maximum disk space to be used by the disk cache, in bytes.
const char kDiskCacheSize[] = "disk-cache-size";
} // namespace switches
} // namespace brightray

View File

@@ -17,7 +17,6 @@ extern const char kProxyPacUrl[];
extern const char kDisableHttp2[];
extern const char kAuthServerWhitelist[];
extern const char kAuthNegotiateDelegateWhitelist[];
extern const char kDiskCacheSize[];
} // namespace switches

View File

@@ -51,8 +51,6 @@
'browser/net/require_ct_delegate.h',
'browser/net_log.cc',
'browser/net_log.h',
'browser/network_delegate.cc',
'browser/network_delegate.h',
'browser/notification_delegate.h',
'browser/notification_presenter.cc',
'browser/notification_presenter.h',

View File

@@ -15,10 +15,7 @@
#include "base/version.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/widevine_cdm_constants.h"
#include "media/media_features.h"
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#if defined(OS_ANDROID)
#include "base/android/path_utils.h"
@@ -361,23 +358,6 @@ bool PathProvider(int key, base::FilePath* result) {
#endif
cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
break;
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(WIDEVINE_CDM_IS_COMPONENT)
case chrome::DIR_COMPONENT_WIDEVINE_CDM:
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
return false;
cur = cur.AppendASCII(kWidevineCdmBaseDirectory);
break;
#endif // defined(WIDEVINE_CDM_IS_COMPONENT)
// TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings.
// In the component case, this is the source adapter. Otherwise, it is the
// actual Pepper module that gets loaded.
case chrome::FILE_WIDEVINE_CDM_ADAPTER:
if (!GetInternalPluginsDirectory(&cur))
return false;
cur = cur.AppendASCII(kWidevineCdmAdapterFileName);
break;
#endif // defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
case chrome::FILE_RESOURCES_PACK:
#if defined(OS_MACOSX) && !defined(OS_IOS)
if (base::mac::AmIBundled()) {

View File

@@ -13,116 +13,66 @@
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#if 0
#include "chrome/renderer/chrome_render_thread_observer.h"
#endif
#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
#include "components/cdm/renderer/widevine_key_system_properties.h"
#include "content/public/renderer/render_thread.h"
#include "media/base/eme_constants.h"
#include "media/base/key_system_properties.h"
#include "media/media_features.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "base/feature_list.h"
#include "content/public/renderer/key_system_support.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#endif
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
// The following must be after widevine_cdm_version.h.
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
#include <gnu/libc-version.h>
#include "base/version.h"
#endif
using media::EmeFeatureSupport;
using media::EmeSessionTypeSupport;
using media::KeySystemProperties;
using media::SupportedCodecs;
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
static const char kExternalClearKeyPepperType[] =
"application/x-ppapi-clearkey-cdm";
// KeySystemProperties implementation for external Clear Key systems.
class ExternalClearKeyProperties : public KeySystemProperties {
public:
explicit ExternalClearKeyProperties(const std::string& key_system_name)
: key_system_name_(key_system_name) {}
std::string GetKeySystemName() const override { return key_system_name_; }
bool IsSupportedInitDataType(
media::EmeInitDataType init_data_type) const override {
switch (init_data_type) {
case media::EmeInitDataType::WEBM:
case media::EmeInitDataType::KEYIDS:
return true;
case media::EmeInitDataType::CENC:
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
return true;
#else
return false;
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
case media::EmeInitDataType::UNKNOWN:
return false;
}
NOTREACHED();
return false;
}
SupportedCodecs GetSupportedCodecs() const override {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL;
#else
return media::EME_CODEC_WEBM_ALL;
#endif
}
media::EmeConfigRule GetRobustnessConfigRule(
media::EmeMediaType media_type,
const std::string& requested_robustness) const override {
return requested_robustness.empty() ? media::EmeConfigRule::SUPPORTED
: media::EmeConfigRule::NOT_SUPPORTED;
}
// Persistent license sessions are faked.
media::EmeSessionTypeSupport GetPersistentLicenseSessionSupport()
const override {
return media::EmeSessionTypeSupport::SUPPORTED;
}
media::EmeSessionTypeSupport GetPersistentReleaseMessageSessionSupport()
const override {
return media::EmeSessionTypeSupport::NOT_SUPPORTED;
}
media::EmeFeatureSupport GetPersistentStateSupport() const override {
return media::EmeFeatureSupport::REQUESTABLE;
}
media::EmeFeatureSupport GetDistinctiveIdentifierSupport() const override {
return media::EmeFeatureSupport::NOT_SUPPORTED;
}
std::string GetPepperType() const override {
return kExternalClearKeyPepperType;
}
private:
const std::string key_system_name_;
};
// External Clear Key (used for testing).
static void AddExternalClearKey(
std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
// TODO(xhwang): Move these into an array so we can use a for loop to add
// supported key systems below.
static const char kExternalClearKeyKeySystem[] =
"org.chromium.externalclearkey";
static const char kExternalClearKeyDecryptOnlyKeySystem[] =
"org.chromium.externalclearkey.decryptonly";
static const char kExternalClearKeyMessageTypeTestKeySystem[] =
"org.chromium.externalclearkey.messagetypetest";
static const char kExternalClearKeyFileIOTestKeySystem[] =
"org.chromium.externalclearkey.fileiotest";
static const char kExternalClearKeyOutputProtectionTestKeySystem[] =
"org.chromium.externalclearkey.outputprotectiontest";
static const char kExternalClearKeyPlatformVerificationTestKeySystem[] =
"org.chromium.externalclearkey.platformverificationtest";
static const char kExternalClearKeyInitializeFailKeySystem[] =
"org.chromium.externalclearkey.initializefail";
static const char kExternalClearKeyCrashKeySystem[] =
"org.chromium.externalclearkey.crash";
static const char kExternalClearKeyVerifyCdmHostTestKeySystem[] =
"org.chromium.externalclearkey.verifycdmhosttest";
static const char kExternalClearKeyStorageIdTestKeySystem[] =
"org.chromium.externalclearkey.storageidtest";
static const char kExternalClearKeyDifferentGuidTestKeySystem[] =
"org.chromium.externalclearkey.differentguid";
static const char kExternalClearKeyCdmProxyTestKeySystem[] =
"org.chromium.externalclearkey.cdmproxytest";
std::vector<media::VideoCodec> supported_video_codecs;
bool supports_persistent_license;
@@ -133,32 +83,107 @@ static void AddExternalClearKey(
}
concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyKeySystem));
new cdm::ExternalClearKeyProperties(kExternalClearKeyKeySystem));
// Add support of decrypt-only mode in ClearKeyCdm.
concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyDecryptOnlyKeySystem));
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyDecryptOnlyKeySystem));
// A key system that triggers FileIO test in ClearKeyCdm.
concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyFileIOTestKeySystem));
// A key system that triggers various types of messages in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyMessageTypeTestKeySystem));
// A key system that triggers the FileIO test in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyFileIOTestKeySystem));
// A key system that triggers the output protection test in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyOutputProtectionTestKeySystem));
// A key system that triggers the platform verification test in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyPlatformVerificationTestKeySystem));
// A key system that Chrome thinks is supported by ClearKeyCdm, but actually
// will be refused by ClearKeyCdm. This is to test the CDM initialization
// failure case.
concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyInitializeFailKeySystem));
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyInitializeFailKeySystem));
// A key system that triggers a crash in ClearKeyCdm.
concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyCrashKeySystem));
new cdm::ExternalClearKeyProperties(kExternalClearKeyCrashKeySystem));
// A key system that triggers the verify host files test in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyVerifyCdmHostTestKeySystem));
// A key system that fetches the Storage ID in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyStorageIdTestKeySystem));
// A key system that is registered with a different CDM GUID.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyDifferentGuidTestKeySystem));
// A key system that triggers CDM Proxy test in ClearKeyCdm.
concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyCdmProxyTestKeySystem));
}
#if defined(WIDEVINE_CDM_AVAILABLE)
// Returns persistent-license session support.
EmeSessionTypeSupport GetPersistentLicenseSupport(bool supported_by_the_cdm) {
#if 0
// Do not support persistent-license if the process cannot persist data.
// TODO(crbug.com/457487): Have a better plan on this. See bug for details.
if (ChromeRenderThreadObserver::is_incognito_process()) {
DVLOG(2) << __func__ << ": Not supported in incognito process.";
return EmeSessionTypeSupport::NOT_SUPPORTED;
}
#endif
if (!supported_by_the_cdm) {
DVLOG(2) << __func__ << ": Not supported by the CDM.";
return EmeSessionTypeSupport::NOT_SUPPORTED;
}
// On ChromeOS, platform verification is similar to CDM host verification.
#if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) || defined(OS_CHROMEOS)
bool cdm_host_verification_potentially_supported = true;
#else
bool cdm_host_verification_potentially_supported = false;
#endif
// If we are sure CDM host verification is NOT supported, we should not
// support persistent-license.
if (!cdm_host_verification_potentially_supported) {
DVLOG(2) << __func__ << ": Not supported without CDM host verification.";
return EmeSessionTypeSupport::NOT_SUPPORTED;
}
#if defined(OS_CHROMEOS)
// On ChromeOS, platform verification (similar to CDM host verification)
// requires identifier to be allowed.
// TODO(jrummell): Currently the ChromeOS CDM does not require storage ID
// to support persistent license. Update this logic when the new CDM requires
// storage ID.
return EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER;
#elif BUILDFLAG(ENABLE_CDM_STORAGE_ID)
// On other platforms, we require storage ID to support persistent license.
return EmeSessionTypeSupport::SUPPORTED;
#else
// Storage ID not implemented, so no support for persistent license.
DVLOG(2) << __func__ << ": Not supported without CDM storage ID.";
return EmeSessionTypeSupport::NOT_SUPPORTED;
#endif // defined(OS_CHROMEOS)
}
static void AddPepperBasedWidevine(
std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
#if defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
Version glibc_version(gnu_get_libc_version());
base::Version glibc_version(gnu_get_libc_version());
DCHECK(glibc_version.IsValid());
if (glibc_version < base::Version(WIDEVINE_CDM_MIN_GLIBC_VERSION))
return;
@@ -205,27 +230,28 @@ static void AddPepperBasedWidevine(
}
}
EmeSessionTypeSupport persistent_license_support =
GetPersistentLicenseSupport(supports_persistent_license);
using Robustness = cdm::WidevineKeySystemProperties::Robustness;
concrete_key_systems->emplace_back(new cdm::WidevineKeySystemProperties(
supported_codecs,
#if defined(OS_CHROMEOS)
media::EmeRobustness::HW_SECURE_ALL, // Maximum audio robustness.
media::EmeRobustness::HW_SECURE_ALL, // Maximim video robustness.
media::EmeSessionTypeSupport::
SUPPORTED_WITH_IDENTIFIER, // Persistent-license.
media::EmeSessionTypeSupport::
NOT_SUPPORTED, // Persistent-release-message.
media::EmeFeatureSupport::REQUESTABLE, // Persistent state.
media::EmeFeatureSupport::REQUESTABLE)); // Distinctive identifier.
#else // (Desktop)
Robustness::SW_SECURE_CRYPTO, // Maximum audio robustness.
Robustness::SW_SECURE_DECODE, // Maximum video robustness.
media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license.
media::EmeSessionTypeSupport::
NOT_SUPPORTED, // persistent-release-message.
media::EmeFeatureSupport::REQUESTABLE, // Persistent state.
media::EmeFeatureSupport::NOT_SUPPORTED)); // Distinctive identifier.
#endif // defined(OS_CHROMEOS)
Robustness::HW_SECURE_ALL, // Maximum audio robustness.
Robustness::HW_SECURE_ALL, // Maximum video robustness.
persistent_license_support, // Persistent-license.
EmeSessionTypeSupport::NOT_SUPPORTED, // Persistent-release-message.
EmeFeatureSupport::REQUESTABLE, // Persistent state.
EmeFeatureSupport::REQUESTABLE)); // Distinctive identifier.
#else // Desktop
Robustness::SW_SECURE_CRYPTO, // Maximum audio robustness.
Robustness::SW_SECURE_DECODE, // Maximum video robustness.
persistent_license_support, // persistent-license.
EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-release-message.
EmeFeatureSupport::REQUESTABLE, // Persistent state.
EmeFeatureSupport::NOT_SUPPORTED)); // Distinctive identifier.
#endif // defined(OS_CHROMEOS)
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -233,10 +259,12 @@ static void AddPepperBasedWidevine(
void AddChromeKeySystems(
std::vector<std::unique_ptr<KeySystemProperties>>* key_systems_properties) {
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
AddExternalClearKey(key_systems_properties);
if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting))
AddExternalClearKey(key_systems_properties);
#if defined(WIDEVINE_CDM_AVAILABLE)
AddPepperBasedWidevine(key_systems_properties);
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}

View File

@@ -0,0 +1,78 @@
// Copyright 2017 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.
#include "chrome/renderer/media/chrome_key_systems_provider.h"
#include "base/time/default_tick_clock.h"
#include "chrome/renderer/media/chrome_key_systems.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
ChromeKeySystemsProvider::ChromeKeySystemsProvider()
: has_updated_(false),
is_update_needed_(true),
tick_clock_(base::DefaultTickClock::GetInstance()) {}
ChromeKeySystemsProvider::~ChromeKeySystemsProvider() {}
void ChromeKeySystemsProvider::AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) {
DCHECK(key_systems);
DCHECK(thread_checker_.CalledOnValidThread());
if (!test_provider_.is_null()) {
test_provider_.Run(key_systems);
} else {
AddChromeKeySystems(key_systems);
}
has_updated_ = true;
last_update_time_ticks_ = tick_clock_->NowTicks();
// Check whether all potentially supported key systems are supported. If so,
// no need to update again.
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
for (const auto& properties : *key_systems) {
if (properties->GetKeySystemName() == kWidevineKeySystem) {
is_update_needed_ = false;
}
}
#else
is_update_needed_ = false;
#endif
}
bool ChromeKeySystemsProvider::IsKeySystemsUpdateNeeded() {
DCHECK(thread_checker_.CalledOnValidThread());
// Always needs update if we have never updated, regardless the
// |last_update_time_ticks_|'s initial value.
if (!has_updated_) {
DCHECK(is_update_needed_);
return true;
}
if (!is_update_needed_)
return false;
// The update could be expensive. For example, it could involve a sync IPC to
// the browser process. Use a minimum update interval to avoid unnecessarily
// frequent update.
static const int kMinUpdateIntervalInMilliseconds = 1000;
if ((tick_clock_->NowTicks() - last_update_time_ticks_).InMilliseconds() <
kMinUpdateIntervalInMilliseconds) {
return false;
}
return true;
}
void ChromeKeySystemsProvider::SetTickClockForTesting(
base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
}
void ChromeKeySystemsProvider::SetProviderDelegateForTesting(
const KeySystemsProviderDelegate& test_provider) {
test_provider_ = test_provider;
}

View File

@@ -0,0 +1,64 @@
// Copyright 2017 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.
#ifndef CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_PROVIDER_H_
#define CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_PROVIDER_H_
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/threading/thread_checker.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "media/base/key_system_properties.h"
typedef std::vector<std::unique_ptr<media::KeySystemProperties>>
KeySystemPropertiesVector;
typedef base::Callback<void(KeySystemPropertiesVector*)>
KeySystemsProviderDelegate;
class ChromeKeySystemsProvider {
public:
ChromeKeySystemsProvider();
~ChromeKeySystemsProvider();
// Adds properties for supported key systems.
void AddSupportedKeySystems(KeySystemPropertiesVector* key_systems);
// Returns whether client key systems properties should be updated.
// TODO(chcunningham): Refactor this to a proper change "observer" API that is
// less fragile (don't assume AddSupportedKeySystems has just one caller).
bool IsKeySystemsUpdateNeeded();
void SetTickClockForTesting(base::TickClock* tick_clock);
void SetProviderDelegateForTesting(
const KeySystemsProviderDelegate& test_provider);
private:
// Whether AddSupportedKeySystems() has ever been called.
bool has_updated_;
// Whether a future update is needed. For example, when some potentially
// supported key systems are NOT supported yet. This could happen when the
// required component for a key system is not yet available.
bool is_update_needed_;
// Throttle how often we signal an update is needed to avoid unnecessary high
// frequency of expensive IPC calls.
base::TimeTicks last_update_time_ticks_;
base::TickClock* tick_clock_;
// Ensure all methods are called from the same (Main) thread.
base::ThreadChecker thread_checker_;
// For unit tests to inject their own key systems. Will bypass adding default
// Chrome key systems when set.
KeySystemsProviderDelegate test_provider_;
DISALLOW_COPY_AND_ASSIGN(ChromeKeySystemsProvider);
};
#endif // CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_PROVIDER_H_

View File

@@ -182,6 +182,10 @@ tray.setHighlightMode('off')
webContents.openDevTools({detach: true})
// Replace with
webContents.openDevTools({mode: 'detach'})
// Removed
webContents.setSize(options)
// There is no replacement for this API
```
## `webFrame`
@@ -198,6 +202,22 @@ webFrame.registerURLSchemeAsPrivileged('app', {secure: true})
protocol.registerStandardSchemes(['app'], {secure: true})
```
## `<webview>`
```js
// Removed
webview.setAttribute('disableguestresize', '')
// There is no replacement for this API
// Removed
webview.setAttribute('guestinstance', instanceId)
// There is no replacement for this API
// Keyboard listeners no longer work on webview tag
webview.onkeydown = () => { /* handler */ }
webview.onkeyup = () => { /* handler */ }
```
## Node Headers URL
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`

View File

@@ -1264,6 +1264,17 @@ Sets the opacity of the window. On Linux does nothing.
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque)
#### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_
* `rects` [Rectangle[]](structures/rectangle.md) - Sets a shape on the window.
Passing an empty list reverts the window to being rectangular.
Setting a window shape determines the area within the window where the system
permits drawing and user interaction. Outside of the given region, no pixels
will be drawn and no mouse events will be registered. Mouse events outside of
the region will not be received by that window, but will fall through to
whatever is behind the window.
#### `win.setThumbarButtons(buttons)` _Windows_
* `buttons` [ThumbarButton[]](structures/thumbar-button.md)

View File

@@ -215,3 +215,17 @@ response object,it will emit the `aborted` event.
#### `request.followRedirect()`
Continues any deferred redirection request when the redirection mode is `manual`.
#### `request.getUploadProgress()`
Returns `Object`:
* `active` Boolean - Whether the request is currently active. If this is false
no other properties will be set
* `started` Boolean - Whether the upload has started. If this is false both
`current` and `total` will be set to 0.
* `current` Integer - The number of bytes that have been uploaded so far
* `total` Integer - The number of bytes that will be uploaded this request
You can use this method in conjunction with `POST` requests to get the progress
of a file upload or other data transfer.

View File

@@ -275,7 +275,7 @@ The `position` is only available on Windows, and it is (0, 0) by default.
#### `tray.setContextMenu(menu)`
* `menu` Menu
* `menu` Menu | null
Sets the context menu for this icon.

View File

@@ -1381,23 +1381,6 @@ win.webContents.on('did-finish-load', () => {
Shows pop-up dictionary that searches the selected word on the page.
#### `contents.setSize(options)`
Set the size of the page. This is only supported for `<webview>` guest contents.
* `options` Object
* `enableAutoSize` Boolean (optional) - true to make the webview container automatically
resize within the bounds specified by the attributes normal, min and max.
* `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents.
* `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents.
* `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
attribute to manually resize the webview guest contents.
#### `contents.isOffscreen()`
Returns `Boolean` - Indicates whether *offscreen rendering* is enabled.

View File

@@ -62,33 +62,28 @@ and displays a "loading..." message during the load time:
</script>
```
## Internal implementation
Under the hood `webview` is implemented with [Out-of-Process iframes (OOPIFs)](https://www.chromium.org/developers/design-documents/oop-iframes).
The `webview` tag is essentially a custom element using shadow DOM to wrap an
`iframe` element inside it.
So the behavior of `webview` is very similar to a cross-domain `iframe`, as
examples:
* When clicking into a `webview`, the page focus will move from the embedder
frame to `webview`.
* You can not add keyboard event listeners to `webview`.
* All reactions between the embedder frame and `webview` are asynchronous.
## CSS Styling Notes
Please note that the `webview` tag's style uses `display:flex;` internally to
ensure the child `object` element fills the full height and width of its `webview`
container when used with traditional and flexbox layouts (since v0.36.11). Please
do not overwrite the default `display:flex;` CSS property, unless specifying
ensure the child `iframe` element fills the full height and width of its `webview`
container when used with traditional and flexbox layouts. Please do not
overwrite the default `display:flex;` CSS property, unless specifying
`display:inline-flex;` for inline layout.
`webview` has issues being hidden using the `hidden` attribute or using
`display: none;`. It can cause unusual rendering behaviour within its child
`browserplugin` object and the web page is reloaded when the `webview` is
un-hidden. The recommended approach is to hide the `webview` using
`visibility: hidden`.
```html
<style>
webview {
display:inline-flex;
width:640px;
height:480px;
}
webview.hide {
visibility: hidden;
}
</style>
```
## Tag Attributes
The `webview` tag has the following attributes:
@@ -244,59 +239,6 @@ A list of strings which specifies the blink features to be disabled separated by
The full list of supported feature strings can be found in the
[RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
### `guestinstance`
```html
<webview src="https://www.github.com/" guestinstance="3"></webview>
```
A value that links the webview to a specific webContents. When a webview
first loads a new webContents is created and this attribute is set to its
instance identifier. Setting this attribute on a new or existing webview
connects it to the existing webContents that currently renders in a different
webview.
The existing webview will see the `destroy` event and will then create a new
webContents when a new url is loaded.
### `disableguestresize`
```html
<webview src="https://www.github.com/" disableguestresize></webview>
```
When this attribute is present the `webview` contents will be prevented from
resizing when the `webview` element itself is resized.
This can be used in combination with
[`webContents.setSize`](web-contents.md#contentssetsizeoptions) to manually
resize the webview contents in reaction to a window size change. This can
make resizing faster compared to relying on the webview element bounds to
automatically resize the contents.
```javascript
const {webContents} = require('electron')
// We assume that `win` points to a `BrowserWindow` instance containing a
// `<webview>` with `disableguestresize`.
win.on('resize', () => {
const [width, height] = win.getContentSize()
for (let wc of webContents.getAllWebContents()) {
// Check if `wc` belongs to a webview in the `win` window.
if (wc.hostWebContents &&
wc.hostWebContents.id === win.webContents.id) {
wc.setSize({
normal: {
width: width,
height: height
}
})
}
}
})
```
## Methods
The `webview` tag has the following methods:

View File

@@ -5,8 +5,8 @@ Follow the guidelines below for building Electron on Windows.
## Prerequisites
* Windows 7 / Server 2008 R2 or higher
* Visual Studio 2017 15.7.2 or higher - [download VS 2017 Community Edition for
free](https://www.visualstudio.com/vs/)
* [Visual Studio 2017 15.4.5](https://web.archive.org/web/20180220131834/https://docs.microsoft.com/en-us/visualstudio/productinfo/installing-an-earlier-release-of-vs2017) - Electron 3-0-x specifically requires Visual Studion 15.4.5 to build and newer versions will not work. You can [download VS 2017 15.4.5 Community Edition for
free](https://aka.ms/eam4b7).
* [Python 2.7](http://www.python.org/download/releases/2.7/)
* [Node.js](https://nodejs.org/download/)
* [Git](http://git-scm.com)

View File

@@ -77,15 +77,20 @@ Whatever you choose, you will periodically have to bump the version in your `pac
The process is as follows:
1. All new major and minor releases lines begin with a `-beta.N` tag for `N >= 1`. At that point, the feature set is **locked**. That release line admits no further features, and focuses only on security and stability.
e.g. `2.0.0-beta.1`.
2. Bug fixes, regression fixes, and security patches can be admitted. Upon doing so, a new beta is released incrementing `N`.
e.g. `2.0.0-beta.2`
3. If a particular beta release is _generally regarded_ as stable, it will be re-released as a stable build, changing only the version information.
e.g. `2.0.0`.
4. If future bug fixes or security patches need to be made once a release is stable, they are applied and the _patch_ version is incremented accordingly
1. All new major and minor releases lines begin with a beta series indicated by semver prerelease tags of `beta.N`, e.g. `2.0.0-beta.1`. After the first beta, subsequent beta releases must meet all of the following conditions:
1. The change is backwards API-compatible (deprecations are allowed)
2. The risk to meeting our stability timeline must be low.
2. If allowed changes need to be made once a release is beta, they are applied and the prerelease tag is incremented, e.g. `2.0.0-beta.2`.
3. If a particular beta release is _generally regarded_ as stable, it will be re-released as a stable build, changing only the version information. e.g. `2.0.0`. After the first stable, all changes must be backwards-compatible bug or security fixes.
4. If future bug fixes or security patches need to be made once a release is stable, they are applied and the _patch_ version is incremented
e.g. `2.0.1`.
Specifically, the above means:
1. Admitting non-breaking-API changes early in the beta cycle is okay, even if those changes have the potential to cause moderate side-affects
2. Admitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.
3. Admitting features of any sort very late in the beta cycle is 👎 without a very good reason.
For each major and minor bump, you should expect to see something like the following:
```text
@@ -125,12 +130,7 @@ Feature flags are a common practice in Chromium, and are well-established in the
* it is enabled/disabled either at runtime, or build-time; we do not support the concept of a request-scoped feature flag
* it completely segments new and old code paths; refactoring old code to support a new feature _violates_ the feature-flag contract
* feature flags are eventually removed after the soft-branch is merged
We reconcile flagged code with our versioning strategy as follows:
1. we do not consider iterating on feature-flagged code in a stability branch; even judicious use of feature flags is not without risk
2. you may break API contracts in feature-flagged code without bumping the major version. Flagged code does not adhere to semver
* feature flags are eventually removed after the feature is released
# Semantic Commits

View File

@@ -4,7 +4,7 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '3.0.0-beta.6',
'version%': '3.0.0-beta.11',
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
},
'includes': [
@@ -288,6 +288,9 @@
# Enables SkBitmap size 64 operations
'SK_SUPPORT_LEGACY_SAFESIZE64',
# Enables widevine cdm support
'WIDEVINE_CDM_AVAILABLE',
],
'sources': [
'<@(lib_sources)',
@@ -340,6 +343,16 @@
'link_settings': {
'libraries': [ '<@(libchromiumcontent_v8_libraries)' ],
},
'sources': [
'<@(lib_sources_location_provider)',
],
'defines': [
# Enable fake location provider to mock geolocation
# responses in component build. Should not be enabled
# for release build. If you need to test with chromium's
# location provider, remove this definition.
'OVERRIDE_LOCATION_PROVIDER',
],
}],
['OS=="win"', {
'sources': [

View File

@@ -306,6 +306,8 @@
'atom/browser/relauncher.h',
'atom/browser/render_process_preferences.cc',
'atom/browser/render_process_preferences.h',
'atom/browser/request_context_delegate.cc',
'atom/browser/request_context_delegate.h',
'atom/browser/session_preferences.cc',
'atom/browser/session_preferences.h',
'atom/browser/ui/accelerator_util.cc',
@@ -646,6 +648,8 @@
'chromium_src/chrome/common/widevine_cdm_constants.h',
'chromium_src/chrome/renderer/media/chrome_key_systems.cc',
'chromium_src/chrome/renderer/media/chrome_key_systems.h',
'chromium_src/chrome/renderer/media/chrome_key_systems_provider.cc',
'chromium_src/chrome/renderer/media/chrome_key_systems_provider.h',
'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc',
'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h',
'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc',
@@ -695,6 +699,10 @@
'chromium_src/chrome/utility/printing_handler_win.cc',
'chromium_src/chrome/utility/printing_handler_win.h',
],
'lib_sources_location_provider': [
'atom/browser/fake_location_provider.cc',
'atom/browser/fake_location_provider.h',
],
'framework_sources': [
'atom/app/atom_library_main.h',
'atom/app/atom_library_main.mm',

View File

@@ -1,9 +1,9 @@
const features = process.atomBinding('features')
// Browser side modules, please sort alphabetically.
module.exports = [
{name: 'app', file: 'app'},
{name: 'autoUpdater', file: 'auto-updater'},
{name: 'BoxLayout', file: 'box-layout'},
{name: 'Button', file: 'button'},
{name: 'BrowserView', file: 'browser-view'},
{name: 'BrowserWindow', file: 'browser-window'},
{name: 'contentTracing', file: 'content-tracing'},
@@ -11,8 +11,6 @@ module.exports = [
{name: 'globalShortcut', file: 'global-shortcut'},
{name: 'ipcMain', file: 'ipc-main'},
{name: 'inAppPurchase', file: 'in-app-purchase'},
{name: 'LabelButton', file: 'label-button'},
{name: 'LayoutManager', file: 'layout-manager'},
{name: 'Menu', file: 'menu'},
{name: 'MenuItem', file: 'menu-item'},
{name: 'net', file: 'net'},
@@ -24,7 +22,6 @@ module.exports = [
{name: 'screen', file: 'screen'},
{name: 'session', file: 'session'},
{name: 'systemPreferences', file: 'system-preferences'},
{name: 'TextField', file: 'text-field'},
{name: 'TopLevelWindow', file: 'top-level-window'},
{name: 'TouchBar', file: 'touch-bar'},
{name: 'Tray', file: 'tray'},
@@ -34,3 +31,13 @@ module.exports = [
// The internal modules, invisible unless you know their names.
{name: 'NavigationController', file: 'navigation-controller', private: true}
]
if (features.isViewApiEnabled()) {
module.exports.push(
{name: 'BoxLayout', file: 'box-layout'},
{name: 'Button', file: 'button'},
{name: 'LabelButton', file: 'label-button'},
{name: 'LayoutManager', file: 'layout-manager'},
{name: 'TextField', file: 'text-field'}
)
}

View File

@@ -352,6 +352,10 @@ class ClientRequest extends EventEmitter {
abort () {
this.urlRequest.cancel()
}
getUploadProgress () {
return this.urlRequest.getUploadProgress()
}
}
function writeAfterEndNT (self, error, callback) {

View File

@@ -264,6 +264,12 @@ WebContents.prototype.getZoomFactor = function (callback) {
})
}
// TODO(zcbenz): Remove the stub in 4.0.
WebContents.prototype.setSize = function () {
console.error('The WebContents.setSize method has been removed, see',
'https://github.com/electron/electron/issues/14120 for more.')
}
// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
// The navigation controller.

View File

@@ -26,6 +26,7 @@ const supportedWebViewEvents = [
'did-navigate',
'did-frame-navigate',
'did-navigate-in-page',
'focus-change',
'close',
'crashed',
'gpu-crashed',
@@ -69,6 +70,19 @@ const createGuest = function (embedder, params) {
}
// Clear the guest from map when it is destroyed.
//
// The guest WebContents is usually destroyed in 2 cases:
// 1. The embedder frame is closed (reloaded or destroyed), and it
// automatically closes the guest frame.
// 2. The guest frame is detached dynamically via JS, and it is manually
// destroyed when the renderer sends the GUEST_VIEW_MANAGER_DESTROY_GUEST
// message.
// The second case relies on the libcc patch:
// https://github.com/electron/libchromiumcontent/pull/676
// The patch was introduced to work around a bug in Chromium:
// https://github.com/electron/electron/issues/14211
// We should revisit the bug to see if we can remove our libcc patch, the
// patch was introduced in Chrome 66.
guest.once('destroyed', () => {
if (guestInstanceId in guestInstances) {
detachGuest(embedder, guestInstanceId)
@@ -318,10 +332,21 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, par
event.returnValue = createGuest(event.sender, params)
})
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) {
const guest = getGuest(guestInstanceId)
if (guest) {
guest.destroy()
}
})
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) {
attachGuest(event, embedderFrameId, elementInstanceId, guestInstanceId, params)
})
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
event.sender.emit('focus-change', {}, focus, guestInstanceId)
})
// Returns WebContents from its guest id.
const getGuest = function (guestInstanceId) {
const guestInstance = guestInstances[guestInstanceId]

View File

@@ -27,11 +27,11 @@ const mergeOptions = function (child, parent, visited) {
for (const key in parent) {
if (key === 'isBrowserView') continue
if (!hasProp.call(parent, key)) continue
if (key in child) continue
if (key in child && key !== 'webPreferences') continue
const value = parent[key]
if (typeof value === 'object') {
child[key] = mergeOptions({}, value, visited)
child[key] = mergeOptions(child[key] || {}, value, visited)
} else {
child[key] = value
}

View File

@@ -2,6 +2,10 @@
const v8Util = process.atomBinding('v8_util')
const getOwnerKey = (webContents, contextId) => {
return `${webContents.id}-${contextId}`
}
class ObjectsRegistry {
constructor () {
this.nextId = 0
@@ -11,7 +15,7 @@ class ObjectsRegistry {
this.storage = {}
// Stores the IDs of objects referenced by WebContents.
// (webContentsContextId) => [id]
// (ownerKey) => [id]
this.owners = {}
}
@@ -22,10 +26,10 @@ class ObjectsRegistry {
const id = this.saveToStorage(obj)
// Add object to the set of referenced objects.
const webContentsContextId = `${webContents.id}-${contextId}`
let owner = this.owners[webContentsContextId]
const ownerKey = getOwnerKey(webContents, contextId)
let owner = this.owners[ownerKey]
if (!owner) {
owner = this.owners[webContentsContextId] = new Set()
owner = this.owners[ownerKey] = new Set()
this.registerDeleteListener(webContents, contextId)
}
if (!owner.has(id)) {
@@ -46,8 +50,8 @@ class ObjectsRegistry {
// Note that an object may be double-freed (cleared when page is reloaded, and
// then garbage collected in old page).
remove (webContents, contextId, id) {
const webContentsContextId = `${webContents.id}-${contextId}`
let owner = this.owners[webContentsContextId]
const ownerKey = getOwnerKey(webContents, contextId)
let owner = this.owners[ownerKey]
if (owner) {
// Remove the reference in owner.
owner.delete(id)
@@ -58,13 +62,13 @@ class ObjectsRegistry {
// Clear all references to objects refrenced by the WebContents.
clear (webContents, contextId) {
const webContentsContextId = `${webContents.id}-${contextId}`
let owner = this.owners[webContentsContextId]
const ownerKey = getOwnerKey(webContents, contextId)
let owner = this.owners[ownerKey]
if (!owner) return
for (let id of owner) this.dereference(id)
delete this.owners[webContentsContextId]
delete this.owners[ownerKey]
}
// Private: Saves the object into storage and assigns an ID for it.
@@ -83,8 +87,6 @@ class ObjectsRegistry {
// Private: Dereference the object from store.
dereference (id) {
if (process.env.ELECTRON_DISABLE_REMOTE_DEREFERENCING) return
let pointer = this.storage[id]
if (pointer == null) {
return
@@ -96,11 +98,13 @@ class ObjectsRegistry {
}
}
// Private: Clear the storage when renderer process is destoryed.
// Private: Clear the storage when renderer process is destroyed.
registerDeleteListener (webContents, contextId) {
const processId = webContents.getProcessId()
const listener = (event, deletedProcessId) => {
if (deletedProcessId === processId) {
// contextId => ${processHostId}-${contextCount}
const processHostId = contextId.split('-')[0]
const listener = (event, deletedProcessHostId) => {
if (deletedProcessHostId &&
deletedProcessHostId.toString() === processHostId) {
webContents.removeListener('render-view-deleted', listener)
this.clear(webContents, contextId)
}

View File

@@ -19,13 +19,15 @@ const getExtensionMetadata = (extensionId) => {
const getMessagesPath = (extensionId, language) => {
const metadata = getExtensionMetadata(extensionId)
const defaultLocale = metadata.default_locale || 'en'
const localesDirectory = path.join(metadata.srcDirectory, '_locales')
let messagesPath = path.join(localesDirectory, language, 'messages.json')
if (!fs.statSyncNoException(messagesPath)) {
messagesPath = path.join(localesDirectory, defaultLocale, 'messages.json')
try {
const filename = path.join(localesDirectory, language, 'messages.json')
fs.accessSync(filename, fs.constants.R_OK)
return filename
} catch (err) {
const defaultLocale = metadata.default_locale || 'en'
return path.join(localesDirectory, defaultLocale, 'messages.json')
}
return messagesPath
}
const getMessages = (extensionId, language) => {

View File

@@ -25,6 +25,7 @@ var v8Util = process.atomBinding('v8_util')
v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter())
// Use electron module after everything is ready.
const {ipcRenderer} = require('electron')
const {
warnAboutNodeWithRemoteContent,
@@ -184,3 +185,15 @@ window.addEventListener('load', function loadHandler () {
window.removeEventListener('load', loadHandler)
})
// Report focus/blur events of webview to browser.
// Note that while Chromium content APIs have observer for focus/blur, they
// unfortunately do not work for webview.
if (process.guestInstanceId) {
window.addEventListener('focus', () => {
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', true, process.guestInstanceId)
})
window.addEventListener('blur', () => {
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', false, process.guestInstanceId)
})
}

View File

@@ -24,6 +24,7 @@ const WEB_VIEW_EVENTS = {
'did-navigate': ['url', 'httpResponseCode', 'httpStatusText'],
'did-frame-navigate': ['url', 'httpResponseCode', 'httpStatusText', 'isMainFrame', 'frameProcessId', 'frameRoutingId'],
'did-navigate-in-page': ['url', 'isMainFrame', 'frameProcessId', 'frameRoutingId'],
'focus-change': ['focus', 'guestInstanceId'],
'close': [],
'crashed': [],
'gpu-crashed': [],
@@ -55,6 +56,8 @@ const dispatchEvent = function (webView, eventName, eventKey, ...args) {
webView.dispatchEvent(domEvent)
if (eventName === 'load-commit') {
webView.onLoadCommit(domEvent)
} else if (eventName === 'focus-change') {
webView.onFocusChange(domEvent)
}
}
@@ -91,6 +94,9 @@ module.exports = {
createGuestSync: function (params) {
return ipcRenderer.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params)
},
destroyGuest: function (guestInstanceId) {
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId)
},
attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) {
const embedderFrameId = webFrame.getWebFrameId(contentWindow)
if (embedderFrameId < 0) { // this error should not happen.

View File

@@ -16,6 +16,13 @@ const getNextId = function () {
return ++nextId
}
// A list of removed attributes from 3.0.
const removedAttributes = [
'autoresize',
'disableguestresize',
'guestinstance'
]
// Represents the internal state of the WebView node.
class WebViewImpl {
constructor (webviewNode) {
@@ -23,22 +30,38 @@ class WebViewImpl {
v8Util.setHiddenValue(this.webviewNode, 'internal', this)
this.elementAttached = false
this.beforeFirstNavigation = true
this.hasFocus = false
// Check for removed attributes.
for (const attributeName of removedAttributes) {
if (this.webviewNode.hasAttribute(attributeName)) {
this.reportRemovedAttribute(attributeName)
}
}
// on* Event handlers.
this.on = {}
// Create internal iframe element.
this.internalElement = this.createInternalElement()
const shadowRoot = this.webviewNode.attachShadow({mode: 'open'})
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>'
this.setupWebViewAttributes()
this.setupFocusPropagation()
this.viewInstanceId = getNextId()
shadowRoot.appendChild(this.internalElement)
// Provide access to contentWindow.
Object.defineProperty(this.webviewNode, 'contentWindow', {
get: () => {
return this.internalElement.contentWindow
},
enumerable: true
})
}
createInternalElement () {
const iframeElement = document.createElement('iframe')
iframeElement.style.width = '100%'
iframeElement.style.height = '100%'
iframeElement.style.flex = '1 1 auto'
iframeElement.style.border = '0'
v8Util.setHiddenValue(iframeElement, 'internal', this)
return iframeElement
@@ -53,6 +76,7 @@ class WebViewImpl {
// heard back from createGuest yet. We will not reset the flag in this case so
// that we don't end up allocating a second guest.
if (this.guestInstanceId) {
guestViewInternal.destroyGuest(this.guestInstanceId)
this.guestInstanceId = void 0
}
@@ -76,32 +100,17 @@ class WebViewImpl {
})
}
setupFocusPropagation () {
if (!this.webviewNode.hasAttribute('tabIndex')) {
// <webview> needs a tabIndex in order to be focusable.
// TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
// to allow <webview> to be focusable.
// See http://crbug.com/231664.
this.webviewNode.setAttribute('tabIndex', -1)
}
// Focus the BrowserPlugin when the <webview> takes focus.
this.webviewNode.addEventListener('focus', () => {
this.internalElement.focus()
})
// Blur the BrowserPlugin when the <webview> loses focus.
this.webviewNode.addEventListener('blur', () => {
this.internalElement.blur()
})
}
// This observer monitors mutations to attributes of the <webview> and
// updates the BrowserPlugin properties accordingly. In turn, updating
// a BrowserPlugin property will update the corresponding BrowserPlugin
// attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
// details.
handleWebviewAttributeMutation (attributeName, oldValue, newValue) {
if (removedAttributes.includes(attributeName)) {
this.reportRemovedAttribute(attributeName)
return
}
if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) {
return
}
@@ -165,6 +174,15 @@ class WebViewImpl {
}
}
// Emits focus/blur events.
onFocusChange () {
const hasFocus = document.activeElement === this.webviewNode
if (hasFocus !== this.hasFocus) {
this.hasFocus = hasFocus
this.dispatchEvent(new Event(hasFocus ? 'focus' : 'blur'))
}
}
onAttach (storagePartitionId) {
return this.attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue(storagePartitionId)
}
@@ -197,6 +215,12 @@ class WebViewImpl {
// even documented.
this.resizeObserver = new ResizeObserver(this.onElementResize.bind(this)).observe(this.internalElement)
}
// TODO(zcbenz): Remove the warning in 4.0.
reportRemovedAttribute (attributeName) {
console.error(`The "${attributeName}" attribute has been removed from the <webview> tag,`,
'see https://github.com/electron/electron/issues/14120 for more.')
}
}
// Registers <webview> custom element.
@@ -343,6 +367,11 @@ const registerWebViewElement = function () {
return internal.webContents
}
// Focusing the webview should move page focus to the underlying iframe.
proto.focus = function () {
this.contentWindow.focus()
}
window.WebView = webFrame.registerEmbedderCustomElement('webview', {
prototype: proto
})

View File

@@ -1,48 +1,17 @@
Object.defineProperties(exports, {
ipcRenderer: {
enumerable: true,
get: function () {
return require('../ipc-renderer')
}
},
remote: {
enumerable: true,
get: function () {
return require('../../../renderer/api/remote')
}
},
webFrame: {
enumerable: true,
get: function () {
return require('../../../renderer/api/web-frame')
}
},
crashReporter: {
enumerable: true,
get: function () {
return require('../../../common/api/crash-reporter')
}
},
CallbacksRegistry: {
get: function () {
return require('../../../common/api/callbacks-registry')
}
},
isPromise: {
get: function () {
return require('../../../common/api/is-promise')
}
},
// XXX(alexeykuzmin): It won't be available if the Desktop Capturer
// was disabled during build time.
desktopCapturer: {
get: function () {
return require('../../../renderer/api/desktop-capturer')
}
},
nativeImage: {
get: function () {
return require('../../../common/api/native-image')
}
const moduleList = require('../module-list')
for (const {
name,
load,
enabled = true,
private: isPrivate = false
} of moduleList) {
if (!enabled) {
continue
}
})
Object.defineProperty(exports, name, {
enumerable: !isPrivate,
get: load
})
}

View File

@@ -0,0 +1,39 @@
const features = process.atomBinding('features')
module.exports = [
{
name: 'CallbacksRegistry',
load: () => require('../../common/api/callbacks-registry'),
private: true
},
{
name: 'crashReporter',
load: () => require('../../common/api/crash-reporter')
},
{
name: 'desktopCapturer',
load: () => require('../../renderer/api/desktop-capturer'),
enabled: features.isDesktopCapturerEnabled()
},
{
name: 'ipcRenderer',
load: () => require('./ipc-renderer')
},
{
name: 'isPromise',
load: () => require('../../common/api/is-promise'),
private: true
},
{
name: 'nativeImage',
load: () => require('../../common/api/native-image')
},
{
name: 'remote',
load: () => require('../../renderer/api/remote')
},
{
name: 'webFrame',
load: () => require('../../renderer/api/web-frame')
}
]

View File

@@ -1,10 +1,12 @@
/* eslint no-eval: "off" */
/* global binding, Buffer */
const events = require('events')
const electron = require('electron')
process.atomBinding = require('../common/atom-binding-setup')(binding.get, 'renderer')
// The electron module depends on process.atomBinding
const electron = require('electron')
const v8Util = process.atomBinding('v8_util')
// Expose browserify Buffer as a hidden value. This is used by C++ code to
// deserialize Buffer instances sent from browser process.

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "3.0.0-nightly.20180818",
"version": "3.0.0-beta.10",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

Some files were not shown because too many files have changed in this diff Show More