mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
134 Commits
fix-codesp
...
v5.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc7d2378df | ||
|
|
e31d3b52ee | ||
|
|
277373a95a | ||
|
|
d9e9bf9b87 | ||
|
|
3396d08a3b | ||
|
|
c76872f3f9 | ||
|
|
c7175b295a | ||
|
|
2ff3a15326 | ||
|
|
a6806e9e1c | ||
|
|
200051ccc0 | ||
|
|
36726bd70f | ||
|
|
9755288527 | ||
|
|
39e380bb66 | ||
|
|
4bdf7674f9 | ||
|
|
cfe8c3efd8 | ||
|
|
46b420158c | ||
|
|
9010ee340c | ||
|
|
f1de4896d4 | ||
|
|
9bbd1074ea | ||
|
|
bb3c08f306 | ||
|
|
203c4a72b5 | ||
|
|
cf504fc1bf | ||
|
|
38c3e61a78 | ||
|
|
337e82a4c0 | ||
|
|
a482d4e288 | ||
|
|
c1cdc38e33 | ||
|
|
38865f46d2 | ||
|
|
e290438a6d | ||
|
|
355d395b00 | ||
|
|
9a5b041f74 | ||
|
|
5395810c45 | ||
|
|
a91054883f | ||
|
|
0459dc7d6f | ||
|
|
28c7b5f0ab | ||
|
|
b7018da0c1 | ||
|
|
bdd272192c | ||
|
|
d9faf76cb5 | ||
|
|
52db4693e8 | ||
|
|
b362a59173 | ||
|
|
e8e4b19348 | ||
|
|
e674061bab | ||
|
|
77b3d218a4 | ||
|
|
364dac53d4 | ||
|
|
29b9281af4 | ||
|
|
4d2815e56b | ||
|
|
302372f4b4 | ||
|
|
bbd72e5658 | ||
|
|
3db0a8ef73 | ||
|
|
1a2df2f309 | ||
|
|
d5c37c301a | ||
|
|
eabc5166ac | ||
|
|
88a5abca4b | ||
|
|
f6b6f9524e | ||
|
|
645b98d81a | ||
|
|
c605d1a044 | ||
|
|
df1d39d6ec | ||
|
|
5f08a4f8be | ||
|
|
cc9c84cad4 | ||
|
|
25e6eb9d04 | ||
|
|
b4bd96b2ca | ||
|
|
4ba51dbad8 | ||
|
|
5a8af35927 | ||
|
|
a4babe6699 | ||
|
|
c1ea592457 | ||
|
|
225264f06b | ||
|
|
30cc82d265 | ||
|
|
14c39620f0 | ||
|
|
b395a66246 | ||
|
|
04158b15bb | ||
|
|
8b5f26a9f0 | ||
|
|
c65e9079cc | ||
|
|
91a67e4867 | ||
|
|
4079787378 | ||
|
|
0dc9e32039 | ||
|
|
28c7b346db | ||
|
|
c4f993add1 | ||
|
|
bb21822c10 | ||
|
|
124bb2910f | ||
|
|
0f54df5867 | ||
|
|
2bd1a7ec1e | ||
|
|
ee97b0864a | ||
|
|
96e0dfcae9 | ||
|
|
379a7b707b | ||
|
|
3963ee6d1d | ||
|
|
64cd5bf3a5 | ||
|
|
05074bae0c | ||
|
|
174a39be8f | ||
|
|
918e3ce0b6 | ||
|
|
9c0eca1d8b | ||
|
|
26e0a7d922 | ||
|
|
a498e0c033 | ||
|
|
0f66918825 | ||
|
|
050b866b6a | ||
|
|
8115a899df | ||
|
|
3dcb7cfef9 | ||
|
|
502f24e50d | ||
|
|
6ebef9d876 | ||
|
|
60af6c2791 | ||
|
|
6d76da55e2 | ||
|
|
b31057ca16 | ||
|
|
16dfa56c77 | ||
|
|
a7ed504575 | ||
|
|
dc4c32972d | ||
|
|
d1d0efbd07 | ||
|
|
afa684ad45 | ||
|
|
f66d21e426 | ||
|
|
9a68ce87eb | ||
|
|
ecb737760c | ||
|
|
5d32cd0269 | ||
|
|
499efd5ee7 | ||
|
|
c4115ed783 | ||
|
|
969a97b54f | ||
|
|
5be0851434 | ||
|
|
233d346d5a | ||
|
|
a879981dfb | ||
|
|
3d90bd4e8e | ||
|
|
ba1dd09be2 | ||
|
|
80aa832ebd | ||
|
|
a950e1d040 | ||
|
|
4d7ddcd750 | ||
|
|
d6612d230b | ||
|
|
1d9abfdb10 | ||
|
|
871ba507a6 | ||
|
|
5d64df141b | ||
|
|
ae846204cb | ||
|
|
6dcf5c5c79 | ||
|
|
e55a9b35b6 | ||
|
|
ae85864959 | ||
|
|
5cc0539919 | ||
|
|
b070774f5c | ||
|
|
7a8548d48f | ||
|
|
ac172abda7 | ||
|
|
29e5195c63 | ||
|
|
3926d9d717 |
File diff suppressed because it is too large
Load Diff
32
BUILD.gn
32
BUILD.gn
@@ -2,7 +2,6 @@ import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//services/service_manager/public/service_manifest.gni")
|
||||
import("//third_party/ffmpeg/ffmpeg_options.gni")
|
||||
import("//tools/generate_library_loader/generate_library_loader.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
@@ -187,7 +186,6 @@ grit("resources") {
|
||||
|
||||
deps = [
|
||||
":copy_shell_devtools_discovery_page",
|
||||
":electron_content_manifest_overlays",
|
||||
]
|
||||
|
||||
output_dir = "$target_gen_dir"
|
||||
@@ -236,6 +234,7 @@ static_library("electron_lib") {
|
||||
":atom_js2c",
|
||||
"buildflags",
|
||||
"chromium_src:chrome",
|
||||
"manifests",
|
||||
"native_mate",
|
||||
"//base",
|
||||
"//base:base_static",
|
||||
@@ -261,8 +260,10 @@ static_library("electron_lib") {
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/shared_impl",
|
||||
"//services/audio/public/mojom:constants",
|
||||
"//services/device/public/mojom",
|
||||
"//services/proxy_resolver:lib",
|
||||
"//services/video_capture/public/mojom:constants",
|
||||
"//services/viz/privileged/interfaces/compositing",
|
||||
"//skia",
|
||||
"//third_party/blink/public:blink",
|
||||
@@ -618,8 +619,10 @@ if (is_mac) {
|
||||
output_name = electron_helper_name
|
||||
deps = [
|
||||
":electron_framework+link",
|
||||
"//sandbox/mac:seatbelt",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//sandbox/mac:seatbelt" ]
|
||||
}
|
||||
defines = [ "HELPER_EXECUTABLE" ]
|
||||
sources = filenames.app_sources
|
||||
include_dirs = [ "." ]
|
||||
@@ -954,26 +957,3 @@ group("electron") {
|
||||
":electron_app",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron_content_manifest_overlays") {
|
||||
deps = [
|
||||
":electron_content_browser_manifest_overlay",
|
||||
":electron_content_packaged_services_manifest_overlay",
|
||||
]
|
||||
}
|
||||
|
||||
service_manifest("electron_content_packaged_services_manifest_overlay") {
|
||||
source = "//electron/manifests/electron_content_packaged_services_manifest_overlay.json"
|
||||
packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ]
|
||||
|
||||
if (enable_basic_printing) {
|
||||
packaged_services += [
|
||||
"//chrome/services/printing:manifest",
|
||||
"//components/services/pdf_compositor:pdf_compositor_manifest",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
service_manifest("electron_content_browser_manifest_overlay") {
|
||||
source = "//electron/manifests/electron_content_browser_manifest_overlay.json"
|
||||
}
|
||||
|
||||
4
DEPS
4
DEPS
@@ -10,9 +10,9 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'72.0.3626.52',
|
||||
'73.0.3683.27',
|
||||
'node_version':
|
||||
'ad2c89ec3be0f5db3ea02b0f591d36a5d84c51ad',
|
||||
'fac6d766c143db8db05bb3b0c0871df8f032363c',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
|
||||
@@ -1 +1 @@
|
||||
5.0.0-nightly.20190122
|
||||
5.0.0-beta.3
|
||||
@@ -81,8 +81,6 @@ test_script:
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- ps: >-
|
||||
if ($env:RUN_TESTS -eq 'true') {
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
@@ -91,8 +89,12 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
|
||||
@@ -7,17 +7,14 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/chrome_version.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
@@ -180,16 +177,6 @@ AtomContentClient::AtomContentClient() {}
|
||||
|
||||
AtomContentClient::~AtomContentClient() {}
|
||||
|
||||
std::string AtomContentClient::GetProduct() const {
|
||||
return "Chrome/" CHROME_VERSION_STRING;
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||
" " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
@@ -213,18 +200,30 @@ base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
std::vector<std::string> splited;
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
switches::kServiceWorkerSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->service_worker_schemes.push_back(scheme);
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kStandardSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->standard_schemes.push_back(scheme);
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->secure_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kBypassCSPSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->csp_bypassing_schemes.push_back(scheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kCORSSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->cors_enabled_schemes.push_back(scheme);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
|
||||
@@ -20,8 +20,6 @@ class AtomContentClient : public content::ContentClient {
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
base::StringPiece GetDataResource(int resource_id,
|
||||
ui::ScaleFactor) const override;
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
#if defined(HELPER_EXECUTABLE)
|
||||
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
#include "sandbox/mac/seatbelt_exec.h" // nogncheck
|
||||
#endif // defined(HELPER_EXECUTABLE)
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -213,7 +213,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HELPER_EXECUTABLE)
|
||||
#if defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
uint32_t exec_path_size = 0;
|
||||
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
|
||||
if (rv != -1) {
|
||||
@@ -240,7 +240,7 @@ int main(int argc, char* argv[]) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // defined(HELPER_EXECUTABLE) && !defined(MAS_BUILD)
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
@@ -164,6 +164,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
if (env->HasVar("ELECTRON_ENABLE_STACK_DUMPING"))
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
|
||||
if (env->HasVar("ELECTRON_DISABLE_SANDBOX"))
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
44
atom/app/manifests.cc
Normal file
44
atom/app/manifests.cc
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/manifests.h"
|
||||
|
||||
#include "base/no_destructor.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "services/proxy_resolver/proxy_resolver_manifest.h"
|
||||
#include "services/service_manager/public/cpp/manifest_builder.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
#include "components/services/pdf_compositor/pdf_compositor_manifest.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
#include "chrome/services/printing/manifest.h"
|
||||
#endif
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest() {
|
||||
static base::NoDestructor<service_manager::Manifest> manifest{
|
||||
service_manager::ManifestBuilder()
|
||||
.WithDisplayName("Electron (browser process)")
|
||||
.RequireCapability("device", "device:geolocation_control")
|
||||
.RequireCapability("proxy_resolver", "factory")
|
||||
.RequireCapability("chrome_printing", "converter")
|
||||
.RequireCapability("pdf_compositor", "compositor")
|
||||
.Build()};
|
||||
return *manifest;
|
||||
}
|
||||
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronPackagedServicesOverlayManifest() {
|
||||
static base::NoDestructor<std::vector<service_manager::Manifest>> manifests{{
|
||||
proxy_resolver::GetManifest(),
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
pdf_compositor::GetManifest(),
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
chrome_printing::GetManifest(),
|
||||
#endif
|
||||
}};
|
||||
return *manifests;
|
||||
}
|
||||
16
atom/app/manifests.h
Normal file
16
atom/app/manifests.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_MANIFESTS_H_
|
||||
#define ATOM_APP_MANIFESTS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "services/service_manager/public/cpp/manifest.h"
|
||||
|
||||
const service_manager::Manifest& GetElectronContentBrowserOverlayManifest();
|
||||
const std::vector<service_manager::Manifest>&
|
||||
GetElectronPackagedServicesOverlayManifest();
|
||||
|
||||
#endif // ATOM_APP_MANIFESTS_H_
|
||||
@@ -690,7 +690,7 @@ bool App::CanCreateWindow(
|
||||
content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
|
||||
@@ -141,7 +141,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
bool CanCreateWindow(content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "gin/converter.h"
|
||||
@@ -130,7 +131,7 @@ void BrowserWindow::RenderViewCreated(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->SetBackgroundOpaque(false);
|
||||
impl->owner_delegate()->SetBackgroundOpaque(false);
|
||||
}
|
||||
|
||||
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
|
||||
@@ -349,7 +350,8 @@ void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
|
||||
impl->owner_delegate()->SetBackgroundOpaque(
|
||||
type.empty() ? !window_->transparent() : false);
|
||||
}
|
||||
|
||||
TopLevelWindow::SetVibrancy(isolate, value);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
@@ -65,23 +66,53 @@ scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
result_file_path, base::Bind(callback, result_file_path));
|
||||
}
|
||||
|
||||
void StopRecording(const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
void OnRecordingStopped(scoped_refptr<atom::util::Promise> promise,
|
||||
const base::FilePath& path) {
|
||||
promise->Resolve(path);
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> StopRecording(v8::Isolate* isolate,
|
||||
const base::FilePath& path) {
|
||||
scoped_refptr<atom::util::Promise> promise = new atom::util::Promise(isolate);
|
||||
|
||||
TracingController::GetInstance()->StopTracing(
|
||||
GetTraceDataEndpoint(path, callback));
|
||||
GetTraceDataEndpoint(path, base::Bind(&OnRecordingStopped, promise)));
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
bool GetCategories(
|
||||
const base::RepeatingCallback<void(const std::set<std::string>&)>&
|
||||
callback) {
|
||||
return TracingController::GetInstance()->GetCategories(
|
||||
base::BindOnce(callback));
|
||||
void OnCategoriesAvailable(scoped_refptr<atom::util::Promise> promise,
|
||||
const std::set<std::string>& categories) {
|
||||
promise->Resolve(categories);
|
||||
}
|
||||
|
||||
bool StartTracing(const base::trace_event::TraceConfig& trace_config,
|
||||
const base::RepeatingCallback<void()>& callback) {
|
||||
return TracingController::GetInstance()->StartTracing(
|
||||
trace_config, base::BindOnce(callback));
|
||||
v8::Local<v8::Promise> GetCategories(v8::Isolate* isolate) {
|
||||
scoped_refptr<atom::util::Promise> promise = new atom::util::Promise(isolate);
|
||||
bool success = TracingController::GetInstance()->GetCategories(
|
||||
base::BindOnce(&OnCategoriesAvailable, promise));
|
||||
|
||||
if (!success)
|
||||
promise->RejectWithErrorMessage("Could not get categories.");
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void OnTracingStarted(scoped_refptr<atom::util::Promise> promise) {
|
||||
promise->Resolve();
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> StartTracing(
|
||||
v8::Isolate* isolate,
|
||||
const base::trace_event::TraceConfig& trace_config) {
|
||||
scoped_refptr<atom::util::Promise> promise = new atom::util::Promise(isolate);
|
||||
|
||||
bool success = TracingController::GetInstance()->StartTracing(
|
||||
trace_config, base::BindOnce(&OnTracingStarted, promise));
|
||||
|
||||
if (!success)
|
||||
promise->RejectWithErrorMessage("Could not start tracing");
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
bool GetTraceBufferUsage(
|
||||
|
||||
@@ -136,6 +136,21 @@ inline net::CookieStore* GetCookieStore(
|
||||
return getter->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
void ResolvePromiseWithCookies(scoped_refptr<util::Promise> promise,
|
||||
net::CookieList cookieList) {
|
||||
promise->Resolve(cookieList);
|
||||
}
|
||||
|
||||
void ResolvePromise(scoped_refptr<util::Promise> promise) {
|
||||
promise->Resolve();
|
||||
}
|
||||
|
||||
// Resolve |promise| in UI thread.
|
||||
void ResolvePromiseInUI(scoped_refptr<util::Promise> promise) {
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(ResolvePromise, std::move(promise)));
|
||||
}
|
||||
|
||||
// Run |callback| on UI thread.
|
||||
void RunCallbackInUI(const base::Closure& callback) {
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, callback);
|
||||
@@ -143,25 +158,28 @@ void RunCallbackInUI(const base::Closure& callback) {
|
||||
|
||||
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
|
||||
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback,
|
||||
scoped_refptr<util::Promise> promise,
|
||||
const net::CookieList& list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
|
||||
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(ResolvePromiseWithCookies, std::move(promise), result));
|
||||
}
|
||||
|
||||
// Receives cookies matching |filter| in IO thread.
|
||||
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback) {
|
||||
scoped_refptr<util::Promise> promise) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
|
||||
auto filtered_callback =
|
||||
base::Bind(FilterCookies, base::Passed(&filter), callback);
|
||||
base::Bind(FilterCookies, base::Passed(&filter), std::move(promise));
|
||||
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
@@ -172,31 +190,42 @@ void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
void RemoveCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
scoped_refptr<util::Promise> promise) {
|
||||
GetCookieStore(getter)->DeleteCookieAsync(
|
||||
url, name, base::BindOnce(RunCallbackInUI, callback));
|
||||
url, name, base::BindOnce(ResolvePromiseInUI, promise));
|
||||
}
|
||||
|
||||
// Resolves/rejects the |promise| in UI thread.
|
||||
void SettlePromiseInUI(scoped_refptr<util::Promise> promise,
|
||||
const std::string& errmsg) {
|
||||
if (errmsg.empty()) {
|
||||
promise->Resolve();
|
||||
} else {
|
||||
promise->RejectWithErrorMessage(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback of SetCookie.
|
||||
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
||||
RunCallbackInUI(
|
||||
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
|
||||
void OnSetCookie(scoped_refptr<util::Promise> promise, bool success) {
|
||||
const std::string errmsg = success ? "" : "Setting cookie failed";
|
||||
RunCallbackInUI(base::Bind(SettlePromiseInUI, std::move(promise), errmsg));
|
||||
}
|
||||
|
||||
// Flushes cookie store in IO thread.
|
||||
void FlushCookieStoreOnIOThread(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->FlushStore(base::BindOnce(RunCallbackInUI, callback));
|
||||
scoped_refptr<util::Promise> promise) {
|
||||
GetCookieStore(getter)->FlushStore(
|
||||
base::BindOnce(ResolvePromiseInUI, promise));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
const Cookies::SetCallback& callback) {
|
||||
scoped_refptr<util::Promise> promise) {
|
||||
std::string url, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
@@ -237,7 +266,7 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
GURL(url), name, value, domain, path, creation_time, expiration_time,
|
||||
last_access_time, secure, http_only,
|
||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, callback);
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
|
||||
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
@@ -267,43 +296,56 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
|
||||
Cookies::~Cookies() {}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
const GetCallback& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Get(const base::DictionaryValue& filter) {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate());
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(filter.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
promise));
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void Cookies::Remove(const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Remove(const GURL& url,
|
||||
const std::string& name) {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate());
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
|
||||
name, callback));
|
||||
base::BindOnce(RemoveCookieOnIO, base::RetainedRef(getter), url, name,
|
||||
promise));
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& details,
|
||||
const SetCallback& callback) {
|
||||
v8::Local<v8::Promise> Cookies::Set(const base::DictionaryValue& details) {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate());
|
||||
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(details.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
promise));
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void Cookies::FlushStore(const base::Closure& callback) {
|
||||
v8::Local<v8::Promise> Cookies::FlushStore() {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate());
|
||||
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
|
||||
base::BindOnce(FlushCookieStoreOnIOThread,
|
||||
base::RetainedRef(getter), callback));
|
||||
base::RetainedRef(getter), promise));
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
@@ -35,9 +36,6 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
FAILED,
|
||||
};
|
||||
|
||||
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
|
||||
using SetCallback = base::Callback<void(Error)>;
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
@@ -49,12 +47,10 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Cookies() override;
|
||||
|
||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||
void Remove(const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback);
|
||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||
void FlushStore(const base::Closure& callback);
|
||||
v8::Local<v8::Promise> Get(const base::DictionaryValue& filter);
|
||||
v8::Local<v8::Promise> Set(const base::DictionaryValue& details);
|
||||
v8::Local<v8::Promise> Remove(const GURL& url, const std::string& name);
|
||||
v8::Local<v8::Promise> FlushStore();
|
||||
|
||||
// CookieChangeNotifier subscription:
|
||||
void OnCookieChanged(const CookieDetails*);
|
||||
|
||||
@@ -61,23 +61,26 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params);
|
||||
} else {
|
||||
auto send_command_callback = pending_requests_[id];
|
||||
pending_requests_.erase(id);
|
||||
if (send_command_callback.is_null())
|
||||
auto it = pending_requests_.find(id);
|
||||
if (it == pending_requests_.end())
|
||||
return;
|
||||
base::DictionaryValue* error_body = nullptr;
|
||||
base::DictionaryValue error;
|
||||
bool has_error;
|
||||
if ((has_error = dict->GetDictionary("error", &error_body))) {
|
||||
error.Swap(error_body);
|
||||
}
|
||||
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body))
|
||||
result.Swap(result_body);
|
||||
send_command_callback.Run(has_error ? error.Clone() : base::Value(),
|
||||
result);
|
||||
scoped_refptr<atom::util::Promise> promise = it->second;
|
||||
pending_requests_.erase(it);
|
||||
|
||||
base::DictionaryValue* error = nullptr;
|
||||
if (dict->GetDictionary("error", &error)) {
|
||||
std::string message;
|
||||
error->GetString("message", &message);
|
||||
promise->RejectWithErrorMessage(message);
|
||||
} else {
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body)) {
|
||||
result.Swap(result_body);
|
||||
}
|
||||
promise->Resolve(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,23 +128,26 @@ void Debugger::Detach() {
|
||||
AgentHostClosed(agent_host_.get());
|
||||
}
|
||||
|
||||
void Debugger::SendCommand(mate::Arguments* args) {
|
||||
if (!agent_host_)
|
||||
return;
|
||||
v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
|
||||
scoped_refptr<util::Promise> promise = new util::Promise(isolate());
|
||||
|
||||
if (!agent_host_) {
|
||||
promise->RejectWithErrorMessage("No target available");
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
std::string method;
|
||||
if (!args->GetNext(&method)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
promise->RejectWithErrorMessage("Invalid method");
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
SendCommandCallback callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_[request_id] = callback;
|
||||
pending_requests_[request_id] = promise;
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty())
|
||||
@@ -151,16 +157,13 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
|
||||
return promise->GetHandle();
|
||||
}
|
||||
|
||||
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());
|
||||
it.second->RejectWithErrorMessage("target closed while handling command");
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/common/promise_util.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/devtools_agent_host_client.h"
|
||||
@@ -32,9 +33,6 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
public content::DevToolsAgentHostClient,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
using SendCommandCallback =
|
||||
base::Callback<void(const base::Value&, const base::Value&)>;
|
||||
|
||||
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
|
||||
@@ -56,12 +54,12 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
content::RenderFrameHost* new_rfh) override;
|
||||
|
||||
private:
|
||||
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
||||
using PendingRequestMap = std::map<int, scoped_refptr<atom::util::Promise>>;
|
||||
|
||||
void Attach(mate::Arguments* args);
|
||||
bool IsAttached();
|
||||
void Detach();
|
||||
void SendCommand(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> SendCommand(mate::Arguments* args);
|
||||
void ClearPendingRequests();
|
||||
|
||||
content::WebContents* web_contents_; // Weak Reference.
|
||||
|
||||
@@ -103,7 +103,7 @@ bool DownloadItem::IsPaused() const {
|
||||
}
|
||||
|
||||
void DownloadItem::Resume() {
|
||||
download_item_->Resume();
|
||||
download_item_->Resume(true /* user_gesture */);
|
||||
}
|
||||
|
||||
bool DownloadItem::CanResume() const {
|
||||
|
||||
@@ -84,19 +84,19 @@ void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback) {
|
||||
ui::IdleState PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold) {
|
||||
if (idle_threshold > 0) {
|
||||
ui::CalculateIdleState(idle_threshold, callback);
|
||||
return ui::CalculateIdleState(idle_threshold);
|
||||
} else {
|
||||
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
|
||||
isolate, "Invalid idle threshold, must be greater than 0")));
|
||||
return ui::IDLE_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void PowerMonitor::QuerySystemIdleTime(const ui::IdleTimeCallback& callback) {
|
||||
ui::CalculateIdleTime(callback);
|
||||
int PowerMonitor::QuerySystemIdleTime() {
|
||||
return ui::CalculateIdleTime();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -122,8 +122,8 @@ void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
|
||||
#endif
|
||||
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
|
||||
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
|
||||
.SetMethod("_querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
|
||||
.SetMethod("_querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -46,10 +46,8 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
void QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback);
|
||||
void QuerySystemIdleTime(const ui::IdleTimeCallback& callback);
|
||||
ui::IdleState QuerySystemIdleState(v8::Isolate* isolate, int idle_threshold);
|
||||
int QuerySystemIdleTime();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
|
||||
@@ -24,47 +24,119 @@
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// List of registered custom standard schemes.
|
||||
std::vector<std::string> g_standard_schemes;
|
||||
|
||||
struct SchemeOptions {
|
||||
bool standard = false;
|
||||
bool secure = false;
|
||||
bool bypassCSP = false;
|
||||
bool allowServiceWorkers = false;
|
||||
bool supportFetchAPI = false;
|
||||
bool corsEnabled = false;
|
||||
};
|
||||
|
||||
struct CustomScheme {
|
||||
std::string scheme;
|
||||
SchemeOptions options;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<CustomScheme> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
CustomScheme* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("scheme", &(out->scheme)))
|
||||
return false;
|
||||
mate::Dictionary opt;
|
||||
// options are optional. Default values specified in SchemeOptions are used
|
||||
if (dict.Get("privileges", &opt)) {
|
||||
opt.Get("standard", &(out->options.standard));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("secure", &(out->options.secure));
|
||||
opt.Get("bypassCSP", &(out->options.bypassCSP));
|
||||
opt.Get("allowServiceWorkers", &(out->options.allowServiceWorkers));
|
||||
opt.Get("supportFetchAPI", &(out->options.supportFetchAPI));
|
||||
opt.Get("corsEnabled", &(out->options.corsEnabled));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes() {
|
||||
return g_standard_schemes;
|
||||
}
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
g_standard_schemes = schemes;
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
std::vector<CustomScheme> custom_schemes;
|
||||
if (!mate::ConvertFromV8(args->isolate(), val, &custom_schemes)) {
|
||||
args->ThrowError("Argument must be an array of custom schemes.");
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary opts;
|
||||
bool secure = false;
|
||||
args->GetNext(&opts) && opts.Get("secure", &secure);
|
||||
|
||||
// Dynamically register the schemes.
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
for (const std::string& scheme : schemes) {
|
||||
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITH_HOST);
|
||||
if (secure) {
|
||||
url::AddSecureScheme(scheme.c_str());
|
||||
std::vector<std::string> secure_schemes, cspbypassing_schemes, fetch_schemes,
|
||||
service_worker_schemes, cors_schemes;
|
||||
for (const auto& custom_scheme : custom_schemes) {
|
||||
// Register scheme to privileged list (https, wss, data, chrome-extension)
|
||||
if (custom_scheme.options.standard) {
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
url::AddStandardScheme(custom_scheme.scheme.c_str(),
|
||||
url::SCHEME_WITH_HOST);
|
||||
g_standard_schemes.push_back(custom_scheme.scheme);
|
||||
policy->RegisterWebSafeScheme(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.secure) {
|
||||
secure_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddSecureScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.bypassCSP) {
|
||||
cspbypassing_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCSPBypassingScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.corsEnabled) {
|
||||
cors_schemes.push_back(custom_scheme.scheme);
|
||||
url::AddCorsEnabledScheme(custom_scheme.scheme.c_str());
|
||||
}
|
||||
if (custom_scheme.options.supportFetchAPI) {
|
||||
fetch_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
if (custom_scheme.options.allowServiceWorkers) {
|
||||
service_worker_schemes.push_back(custom_scheme.scheme);
|
||||
}
|
||||
policy->RegisterWebSafeScheme(scheme);
|
||||
}
|
||||
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
|
||||
if (secure) {
|
||||
const auto AppendSchemesToCmdLine = [](const char* switch_name,
|
||||
std::vector<std::string> schemes) {
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
|
||||
}
|
||||
switch_name, base::JoinString(schemes, ","));
|
||||
};
|
||||
|
||||
AppendSchemesToCmdLine(atom::switches::kSecureSchemes, secure_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kBypassCSPSchemes,
|
||||
cspbypassing_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kCORSSchemes, cors_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kFetchSchemes, fetch_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kServiceWorkerSchemes,
|
||||
service_worker_schemes);
|
||||
AppendSchemesToCmdLine(atom::switches::kStandardSchemes, g_standard_schemes);
|
||||
}
|
||||
|
||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
@@ -73,12 +145,6 @@ Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
}
|
||||
|
||||
Protocol::~Protocol() {}
|
||||
|
||||
void Protocol::RegisterServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
@@ -195,8 +261,6 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
@@ -228,16 +292,16 @@ void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
if (atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"protocol.registerStandardSchemes should be called before "
|
||||
"protocol.registerSchemesAsPrivileged should be called before "
|
||||
"app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
atom::api::RegisterStandardSchemes(schemes, args);
|
||||
atom::api::RegisterSchemesAsPrivileged(val, args);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
@@ -246,7 +310,7 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
||||
dict.SetMethod("registerSchemesAsPrivileged", &RegisterSchemesAsPrivileged);
|
||||
dict.SetMethod("getStandardSchemes", &atom::api::GetStandardSchemes);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,9 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes();
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args);
|
||||
|
||||
void RegisterSchemesAsPrivileged(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
|
||||
class Protocol : public mate::TrackableObject<Protocol> {
|
||||
public:
|
||||
@@ -94,9 +95,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register schemes that can handle service worker.
|
||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template <typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
|
||||
@@ -659,6 +659,11 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
}
|
||||
}
|
||||
|
||||
void TopLevelWindow::RemoveMenu() {
|
||||
menu_.Reset();
|
||||
window_->SetMenu(nullptr);
|
||||
}
|
||||
|
||||
void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
|
||||
mate::Arguments* args) {
|
||||
if (IsModal()) {
|
||||
@@ -1103,6 +1108,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection)
|
||||
.SetMethod("setFocusable", &TopLevelWindow::SetFocusable)
|
||||
.SetMethod("setMenu", &TopLevelWindow::SetMenu)
|
||||
.SetMethod("removeMenu", &TopLevelWindow::RemoveMenu)
|
||||
.SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow)
|
||||
.SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView)
|
||||
.SetMethod("addBrowserView", &TopLevelWindow::AddBrowserView)
|
||||
|
||||
@@ -165,6 +165,7 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
|
||||
void RemoveMenu();
|
||||
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
|
||||
virtual void SetBrowserView(v8::Local<v8::Value> value);
|
||||
virtual void AddBrowserView(v8::Local<v8::Value> value);
|
||||
|
||||
@@ -725,7 +725,7 @@ void WebContents::FindReply(content::WebContents* web_contents,
|
||||
bool WebContents::CheckMediaAccessPermission(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) {
|
||||
blink::MediaStreamType type) {
|
||||
auto* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(render_frame_host);
|
||||
auto* permission_helper =
|
||||
@@ -1012,8 +1012,7 @@ void WebContents::DevToolsOpened() {
|
||||
|
||||
// Inherit owner window in devtools when it doesn't have one.
|
||||
auto* devtools = managed_web_contents()->GetDevToolsWebContents();
|
||||
bool has_window =
|
||||
devtools->GetUserData(NativeWindowRelay::kNativeWindowRelayUserDataKey);
|
||||
bool has_window = devtools->GetUserData(NativeWindowRelay::UserDataKey());
|
||||
if (owner_window() && !has_window)
|
||||
handle->SetOwnerWindow(devtools, owner_window());
|
||||
|
||||
@@ -1139,7 +1138,7 @@ void WebContents::SetBackgroundThrottling(bool allowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* render_process_host = render_view_host->GetProcess();
|
||||
auto* render_process_host = render_view_host->GetProcess();
|
||||
if (!render_process_host) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool final_update) override;
|
||||
bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) override;
|
||||
blink::MediaStreamType type) override;
|
||||
void RequestMediaAccessPermission(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
|
||||
@@ -31,9 +31,13 @@ class WebContentsViewRelay
|
||||
|
||||
atom::api::WebContentsView* view_ = nullptr;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsViewRelay);
|
||||
};
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsViewRelay)
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -57,7 +57,9 @@ void SavePageHandler::OnDownloadUpdated(download::DownloadItem* item) {
|
||||
callback_.Run(v8::Null(isolate));
|
||||
} else {
|
||||
v8::Local<v8::String> error_message =
|
||||
v8::String::NewFromUtf8(isolate, "Fail to save page");
|
||||
v8::String::NewFromUtf8(isolate, "Fail to save page",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
callback_.Run(v8::Exception::Error(error_message));
|
||||
}
|
||||
Destroy(item);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/manifests.h"
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
@@ -32,6 +33,7 @@
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/common/platform_util.h"
|
||||
#include "base/command_line.h"
|
||||
@@ -47,6 +49,7 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/chrome_version.h"
|
||||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
@@ -82,6 +85,8 @@
|
||||
#include "net/ssl/client_cert_store_win.h"
|
||||
#elif defined(OS_MACOSX)
|
||||
#include "net/ssl/client_cert_store_mac.h"
|
||||
#include "services/audio/public/mojom/constants.mojom.h"
|
||||
#include "services/video_capture/public/mojom/constants.mojom.h"
|
||||
#elif defined(USE_OPENSSL)
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
#endif
|
||||
@@ -114,19 +119,15 @@ namespace {
|
||||
// Next navigation should not restart renderer process.
|
||||
bool g_suppress_renderer_process_restart = false;
|
||||
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
base::NoDestructor<std::string> g_custom_service_worker_schemes;
|
||||
|
||||
bool IsSameWebSite(content::BrowserContext* browser_context,
|
||||
const GURL& src_url,
|
||||
content::SiteInstance* site_instance,
|
||||
const GURL& dest_url) {
|
||||
return content::SiteInstance::IsSameWebSite(browser_context, src_url,
|
||||
dest_url) ||
|
||||
// `IsSameWebSite` doesn't seem to work for some URIs such as `file:`,
|
||||
// handle these scenarios by comparing only the site as defined by
|
||||
// `GetSiteForURL`.
|
||||
content::SiteInstance::GetSiteForURL(browser_context, dest_url) ==
|
||||
src_url;
|
||||
return site_instance->IsSameSiteWithURL(dest_url) ||
|
||||
// `IsSameSiteWithURL` doesn't seem to work for some URIs such as
|
||||
// `file:`, handle these scenarios by comparing only the site as
|
||||
// defined by `GetSiteForURL`.
|
||||
(content::SiteInstance::GetSiteForURL(browser_context, dest_url) ==
|
||||
site_instance->GetSiteURL());
|
||||
}
|
||||
|
||||
AtomBrowserClient* g_browser_client = nullptr;
|
||||
@@ -148,11 +149,6 @@ void AtomBrowserClient::SuppressRendererProcessRestartForOnce() {
|
||||
g_suppress_renderer_process_restart = true;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
*g_custom_service_worker_schemes = base::JoinString(schemes, ",");
|
||||
}
|
||||
|
||||
AtomBrowserClient* AtomBrowserClient::Get() {
|
||||
return g_browser_client;
|
||||
}
|
||||
@@ -230,8 +226,7 @@ bool AtomBrowserClient::ShouldForceNewSiteInstance(
|
||||
}
|
||||
|
||||
// Create new a SiteInstance if navigating to a different site.
|
||||
auto src_url = current_instance->GetSiteURL();
|
||||
return !IsSameWebSite(browser_context, src_url, url);
|
||||
return !IsSameWebSite(browser_context, current_instance, url);
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::NavigationWasRedirectedCrossSite(
|
||||
@@ -242,13 +237,12 @@ bool AtomBrowserClient::NavigationWasRedirectedCrossSite(
|
||||
bool has_response_started) const {
|
||||
bool navigation_was_redirected = false;
|
||||
if (has_response_started) {
|
||||
navigation_was_redirected = !IsSameWebSite(
|
||||
browser_context, current_instance->GetSiteURL(), dest_url);
|
||||
navigation_was_redirected =
|
||||
!IsSameWebSite(browser_context, current_instance, dest_url);
|
||||
} else {
|
||||
navigation_was_redirected =
|
||||
speculative_instance &&
|
||||
!IsSameWebSite(browser_context, speculative_instance->GetSiteURL(),
|
||||
dest_url);
|
||||
!IsSameWebSite(browser_context, speculative_instance, dest_url);
|
||||
}
|
||||
|
||||
return navigation_was_redirected;
|
||||
@@ -312,7 +306,7 @@ content::SiteInstance* AtomBrowserClient::GetSiteInstanceFromAffinity(
|
||||
auto iter = site_per_affinities_.find(affinity);
|
||||
GURL dest_site = content::SiteInstance::GetSiteForURL(browser_context, url);
|
||||
if (iter != site_per_affinities_.end() &&
|
||||
IsSameWebSite(browser_context, iter->second->GetSiteURL(), dest_site)) {
|
||||
IsSameWebSite(browser_context, iter->second, dest_site)) {
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
@@ -477,17 +471,14 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
return;
|
||||
|
||||
// Copy following switches to child process.
|
||||
static const char* const kCommonSwitchNames[] = {switches::kStandardSchemes,
|
||||
switches::kEnableSandbox,
|
||||
switches::kSecureSchemes};
|
||||
static const char* const kCommonSwitchNames[] = {
|
||||
switches::kStandardSchemes, switches::kEnableSandbox,
|
||||
switches::kSecureSchemes, switches::kBypassCSPSchemes,
|
||||
switches::kCORSSchemes, switches::kFetchSchemes,
|
||||
switches::kServiceWorkerSchemes};
|
||||
command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
|
||||
kCommonSwitchNames,
|
||||
arraysize(kCommonSwitchNames));
|
||||
|
||||
// The registered service worker schemes.
|
||||
if (!g_custom_service_worker_schemes->empty())
|
||||
command_line->AppendSwitchASCII(switches::kRegisterServiceWorkerSchemes,
|
||||
*g_custom_service_worker_schemes);
|
||||
base::size(kCommonSwitchNames));
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Append --app-user-model-id.
|
||||
@@ -523,6 +514,16 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
}
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AdjustUtilityServiceProcessCommandLine(
|
||||
const service_manager::Identity& identity,
|
||||
base::CommandLine* command_line) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (identity.name() == video_capture::mojom::kServiceName ||
|
||||
identity.name() == audio::mojom::kServiceName)
|
||||
command_line->AppendSwitch(::switches::kMessageLoopTypeUi);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomBrowserClient::DidCreatePpapiPlugin(content::BrowserPpapiHost* host) {
|
||||
#if BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
host->GetPpapiHost()->AddHostFactoryFilter(
|
||||
@@ -594,7 +595,7 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -713,20 +714,17 @@ void AtomBrowserClient::RegisterOutOfProcessServices(
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> AtomBrowserClient::GetServiceManifestOverlay(
|
||||
base::StringPiece name) {
|
||||
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
||||
int id = -1;
|
||||
if (name == content::mojom::kBrowserServiceName)
|
||||
id = IDR_ELECTRON_CONTENT_BROWSER_MANIFEST_OVERLAY;
|
||||
else if (name == content::mojom::kPackagedServicesServiceName)
|
||||
id = IDR_ELECTRON_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY;
|
||||
base::Optional<service_manager::Manifest>
|
||||
AtomBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
|
||||
if (name == content::mojom::kBrowserServiceName) {
|
||||
return GetElectronContentBrowserOverlayManifest();
|
||||
} else if (name == content::mojom::kPackagedServicesServiceName) {
|
||||
service_manager::Manifest overlay;
|
||||
overlay.packaged_services = GetElectronPackagedServicesOverlayManifest();
|
||||
return overlay;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
return nullptr;
|
||||
|
||||
base::StringPiece manifest_contents = rb.GetRawDataResource(id);
|
||||
return base::JSONReader::Read(manifest_contents);
|
||||
return base::nullopt;
|
||||
}
|
||||
|
||||
net::NetLog* AtomBrowserClient::GetNetLog() {
|
||||
@@ -895,6 +893,14 @@ bool AtomBrowserClient::ShouldBypassCORB(int render_process_id) const {
|
||||
return it != process_preferences_.end() && !it->second.web_security;
|
||||
}
|
||||
|
||||
std::string AtomBrowserClient::GetProduct() const {
|
||||
return "Chrome/" CHROME_VERSION_STRING;
|
||||
}
|
||||
|
||||
std::string AtomBrowserClient::GetUserAgent() const {
|
||||
return GetApplicationUserAgent();
|
||||
}
|
||||
|
||||
std::string AtomBrowserClient::GetApplicationLocale() {
|
||||
if (BrowserThread::CurrentlyOn(BrowserThread::IO))
|
||||
return g_io_thread_application_locale.Get();
|
||||
|
||||
@@ -49,10 +49,6 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
// Don't force renderer process to restart for once.
|
||||
static void SuppressRendererProcessRestartForOnce();
|
||||
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
static void SetCustomServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes);
|
||||
|
||||
NotificationPresenter* GetNotificationPresenter();
|
||||
|
||||
void WebNotificationAllowed(int render_process_id,
|
||||
@@ -89,6 +85,9 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
content::SiteInstance* pending_site_instance) override;
|
||||
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
|
||||
int child_process_id) override;
|
||||
void AdjustUtilityServiceProcessCommandLine(
|
||||
const service_manager::Identity& identity,
|
||||
base::CommandLine* command_line) override;
|
||||
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
|
||||
std::string GetGeolocationApiKey() override;
|
||||
content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
|
||||
@@ -113,7 +112,7 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
bool CanCreateWindow(content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
const url::Origin& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -139,7 +138,7 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path) override;
|
||||
void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
|
||||
std::unique_ptr<base::Value> GetServiceManifestOverlay(
|
||||
base::Optional<service_manager::Manifest> GetServiceManifestOverlay(
|
||||
base::StringPiece name) override;
|
||||
net::NetLog* GetNetLog() override;
|
||||
content::MediaObserver* GetMediaObserver() override;
|
||||
@@ -154,6 +153,8 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
||||
void OnNetworkServiceCreated(
|
||||
network::mojom::NetworkService* network_service) override;
|
||||
bool ShouldBypassCORB(int render_process_id) const override;
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_paths.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/cookie_change_notifier.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "atom/browser/pref_store_delegate.h"
|
||||
@@ -20,17 +19,14 @@
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/browser/zoom_level_delegate.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/chrome_version.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "components/prefs/json_pref_store.h"
|
||||
@@ -41,8 +37,8 @@
|
||||
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
|
||||
#include "components/proxy_config/proxy_config_pref_names.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/user_agent.h"
|
||||
#include "net/base/escape.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
@@ -51,14 +47,6 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
// Convert string to lower case and escape it.
|
||||
std::string MakePartitionName(const std::string& input) {
|
||||
return net::EscapePath(base::ToLowerASCII(input));
|
||||
@@ -78,19 +66,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
storage_policy_(new SpecialStoragePolicy),
|
||||
in_memory_(in_memory),
|
||||
weak_factory_(this) {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||
user_agent_ = GetApplicationUserAgent();
|
||||
|
||||
// Read options.
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
@@ -285,6 +261,11 @@ AtomBrowserContext::GetBrowsingDataRemoverDelegate() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
content::ClientHintsControllerDelegate*
|
||||
AtomBrowserContext::GetClientHintsControllerDelegate() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter*
|
||||
AtomBrowserContext::CreateRequestContextForStoragePartition(
|
||||
const base::FilePath& partition_path,
|
||||
|
||||
@@ -88,6 +88,8 @@ class AtomBrowserContext
|
||||
content::ProtocolHandlerMap* protocol_handlers,
|
||||
content::URLRequestInterceptorScopedVector request_interceptors) override;
|
||||
net::URLRequestContextGetter* CreateMediaRequestContext() override;
|
||||
content::ClientHintsControllerDelegate* GetClientHintsControllerDelegate()
|
||||
override;
|
||||
|
||||
CookieChangeNotifier* cookie_change_notifier() const {
|
||||
return cookie_change_notifier_.get();
|
||||
|
||||
@@ -455,7 +455,7 @@ bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) {
|
||||
|
||||
void AtomBrowserMainParts::PreDefaultMainMessageLoopRun(
|
||||
base::OnceClosure quit_closure) {
|
||||
Browser::SetMainMessageLoopQuitClosure(std::move(quit_closure));
|
||||
Browser::Get()->SetMainMessageLoopQuitClosure(std::move(quit_closure));
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
||||
|
||||
@@ -100,23 +100,58 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
if (relay)
|
||||
window = relay->GetNativeWindow();
|
||||
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
bool offscreen =
|
||||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||
|
||||
// Show save dialog if save path was not set already on item
|
||||
base::FilePath path;
|
||||
GetItemSavePath(item, &path);
|
||||
// Show save dialog if save path was not set already on item
|
||||
file_dialog::DialogSettings settings;
|
||||
GetItemSaveDialogOptions(item, &settings);
|
||||
if (!settings.parent_window)
|
||||
settings.parent_window = window;
|
||||
settings.force_detached = offscreen;
|
||||
if (settings.title.size() == 0)
|
||||
settings.title = item->GetURL().spec();
|
||||
if (!settings.default_path.empty())
|
||||
settings.default_path = default_path;
|
||||
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
|
||||
if (path.empty()) {
|
||||
file_dialog::DialogSettings settings;
|
||||
GetItemSaveDialogOptions(item, &settings);
|
||||
|
||||
if (!settings.parent_window)
|
||||
settings.parent_window = window;
|
||||
if (settings.title.size() == 0)
|
||||
settings.title = item->GetURL().spec();
|
||||
if (!settings.default_path.empty())
|
||||
settings.default_path = default_path;
|
||||
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
const bool offscreen =
|
||||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||
settings.force_detached = offscreen;
|
||||
|
||||
auto dialog_callback =
|
||||
base::Bind(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
|
||||
base::Unretained(this), download_id, callback);
|
||||
file_dialog::ShowSaveDialog(settings, dialog_callback);
|
||||
} else {
|
||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark)
|
||||
#else
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path)
|
||||
#endif
|
||||
{
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
auto* item = download_manager_->GetDownload(download_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (result) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
@@ -133,12 +168,16 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
}
|
||||
|
||||
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
||||
// download should be cancelled.
|
||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
// download should be cancelled. If user cancels the file save dialog, run
|
||||
// the callback with empty FilePath.
|
||||
const base::FilePath download_path = result ? path : base::FilePath();
|
||||
const auto interrupt_reason =
|
||||
download_path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
||||
download_callback.Run(download_path,
|
||||
download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download_path, interrupt_reason);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
|
||||
@@ -25,10 +25,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
|
||||
~AtomDownloadManagerDelegate() override;
|
||||
|
||||
void OnDownloadPathGenerated(uint32_t download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
// content::DownloadManagerDelegate:
|
||||
void Shutdown() override;
|
||||
bool DetermineDownloadTarget(
|
||||
@@ -45,6 +41,25 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
void GetItemSaveDialogOptions(download::DownloadItem* item,
|
||||
file_dialog::DialogSettings* settings);
|
||||
|
||||
void OnDownloadPathGenerated(uint32_t download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark);
|
||||
#else
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path);
|
||||
#endif
|
||||
|
||||
content::DownloadManager* download_manager_;
|
||||
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
||||
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
// Null until/unless the default main message loop is running.
|
||||
base::NoDestructor<base::OnceClosure> g_quit_main_message_loop;
|
||||
|
||||
Browser::LoginItemSettings::LoginItemSettings() = default;
|
||||
Browser::LoginItemSettings::~LoginItemSettings() = default;
|
||||
Browser::LoginItemSettings::LoginItemSettings(const LoginItemSettings& other) =
|
||||
@@ -95,11 +92,12 @@ void Browser::Shutdown() {
|
||||
for (BrowserObserver& observer : observers_)
|
||||
observer.OnQuit();
|
||||
|
||||
if (*g_quit_main_message_loop) {
|
||||
std::move(*g_quit_main_message_loop).Run();
|
||||
if (quit_main_message_loop_) {
|
||||
std::move(quit_main_message_loop_).Run();
|
||||
} else {
|
||||
// There is no message loop available so we are in early stage.
|
||||
exit(0);
|
||||
// There is no message loop available so we are in early stage, wait until
|
||||
// the quit_main_message_loop_ is available.
|
||||
// Exiting now would leave defunct processes behind.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +194,10 @@ void Browser::PreMainMessageLoopRun() {
|
||||
}
|
||||
|
||||
void Browser::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) {
|
||||
*g_quit_main_message_loop = std::move(quit_closure);
|
||||
if (is_shutdown_)
|
||||
std::move(quit_closure).Run();
|
||||
else
|
||||
quit_main_message_loop_ = std::move(quit_closure);
|
||||
}
|
||||
|
||||
void Browser::NotifyAndShutdown() {
|
||||
|
||||
@@ -244,7 +244,7 @@ class Browser : public WindowListObserver {
|
||||
|
||||
// Stores the supplied |quit_closure|, to be run when the last Browser
|
||||
// instance is destroyed.
|
||||
static void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure);
|
||||
void SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure);
|
||||
|
||||
void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); }
|
||||
|
||||
@@ -287,6 +287,9 @@ class Browser : public WindowListObserver {
|
||||
// The browser is being shutdown.
|
||||
bool is_shutdown_ = false;
|
||||
|
||||
// Null until/unless the default main message loop is running.
|
||||
base::OnceClosure quit_main_message_loop_;
|
||||
|
||||
int badge_count_ = 0;
|
||||
|
||||
util::Promise* ready_promise_ = nullptr;
|
||||
|
||||
@@ -231,9 +231,10 @@ LSSharedFileListItemRef GetLoginItemForApp() {
|
||||
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
|
||||
LSSharedFileListItemRef item =
|
||||
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
|
||||
CFURLRef item_url_ref = NULL;
|
||||
if (LSSharedFileListItemResolve(item, 0, &item_url_ref, NULL) == noErr &&
|
||||
item_url_ref) {
|
||||
base::ScopedCFTypeRef<CFErrorRef> error;
|
||||
CFURLRef item_url_ref =
|
||||
LSSharedFileListItemCopyResolvedURL(item, 0, error.InitializeInto());
|
||||
if (!error && item_url_ref) {
|
||||
base::ScopedCFTypeRef<CFURLRef> item_url(item_url_ref);
|
||||
if (CFEqual(item_url, url)) {
|
||||
CFRetain(item);
|
||||
@@ -264,9 +265,10 @@ void RemoveFromLoginItems() {
|
||||
for (NSUInteger i = 0; i < [login_items_array count]; ++i) {
|
||||
LSSharedFileListItemRef item =
|
||||
reinterpret_cast<LSSharedFileListItemRef>(login_items_array[i]);
|
||||
CFURLRef url_ref = NULL;
|
||||
if (LSSharedFileListItemResolve(item, 0, &url_ref, NULL) == noErr &&
|
||||
item) {
|
||||
base::ScopedCFTypeRef<CFErrorRef> error;
|
||||
CFURLRef url_ref =
|
||||
LSSharedFileListItemCopyResolvedURL(item, 0, error.InitializeInto());
|
||||
if (!error && url_ref) {
|
||||
base::ScopedCFTypeRef<CFURLRef> url(url_ref);
|
||||
if ([[base::mac::CFToNSCast(url.get()) path]
|
||||
hasPrefix:[[NSBundle mainBundle] bundlePath]])
|
||||
|
||||
14
atom/browser/child_web_contents_tracker.cc
Normal file
14
atom/browser/child_web_contents_tracker.cc
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2019 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/child_web_contents_tracker.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
ChildWebContentsTracker::ChildWebContentsTracker(
|
||||
content::WebContents* web_contents) {}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(ChildWebContentsTracker)
|
||||
|
||||
} // namespace atom
|
||||
@@ -18,11 +18,12 @@ struct ChildWebContentsTracker
|
||||
GURL url;
|
||||
std::string frame_name;
|
||||
|
||||
explicit ChildWebContentsTracker(content::WebContents* web_contents) {}
|
||||
|
||||
private:
|
||||
explicit ChildWebContentsTracker(content::WebContents* web_contents);
|
||||
friend class content::WebContentsUserData<ChildWebContentsTracker>;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChildWebContentsTracker);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
@@ -23,7 +24,7 @@
|
||||
#include "base/threading/scoped_blocking_call.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||
#include "chrome/browser/ui/browser_dialogs.h"
|
||||
#include "chrome/browser/ui/color_chooser.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
@@ -183,7 +184,8 @@ void CommonWebContentsDelegate::InitWithWebContents(
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
PrintPreviewMessageHandler::CreateForWebContents(web_contents);
|
||||
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
|
||||
printing::CreateCompositeClientIfNeeded(web_contents);
|
||||
printing::CreateCompositeClientIfNeeded(web_contents,
|
||||
browser_context->GetUserAgent());
|
||||
#endif
|
||||
|
||||
// Determien whether the WebContents is offscreen.
|
||||
@@ -213,8 +215,7 @@ void CommonWebContentsDelegate::SetOwnerWindow(
|
||||
owner_window->GetWeakPtr());
|
||||
} else {
|
||||
owner_window_ = nullptr;
|
||||
web_contents->RemoveUserData(
|
||||
NativeWindowRelay::kNativeWindowRelayUserDataKey);
|
||||
web_contents->RemoveUserData(NativeWindowRelay::UserDataKey());
|
||||
}
|
||||
#if BUILDFLAG(ENABLE_OSR)
|
||||
auto* osr_wcv = GetOffScreenWebContentsView();
|
||||
@@ -274,6 +275,7 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab(
|
||||
load_url_params.should_replace_current_entry =
|
||||
params.should_replace_current_entry;
|
||||
load_url_params.is_renderer_initiated = params.is_renderer_initiated;
|
||||
load_url_params.initiator_origin = params.initiator_origin;
|
||||
load_url_params.should_clear_history_list = true;
|
||||
|
||||
source->GetController().LoadURLWithParams(load_url_params);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
@@ -103,7 +104,7 @@ const FontDefault kFontDefaults[] = {
|
||||
IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN},
|
||||
#endif
|
||||
};
|
||||
const size_t kFontDefaultsLength = arraysize(kFontDefaults);
|
||||
const size_t kFontDefaultsLength = base::size(kFontDefaults);
|
||||
|
||||
// ^^^^^ DO NOT EDIT ^^^^^
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop) {
|
||||
tracing_controller);
|
||||
|
||||
v8::V8::InitializePlatform(platform_);
|
||||
gin::IsolateHolder::Initialize(
|
||||
gin::IsolateHolder::kNonStrictMode, gin::IsolateHolder::kStableV8Extras,
|
||||
gin::ArrayBufferAllocator::SharedInstance(),
|
||||
nullptr /* external_reference_table */, false /* create_v8_platform */);
|
||||
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
||||
gin::ArrayBufferAllocator::SharedInstance(),
|
||||
nullptr /* external_reference_table */,
|
||||
false /* create_v8_platform */);
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::Allocate();
|
||||
platform_->RegisterIsolate(isolate, event_loop);
|
||||
|
||||
@@ -7,18 +7,16 @@
|
||||
#include "base/logging.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/media_capture_devices.h"
|
||||
#include "content/public/common/media_stream_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::MediaStreamDevices;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Finds a device in |devices| that has |device_id|, or NULL if not found.
|
||||
const content::MediaStreamDevice* FindDeviceWithId(
|
||||
const content::MediaStreamDevices& devices,
|
||||
const blink::MediaStreamDevice* FindDeviceWithId(
|
||||
const blink::MediaStreamDevices& devices,
|
||||
const std::string& device_id) {
|
||||
auto iter = devices.begin();
|
||||
for (; iter != devices.end(); ++iter) {
|
||||
@@ -29,11 +27,6 @@ const content::MediaStreamDevice* FindDeviceWithId(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MediaStreamDevices& EmptyDevices() {
|
||||
static MediaStreamDevices* devices = new MediaStreamDevices;
|
||||
return *devices;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() {
|
||||
@@ -49,75 +42,75 @@ MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher()
|
||||
|
||||
MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {}
|
||||
|
||||
const MediaStreamDevices&
|
||||
const blink::MediaStreamDevices&
|
||||
MediaCaptureDevicesDispatcher::GetAudioCaptureDevices() {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
if (is_device_enumeration_disabled_)
|
||||
return EmptyDevices();
|
||||
return test_audio_devices_;
|
||||
return content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices();
|
||||
}
|
||||
|
||||
const MediaStreamDevices&
|
||||
const blink::MediaStreamDevices&
|
||||
MediaCaptureDevicesDispatcher::GetVideoCaptureDevices() {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
if (is_device_enumeration_disabled_)
|
||||
return EmptyDevices();
|
||||
return test_video_devices_;
|
||||
return content::MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices();
|
||||
}
|
||||
|
||||
void MediaCaptureDevicesDispatcher::GetDefaultDevices(
|
||||
bool audio,
|
||||
bool video,
|
||||
content::MediaStreamDevices* devices) {
|
||||
blink::MediaStreamDevices* devices) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
DCHECK(audio || video);
|
||||
|
||||
if (audio) {
|
||||
const content::MediaStreamDevice* device = GetFirstAvailableAudioDevice();
|
||||
const blink::MediaStreamDevice* device = GetFirstAvailableAudioDevice();
|
||||
if (device)
|
||||
devices->push_back(*device);
|
||||
}
|
||||
|
||||
if (video) {
|
||||
const content::MediaStreamDevice* device = GetFirstAvailableVideoDevice();
|
||||
const blink::MediaStreamDevice* device = GetFirstAvailableVideoDevice();
|
||||
if (device)
|
||||
devices->push_back(*device);
|
||||
}
|
||||
}
|
||||
|
||||
const content::MediaStreamDevice*
|
||||
const blink::MediaStreamDevice*
|
||||
MediaCaptureDevicesDispatcher::GetRequestedAudioDevice(
|
||||
const std::string& requested_audio_device_id) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
|
||||
const content::MediaStreamDevice* const device =
|
||||
const blink::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
|
||||
const blink::MediaStreamDevice* const device =
|
||||
FindDeviceWithId(audio_devices, requested_audio_device_id);
|
||||
return device;
|
||||
}
|
||||
|
||||
const content::MediaStreamDevice*
|
||||
const blink::MediaStreamDevice*
|
||||
MediaCaptureDevicesDispatcher::GetFirstAvailableAudioDevice() {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
|
||||
const blink::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
|
||||
if (audio_devices.empty())
|
||||
return nullptr;
|
||||
return &(*audio_devices.begin());
|
||||
}
|
||||
|
||||
const content::MediaStreamDevice*
|
||||
const blink::MediaStreamDevice*
|
||||
MediaCaptureDevicesDispatcher::GetRequestedVideoDevice(
|
||||
const std::string& requested_video_device_id) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
|
||||
const content::MediaStreamDevice* const device =
|
||||
const blink::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
|
||||
const blink::MediaStreamDevice* const device =
|
||||
FindDeviceWithId(video_devices, requested_video_device_id);
|
||||
return device;
|
||||
}
|
||||
|
||||
const content::MediaStreamDevice*
|
||||
const blink::MediaStreamDevice*
|
||||
MediaCaptureDevicesDispatcher::GetFirstAvailableVideoDevice() {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
|
||||
const blink::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
|
||||
if (video_devices.empty())
|
||||
return nullptr;
|
||||
return &(*video_devices.begin());
|
||||
@@ -136,7 +129,7 @@ void MediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(
|
||||
int render_view_id,
|
||||
int page_request_id,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType stream_type,
|
||||
blink::MediaStreamType stream_type,
|
||||
content::MediaRequestState state) {}
|
||||
|
||||
void MediaCaptureDevicesDispatcher::OnCreatingAudioStream(int render_process_id,
|
||||
@@ -146,7 +139,7 @@ void MediaCaptureDevicesDispatcher::OnSetCapturingLinkSecured(
|
||||
int render_process_id,
|
||||
int render_frame_id,
|
||||
int page_request_id,
|
||||
content::MediaStreamType stream_type,
|
||||
blink::MediaStreamType stream_type,
|
||||
bool is_secure) {}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#include "base/memory/singleton.h"
|
||||
#include "content/public/browser/media_observer.h"
|
||||
#include "content/public/common/media_stream_request.h"
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -20,8 +21,8 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver {
|
||||
static MediaCaptureDevicesDispatcher* GetInstance();
|
||||
|
||||
// Methods for observers. Called on UI thread.
|
||||
const content::MediaStreamDevices& GetAudioCaptureDevices();
|
||||
const content::MediaStreamDevices& GetVideoCaptureDevices();
|
||||
const blink::MediaStreamDevices& GetAudioCaptureDevices();
|
||||
const blink::MediaStreamDevices& GetVideoCaptureDevices();
|
||||
|
||||
// Helper to get the default devices which can be used by the media request.
|
||||
// Uses the first available devices if the default devices are not available.
|
||||
@@ -30,19 +31,19 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver {
|
||||
// Called on the UI thread.
|
||||
void GetDefaultDevices(bool audio,
|
||||
bool video,
|
||||
content::MediaStreamDevices* devices);
|
||||
blink::MediaStreamDevices* devices);
|
||||
|
||||
// Helpers for picking particular requested devices, identified by raw id.
|
||||
// If the device requested is not available it will return NULL.
|
||||
const content::MediaStreamDevice* GetRequestedAudioDevice(
|
||||
const blink::MediaStreamDevice* GetRequestedAudioDevice(
|
||||
const std::string& requested_audio_device_id);
|
||||
const content::MediaStreamDevice* GetRequestedVideoDevice(
|
||||
const blink::MediaStreamDevice* GetRequestedVideoDevice(
|
||||
const std::string& requested_video_device_id);
|
||||
|
||||
// Returns the first available audio or video device, or NULL if no devices
|
||||
// are available.
|
||||
const content::MediaStreamDevice* GetFirstAvailableAudioDevice();
|
||||
const content::MediaStreamDevice* GetFirstAvailableVideoDevice();
|
||||
const blink::MediaStreamDevice* GetFirstAvailableAudioDevice();
|
||||
const blink::MediaStreamDevice* GetFirstAvailableVideoDevice();
|
||||
|
||||
// Unittests that do not require actual device enumeration should call this
|
||||
// API on the singleton. It is safe to call this multiple times on the
|
||||
@@ -56,14 +57,14 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver {
|
||||
int render_view_id,
|
||||
int page_request_id,
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType stream_type,
|
||||
blink::MediaStreamType stream_type,
|
||||
content::MediaRequestState state) override;
|
||||
void OnCreatingAudioStream(int render_process_id,
|
||||
int render_view_id) override;
|
||||
void OnSetCapturingLinkSecured(int render_process_id,
|
||||
int render_frame_id,
|
||||
int page_request_id,
|
||||
content::MediaStreamType stream_type,
|
||||
blink::MediaStreamType stream_type,
|
||||
bool is_secure) override;
|
||||
|
||||
private:
|
||||
@@ -72,6 +73,12 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver {
|
||||
MediaCaptureDevicesDispatcher();
|
||||
~MediaCaptureDevicesDispatcher() override;
|
||||
|
||||
// Only for testing, a list of cached audio capture devices.
|
||||
blink::MediaStreamDevices test_audio_devices_;
|
||||
|
||||
// Only for testing, a list of cached video capture devices.
|
||||
blink::MediaStreamDevices test_video_devices_;
|
||||
|
||||
// Flag used by unittests to disable device enumeration.
|
||||
bool is_device_enumeration_disabled_;
|
||||
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
#include "atom/browser/media/media_capture_devices_dispatcher.h"
|
||||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "content/public/common/media_stream_request.h"
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
bool HasAnyAvailableDevice() {
|
||||
const content::MediaStreamDevices& audio_devices =
|
||||
const blink::MediaStreamDevices& audio_devices =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
|
||||
const content::MediaStreamDevices& video_devices =
|
||||
const blink::MediaStreamDevices& video_devices =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices();
|
||||
|
||||
return !audio_devices.empty() || !video_devices.empty();
|
||||
@@ -34,33 +34,33 @@ MediaStreamDevicesController::MediaStreamDevicesController(
|
||||
// For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
|
||||
// and microphone to avoid popping two infobars.
|
||||
microphone_requested_(
|
||||
request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
|
||||
request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY),
|
||||
request.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE ||
|
||||
request.request_type == blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY),
|
||||
webcam_requested_(
|
||||
request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
|
||||
request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) {}
|
||||
request.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE ||
|
||||
request.request_type == blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY) {}
|
||||
|
||||
MediaStreamDevicesController::~MediaStreamDevicesController() {
|
||||
if (!callback_.is_null()) {
|
||||
std::move(callback_).Run(content::MediaStreamDevices(),
|
||||
content::MEDIA_DEVICE_INVALID_STATE,
|
||||
std::move(callback_).Run(blink::MediaStreamDevices(),
|
||||
blink::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
|
||||
std::unique_ptr<content::MediaStreamUI>());
|
||||
}
|
||||
}
|
||||
|
||||
bool MediaStreamDevicesController::TakeAction() {
|
||||
// Do special handling of desktop screen cast.
|
||||
if (request_.audio_type == content::MEDIA_GUM_TAB_AUDIO_CAPTURE ||
|
||||
request_.video_type == content::MEDIA_GUM_TAB_VIDEO_CAPTURE ||
|
||||
request_.audio_type == content::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE ||
|
||||
request_.video_type == content::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) {
|
||||
if (request_.audio_type == blink::MEDIA_GUM_TAB_AUDIO_CAPTURE ||
|
||||
request_.video_type == blink::MEDIA_GUM_TAB_VIDEO_CAPTURE ||
|
||||
request_.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE ||
|
||||
request_.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) {
|
||||
HandleUserMediaRequest();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deny the request if there is no device attached to the OS.
|
||||
if (!HasAnyAvailableDevice()) {
|
||||
Deny(content::MEDIA_DEVICE_NO_HARDWARE);
|
||||
Deny(blink::MEDIA_DEVICE_NO_HARDWARE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ bool MediaStreamDevicesController::TakeAction() {
|
||||
|
||||
void MediaStreamDevicesController::Accept() {
|
||||
// Get the default devices for the request.
|
||||
content::MediaStreamDevices devices;
|
||||
blink::MediaStreamDevices devices;
|
||||
if (microphone_requested_ || webcam_requested_) {
|
||||
switch (request_.request_type) {
|
||||
case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: {
|
||||
const content::MediaStreamDevice* device = nullptr;
|
||||
case blink::MEDIA_OPEN_DEVICE_PEPPER_ONLY: {
|
||||
const blink::MediaStreamDevice* device = nullptr;
|
||||
// For open device request pick the desired device or fall back to the
|
||||
// first available of the given type.
|
||||
if (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
|
||||
if (request_.audio_type == blink::MEDIA_DEVICE_AUDIO_CAPTURE) {
|
||||
device =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()
|
||||
->GetRequestedAudioDevice(request_.requested_audio_device_id);
|
||||
@@ -86,7 +86,7 @@ void MediaStreamDevicesController::Accept() {
|
||||
device = MediaCaptureDevicesDispatcher::GetInstance()
|
||||
->GetFirstAvailableAudioDevice();
|
||||
}
|
||||
} else if (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
|
||||
} else if (request_.video_type == blink::MEDIA_DEVICE_VIDEO_CAPTURE) {
|
||||
// Pepper API opens only one device at a time.
|
||||
device =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()
|
||||
@@ -101,13 +101,13 @@ void MediaStreamDevicesController::Accept() {
|
||||
devices.push_back(*device);
|
||||
break;
|
||||
}
|
||||
case content::MEDIA_GENERATE_STREAM: {
|
||||
case blink::MEDIA_GENERATE_STREAM: {
|
||||
bool needs_audio_device = microphone_requested_;
|
||||
bool needs_video_device = webcam_requested_;
|
||||
|
||||
// Get the exact audio or video device if an id is specified.
|
||||
if (!request_.requested_audio_device_id.empty()) {
|
||||
const content::MediaStreamDevice* audio_device =
|
||||
const blink::MediaStreamDevice* audio_device =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()
|
||||
->GetRequestedAudioDevice(request_.requested_audio_device_id);
|
||||
if (audio_device) {
|
||||
@@ -116,7 +116,7 @@ void MediaStreamDevicesController::Accept() {
|
||||
}
|
||||
}
|
||||
if (!request_.requested_video_device_id.empty()) {
|
||||
const content::MediaStreamDevice* video_device =
|
||||
const blink::MediaStreamDevice* video_device =
|
||||
MediaCaptureDevicesDispatcher::GetInstance()
|
||||
->GetRequestedVideoDevice(request_.requested_video_device_id);
|
||||
if (video_device) {
|
||||
@@ -133,40 +133,45 @@ void MediaStreamDevicesController::Accept() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case content::MEDIA_DEVICE_ACCESS:
|
||||
case blink::MEDIA_DEVICE_ACCESS: {
|
||||
// Get the default devices for the request.
|
||||
MediaCaptureDevicesDispatcher::GetInstance()->GetDefaultDevices(
|
||||
microphone_requested_, webcam_requested_, &devices);
|
||||
break;
|
||||
}
|
||||
case blink::MEDIA_DEVICE_UPDATE: {
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::move(callback_).Run(devices, content::MEDIA_DEVICE_OK,
|
||||
std::move(callback_).Run(devices, blink::MEDIA_DEVICE_OK,
|
||||
std::unique_ptr<content::MediaStreamUI>());
|
||||
}
|
||||
|
||||
void MediaStreamDevicesController::Deny(
|
||||
content::MediaStreamRequestResult result) {
|
||||
std::move(callback_).Run(content::MediaStreamDevices(), result,
|
||||
blink::MediaStreamRequestResult result) {
|
||||
std::move(callback_).Run(blink::MediaStreamDevices(), result,
|
||||
std::unique_ptr<content::MediaStreamUI>());
|
||||
}
|
||||
|
||||
void MediaStreamDevicesController::HandleUserMediaRequest() {
|
||||
content::MediaStreamDevices devices;
|
||||
blink::MediaStreamDevices devices;
|
||||
|
||||
if (request_.audio_type == content::MEDIA_GUM_TAB_AUDIO_CAPTURE) {
|
||||
devices.push_back(content::MediaStreamDevice(
|
||||
content::MEDIA_GUM_TAB_AUDIO_CAPTURE, "", ""));
|
||||
if (request_.audio_type == blink::MEDIA_GUM_TAB_AUDIO_CAPTURE) {
|
||||
devices.push_back(
|
||||
blink::MediaStreamDevice(blink::MEDIA_GUM_TAB_AUDIO_CAPTURE, "", ""));
|
||||
}
|
||||
if (request_.video_type == content::MEDIA_GUM_TAB_VIDEO_CAPTURE) {
|
||||
devices.push_back(content::MediaStreamDevice(
|
||||
content::MEDIA_GUM_TAB_VIDEO_CAPTURE, "", ""));
|
||||
if (request_.video_type == blink::MEDIA_GUM_TAB_VIDEO_CAPTURE) {
|
||||
devices.push_back(
|
||||
blink::MediaStreamDevice(blink::MEDIA_GUM_TAB_VIDEO_CAPTURE, "", ""));
|
||||
}
|
||||
if (request_.audio_type == content::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE) {
|
||||
devices.push_back(content::MediaStreamDevice(
|
||||
content::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE, "loopback", "System Audio"));
|
||||
if (request_.audio_type == blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE) {
|
||||
devices.push_back(blink::MediaStreamDevice(
|
||||
blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE, "loopback", "System Audio"));
|
||||
}
|
||||
if (request_.video_type == content::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) {
|
||||
if (request_.video_type == blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) {
|
||||
content::DesktopMediaID screen_id;
|
||||
// If the device id wasn't specified then this is a screen capture request
|
||||
// (i.e. chooseDesktopMedia() API wasn't used to generate device id).
|
||||
@@ -179,13 +184,13 @@ void MediaStreamDevicesController::HandleUserMediaRequest() {
|
||||
}
|
||||
|
||||
devices.push_back(
|
||||
content::MediaStreamDevice(content::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE,
|
||||
screen_id.ToString(), "Screen"));
|
||||
blink::MediaStreamDevice(blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE,
|
||||
screen_id.ToString(), "Screen"));
|
||||
}
|
||||
|
||||
std::move(callback_).Run(devices,
|
||||
devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE
|
||||
: content::MEDIA_DEVICE_OK,
|
||||
devices.empty() ? blink::MEDIA_DEVICE_NO_HARDWARE
|
||||
: blink::MEDIA_DEVICE_OK,
|
||||
std::unique_ptr<content::MediaStreamUI>());
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ATOM_BROWSER_MEDIA_MEDIA_STREAM_DEVICES_CONTROLLER_H_
|
||||
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -21,7 +22,7 @@ class MediaStreamDevicesController {
|
||||
|
||||
// Explicitly accept or deny the request.
|
||||
void Accept();
|
||||
void Deny(content::MediaStreamRequestResult result);
|
||||
void Deny(blink::MediaStreamRequestResult result);
|
||||
|
||||
private:
|
||||
// Handle the request of desktop or tab screen cast.
|
||||
|
||||
@@ -574,18 +574,15 @@ const views::Widget* NativeWindow::GetWidget() const {
|
||||
return widget();
|
||||
}
|
||||
|
||||
// static
|
||||
const void* const NativeWindowRelay::kNativeWindowRelayUserDataKey =
|
||||
&NativeWindowRelay::kNativeWindowRelayUserDataKey;
|
||||
|
||||
// static
|
||||
void NativeWindowRelay::CreateForWebContents(
|
||||
content::WebContents* web_contents,
|
||||
base::WeakPtr<NativeWindow> window) {
|
||||
DCHECK(web_contents);
|
||||
DCHECK(!web_contents->GetUserData(kNativeWindowRelayUserDataKey));
|
||||
web_contents->SetUserData(kNativeWindowRelayUserDataKey,
|
||||
base::WrapUnique(new NativeWindowRelay(window)));
|
||||
if (!web_contents->GetUserData(UserDataKey())) {
|
||||
web_contents->SetUserData(UserDataKey(),
|
||||
base::WrapUnique(new NativeWindowRelay(window)));
|
||||
}
|
||||
}
|
||||
|
||||
NativeWindowRelay::NativeWindowRelay(base::WeakPtr<NativeWindow> window)
|
||||
@@ -593,4 +590,6 @@ NativeWindowRelay::NativeWindowRelay(base::WeakPtr<NativeWindow> window)
|
||||
|
||||
NativeWindowRelay::~NativeWindowRelay() = default;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(NativeWindowRelay)
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -362,8 +362,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
class NativeWindowRelay
|
||||
: public content::WebContentsUserData<NativeWindowRelay> {
|
||||
public:
|
||||
static const void* const kNativeWindowRelayUserDataKey;
|
||||
|
||||
static void CreateForWebContents(content::WebContents*,
|
||||
base::WeakPtr<NativeWindow>);
|
||||
|
||||
@@ -371,6 +369,8 @@ class NativeWindowRelay
|
||||
|
||||
NativeWindow* GetNativeWindow() const { return native_window_.get(); }
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
private:
|
||||
friend class content::WebContentsUserData<NativeWindow>;
|
||||
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window);
|
||||
|
||||
@@ -1131,17 +1131,23 @@ void NativeWindowMac::SetProgressBar(double progress,
|
||||
const NativeWindow::ProgressState state) {
|
||||
NSDockTile* dock_tile = [NSApp dockTile];
|
||||
|
||||
// Sometimes macOS would install a default contentView for dock, we must
|
||||
// verify whether NSProgressIndicator has been installed.
|
||||
bool first_time = !dock_tile.contentView ||
|
||||
[[dock_tile.contentView subviews] count] == 0 ||
|
||||
![[[dock_tile.contentView subviews] lastObject]
|
||||
isKindOfClass:[NSProgressIndicator class]];
|
||||
|
||||
// For the first time API invoked, we need to create a ContentView in
|
||||
// DockTile.
|
||||
if (dock_tile.contentView == nullptr) {
|
||||
NSImageView* image_view = [[NSImageView alloc] init];
|
||||
if (first_time) {
|
||||
NSImageView* image_view = [[[NSImageView alloc] init] autorelease];
|
||||
[image_view setImage:[NSApp applicationIconImage]];
|
||||
[dock_tile setContentView:image_view];
|
||||
}
|
||||
|
||||
if ([[dock_tile.contentView subviews] count] == 0) {
|
||||
NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc]
|
||||
initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)];
|
||||
NSRect frame = NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0);
|
||||
NSProgressIndicator* progress_indicator =
|
||||
[[[AtomProgressBar alloc] initWithFrame:frame] autorelease];
|
||||
[progress_indicator setStyle:NSProgressIndicatorBarStyle];
|
||||
[progress_indicator setIndeterminate:NO];
|
||||
[progress_indicator setBezeled:YES];
|
||||
@@ -1152,7 +1158,7 @@ void NativeWindowMac::SetProgressBar(double progress,
|
||||
}
|
||||
|
||||
NSProgressIndicator* progress_indicator = static_cast<NSProgressIndicator*>(
|
||||
[[[dock_tile contentView] subviews] objectAtIndex:0]);
|
||||
[[[dock_tile contentView] subviews] lastObject]);
|
||||
if (progress < 0) {
|
||||
[progress_indicator setHidden:YES];
|
||||
} else if (progress > 1) {
|
||||
|
||||
@@ -267,8 +267,8 @@ void AtomURLRequest::DoCancel() {
|
||||
void AtomURLRequest::DoFollowRedirect() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (request_ && request_->is_redirecting() && redirect_policy_ == "manual") {
|
||||
request_->FollowDeferredRedirect(
|
||||
base::nullopt /* modified_request_headers */);
|
||||
request_->FollowDeferredRedirect(base::nullopt /* removed_headers */,
|
||||
base::nullopt /* modified_headers */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ void ResolveProxyHelper::StartPendingRequest() {
|
||||
binding_.Bind(mojo::MakeRequest(&proxy_lookup_client));
|
||||
binding_.set_connection_error_handler(
|
||||
base::BindOnce(&ResolveProxyHelper::OnProxyLookupComplete,
|
||||
base::Unretained(this), base::nullopt));
|
||||
base::Unretained(this), net::ERR_ABORTED, base::nullopt));
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
|
||||
->GetNetworkContext()
|
||||
->LookUpProxyForURL(pending_requests_.front().url,
|
||||
@@ -60,6 +60,7 @@ void ResolveProxyHelper::StartPendingRequest() {
|
||||
}
|
||||
|
||||
void ResolveProxyHelper::OnProxyLookupComplete(
|
||||
int32_t net_error,
|
||||
const base::Optional<net::ProxyInfo>& proxy_info) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(!pending_requests_.empty());
|
||||
|
||||
@@ -54,6 +54,7 @@ class ResolveProxyHelper
|
||||
|
||||
// network::mojom::ProxyLookupClient implementation.
|
||||
void OnProxyLookupComplete(
|
||||
int32_t net_error,
|
||||
const base::Optional<net::ProxyInfo>& proxy_info) override;
|
||||
|
||||
// Self-reference. Owned as long as there's an outstanding proxy lookup.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/io_thread.h"
|
||||
#include "atom/common/application_info.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/lazy_instance.h"
|
||||
@@ -222,6 +223,8 @@ SystemNetworkContextManager::CreateNetworkContextParams() {
|
||||
|
||||
network_context_params->context_name = std::string("system");
|
||||
|
||||
network_context_params->user_agent = atom::GetApplicationUserAgent();
|
||||
|
||||
network_context_params->http_cache_enabled = false;
|
||||
|
||||
// These are needed for PAC scripts that use file or data URLs (Or FTP URLs?).
|
||||
|
||||
@@ -29,7 +29,7 @@ void BeforeStartInUI(base::WeakPtr<URLRequestAsyncAsarJob> job,
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options.reset(converter.FromV8Value(value, context));
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
|
||||
@@ -40,7 +40,7 @@ void BeforeStartInUI(base::WeakPtr<URLRequestBufferJob> job,
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options.reset(converter.FromV8Value(value, context));
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
|
||||
@@ -141,6 +141,7 @@ void URLRequestStreamJob::StartAsync(
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::OnData(std::vector<char>&& buffer) { // NOLINT
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
if (write_buffer_.empty()) {
|
||||
// Quick branch without copying.
|
||||
write_buffer_ = std::move(buffer);
|
||||
@@ -175,7 +176,7 @@ void URLRequestStreamJob::OnError(int error) {
|
||||
int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
response_start_time_ = base::TimeTicks::Now();
|
||||
|
||||
if (ended_)
|
||||
if (ended_ && write_buffer_.empty())
|
||||
return 0;
|
||||
|
||||
// When write_buffer_ is empty, there is no data valable yet, we have to save
|
||||
|
||||
@@ -29,7 +29,7 @@ void BeforeStartInUI(base::WeakPtr<URLRequestStringJob> job,
|
||||
if (args->GetNext(&value)) {
|
||||
V8ValueConverter converter;
|
||||
v8::Local<v8::Context> context = args->isolate()->GetCurrentContext();
|
||||
request_options.reset(converter.FromV8Value(value, context));
|
||||
request_options = converter.FromV8Value(value, context);
|
||||
}
|
||||
|
||||
if (request_options) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "content/browser/renderer_host/cursor_manager.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_delegate.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -252,6 +253,52 @@ class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
|
||||
};
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
|
||||
public:
|
||||
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
|
||||
: view_(view) {}
|
||||
|
||||
ui::Layer* DelegatedFrameHostGetLayer() const override {
|
||||
return view_->GetRootLayer();
|
||||
}
|
||||
|
||||
bool DelegatedFrameHostIsVisible() const override {
|
||||
return view_->IsShowing();
|
||||
}
|
||||
|
||||
SkColor DelegatedFrameHostGetGutterColor() const override {
|
||||
if (view_->render_widget_host()->delegate() &&
|
||||
view_->render_widget_host()->delegate()->IsFullscreenForCurrentTab()) {
|
||||
return SK_ColorWHITE;
|
||||
}
|
||||
return *view_->GetBackgroundColor();
|
||||
}
|
||||
|
||||
void OnFrameTokenChanged(uint32_t frame_token) override {
|
||||
view_->render_widget_host()->DidProcessFrame(frame_token);
|
||||
}
|
||||
|
||||
float GetDeviceScaleFactor() const override {
|
||||
return view_->GetDeviceScaleFactor();
|
||||
}
|
||||
|
||||
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
|
||||
return view_->render_widget_host()->CollectSurfaceIdsForEviction();
|
||||
}
|
||||
|
||||
bool ShouldShowStaleContentOnEviction() override { return false; }
|
||||
|
||||
void OnBeginFrame(base::TimeTicks frame_time) override {}
|
||||
void InvalidateLocalSurfaceIdOnEviction() override {}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* const view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
|
||||
};
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
bool transparent,
|
||||
bool painting,
|
||||
@@ -274,18 +321,22 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
bool is_guest_view_hack = parent_host_view_ != nullptr;
|
||||
|
||||
current_device_scale_factor_ = kDefaultScaleFactor;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
local_surface_id_allocator_.GenerateId();
|
||||
local_surface_id_allocation_ =
|
||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
|
||||
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
|
||||
AllocateFrameSinkId(is_guest_view_hack), this,
|
||||
AllocateFrameSinkId(is_guest_view_hack),
|
||||
delegated_frame_host_client_.get(),
|
||||
true /* should_register_frame_sink_id */);
|
||||
|
||||
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
|
||||
#endif
|
||||
|
||||
current_device_scale_factor_ = kDefaultScaleFactor;
|
||||
|
||||
local_surface_id_ = local_surface_id_allocator_.GenerateId();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
last_frame_root_background_color_ = SK_ColorTRANSPARENT;
|
||||
CreatePlatformWidget(is_guest_view_hack);
|
||||
@@ -301,12 +352,10 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
content::ImageTransportFactory::GetInstance();
|
||||
ui::ContextFactoryPrivate* context_factory_private =
|
||||
factory->GetContextFactoryPrivate();
|
||||
compositor_.reset(
|
||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(),
|
||||
features::IsSurfaceSynchronizationEnabled(),
|
||||
false /* enable_pixel_canvas */));
|
||||
compositor_.reset(new ui::Compositor(
|
||||
context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */));
|
||||
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
@@ -374,7 +423,7 @@ void OffScreenRenderWidgetHostView::SendBeginFrame(
|
||||
begin_frame_number_++;
|
||||
|
||||
if (renderer_compositor_frame_sink_)
|
||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args);
|
||||
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
||||
@@ -433,8 +482,9 @@ void OffScreenRenderWidgetHostView::Show() {
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(false);
|
||||
#else
|
||||
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
||||
delegated_frame_host_->WasShown(GetLocalSurfaceId(),
|
||||
GetRootLayer()->bounds().size(), false);
|
||||
delegated_frame_host_->WasShown(
|
||||
GetLocalSurfaceIdAllocation().local_surface_id(),
|
||||
GetRootLayer()->bounds().size(), false);
|
||||
#endif
|
||||
|
||||
if (render_widget_host_)
|
||||
@@ -462,7 +512,7 @@ bool OffScreenRenderWidgetHostView::IsShowing() {
|
||||
return is_showing_;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::EnsureSurfaceSynchronizedForLayoutTest() {
|
||||
void OffScreenRenderWidgetHostView::EnsureSurfaceSynchronizedForWebTest() {
|
||||
++latest_capture_sequence_number_;
|
||||
SynchronizeVisualProperties();
|
||||
}
|
||||
@@ -479,9 +529,9 @@ void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
|
||||
// We short-cut here to show a sensible color before that happens.
|
||||
UpdateBackgroundColorFromRenderer(color);
|
||||
|
||||
if (render_widget_host_) {
|
||||
render_widget_host_->SetBackgroundOpaque(SkColorGetA(color) ==
|
||||
SK_AlphaOPAQUE);
|
||||
if (render_widget_host_ && render_widget_host_->owner_delegate()) {
|
||||
render_widget_host_->owner_delegate()->SetBackgroundOpaque(
|
||||
SkColorGetA(color) == SK_AlphaOPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,19 +575,22 @@ void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
|
||||
void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
|
||||
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
|
||||
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
#else
|
||||
if (GetDelegatedFrameHost()) {
|
||||
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
|
||||
renderer_compositor_frame_sink_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
const viz::LocalSurfaceId& local_surface_id,
|
||||
viz::CompositorFrame frame,
|
||||
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
|
||||
TRACE_EVENT0("electron",
|
||||
"OffScreenRenderWidgetHostView::SubmitCompositorFrame");
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
last_frame_root_background_color_ = frame.metadata.root_background_color;
|
||||
#endif
|
||||
@@ -587,7 +640,7 @@ void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
||||
GetDelegatedFrameHost()->ClearDelegatedFrame();
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {
|
||||
@@ -667,9 +720,6 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetTooltipText(const base::string16&) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SelectionBoundsChanged(
|
||||
const ViewHostMsg_SelectionBounds_Params&) {}
|
||||
|
||||
uint32_t OffScreenRenderWidgetHostView::GetCaptureSequenceNumber() const {
|
||||
return latest_capture_sequence_number_;
|
||||
}
|
||||
@@ -698,7 +748,6 @@ void OffScreenRenderWidgetHostView::InitAsGuest(
|
||||
content::RenderWidgetHostView* parent_host_view,
|
||||
content::RenderWidgetHostViewGuest* guest_view) {
|
||||
parent_host_view_->AddGuestHostView(this);
|
||||
parent_host_view_->RegisterGuestViewFrameSwappedCallback(guest_view);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
|
||||
@@ -745,40 +794,6 @@ OffScreenRenderWidgetHostView::CreateViewForWidget(
|
||||
render_widget_host, embedder_host_view, size());
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
ui::Layer* OffScreenRenderWidgetHostView::DelegatedFrameHostGetLayer() const {
|
||||
return const_cast<ui::Layer*>(root_layer_.get());
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::DelegatedFrameHostIsVisible() const {
|
||||
return is_showing_;
|
||||
}
|
||||
|
||||
SkColor OffScreenRenderWidgetHostView::DelegatedFrameHostGetGutterColor()
|
||||
const {
|
||||
if (render_widget_host_->delegate() &&
|
||||
render_widget_host_->delegate()->IsFullscreenForCurrentTab()) {
|
||||
return SK_ColorWHITE;
|
||||
}
|
||||
return background_color_;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnFirstSurfaceActivation(
|
||||
const viz::SurfaceInfo& surface_info) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnBeginFrame(base::TimeTicks frame_time) {}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnFrameTokenChanged(uint32_t frame_token) {
|
||||
render_widget_host_->DidProcessFrame(frame_token);
|
||||
}
|
||||
|
||||
const viz::LocalSurfaceId& OffScreenRenderWidgetHostView::GetLocalSurfaceId()
|
||||
const {
|
||||
return local_surface_id_;
|
||||
}
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
|
||||
return GetDelegatedFrameHost()->frame_sink_id();
|
||||
}
|
||||
@@ -875,21 +890,6 @@ void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view) {
|
||||
guest_host_view->RegisterFrameSwappedCallback(base::BindOnce(
|
||||
&OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped,
|
||||
weak_ptr_factory_.GetWeakPtr(), base::Unretained(guest_host_view)));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view) {
|
||||
InvalidateBounds(gfx::ConvertRectToPixel(current_device_scale_factor_,
|
||||
guest_host_view->GetViewBounds()));
|
||||
|
||||
RegisterGuestViewFrameSwappedCallback(guest_host_view);
|
||||
}
|
||||
|
||||
std::unique_ptr<viz::SoftwareOutputDevice>
|
||||
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
|
||||
ui::Compositor* compositor) {
|
||||
@@ -925,7 +925,7 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->SetActive(needs_begin_frames && painting_, false);
|
||||
software_output_device_->SetActive(painting_, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -937,8 +937,6 @@ void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap) {
|
||||
TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint");
|
||||
|
||||
HoldResize();
|
||||
|
||||
if (parent_callback_) {
|
||||
@@ -1023,10 +1021,6 @@ void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
|
||||
}
|
||||
|
||||
ResizeRootLayer(false);
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->SynchronizeVisualProperties();
|
||||
GetDelegatedFrameHost()->EmbedSurface(
|
||||
local_surface_id_, size_, cc::DeadlinePolicy::UseDefaultDeadline());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SendMouseEvent(
|
||||
@@ -1087,7 +1081,11 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
|
||||
|
||||
blink::WebMouseWheelEvent mouse_wheel_event(event);
|
||||
|
||||
mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded();
|
||||
bool should_route_event =
|
||||
render_widget_host_->delegate() &&
|
||||
render_widget_host_->delegate()->GetInputEventRouter();
|
||||
mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(
|
||||
should_route_event);
|
||||
mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
|
||||
mouse_wheel_event, false);
|
||||
|
||||
@@ -1192,6 +1190,13 @@ ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||
return root_layer_.get();
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
const viz::LocalSurfaceIdAllocation&
|
||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
||||
return local_surface_id_allocation_;
|
||||
}
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
content::DelegatedFrameHost*
|
||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||
return delegated_frame_host_.get();
|
||||
@@ -1204,11 +1209,6 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||
|
||||
if (GetCompositor()) {
|
||||
GetCompositor()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
}
|
||||
|
||||
if (copy_frame_generator_.get()) {
|
||||
copy_frame_generator_->set_frame_rate_threshold_us(
|
||||
frame_rate_threshold_us_);
|
||||
@@ -1257,28 +1257,32 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
||||
size == GetRootLayer()->bounds().size())
|
||||
return;
|
||||
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
|
||||
|
||||
local_surface_id_ = local_surface_id_allocator_.GenerateId();
|
||||
|
||||
GetRootLayer()->SetBounds(gfx::Rect(size));
|
||||
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
|
||||
local_surface_id_);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool resized = UpdateNSViewAndDisplay();
|
||||
#else
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
|
||||
|
||||
local_surface_id_allocator_.GenerateId();
|
||||
local_surface_id_allocation_ =
|
||||
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
|
||||
|
||||
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
|
||||
local_surface_id_allocation_);
|
||||
bool resized = true;
|
||||
GetDelegatedFrameHost()->EmbedSurface(
|
||||
local_surface_id_, size, cc::DeadlinePolicy::UseDefaultDeadline());
|
||||
local_surface_id_allocation_.local_surface_id(), size,
|
||||
cc::DeadlinePolicy::UseDefaultDeadline());
|
||||
#endif
|
||||
|
||||
// Note that |render_widget_host_| will retrieve resize parameters from the
|
||||
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
|
||||
// after.
|
||||
if (resized && render_widget_host_)
|
||||
if (resized && render_widget_host_) {
|
||||
render_widget_host_->SynchronizeVisualProperties();
|
||||
}
|
||||
}
|
||||
|
||||
viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
|
||||
|
||||
@@ -66,13 +66,12 @@ class AtomBeginFrameTimer;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
class MacHelper;
|
||||
#else
|
||||
class AtomDelegatedFrameHostClient;
|
||||
#endif
|
||||
|
||||
class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
public ui::CompositorDelegate,
|
||||
#if !defined(OS_MACOSX)
|
||||
public content::DelegatedFrameHostClient,
|
||||
#endif
|
||||
public OffscreenViewProxyObserver {
|
||||
public:
|
||||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
@@ -102,7 +101,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void Show(void) override;
|
||||
void Hide(void) override;
|
||||
bool IsShowing(void) override;
|
||||
void EnsureSurfaceSynchronizedForLayoutTest() override;
|
||||
void EnsureSurfaceSynchronizedForWebTest() override;
|
||||
gfx::Rect GetViewBounds(void) const override;
|
||||
gfx::Size GetVisibleViewportSize() const override;
|
||||
void SetInsets(const gfx::Insets&) override;
|
||||
@@ -118,7 +117,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void SetActive(bool active) override;
|
||||
void ShowDefinitionForSelection() override;
|
||||
void SpeakSelection() override;
|
||||
bool ShouldContinueToPauseForFrame() override;
|
||||
bool UpdateNSViewAndDisplay();
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
@@ -144,8 +142,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void Destroy(void) override;
|
||||
void SetTooltipText(const base::string16&) override;
|
||||
content::CursorManager* GetCursorManager() override;
|
||||
void SelectionBoundsChanged(
|
||||
const ViewHostMsg_SelectionBounds_Params&) override;
|
||||
void CopyFromSurface(
|
||||
const gfx::Rect& src_rect,
|
||||
const gfx::Size& output_size,
|
||||
@@ -170,18 +166,8 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
content::RenderWidgetHost*,
|
||||
content::WebContentsView*) override;
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// content::DelegatedFrameHostClient:
|
||||
int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const;
|
||||
ui::Layer* DelegatedFrameHostGetLayer(void) const override;
|
||||
bool DelegatedFrameHostIsVisible(void) const override;
|
||||
SkColor DelegatedFrameHostGetGutterColor() const override;
|
||||
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
|
||||
void OnBeginFrame(base::TimeTicks frame_time) override;
|
||||
void OnFrameTokenChanged(uint32_t frame_token) override;
|
||||
#endif // !defined(OS_MACOSX)
|
||||
|
||||
const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
|
||||
const viz::LocalSurfaceIdAllocation& GetLocalSurfaceIdAllocation()
|
||||
const override;
|
||||
const viz::FrameSinkId& GetFrameSinkId() const override;
|
||||
|
||||
void DidNavigate() override;
|
||||
@@ -220,16 +206,13 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
void RemoveViewProxy(OffscreenViewProxy* proxy);
|
||||
void ProxyViewDestroyed(OffscreenViewProxy* proxy) override;
|
||||
|
||||
void RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view);
|
||||
void OnGuestViewFrameSwapped(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view);
|
||||
|
||||
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnProxyViewPaint(const gfx::Rect& damage_rect) override;
|
||||
|
||||
bool IsPopupWidget() const { return popup_type_ != blink::kWebPopupTypeNone; }
|
||||
bool IsPopupWidget() const {
|
||||
return widget_type_ == content::WidgetType::kPopup;
|
||||
}
|
||||
|
||||
void HoldResize();
|
||||
void ReleaseResize();
|
||||
@@ -322,7 +305,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
bool paint_callback_running_ = false;
|
||||
|
||||
viz::LocalSurfaceId local_surface_id_;
|
||||
viz::LocalSurfaceIdAllocation local_surface_id_allocation_;
|
||||
viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
|
||||
|
||||
std::unique_ptr<ui::Layer> root_layer_;
|
||||
@@ -349,6 +332,8 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
// Selected text on the renderer.
|
||||
std::string selected_text_;
|
||||
#else
|
||||
std::unique_ptr<AtomDelegatedFrameHostClient> delegated_frame_host_client_;
|
||||
#endif
|
||||
|
||||
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
|
||||
@@ -358,7 +343,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
|
||||
|
||||
// Latest capture sequence number which is incremented when the caller
|
||||
// requests surfaces be synchronized via
|
||||
// EnsureSurfaceSynchronizedForLayoutTest().
|
||||
// EnsureSurfaceSynchronizedForWebTest().
|
||||
uint32_t latest_capture_sequence_number_ = 0u;
|
||||
|
||||
SkColor background_color_ = SkColor();
|
||||
|
||||
@@ -11,13 +11,15 @@
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#include "components/viz/common/features.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class MacHelper : public content::BrowserCompositorMacClient,
|
||||
public ui::AcceleratedWidgetMacNSView {
|
||||
public:
|
||||
explicit MacHelper(OffScreenRenderWidgetHostView* view) : view_(view) {
|
||||
[view_->GetNativeView() setWantsLayer:YES];
|
||||
[view_->GetNativeView().GetNativeNSView() setWantsLayer:YES];
|
||||
}
|
||||
|
||||
virtual ~MacHelper() {}
|
||||
@@ -44,25 +46,14 @@ class MacHelper : public content::BrowserCompositorMacClient,
|
||||
|
||||
void DestroyCompositorForShutdown() override {}
|
||||
|
||||
bool SynchronizeVisualProperties(
|
||||
const base::Optional<viz::LocalSurfaceId>&
|
||||
child_allocated_local_surface_id) override {
|
||||
auto* browser_compositor = view_->browser_compositor();
|
||||
if (child_allocated_local_surface_id) {
|
||||
browser_compositor->UpdateRendererLocalSurfaceIdFromChild(
|
||||
*child_allocated_local_surface_id);
|
||||
} else {
|
||||
browser_compositor->AllocateNewRendererLocalSurfaceId();
|
||||
}
|
||||
|
||||
if (auto* host = browser_compositor->GetDelegatedFrameHost()) {
|
||||
host->EmbedSurface(browser_compositor->GetRendererLocalSurfaceId(),
|
||||
browser_compositor->GetRendererSize(),
|
||||
cc::DeadlinePolicy::UseDefaultDeadline());
|
||||
}
|
||||
bool OnBrowserCompositorSurfaceIdChanged() override {
|
||||
return view_->render_widget_host()->SynchronizeVisualProperties();
|
||||
}
|
||||
|
||||
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
|
||||
return view_->render_widget_host()->CollectSurfaceIdsForEviction();
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
|
||||
@@ -76,20 +67,20 @@ void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
|
||||
void OffScreenRenderWidgetHostView::SpeakSelection() {}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
||||
return browser_compositor_->UpdateNSViewAndDisplay(
|
||||
return browser_compositor_->UpdateSurfaceFromNSView(
|
||||
GetRootLayer()->bounds().size(), GetDisplay());
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::ShouldContinueToPauseForFrame() {
|
||||
return browser_compositor_->ShouldContinueToPauseForFrame();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::CreatePlatformWidget(
|
||||
bool is_guest_view_hack) {
|
||||
mac_helper_ = new MacHelper(this);
|
||||
browser_compositor_.reset(new content::BrowserCompositorMac(
|
||||
mac_helper_, mac_helper_, render_widget_host_->is_hidden(), GetDisplay(),
|
||||
AllocateFrameSinkId(is_guest_view_hack)));
|
||||
|
||||
if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
|
||||
SetNeedsBeginFrames(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
|
||||
@@ -132,14 +123,15 @@ display::Display OffScreenRenderWidgetHostView::GetDisplay() {
|
||||
void OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete(
|
||||
const cc::RenderFrameMetadata& metadata) {
|
||||
DCHECK_EQ(current_device_scale_factor_, metadata.device_scale_factor);
|
||||
browser_compositor_->SynchronizeVisualProperties(
|
||||
browser_compositor_->UpdateSurfaceFromChild(
|
||||
metadata.device_scale_factor, metadata.viewport_size_in_pixels,
|
||||
metadata.local_surface_id.value_or(viz::LocalSurfaceId()));
|
||||
metadata.local_surface_id_allocation.value_or(
|
||||
viz::LocalSurfaceIdAllocation()));
|
||||
}
|
||||
|
||||
const viz::LocalSurfaceId& OffScreenRenderWidgetHostView::GetLocalSurfaceId()
|
||||
const {
|
||||
return browser_compositor_->GetRendererLocalSurfaceId();
|
||||
const viz::LocalSurfaceIdAllocation&
|
||||
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
|
||||
return browser_compositor_->GetRendererLocalSurfaceIdAllocation();
|
||||
}
|
||||
|
||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||
|
||||
@@ -128,7 +128,7 @@ OffScreenWebContentsView::CreateViewForWidget(
|
||||
}
|
||||
|
||||
content::RenderWidgetHostViewBase*
|
||||
OffScreenWebContentsView::CreateViewForPopupWidget(
|
||||
OffScreenWebContentsView::CreateViewForChildWidget(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
content::WebContentsImpl* web_contents_impl =
|
||||
static_cast<content::WebContentsImpl*>(web_contents_);
|
||||
|
||||
@@ -57,7 +57,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
bool is_guest_view_hack) override;
|
||||
content::RenderWidgetHostViewBase* CreateViewForPopupWidget(
|
||||
content::RenderWidgetHostViewBase* CreateViewForChildWidget(
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
void SetPageTitle(const base::string16& title) override;
|
||||
void RenderViewCreated(content::RenderViewHost* host) override;
|
||||
|
||||
@@ -173,11 +173,15 @@ void PrintPreviewMessageHandler::RunPrintToPDFCallback(
|
||||
print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer);
|
||||
} else {
|
||||
v8::Local<v8::String> error_message =
|
||||
v8::String::NewFromUtf8(isolate, "Failed to generate PDF");
|
||||
v8::String::NewFromUtf8(isolate, "Failed to generate PDF",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
print_to_pdf_callback_map_[request_id].Run(
|
||||
v8::Exception::Error(error_message), v8::Null(isolate));
|
||||
}
|
||||
print_to_pdf_callback_map_.erase(request_id);
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(PrintPreviewMessageHandler)
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -65,6 +65,8 @@ class PrintPreviewMessageHandler
|
||||
|
||||
base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler);
|
||||
};
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5.0.0-nightly.20190122</string>
|
||||
<string>5.0.0-beta.3</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.0.0-nightly.20190122</string>
|
||||
<string>5.0.0-beta.3</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 5,0,0,20190122
|
||||
PRODUCTVERSION 5,0,0,20190122
|
||||
FILEVERSION 5,0,0,3
|
||||
PRODUCTVERSION 5,0,0,3
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -167,20 +167,11 @@ NSString* AtomBundleMover::ContainingDiskImageDevice(NSString* bundlePath) {
|
||||
NSData* data =
|
||||
[[[hdiutil standardOutput] fileHandleForReading] readDataToEndOfFile];
|
||||
|
||||
NSDictionary* info = nil;
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
|
||||
info = [NSPropertyListSerialization
|
||||
propertyListWithData:data
|
||||
options:NSPropertyListImmutable
|
||||
format:NULL
|
||||
error:NULL];
|
||||
} else {
|
||||
info = [NSPropertyListSerialization
|
||||
propertyListFromData:data
|
||||
mutabilityOption:NSPropertyListImmutable
|
||||
format:NULL
|
||||
errorDescription:NULL];
|
||||
}
|
||||
NSDictionary* info =
|
||||
[NSPropertyListSerialization propertyListWithData:data
|
||||
options:NSPropertyListImmutable
|
||||
format:NULL
|
||||
error:NULL];
|
||||
|
||||
if (![info isKindOfClass:[NSDictionary class]])
|
||||
return nil;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
@@ -58,6 +59,29 @@ Role kRolesMap[] = {
|
||||
{@selector(clearRecentDocuments:), "clearrecentdocuments"},
|
||||
};
|
||||
|
||||
// Called when adding a submenu to the menu and checks if the submenu, via its
|
||||
// |model|, has visible child items.
|
||||
bool MenuHasVisibleItems(const atom::AtomMenuModel* model) {
|
||||
int count = model->GetItemCount();
|
||||
for (int index = 0; index < count; index++) {
|
||||
if (model->IsVisibleAt(index))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called when an empty submenu is created. This inserts a menu item labeled
|
||||
// "(empty)" into the submenu. Matches Windows behavior.
|
||||
NSMenu* MakeEmptySubmenu() {
|
||||
base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:@""]);
|
||||
NSString* empty_menu_title =
|
||||
l10n_util::GetNSString(IDS_APP_MENU_EMPTY_SUBMENU);
|
||||
|
||||
[submenu addItemWithTitle:empty_menu_title action:NULL keyEquivalent:@""];
|
||||
[[submenu itemAtIndex:0] setEnabled:NO];
|
||||
return submenu.autorelease();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Menu item is located for ease of removing it from the parent owner
|
||||
@@ -220,13 +244,21 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
NSMenu* submenu = [[NSMenu alloc] initWithTitle:label];
|
||||
[item setSubmenu:submenu];
|
||||
[NSApp setServicesMenu:submenu];
|
||||
} else if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
|
||||
} else if (type == atom::AtomMenuModel::TYPE_SUBMENU &&
|
||||
model->IsVisibleAt(index)) {
|
||||
// We need to specifically check that the submenu top-level item has been
|
||||
// enabled as it's not validated by validateUserInterfaceItem
|
||||
if (!model->IsEnabledAt(index))
|
||||
[item setEnabled:NO];
|
||||
|
||||
// Recursively build a submenu from the sub-model at this index.
|
||||
[item setTarget:nil];
|
||||
[item setAction:nil];
|
||||
atom::AtomMenuModel* submenuModel =
|
||||
static_cast<atom::AtomMenuModel*>(model->GetSubmenuModelAt(index));
|
||||
NSMenu* submenu = [self menuFromModel:submenuModel];
|
||||
NSMenu* submenu = MenuHasVisibleItems(submenuModel)
|
||||
? [self menuFromModel:submenuModel]
|
||||
: MakeEmptySubmenu();
|
||||
[submenu setTitle:[item title]];
|
||||
[item setSubmenu:submenu];
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/pattern.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
@@ -109,7 +110,7 @@ void SetZoomLevelForWebContents(content::WebContents* web_contents,
|
||||
|
||||
double GetNextZoomLevel(double level, bool out) {
|
||||
double factor = content::ZoomLevelToZoomFactor(level);
|
||||
size_t size = arraysize(kPresetZoomFactors);
|
||||
size_t size = base::size(kPresetZoomFactors);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (!content::ZoomValuesEqual(kPresetZoomFactors[i], factor))
|
||||
continue;
|
||||
@@ -320,8 +321,8 @@ void InspectableWebContentsImpl::ShowDevTools(bool activate) {
|
||||
|
||||
// Show devtools only after it has done loading, this is to make sure the
|
||||
// SetIsDocked is called *BEFORE* ShowDevTools.
|
||||
embedder_message_dispatcher_.reset(
|
||||
DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this));
|
||||
embedder_message_dispatcher_ =
|
||||
DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this);
|
||||
|
||||
if (!external_devtools_web_contents_) { // no external devtools
|
||||
managed_devtools_web_contents_ = content::WebContents::Create(
|
||||
@@ -731,10 +732,10 @@ void InspectableWebContentsImpl::RenderFrameHostChanged(
|
||||
content::RenderFrameHost* new_host) {
|
||||
if (new_host->GetParent())
|
||||
return;
|
||||
frontend_host_.reset(content::DevToolsFrontendHost::Create(
|
||||
frontend_host_ = content::DevToolsFrontendHost::Create(
|
||||
new_host,
|
||||
base::Bind(&InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend,
|
||||
weak_factory_.GetWeakPtr())));
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::WebContentsDestroyed() {
|
||||
@@ -835,11 +836,11 @@ void InspectableWebContentsImpl::ReadyToCommitNavigation(
|
||||
frontend_host_) {
|
||||
return;
|
||||
}
|
||||
frontend_host_.reset(content::DevToolsFrontendHost::Create(
|
||||
frontend_host_ = content::DevToolsFrontendHost::Create(
|
||||
web_contents()->GetMainFrame(),
|
||||
base::Bind(
|
||||
&InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend,
|
||||
base::Unretained(this))));
|
||||
base::Unretained(this)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +157,13 @@ int ShowMessageBox(NativeWindow* parent_window,
|
||||
callEndModal:true];
|
||||
|
||||
NSWindow* window = parent_window->GetNativeWindow().GetNativeNSWindow();
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
[alert beginSheetModalForWindow:window
|
||||
modalDelegate:delegate
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
[NSApp runModalForWindow:window];
|
||||
return ret_code;
|
||||
@@ -196,11 +199,14 @@ void ShowMessageBox(NativeWindow* parent_window,
|
||||
NSWindow* window =
|
||||
parent_window ? parent_window->GetNativeWindow().GetNativeNSWindow()
|
||||
: nil;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
[alert
|
||||
beginSheetModalForWindow:window
|
||||
modalDelegate:delegate
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:nil];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,8 +82,7 @@ int FramelessView::NonClientHitTest(const gfx::Point& cursor) {
|
||||
return HTCLIENT;
|
||||
}
|
||||
|
||||
void FramelessView::GetWindowMask(const gfx::Size& size,
|
||||
gfx::Path* window_mask) {}
|
||||
void FramelessView::GetWindowMask(const gfx::Size& size, SkPath* window_mask) {}
|
||||
|
||||
void FramelessView::ResetWindowControls() {}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class FramelessView : public views::NonClientFrameView {
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override;
|
||||
int NonClientHitTest(const gfx::Point& point) override;
|
||||
void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override;
|
||||
void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override;
|
||||
void ResetWindowControls() override;
|
||||
void UpdateWindowIcon() override;
|
||||
void UpdateWindowTitle() override;
|
||||
|
||||
@@ -88,10 +88,6 @@ bool MenuDelegate::IsItemChecked(int id) const {
|
||||
return adapter_->IsItemChecked(id);
|
||||
}
|
||||
|
||||
void MenuDelegate::SelectionChanged(views::MenuItemView* menu) {
|
||||
adapter_->SelectionChanged(menu);
|
||||
}
|
||||
|
||||
void MenuDelegate::WillShowMenu(views::MenuItemView* menu) {
|
||||
adapter_->WillShowMenu(menu);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ class MenuDelegate : public views::MenuDelegate {
|
||||
bool IsCommandEnabled(int id) const override;
|
||||
bool IsCommandVisible(int id) const override;
|
||||
bool IsItemChecked(int id) const override;
|
||||
void SelectionChanged(views::MenuItemView* menu) override;
|
||||
void WillShowMenu(views::MenuItemView* menu) override;
|
||||
void WillHideMenu(views::MenuItemView* menu) override;
|
||||
void OnMenuClosed(views::MenuItemView* menu) override;
|
||||
|
||||
@@ -37,7 +37,7 @@ SubmenuButton::SubmenuButton(const base::string16& title,
|
||||
|
||||
SetInkDropMode(InkDropMode::ON);
|
||||
set_ink_drop_base_color(
|
||||
color_utils::BlendTowardOppositeLuma(background_color_, 0x61));
|
||||
color_utils::BlendTowardMaxContrast(background_color_, 0x61));
|
||||
}
|
||||
|
||||
SubmenuButton::~SubmenuButton() {}
|
||||
|
||||
@@ -83,7 +83,7 @@ bool ConvertShellLinkToJumpListItem(IShellLink* shell_link,
|
||||
|
||||
item->type = JumpListItem::Type::TASK;
|
||||
wchar_t path[MAX_PATH];
|
||||
if (FAILED(shell_link->GetPath(path, arraysize(path), nullptr, 0)))
|
||||
if (FAILED(shell_link->GetPath(path, MAX_PATH, nullptr, 0)))
|
||||
return false;
|
||||
|
||||
CComQIPtr<IPropertyStore> property_store = shell_link;
|
||||
@@ -100,14 +100,13 @@ bool ConvertShellLinkToJumpListItem(IShellLink* shell_link,
|
||||
}
|
||||
|
||||
int icon_index;
|
||||
if (SUCCEEDED(
|
||||
shell_link->GetIconLocation(path, arraysize(path), &icon_index))) {
|
||||
if (SUCCEEDED(shell_link->GetIconLocation(path, MAX_PATH, &icon_index))) {
|
||||
item->icon_path = base::FilePath(path);
|
||||
item->icon_index = icon_index;
|
||||
}
|
||||
|
||||
wchar_t item_desc[INFOTIPSIZE];
|
||||
if (SUCCEEDED(shell_link->GetDescription(item_desc, arraysize(item_desc))))
|
||||
if (SUCCEEDED(shell_link->GetDescription(item_desc, INFOTIPSIZE)))
|
||||
item->description = item_desc;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
namespace {
|
||||
|
||||
std::string MediaStreamTypeToString(content::MediaStreamType type) {
|
||||
std::string MediaStreamTypeToString(blink::MediaStreamType type) {
|
||||
switch (type) {
|
||||
case content::MediaStreamType::MEDIA_DEVICE_AUDIO_CAPTURE:
|
||||
case blink::MediaStreamType::MEDIA_DEVICE_AUDIO_CAPTURE:
|
||||
return "audio";
|
||||
case content::MediaStreamType::MEDIA_DEVICE_VIDEO_CAPTURE:
|
||||
case blink::MediaStreamType::MEDIA_DEVICE_VIDEO_CAPTURE:
|
||||
return "video";
|
||||
default:
|
||||
return "unknown";
|
||||
@@ -40,7 +40,7 @@ void MediaAccessAllowed(const content::MediaStreamRequest& request,
|
||||
if (allowed)
|
||||
controller.TakeAction();
|
||||
else
|
||||
controller.Deny(content::MEDIA_DEVICE_PERMISSION_DENIED);
|
||||
controller.Deny(blink::MEDIA_DEVICE_PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
void OnPointerLockResponse(content::WebContents* web_contents, bool allowed) {
|
||||
@@ -105,11 +105,11 @@ void WebContentsPermissionHelper::RequestMediaAccessPermission(
|
||||
base::DictionaryValue details;
|
||||
std::unique_ptr<base::ListValue> media_types(new base::ListValue);
|
||||
if (request.audio_type ==
|
||||
content::MediaStreamType::MEDIA_DEVICE_AUDIO_CAPTURE) {
|
||||
blink::MediaStreamType::MEDIA_DEVICE_AUDIO_CAPTURE) {
|
||||
media_types->AppendString("audio");
|
||||
}
|
||||
if (request.video_type ==
|
||||
content::MediaStreamType::MEDIA_DEVICE_VIDEO_CAPTURE) {
|
||||
blink::MediaStreamType::MEDIA_DEVICE_VIDEO_CAPTURE) {
|
||||
media_types->AppendString("video");
|
||||
}
|
||||
details.SetList("mediaTypes", std::move(media_types));
|
||||
@@ -145,7 +145,7 @@ void WebContentsPermissionHelper::RequestOpenExternalPermission(
|
||||
|
||||
bool WebContentsPermissionHelper::CheckMediaAccessPermission(
|
||||
const GURL& security_origin,
|
||||
content::MediaStreamType type) const {
|
||||
blink::MediaStreamType type) const {
|
||||
base::DictionaryValue details;
|
||||
details.SetString("securityOrigin", security_origin.spec());
|
||||
details.SetString("mediaType", MediaStreamTypeToString(type));
|
||||
@@ -154,4 +154,6 @@ bool WebContentsPermissionHelper::CheckMediaAccessPermission(
|
||||
return CheckPermission(content::PermissionType::AUDIO_CAPTURE, &details);
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsPermissionHelper)
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#ifndef ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_
|
||||
#define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_
|
||||
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "content/public/common/media_stream_request.h"
|
||||
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -36,7 +37,7 @@ class WebContentsPermissionHelper
|
||||
|
||||
// Synchronous Checks
|
||||
bool CheckMediaAccessPermission(const GURL& security_origin,
|
||||
content::MediaStreamType type) const;
|
||||
blink::MediaStreamType type) const;
|
||||
|
||||
private:
|
||||
explicit WebContentsPermissionHelper(content::WebContents* web_contents);
|
||||
@@ -52,6 +53,8 @@ class WebContentsPermissionHelper
|
||||
|
||||
content::WebContents* web_contents_;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsPermissionHelper);
|
||||
};
|
||||
|
||||
|
||||
@@ -84,9 +84,6 @@ bool GetAsAutoplayPolicy(const base::Value* val,
|
||||
} else if (policy_str == "user-gesture-required") {
|
||||
*out = content::AutoplayPolicy::kUserGestureRequired;
|
||||
return true;
|
||||
} else if (policy_str == "user-gesture-required-for-cross-origin") {
|
||||
*out = content::AutoplayPolicy::kUserGestureRequiredForCrossOrigin;
|
||||
return true;
|
||||
} else if (policy_str == "document-user-activation-required") {
|
||||
*out = content::AutoplayPolicy::kDocumentUserActivationRequired;
|
||||
return true;
|
||||
@@ -435,4 +432,6 @@ void WebContentsPreferences::OverrideWebkitPrefs(
|
||||
prefs->default_encoding = encoding;
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsPreferences)
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -82,6 +82,8 @@ class WebContentsPreferences
|
||||
base::Value preference_ = base::Value(base::Value::Type::DICTIONARY);
|
||||
base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY);
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences);
|
||||
};
|
||||
|
||||
|
||||
@@ -278,4 +278,6 @@ void WebContentsZoomController::SetZoomFactorOnNavigationIfNeeded(
|
||||
SetZoomLevel(zoom_level);
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsZoomController)
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -112,6 +112,8 @@ class WebContentsZoomController
|
||||
|
||||
content::HostZoomMap* host_zoom_map_;
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContentsZoomController);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/skia/include/core/SkImageInfo.h"
|
||||
#include "third_party/skia/include/core/SkPixmap.h"
|
||||
#include "ui/base/clipboard/clipboard_format_type.h"
|
||||
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -36,13 +37,15 @@ std::vector<base::string16> Clipboard::AvailableFormats(mate::Arguments* args) {
|
||||
|
||||
bool Clipboard::Has(const std::string& format_string, mate::Arguments* args) {
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
|
||||
ui::ClipboardFormatType format(
|
||||
ui::ClipboardFormatType::GetType(format_string));
|
||||
return clipboard->IsFormatAvailable(format, GetClipboardType(args));
|
||||
}
|
||||
|
||||
std::string Clipboard::Read(const std::string& format_string) {
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
|
||||
ui::ClipboardFormatType format(
|
||||
ui::ClipboardFormatType::GetType(format_string));
|
||||
|
||||
std::string data;
|
||||
clipboard->ReadData(format, &data);
|
||||
@@ -66,7 +69,7 @@ void Clipboard::WriteBuffer(const std::string& format,
|
||||
|
||||
ui::ScopedClipboardWriter writer(GetClipboardType(args));
|
||||
writer.WriteData(
|
||||
ui::Clipboard::GetFormatType(format).Serialize(),
|
||||
ui::ClipboardFormatType::GetType(format).Serialize(),
|
||||
std::string(node::Buffer::Data(buffer), node::Buffer::Length(buffer)));
|
||||
}
|
||||
|
||||
@@ -98,11 +101,11 @@ base::string16 Clipboard::ReadText(mate::Arguments* args) {
|
||||
base::string16 data;
|
||||
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
|
||||
auto type = GetClipboardType(args);
|
||||
if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
|
||||
if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextWType(),
|
||||
type)) {
|
||||
clipboard->ReadText(type, &data);
|
||||
} else if (clipboard->IsFormatAvailable(
|
||||
ui::Clipboard::GetPlainTextFormatType(), type)) {
|
||||
ui::ClipboardFormatType::GetPlainTextType(), type)) {
|
||||
std::string result;
|
||||
clipboard->ReadAsciiText(type, &result);
|
||||
data = base::ASCIIToUTF16(result);
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
#include "atom/common/application_info.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chrome/common/chrome_version.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -31,4 +36,21 @@ std::string GetOverriddenApplicationVersion() {
|
||||
return *g_overridden_application_version;
|
||||
}
|
||||
|
||||
std::string GetApplicationUserAgent() {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name, user_agent;
|
||||
if (!base::RemoveChars(browser->GetName(), " ", &name))
|
||||
name = browser->GetName();
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -22,6 +22,8 @@ std::string GetOverriddenApplicationVersion();
|
||||
|
||||
std::string GetApplicationName();
|
||||
std::string GetApplicationVersion();
|
||||
// Returns the user agent of Electron.
|
||||
std::string GetApplicationUserAgent();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
PCWSTR GetRawAppUserModelID();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 0
|
||||
// clang-format off
|
||||
#define ATOM_PRE_RELEASE_VERSION -nightly.20190122
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.3
|
||||
// clang-format on
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/time/time.h"
|
||||
@@ -414,7 +415,7 @@ DWORD CrashService::AsyncSendDump(void* context) {
|
||||
const DWORD kSleepSchedule[] = {24 * kOneHour, 8 * kOneHour, 4 * kOneHour,
|
||||
kOneHour, 15 * kOneMinute, 0};
|
||||
|
||||
int retry_round = arraysize(kSleepSchedule) - 1;
|
||||
int retry_round = base::size(kSleepSchedule) - 1;
|
||||
|
||||
do {
|
||||
::Sleep(kSleepSchedule[retry_round]);
|
||||
|
||||
@@ -38,6 +38,10 @@ ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& s,
|
||||
} else if (str == "plus") {
|
||||
*shifted = true;
|
||||
return ui::VKEY_OEM_PLUS;
|
||||
} else if (str == "capslock") {
|
||||
return ui::VKEY_CAPITAL;
|
||||
} else if (str == "numlock") {
|
||||
return ui::VKEY_NUMLOCK;
|
||||
} else if (str == "tab") {
|
||||
return ui::VKEY_TAB;
|
||||
} else if (str == "num0") {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -151,7 +152,7 @@ v8::Local<v8::Value> BindFunctionWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Function> bind_func =
|
||||
v8::Local<v8::Function>::Cast(bind.ToLocalChecked());
|
||||
v8::Local<v8::Value> converted[] = {func, arg1, arg2};
|
||||
return bind_func->Call(context, func, arraysize(converted), converted)
|
||||
return bind_func->Call(context, func, base::size(converted), converted)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
|
||||
@@ -198,16 +198,16 @@ bool Converter<net::HttpResponseHeaders*>::FromV8(
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto headers = v8::Local<v8::Object>::Cast(val);
|
||||
auto keys = headers->GetOwnPropertyNames();
|
||||
auto keys = headers->GetOwnPropertyNames(context).ToLocalChecked();
|
||||
for (uint32_t i = 0; i < keys->Length(); i++) {
|
||||
v8::Local<v8::String> keyVal;
|
||||
if (!keys->Get(i)->ToString(context).ToLocal(&keyVal)) {
|
||||
v8::Local<v8::Value> keyVal;
|
||||
if (!keys->Get(context, i).ToLocal(&keyVal)) {
|
||||
return false;
|
||||
}
|
||||
std::string key;
|
||||
mate::ConvertFromV8(isolate, keyVal, &key);
|
||||
|
||||
auto localVal = headers->Get(keyVal);
|
||||
auto localVal = headers->Get(context, keyVal).ToLocalChecked();
|
||||
if (localVal->IsArray()) {
|
||||
auto values = v8::Local<v8::Array>::Cast(localVal);
|
||||
for (uint32_t j = 0; j < values->Length(); j++) {
|
||||
|
||||
@@ -27,12 +27,12 @@ Converter<scoped_refptr<network::ResourceRequestBody>>::ToV8(
|
||||
for (const auto& element : *(val->elements())) {
|
||||
auto post_data_dict = std::make_unique<base::DictionaryValue>();
|
||||
auto type = element.type();
|
||||
if (type == network::DataElement::TYPE_BYTES) {
|
||||
if (type == network::mojom::DataElementType::kBytes) {
|
||||
auto bytes = std::make_unique<base::Value>(std::vector<char>(
|
||||
element.bytes(), element.bytes() + (element.length())));
|
||||
post_data_dict->SetString("type", "rawData");
|
||||
post_data_dict->Set("bytes", std::move(bytes));
|
||||
} else if (type == network::DataElement::TYPE_FILE) {
|
||||
} else if (type == network::mojom::DataElementType::kFile) {
|
||||
post_data_dict->SetString("type", "file");
|
||||
post_data_dict->SetKey("filePath",
|
||||
base::Value(element.path().AsUTF8Unsafe()));
|
||||
@@ -40,7 +40,7 @@ Converter<scoped_refptr<network::ResourceRequestBody>>::ToV8(
|
||||
post_data_dict->SetInteger("length", static_cast<int>(element.length()));
|
||||
post_data_dict->SetDouble(
|
||||
"modificationTime", element.expected_modification_time().ToDoubleT());
|
||||
} else if (type == network::DataElement::TYPE_BLOB) {
|
||||
} else if (type == network::mojom::DataElementType::kBlob) {
|
||||
post_data_dict->SetString("type", "blob");
|
||||
post_data_dict->SetString("blobUUID", element.blob_uuid());
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ v8::Local<v8::Value> V8ValueConverter::ToV8Value(
|
||||
return handle_scope.Escape(ToV8ValueImpl(context->GetIsolate(), value));
|
||||
}
|
||||
|
||||
base::Value* V8ValueConverter::FromV8Value(
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Value(
|
||||
v8::Local<v8::Value> val,
|
||||
v8::Local<v8::Context> context) const {
|
||||
v8::Context::Scope context_scope(context);
|
||||
@@ -180,7 +180,8 @@ v8::Local<v8::Value> V8ValueConverter::ToV8ValueImpl(
|
||||
case base::Value::Type::STRING: {
|
||||
std::string val = value->GetString();
|
||||
return v8::String::NewFromUtf8(isolate, val.c_str(),
|
||||
v8::String::kNormalString, val.length());
|
||||
v8::NewStringType::kNormal, val.length())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
case base::Value::Type::LIST:
|
||||
@@ -288,38 +289,38 @@ v8::Local<v8::Value> V8ValueConverter::ToArrayBuffer(
|
||||
return v8::Uint8Array::New(array_buffer, 0, length);
|
||||
}
|
||||
|
||||
base::Value* V8ValueConverter::FromV8ValueImpl(FromV8ValueState* state,
|
||||
v8::Local<v8::Value> val,
|
||||
v8::Isolate* isolate) const {
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8ValueImpl(
|
||||
FromV8ValueState* state,
|
||||
v8::Local<v8::Value> val,
|
||||
v8::Isolate* isolate) const {
|
||||
FromV8ValueState::Level state_level(state);
|
||||
if (state->HasReachedMaxRecursionDepth())
|
||||
return nullptr;
|
||||
|
||||
if (val->IsExternal())
|
||||
return std::make_unique<base::Value>().release();
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
if (val->IsNull())
|
||||
return std::make_unique<base::Value>().release();
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
|
||||
if (val->IsBoolean())
|
||||
return new base::Value(val->ToBoolean(context).ToLocalChecked()->Value());
|
||||
return std::make_unique<base::Value>(val->ToBoolean(isolate)->Value());
|
||||
|
||||
if (val->IsInt32())
|
||||
return new base::Value(val->ToInt32(context).ToLocalChecked()->Value());
|
||||
return std::make_unique<base::Value>(val.As<v8::Int32>()->Value());
|
||||
|
||||
if (val->IsNumber()) {
|
||||
double val_as_double = val->ToNumber(context).ToLocalChecked()->Value();
|
||||
double val_as_double = val.As<v8::Number>()->Value();
|
||||
if (!std::isfinite(val_as_double))
|
||||
return nullptr;
|
||||
return new base::Value(val_as_double);
|
||||
return std::make_unique<base::Value>(val_as_double);
|
||||
}
|
||||
|
||||
if (val->IsString()) {
|
||||
v8::String::Utf8Value utf8(isolate,
|
||||
val->ToString(context).ToLocalChecked());
|
||||
return new base::Value(std::string(*utf8, utf8.length()));
|
||||
v8::String::Utf8Value utf8(isolate, val);
|
||||
return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
|
||||
}
|
||||
|
||||
if (val->IsUndefined())
|
||||
@@ -329,15 +330,16 @@ base::Value* V8ValueConverter::FromV8ValueImpl(FromV8ValueState* state,
|
||||
if (val->IsDate()) {
|
||||
v8::Date* date = v8::Date::Cast(*val);
|
||||
v8::Local<v8::Value> toISOString =
|
||||
date->Get(v8::String::NewFromUtf8(isolate, "toISOString"));
|
||||
date->Get(v8::String::NewFromUtf8(isolate, "toISOString",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
if (toISOString->IsFunction()) {
|
||||
v8::Local<v8::Value> result = toISOString.As<v8::Function>()
|
||||
->Call(context, val, 0, nullptr)
|
||||
.ToLocalChecked();
|
||||
if (!result.IsEmpty()) {
|
||||
v8::String::Utf8Value utf8(isolate,
|
||||
result->ToString(context).ToLocalChecked());
|
||||
return new base::Value(std::string(*utf8, utf8.length()));
|
||||
v8::String::Utf8Value utf8(isolate, result);
|
||||
return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,10 +347,8 @@ base::Value* V8ValueConverter::FromV8ValueImpl(FromV8ValueState* state,
|
||||
if (val->IsRegExp()) {
|
||||
if (!reg_exp_allowed_)
|
||||
// JSON.stringify converts to an object.
|
||||
return FromV8Object(val->ToObject(context).ToLocalChecked(), state,
|
||||
isolate);
|
||||
return new base::Value(*v8::String::Utf8Value(
|
||||
isolate, val->ToString(context).ToLocalChecked()));
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
return std::make_unique<base::Value>(*v8::String::Utf8Value(isolate, val));
|
||||
}
|
||||
|
||||
// v8::Value doesn't have a ToArray() method for some reason.
|
||||
@@ -359,8 +359,7 @@ base::Value* V8ValueConverter::FromV8ValueImpl(FromV8ValueState* state,
|
||||
if (!function_allowed_)
|
||||
// JSON.stringify refuses to convert function(){}.
|
||||
return nullptr;
|
||||
return FromV8Object(val->ToObject(context).ToLocalChecked(), state,
|
||||
isolate);
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
}
|
||||
|
||||
if (node::Buffer::HasInstance(val)) {
|
||||
@@ -368,20 +367,20 @@ base::Value* V8ValueConverter::FromV8ValueImpl(FromV8ValueState* state,
|
||||
}
|
||||
|
||||
if (val->IsObject()) {
|
||||
return FromV8Object(val->ToObject(context).ToLocalChecked(), state,
|
||||
isolate);
|
||||
return FromV8Object(val.As<v8::Object>(), state, isolate);
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Unexpected v8 value type encountered.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
base::Value* V8ValueConverter::FromV8Array(v8::Local<v8::Array> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Array(
|
||||
v8::Local<v8::Array> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
ScopedUniquenessGuard uniqueness_guard(state, val);
|
||||
if (!uniqueness_guard.is_valid())
|
||||
return std::make_unique<base::Value>().release();
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
std::unique_ptr<v8::Context::Scope> scope;
|
||||
// If val was created in a different context than our current one, change to
|
||||
@@ -390,45 +389,54 @@ base::Value* V8ValueConverter::FromV8Array(v8::Local<v8::Array> val,
|
||||
val->CreationContext() != isolate->GetCurrentContext())
|
||||
scope.reset(new v8::Context::Scope(val->CreationContext()));
|
||||
|
||||
auto* result = new base::ListValue();
|
||||
std::unique_ptr<base::ListValue> result(new base::ListValue());
|
||||
|
||||
// Only fields with integer keys are carried over to the ListValue.
|
||||
for (uint32_t i = 0; i < val->Length(); ++i) {
|
||||
v8::TryCatch try_catch(isolate);
|
||||
v8::Local<v8::Value> child_v8 = val->Get(i);
|
||||
if (try_catch.HasCaught()) {
|
||||
v8::Local<v8::Value> child_v8;
|
||||
v8::MaybeLocal<v8::Value> maybe_child =
|
||||
val->Get(isolate->GetCurrentContext(), i);
|
||||
if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) {
|
||||
LOG(ERROR) << "Getter for index " << i << " threw an exception.";
|
||||
child_v8 = v8::Null(isolate);
|
||||
}
|
||||
|
||||
if (!val->HasRealIndexedProperty(i))
|
||||
if (!val->HasRealIndexedProperty(isolate->GetCurrentContext(), i)
|
||||
.FromMaybe(false)) {
|
||||
result->Append(std::make_unique<base::Value>());
|
||||
continue;
|
||||
}
|
||||
|
||||
base::Value* child = FromV8ValueImpl(state, child_v8, isolate);
|
||||
std::unique_ptr<base::Value> child =
|
||||
FromV8ValueImpl(state, child_v8, isolate);
|
||||
if (child)
|
||||
result->Append(std::unique_ptr<base::Value>(child));
|
||||
result->Append(std::move(child));
|
||||
else
|
||||
// JSON.stringify puts null in places where values don't serialize, for
|
||||
// example undefined and functions. Emulate that behavior.
|
||||
result->Append(std::make_unique<base::Value>());
|
||||
}
|
||||
return result;
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
base::Value* V8ValueConverter::FromNodeBuffer(v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
return new base::Value(std::vector<char>(
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromNodeBuffer(
|
||||
v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
std::vector<char> buffer(
|
||||
node::Buffer::Data(value),
|
||||
node::Buffer::Data(value) + node::Buffer::Length(value)));
|
||||
node::Buffer::Data(value) + node::Buffer::Length(value));
|
||||
return std::make_unique<base::Value>(std::move(buffer));
|
||||
}
|
||||
|
||||
base::Value* V8ValueConverter::FromV8Object(v8::Local<v8::Object> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
std::unique_ptr<base::Value> V8ValueConverter::FromV8Object(
|
||||
v8::Local<v8::Object> val,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const {
|
||||
ScopedUniquenessGuard uniqueness_guard(state, val);
|
||||
if (!uniqueness_guard.is_valid())
|
||||
return std::make_unique<base::Value>().release();
|
||||
return std::make_unique<base::Value>();
|
||||
|
||||
std::unique_ptr<v8::Context::Scope> scope;
|
||||
// If val was created in a different context than our current one, change to
|
||||
@@ -438,10 +446,15 @@ base::Value* V8ValueConverter::FromV8Object(v8::Local<v8::Object> val,
|
||||
scope.reset(new v8::Context::Scope(val->CreationContext()));
|
||||
|
||||
auto result = std::make_unique<base::DictionaryValue>();
|
||||
v8::Local<v8::Array> property_names(val->GetOwnPropertyNames());
|
||||
v8::Local<v8::Array> property_names;
|
||||
if (!val->GetOwnPropertyNames(isolate->GetCurrentContext())
|
||||
.ToLocal(&property_names)) {
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < property_names->Length(); ++i) {
|
||||
v8::Local<v8::Value> key(property_names->Get(i));
|
||||
v8::Local<v8::Value> key =
|
||||
property_names->Get(isolate->GetCurrentContext(), i).ToLocalChecked();
|
||||
|
||||
// Extend this test to cover more types as necessary and if sensible.
|
||||
if (!key->IsString() && !key->IsNumber()) {
|
||||
@@ -451,21 +464,21 @@ base::Value* V8ValueConverter::FromV8Object(v8::Local<v8::Object> val,
|
||||
continue;
|
||||
}
|
||||
|
||||
v8::String::Utf8Value name_utf8(
|
||||
isolate, key->ToString(isolate->GetCurrentContext()).ToLocalChecked());
|
||||
v8::String::Utf8Value name_utf8(isolate, key);
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
v8::Local<v8::Value> child_v8 = val->Get(key);
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
v8::Local<v8::Value> child_v8;
|
||||
v8::MaybeLocal<v8::Value> maybe_child =
|
||||
val->Get(isolate->GetCurrentContext(), key);
|
||||
if (try_catch.HasCaught() || !maybe_child.ToLocal(&child_v8)) {
|
||||
LOG(ERROR) << "Getter for property " << *name_utf8
|
||||
<< " threw an exception.";
|
||||
child_v8 = v8::Null(isolate);
|
||||
}
|
||||
|
||||
std::unique_ptr<base::Value> child(
|
||||
FromV8ValueImpl(state, child_v8, isolate));
|
||||
if (!child.get())
|
||||
std::unique_ptr<base::Value> child =
|
||||
FromV8ValueImpl(state, child_v8, isolate);
|
||||
if (!child)
|
||||
// JSON.stringify skips properties whose values don't serialize, for
|
||||
// example undefined and functions. Emulate that behavior.
|
||||
continue;
|
||||
@@ -497,7 +510,7 @@ base::Value* V8ValueConverter::FromV8Object(v8::Local<v8::Object> val,
|
||||
std::move(child));
|
||||
}
|
||||
|
||||
return result.release();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "v8/include/v8.h"
|
||||
@@ -26,8 +28,9 @@ class V8ValueConverter {
|
||||
void SetStripNullFromObjects(bool val);
|
||||
v8::Local<v8::Value> ToV8Value(const base::Value* value,
|
||||
v8::Local<v8::Context> context) const;
|
||||
base::Value* FromV8Value(v8::Local<v8::Value> value,
|
||||
v8::Local<v8::Context> context) const;
|
||||
std::unique_ptr<base::Value> FromV8Value(
|
||||
v8::Local<v8::Value> value,
|
||||
v8::Local<v8::Context> context) const;
|
||||
|
||||
private:
|
||||
class FromV8ValueState;
|
||||
@@ -43,18 +46,18 @@ class V8ValueConverter {
|
||||
v8::Local<v8::Value> ToArrayBuffer(v8::Isolate* isolate,
|
||||
const base::Value* value) const;
|
||||
|
||||
base::Value* FromV8ValueImpl(FromV8ValueState* state,
|
||||
v8::Local<v8::Value> value,
|
||||
v8::Isolate* isolate) const;
|
||||
base::Value* FromV8Array(v8::Local<v8::Array> array,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
base::Value* FromNodeBuffer(v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
base::Value* FromV8Object(v8::Local<v8::Object> object,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromV8ValueImpl(FromV8ValueState* state,
|
||||
v8::Local<v8::Value> value,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromV8Array(v8::Local<v8::Array> array,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromNodeBuffer(v8::Local<v8::Value> value,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
std::unique_ptr<base::Value> FromV8Object(v8::Local<v8::Object> object,
|
||||
FromV8ValueState* state,
|
||||
v8::Isolate* isolate) const;
|
||||
|
||||
// If true, we will convert RegExp JavaScript objects to string.
|
||||
bool reg_exp_allowed_ = false;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#undef DISALLOW_COPY_AND_ASSIGN
|
||||
#undef NO_RETURN
|
||||
#undef LIKELY
|
||||
#undef arraysize
|
||||
#undef debug_string // This is defined in macOS SDK in AssertMacros.h.
|
||||
#undef require_string // This is defined in macOS SDK in AssertMacros.h.
|
||||
#include "env-inl.h"
|
||||
|
||||
@@ -179,11 +179,20 @@ const char kDisableHttpCache[] = "disable-http-cache";
|
||||
const char kStandardSchemes[] = "standard-schemes";
|
||||
|
||||
// Register schemes to handle service worker.
|
||||
const char kRegisterServiceWorkerSchemes[] = "register-service-worker-schemes";
|
||||
const char kServiceWorkerSchemes[] = "service-worker-schemes";
|
||||
|
||||
// Register schemes as secure.
|
||||
const char kSecureSchemes[] = "secure-schemes";
|
||||
|
||||
// Register schemes as bypassing CSP.
|
||||
const char kBypassCSPSchemes[] = "bypasscsp-schemes";
|
||||
|
||||
// Register schemes as support fetch API.
|
||||
const char kFetchSchemes[] = "fetch-schemes";
|
||||
|
||||
// Register schemes as CORS enabled.
|
||||
const char kCORSSchemes[] = "cors-schemes";
|
||||
|
||||
// The browser process app model ID
|
||||
const char kAppUserModelId[] = "app-user-model-id";
|
||||
|
||||
|
||||
@@ -89,8 +89,11 @@ extern const char kPpapiFlashPath[];
|
||||
extern const char kPpapiFlashVersion[];
|
||||
extern const char kDisableHttpCache[];
|
||||
extern const char kStandardSchemes[];
|
||||
extern const char kRegisterServiceWorkerSchemes[];
|
||||
extern const char kServiceWorkerSchemes[];
|
||||
extern const char kSecureSchemes[];
|
||||
extern const char kBypassCSPSchemes[];
|
||||
extern const char kFetchSchemes[];
|
||||
extern const char kCORSSchemes[];
|
||||
extern const char kAppUserModelId[];
|
||||
extern const char kAppPath[];
|
||||
|
||||
|
||||
@@ -141,8 +141,11 @@ void Beep() {
|
||||
|
||||
bool GetLoginItemEnabled() {
|
||||
BOOL enabled = NO;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
// SMJobCopyDictionary does not work in sandbox (see rdar://13626319)
|
||||
CFArrayRef jobs = SMCopyAllJobDictionaries(kSMDomainUserLaunchd);
|
||||
#pragma clang diagnostic pop
|
||||
NSArray* jobs_ = CFBridgingRelease(jobs);
|
||||
NSString* identifier = GetLoginHelperBundleIdentifier();
|
||||
if (jobs_ && [jobs_ count] > 0) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user