diff --git a/README.md b/README.md index 213580a5e2a..f32fbfab929 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,11 @@ locations: forums - `#atom-shell` channel on Freenode - [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack +- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)* - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-jp`](https://electron-jp.slack.com) *(Japanese)* -- [`electron-tr`](https://electron-tr.slack.com) *(Turkish)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)* - [`electron-id`](https://electron-id.slack.com) *(Indonesia)* Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index 8e2a6c57309..09683211c58 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -93,9 +93,9 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path, std::vector codecs; codecs.push_back(kCdmSupportedCodecVp8); codecs.push_back(kCdmSupportedCodecVp9); -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) codecs.push_back(kCdmSupportedCodecAvc1); -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) std::string codec_string = base::JoinString( codecs, std::string(1, kCdmSupportedCodecsValueDelimiter)); widevine_cdm_mime_type.additional_param_names.push_back( @@ -198,11 +198,19 @@ base::string16 AtomContentClient::GetLocalizedString(int message_id) const { return l10n_util::GetStringUTF16(message_id); } -void AtomContentClient::AddAdditionalSchemes( - std::vector* standard_schemes, - std::vector* referrer_schemes, - std::vector* savable_schemes) { - standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT}); +void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) { + schemes->standard_schemes.push_back("chrome-extension"); + + std::vector splited; + ConvertStringWithSeparatorToVector(&splited, ",", + switches::kRegisterServiceWorkerSchemes); + for (const std::string& scheme : splited) + schemes->service_worker_schemes.push_back(scheme); + schemes->service_worker_schemes.push_back(url::kFileScheme); + + ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes); + for (const std::string& scheme : splited) + schemes->secure_schemes.push_back(scheme); } void AtomContentClient::AddPepperPlugins( @@ -214,25 +222,4 @@ void AtomContentClient::AddPepperPlugins( ComputeBuiltInPlugins(plugins); } -void AtomContentClient::AddServiceWorkerSchemes( - std::set* service_worker_schemes) { - std::vector schemes; - ConvertStringWithSeparatorToVector(&schemes, ",", - switches::kRegisterServiceWorkerSchemes); - for (const std::string& scheme : schemes) - service_worker_schemes->insert(scheme); - - service_worker_schemes->insert(url::kFileScheme); -} - -void AtomContentClient::AddSecureSchemesAndOrigins( - std::set* secure_schemes, - std::set* secure_origins) { - std::vector schemes; - ConvertStringWithSeparatorToVector(&schemes, ",", switches::kSecureSchemes); - for (const std::string& scheme : schemes) - secure_schemes->insert(scheme); -} - - } // namespace atom diff --git a/atom/app/atom_content_client.h b/atom/app/atom_content_client.h index e396dc23c8e..fcd26f84183 100644 --- a/atom/app/atom_content_client.h +++ b/atom/app/atom_content_client.h @@ -23,17 +23,9 @@ class AtomContentClient : public brightray::ContentClient { std::string GetProduct() const override; std::string GetUserAgent() const override; base::string16 GetLocalizedString(int message_id) const override; - void AddAdditionalSchemes( - std::vector* standard_schemes, - std::vector* referrer_schemes, - std::vector* savable_schemes) override; + void AddAdditionalSchemes(Schemes* schemes) override; void AddPepperPlugins( std::vector* plugins) override; - void AddServiceWorkerSchemes( - std::set* service_worker_schemes) override; - void AddSecureSchemesAndOrigins( - std::set* secure_schemes, - std::set* secure_origins) override; private: DISALLOW_COPY_AND_ASSIGN(AtomContentClient); diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 115041d0082..cf5cb4386cb 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -34,12 +34,12 @@ #include "chrome/browser/icon_manager.h" #include "chrome/common/chrome_paths.h" #include "content/public/browser/browser_accessibility_state.h" +#include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/render_frame_host.h" #include "content/public/common/content_switches.h" #include "media/audio/audio_manager.h" -#include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "net/ssl/ssl_cert_request_info.h" #include "ui/base/l10n/l10n_util.h" @@ -337,6 +337,17 @@ namespace api { namespace { +class AppIdProcessIterator : public base::ProcessIterator { + public: + AppIdProcessIterator() : base::ProcessIterator(nullptr) {} + + protected: + bool IncludeEntry() override { + return (entry().parent_pid() == base::GetCurrentProcId() || + entry().pid() == base::GetCurrentProcId()); + } +}; + IconLoader::IconSize GetIconSizeByString(const std::string& size) { if (size == "small") { return IconLoader::IconSize::SMALL; @@ -453,8 +464,8 @@ int ImportIntoCertStore( if (!cert_path.empty()) { if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) { - auto module = model->cert_db()->GetPublicModule(); - rv = model->ImportFromPKCS12(module, + auto module = model->cert_db()->GetPrivateSlot(); + rv = model->ImportFromPKCS12(module.get(), file_data, password, true, @@ -912,6 +923,47 @@ void App::GetFileIcon(const base::FilePath& path, } } +std::vector App::GetAppMemoryInfo(v8::Isolate* isolate) { + AppIdProcessIterator process_iterator; + auto process_entry = process_iterator.NextProcessEntry(); + std::vector result; + + while (process_entry != nullptr) { + int64_t pid = process_entry->pid(); + auto process = base::Process::OpenWithExtraPrivileges(pid); + +#if defined(OS_MACOSX) + std::unique_ptr metrics( + base::ProcessMetrics::CreateProcessMetrics( + process.Handle(), content::BrowserChildProcessHost::GetPortProvider())); +#else + std::unique_ptr metrics( + base::ProcessMetrics::CreateProcessMetrics(process.Handle())); +#endif + + mate::Dictionary pid_dict = mate::Dictionary::CreateEmpty(isolate); + mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate); + + memory_dict.Set("workingSetSize", + static_cast(metrics->GetWorkingSetSize() >> 10)); + memory_dict.Set("peakWorkingSetSize", + static_cast(metrics->GetPeakWorkingSetSize() >> 10)); + + size_t private_bytes, shared_bytes; + if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) { + memory_dict.Set("privateBytes", static_cast(private_bytes >> 10)); + memory_dict.Set("sharedBytes", static_cast(shared_bytes >> 10)); + } + + pid_dict.Set("memory", memory_dict); + pid_dict.Set("pid", pid); + result.push_back(pid_dict); + process_entry = process_iterator.NextProcessEntry(); + } + + return result; +} + // static mate::Handle App::Create(v8::Isolate* isolate) { return mate::CreateHandle(isolate, new App(isolate)); @@ -983,7 +1035,8 @@ void App::BuildPrototype( &App::IsAccessibilitySupportEnabled) .SetMethod("disableHardwareAcceleration", &App::DisableHardwareAcceleration) - .SetMethod("getFileIcon", &App::GetFileIcon); + .SetMethod("getFileIcon", &App::GetFileIcon) + .SetMethod("getAppMemoryInfo", &App::GetAppMemoryInfo); } } // namespace api diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index a87b88bc464..9543e4b74b2 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -13,10 +13,12 @@ #include "atom/browser/browser.h" #include "atom/browser/browser_observer.h" #include "atom/common/native_mate_converters/callback.h" +#include "base/process/process_iterator.h" #include "base/task/cancelable_task_tracker.h" #include "chrome/browser/icon_manager.h" #include "chrome/browser/process_singleton.h" #include "content/public/browser/gpu_data_manager_observer.h" +#include "native_mate/dictionary.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" @@ -141,6 +143,8 @@ class App : public AtomBrowserClient::Delegate, void GetFileIcon(const base::FilePath& path, mate::Arguments* args); + std::vector GetAppMemoryInfo(v8::Isolate* isolate); + #if defined(OS_WIN) // Get the current Jump List settings. v8::Local GetJumpListSettings(); diff --git a/atom/browser/api/atom_api_browser_view.cc b/atom/browser/api/atom_api_browser_view.cc index dc17fce9e9a..d37d2df41c5 100644 --- a/atom/browser/api/atom_api_browser_view.cc +++ b/atom/browser/api/atom_api_browser_view.cc @@ -75,7 +75,7 @@ void BrowserView::Init(v8::Isolate* isolate, } BrowserView::~BrowserView() { - api_web_contents_->DestroyWebContents(); + api_web_contents_->DestroyWebContents(true /* async */); } // static diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 2ce9e12f6c5..9f58922fd0a 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -62,6 +62,10 @@ struct Converter { switch (val) { case net::CookieStore::ChangeCause::INSERTED: case net::CookieStore::ChangeCause::EXPLICIT: + case net::CookieStore::ChangeCause::EXPLICIT_DELETE_BETWEEN: + case net::CookieStore::ChangeCause::EXPLICIT_DELETE_PREDICATE: + case net::CookieStore::ChangeCause::EXPLICIT_DELETE_SINGLE: + case net::CookieStore::ChangeCause::EXPLICIT_DELETE_CANONICAL: return mate::StringToV8(isolate, "explicit"); case net::CookieStore::ChangeCause::OVERWRITE: return mate::StringToV8(isolate, "overwrite"); @@ -228,8 +232,8 @@ void SetCookieOnIO(scoped_refptr getter, GetCookieStore(getter)->SetCookieWithDetailsAsync( GURL(url), name, value, domain, path, creation_time, expiration_time, last_access_time, secure, http_only, - net::CookieSameSite::DEFAULT_MODE, false, - net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback)); + net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT, + base::Bind(OnSetCookie, callback)); } } // namespace diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index 90999a4f602..07582318525 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -9,7 +9,6 @@ #include "atom/browser/atom_browser_main_parts.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/value_converter.h" -#include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/web_contents.h" @@ -45,12 +44,23 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, const std::string& message) { DCHECK(agent_host == agent_host_.get()); - std::unique_ptr parsed_message(base::JSONReader::Read(message)); - if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY)) - return; + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + + v8::Local local_message = + v8::String::NewFromUtf8(isolate(), message.data()); + v8::MaybeLocal parsed_message = v8::JSON::Parse( + isolate()->GetCurrentContext(), local_message); + if (parsed_message.IsEmpty()) { + return; + } + + std::unique_ptr dict(new base::DictionaryValue()); + if (!mate::ConvertFromV8(isolate(), parsed_message.ToLocalChecked(), + dict.get())) { + return; + } - base::DictionaryValue* dict = - static_cast(parsed_message.get()); int id; if (!dict->GetInteger("id", &id)) { std::string method; diff --git a/atom/browser/api/atom_api_desktop_capturer.cc b/atom/browser/api/atom_api_desktop_capturer.cc index 118b3e3bdc6..79feb7520b0 100644 --- a/atom/browser/api/atom_api_desktop_capturer.cc +++ b/atom/browser/api/atom_api_desktop_capturer.cc @@ -4,6 +4,8 @@ #include "atom/browser/api/atom_api_desktop_capturer.h" +using base::PlatformThreadRef; + #include "atom/common/api/atom_api_native_image.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "base/strings/utf_string_conversions.h" diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index cb9f17f704f..efa8750eb9b 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -129,7 +129,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showOpenDialog", &ShowOpenDialog); dict.SetMethod("showSaveDialog", &ShowSaveDialog); -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_WIN) dict.SetMethod("showCertificateTrustDialog", &certificate_trust::ShowCertificateTrust); #endif diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index e3b15ed4329..4ff8c5c6bab 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -50,20 +50,25 @@ void RegisterStandardSchemes(const std::vector& schemes, mate::Arguments* args) { g_standard_schemes = schemes; + 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_WITHOUT_PORT); + if (secure) { + url::AddSecureScheme(scheme.c_str()); + } policy->RegisterWebSafeScheme(scheme); } - // add switches to register as standard + // Add the schemes to command line switches, so child processes can also + // register them. base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( atom::switches::kStandardSchemes, base::JoinString(schemes, ",")); - - mate::Dictionary opts; - bool secure = false; - if (args->GetNext(&opts) && opts.Get("secure", &secure) && secure) { - // add switches to register as secure + if (secure) { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( atom::switches::kSecureSchemes, base::JoinString(schemes, ",")); } diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 83d103a631f..3a2d5f44007 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -432,7 +432,8 @@ void DownloadIdCallback(content::DownloadManager* download_manager, last_modified, offset, length, std::string(), content::DownloadItem::INTERRUPTED, content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false); + content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, + std::vector()); } } // namespace diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b2c4c9b09b6..fedb5af844f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -77,6 +77,7 @@ #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "ui/display/screen.h" +#include "ui/events/base_event_utils.h" #if !defined(OS_MACOSX) #include "ui/aura/window.h" @@ -418,15 +419,28 @@ WebContents::~WebContents() { guest_delegate_->Destroy(); RenderViewDeleted(web_contents()->GetRenderViewHost()); - DestroyWebContents(); + + if (type_ == WEB_VIEW) { + DestroyWebContents(false /* async */); + } else { + if (type_ == BROWSER_WINDOW && owner_window()) { + owner_window()->CloseContents(nullptr); + } else { + DestroyWebContents(true /* async */); + } + // The WebContentsDestroyed will not be called automatically because we + // destroy the webContents in the next tick. So we have to manually + // call it here to make sure "destroyed" event is emitted. + WebContentsDestroyed(); + } } } -void WebContents::DestroyWebContents() { +void WebContents::DestroyWebContents(bool async) { // This event is only for internal use, which is emitted when WebContents is // being destroyed. Emit("will-destroy"); - ResetManagedWebContents(); + ResetManagedWebContents(async); } bool WebContents::DidAddMessageToConsole(content::WebContents* source, @@ -479,7 +493,7 @@ void WebContents::AddNewContents(content::WebContents* source, if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture, initial_rect.x(), initial_rect.y(), initial_rect.width(), initial_rect.height())) { - api_web_contents->DestroyWebContents(); + api_web_contents->DestroyWebContents(true /* async */); } } @@ -556,8 +570,8 @@ bool WebContents::PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { - if (event.type == blink::WebInputEvent::Type::RawKeyDown - || event.type == blink::WebInputEvent::Type::KeyUp) + if (event.type() == blink::WebInputEvent::Type::RawKeyDown || + event.type() == blink::WebInputEvent::Type::KeyUp) return Emit("before-input-event", event); else return false; @@ -818,10 +832,8 @@ void WebContents::DidFinishNavigation( void WebContents::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { - if (entry) - Emit("-page-title-updated", entry->GetTitle(), explicit_set); - else - Emit("-page-title-updated", "", explicit_set); + auto title = entry ? entry->GetTitle() : base::string16(); + Emit("page-title-updated", title, explicit_set); } void WebContents::DidUpdateFaviconURL( @@ -863,6 +875,15 @@ void WebContents::Observe(int type, } } +void WebContents::BeforeUnloadDialogCancelled() { + if (deferred_load_url_.id) { + auto& controller = web_contents()->GetController(); + if (!controller.GetPendingEntry()) { + deferred_load_url_.id = 0; + } + } +} + void WebContents::DevToolsReloadPage() { Emit("devtools-reload-page"); } @@ -879,7 +900,7 @@ void WebContents::DevToolsOpened() { devtools_web_contents_.Reset(isolate(), handle.ToV8()); // Set inspected tabID. - base::FundamentalValue tab_id(ID()); + base::Value tab_id(ID()); managed_web_contents()->CallClientFunction( "DevToolsAPI.setInspectedTabId", &tab_id, nullptr, nullptr); @@ -952,7 +973,7 @@ void WebContents::NavigationEntryCommitted( int64_t WebContents::GetID() const { int64_t process_id = web_contents()->GetRenderProcessHost()->GetID(); - int64_t routing_id = web_contents()->GetRoutingID(); + int64_t routing_id = web_contents()->GetRenderViewHost()->GetRoutingID(); int64_t rv = (process_id << 32) + routing_id; return rv; } @@ -1308,7 +1329,7 @@ void WebContents::SelectAll() { } void WebContents::Unselect() { - web_contents()->Unselect(); + web_contents()->CollapseSelection(); } void WebContents::Replace(const base::string16& word) { @@ -1398,7 +1419,10 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, return; } } else if (blink::WebInputEvent::isKeyboardEventType(type)) { - content::NativeWebKeyboardEvent keyboard_event; + content::NativeWebKeyboardEvent keyboard_event( + blink::WebKeyboardEvent::RawKeyDown, + blink::WebInputEvent::NoModifiers, + ui::EventTimeForNow()); if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) { host->ForwardKeyboardEvent(keyboard_event); return; @@ -1488,8 +1512,7 @@ void WebContents::CapturePage(mate::Arguments* args) { } const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - if (!view || !host) { + if (!view) { callback.Run(gfx::Image()); return; } @@ -1509,10 +1532,10 @@ void WebContents::CapturePage(mate::Arguments* args) { if (scale > 1.0f) bitmap_size = gfx::ScaleToCeiledSize(view_size, scale); - host->CopyFromBackingStore(gfx::Rect(rect.origin(), view_size), - bitmap_size, - base::Bind(&OnCapturePageDone, callback), - kBGRA_8888_SkColorType); + view->CopyFromSurface(gfx::Rect(rect.origin(), view_size), + bitmap_size, + base::Bind(&OnCapturePageDone, callback), + kBGRA_8888_SkColorType); } void WebContents::OnCursorChange(const content::WebCursor& cursor) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1301ed15f7f..1f926dbd7a5 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -78,7 +78,7 @@ class WebContents : public mate::TrackableObject, v8::Local prototype); // Notifies to destroy any guest web contents before destroying self. - void DestroyWebContents(); + void DestroyWebContents(bool async); int64_t GetID() const; int GetProcessID() const; @@ -340,6 +340,7 @@ class WebContents : public mate::TrackableObject, void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) override; + void BeforeUnloadDialogCancelled() override; // brightray::InspectableWebContentsDelegate: void DevToolsReloadPage() override; diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 72b8e33ef7b..6862915f9cf 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -173,7 +173,7 @@ void Window::WillDestroyNativeObject() { } void Window::OnWindowClosed() { - api_web_contents_->DestroyWebContents(); + api_web_contents_->DestroyWebContents(true /* async */); RemoveFromWeakMap(); window_->RemoveObserver(this); diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index b5009e15794..076ebde9826 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -24,6 +24,7 @@ FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, view_(view), callback_(callback), only_dirty_(only_dirty), + source_id_for_copy_request_(base::UnguessableToken::Create()), weak_factory_(this) { } @@ -32,8 +33,7 @@ bool FrameSubscriber::ShouldCaptureFrame( base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { - const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr; - if (!view_ || !host) + if (!view_) return false; if (dirty_rect.IsEmpty()) @@ -54,7 +54,7 @@ bool FrameSubscriber::ShouldCaptureFrame( rect = gfx::Rect(rect.origin(), bitmap_size); - host->CopyFromBackingStore( + view_->CopyFromSurface( rect, rect.size(), base::Bind(&FrameSubscriber::OnFrameDelivered, @@ -64,6 +64,10 @@ bool FrameSubscriber::ShouldCaptureFrame( return false; } +const base::UnguessableToken& FrameSubscriber::GetSourceIdForCopyRequest() { + return source_id_for_copy_request_; +} + void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, const gfx::Rect& damage_rect, const SkBitmap& bitmap, diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index f1c7f0af45e..3761f144d04 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -7,9 +7,9 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h" #include "content/public/browser/readback_types.h" #include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" @@ -32,6 +32,7 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) override; + const base::UnguessableToken& GetSourceIdForCopyRequest() override; private: void OnFrameDelivered(const FrameCaptureCallback& callback, @@ -44,6 +45,8 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { FrameCaptureCallback callback_; bool only_dirty_; + base::UnguessableToken source_id_for_copy_request_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 9598a0d1e1c..6cede9c0112 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -322,28 +322,27 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() { } bool AtomBrowserClient::CanCreateWindow( + int opener_render_process_id, + int opener_render_frame_id, const GURL& opener_url, const GURL& opener_top_level_frame_url, const GURL& source_origin, - WindowContainerType container_type, + content::mojom::WindowContainerType container_type, const GURL& target_url, const content::Referrer& referrer, const std::string& frame_name, WindowOpenDisposition disposition, - const blink::WebWindowFeatures& features, + const blink::mojom::WindowFeatures& features, const std::vector& additional_features, const scoped_refptr& body, bool user_gesture, bool opener_suppressed, content::ResourceContext* context, - int render_process_id, - int opener_render_view_id, - int opener_render_frame_id, bool* no_javascript_access) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (IsRendererSandboxed(render_process_id) - || RendererUsesNativeWindowOpen(render_process_id)) { + if (IsRendererSandboxed(opener_render_process_id) + || RendererUsesNativeWindowOpen(opener_render_process_id)) { *no_javascript_access = false; return true; } @@ -357,7 +356,7 @@ bool AtomBrowserClient::CanCreateWindow( disposition, additional_features, body, - render_process_id, + opener_render_process_id, opener_render_frame_id)); } diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index cd73b559e60..c9a58981a2c 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -80,23 +80,22 @@ class AtomBrowserClient : public brightray::BrowserClient, std::unique_ptr delegate) override; void ResourceDispatcherHostCreated() override; bool CanCreateWindow( + int opener_render_process_id, + int opener_render_frame_id, const GURL& opener_url, const GURL& opener_top_level_frame_url, const GURL& source_origin, - WindowContainerType container_type, + content::mojom::WindowContainerType container_type, const GURL& target_url, const content::Referrer& referrer, const std::string& frame_name, WindowOpenDisposition disposition, - const blink::WebWindowFeatures& features, + const blink::mojom::WindowFeatures& features, const std::vector& additional_features, const scoped_refptr& body, bool user_gesture, bool opener_suppressed, content::ResourceContext* context, - int render_process_id, - int opener_render_view_id, - int opener_render_frame_id, bool* no_javascript_access) override; void GetAdditionalAllowedSchemesForFileSystem( std::vector* schemes) override; diff --git a/atom/browser/atom_javascript_dialog_manager.cc b/atom/browser/atom_javascript_dialog_manager.cc index f874a99db55..79f82d99441 100644 --- a/atom/browser/atom_javascript_dialog_manager.cc +++ b/atom/browser/atom_javascript_dialog_manager.cc @@ -13,27 +13,27 @@ #include "base/strings/utf_string_conversions.h" #include "ui/gfx/image/image_skia.h" -using content::JavaScriptMessageType; +using content::JavaScriptDialogType; namespace atom { void AtomJavaScriptDialogManager::RunJavaScriptDialog( content::WebContents* web_contents, const GURL& origin_url, - JavaScriptMessageType message_type, + JavaScriptDialogType dialog_type, const base::string16& message_text, const base::string16& default_prompt_text, const DialogClosedCallback& callback, bool* did_suppress_message) { - if (message_type != JavaScriptMessageType::JAVASCRIPT_MESSAGE_TYPE_ALERT && - message_type != JavaScriptMessageType::JAVASCRIPT_MESSAGE_TYPE_CONFIRM) { + if (dialog_type != JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_ALERT && + dialog_type != JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) { callback.Run(false, base::string16()); return; } std::vector buttons = {"OK"}; - if (message_type == JavaScriptMessageType::JAVASCRIPT_MESSAGE_TYPE_CONFIRM) { + if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) { buttons.push_back("Cancel"); } @@ -55,7 +55,6 @@ void AtomJavaScriptDialogManager::RunBeforeUnloadDialog( void AtomJavaScriptDialogManager::CancelDialogs( content::WebContents* web_contents, - bool suppress_callbacks, bool reset_state) { } diff --git a/atom/browser/atom_javascript_dialog_manager.h b/atom/browser/atom_javascript_dialog_manager.h index 01cc76248c8..56b62afe877 100644 --- a/atom/browser/atom_javascript_dialog_manager.h +++ b/atom/browser/atom_javascript_dialog_manager.h @@ -17,7 +17,7 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager { void RunJavaScriptDialog( content::WebContents* web_contents, const GURL& origin_url, - content::JavaScriptMessageType javascript_message_type, + content::JavaScriptDialogType dialog_type, const base::string16& message_text, const base::string16& default_prompt_text, const DialogClosedCallback& callback, @@ -27,7 +27,6 @@ class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager { bool is_reload, const DialogClosedCallback& callback) override; void CancelDialogs(content::WebContents* web_contents, - bool suppress_callbacks, bool reset_state) override; private: diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index b22f4253237..e890618be73 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -131,7 +131,7 @@ int AtomPermissionManager::RequestPermissions( auto web_contents = content::WebContents::FromRenderFrameHost(render_frame_host); - int request_id = pending_requests_.Add(new PendingRequest( + int request_id = pending_requests_.Add(base::MakeUnique( render_frame_host, permissions, response_callback)); for (size_t i = 0; i < permissions.size(); ++i) { @@ -187,12 +187,6 @@ blink::mojom::PermissionStatus AtomPermissionManager::GetPermissionStatus( return blink::mojom::PermissionStatus::GRANTED; } -void AtomPermissionManager::RegisterPermissionUsage( - content::PermissionType permission, - const GURL& requesting_origin, - const GURL& embedding_origin) { -} - int AtomPermissionManager::SubscribePermissionStatusChange( content::PermissionType permission, const GURL& requesting_origin, diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index 7b74fe3fba4..b8a768a0794 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -66,9 +66,6 @@ class AtomPermissionManager : public content::PermissionManager { content::PermissionType permission, const GURL& requesting_origin, const GURL& embedding_origin) override; - void RegisterPermissionUsage(content::PermissionType permission, - const GURL& requesting_origin, - const GURL& embedding_origin) override; int SubscribePermissionStatusChange( content::PermissionType permission, const GURL& requesting_origin, @@ -79,7 +76,7 @@ class AtomPermissionManager : public content::PermissionManager { private: class PendingRequest; - using PendingRequestsMap = IDMap; + using PendingRequestsMap = IDMap>; RequestHandler request_handler_; diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index a10f959dce9..06ac0089714 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -188,8 +188,13 @@ void CommonWebContentsDelegate::SetOwnerWindow( } } -void CommonWebContentsDelegate::ResetManagedWebContents() { - web_contents_.reset(); +void CommonWebContentsDelegate::ResetManagedWebContents(bool async) { + if (async) { + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, + web_contents_.release()); + } else { + web_contents_.reset(); + } } content::WebContents* CommonWebContentsDelegate::GetWebContents() const { @@ -489,9 +494,9 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorkCalculated( int request_id, const std::string& file_system_path, int total_work) { - base::FundamentalValue request_id_value(request_id); + base::Value request_id_value(request_id); base::StringValue file_system_path_value(file_system_path); - base::FundamentalValue total_work_value(total_work); + base::Value total_work_value(total_work); web_contents_->CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated", &request_id_value, &file_system_path_value, @@ -502,9 +507,9 @@ void CommonWebContentsDelegate::OnDevToolsIndexingWorked( int request_id, const std::string& file_system_path, int worked) { - base::FundamentalValue request_id_value(request_id); + base::Value request_id_value(request_id); base::StringValue file_system_path_value(file_system_path); - base::FundamentalValue worked_value(worked); + base::Value worked_value(worked); web_contents_->CallClientFunction("DevToolsAPI.indexingWorked", &request_id_value, &file_system_path_value, @@ -515,7 +520,7 @@ void CommonWebContentsDelegate::OnDevToolsIndexingDone( int request_id, const std::string& file_system_path) { devtools_indexing_jobs_.erase(request_id); - base::FundamentalValue request_id_value(request_id); + base::Value request_id_value(request_id); base::StringValue file_system_path_value(file_system_path); web_contents_->CallClientFunction("DevToolsAPI.indexingDone", &request_id_value, @@ -531,7 +536,7 @@ void CommonWebContentsDelegate::OnDevToolsSearchCompleted( for (const auto& file_path : file_paths) { file_paths_value.AppendString(file_path); } - base::FundamentalValue request_id_value(request_id); + base::Value request_id_value(request_id); base::StringValue file_system_path_value(file_system_path); web_contents_->CallClientFunction("DevToolsAPI.searchCompleted", &request_id_value, diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index 27209411c72..d1d26314966 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -112,7 +112,7 @@ class CommonWebContentsDelegate #endif // Destroy the managed InspectableWebContents object. - void ResetManagedWebContents(); + void ResetManagedWebContents(bool async); private: // Callback for when DevToolsSaveToFile has completed. diff --git a/atom/browser/common_web_contents_delegate_mac.mm b/atom/browser/common_web_contents_delegate_mac.mm index c7660613793..079d17624c9 100644 --- a/atom/browser/common_web_contents_delegate_mac.mm +++ b/atom/browser/common_web_contents_delegate_mac.mm @@ -20,7 +20,7 @@ void CommonWebContentsDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { if (event.skip_in_browser || - event.type == content::NativeWebKeyboardEvent::Char) + event.type() == content::NativeWebKeyboardEvent::Char) return; // Escape exits tabbed fullscreen mode. diff --git a/atom/browser/javascript_environment.cc b/atom/browser/javascript_environment.cc index b3e01c1c300..d13b955972f 100644 --- a/atom/browser/javascript_environment.cc +++ b/atom/browser/javascript_environment.cc @@ -8,16 +8,45 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" +#include "base/threading/thread_task_runner_handle.h" #include "content/public/common/content_switches.h" -#include "gin/array_buffer.h" #include "gin/v8_initializer.h" +#if defined(OS_WIN) +#include "atom/node/osfhandle.h" +#endif + #include "atom/common/node_includes.h" namespace atom { +void* ArrayBufferAllocator::Allocate(size_t length) { +#if defined(OS_WIN) + return node::ArrayBufferCalloc(length); +#else + return calloc(1, length); +#endif +} + +void* ArrayBufferAllocator::AllocateUninitialized(size_t length) { +#if defined(OS_WIN) + return node::ArrayBufferMalloc(length); +#else + return malloc(length); +#endif +} + +void ArrayBufferAllocator::Free(void* data, size_t length) { +#if defined(OS_WIN) + node::ArrayBufferFree(data, length); +#else + free(data); +#endif +} + JavascriptEnvironment::JavascriptEnvironment() : initialized_(Initialize()), + isolate_holder_(base::ThreadTaskRunnerHandle::Get()), isolate_(isolate_holder_.isolate()), isolate_scope_(isolate_), locker_(isolate_), @@ -44,7 +73,7 @@ bool JavascriptEnvironment::Initialize() { gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, gin::IsolateHolder::kStableV8Extras, - gin::ArrayBufferAllocator::SharedInstance()); + &allocator_); return true; } diff --git a/atom/browser/javascript_environment.h b/atom/browser/javascript_environment.h index 43a7295f902..75d1629f661 100644 --- a/atom/browser/javascript_environment.h +++ b/atom/browser/javascript_environment.h @@ -14,6 +14,14 @@ class Environment; namespace atom { +// ArrayBuffer's allocator, used on Chromium's side. +class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { + public: + void* Allocate(size_t length) override; + void* AllocateUninitialized(size_t length) override; + void Free(void* data, size_t length) override; +}; + // Manage the V8 isolate and context automatically. class JavascriptEnvironment { public: @@ -31,6 +39,7 @@ class JavascriptEnvironment { bool Initialize(); bool initialized_; + ArrayBufferAllocator allocator_; gin::IsolateHolder isolate_holder_; v8::Isolate* isolate_; v8::Isolate::Scope isolate_scope_; diff --git a/atom/browser/loader/layered_resource_handler.cc b/atom/browser/loader/layered_resource_handler.cc index 8b41b1ad638..c22ddd355de 100644 --- a/atom/browser/loader/layered_resource_handler.cc +++ b/atom/browser/loader/layered_resource_handler.cc @@ -15,12 +15,12 @@ LayeredResourceHandler::LayeredResourceHandler( LayeredResourceHandler::~LayeredResourceHandler() {} -bool LayeredResourceHandler::OnResponseStarted( +void LayeredResourceHandler::OnResponseStarted( content::ResourceResponse* response, - bool* defer) { + std::unique_ptr controller) { if (delegate_) delegate_->OnResponseStarted(response); - return next_handler_->OnResponseStarted(response, defer); + next_handler_->OnResponseStarted(response, std::move(controller)); } } // namespace atom diff --git a/atom/browser/loader/layered_resource_handler.h b/atom/browser/loader/layered_resource_handler.h index db3a974eea3..9aad269c7e6 100644 --- a/atom/browser/loader/layered_resource_handler.h +++ b/atom/browser/loader/layered_resource_handler.h @@ -26,8 +26,9 @@ class LayeredResourceHandler : public content::LayeredResourceHandler { ~LayeredResourceHandler() override; // content::LayeredResourceHandler: - bool OnResponseStarted(content::ResourceResponse* response, - bool* defer) override; + void OnResponseStarted( + content::ResourceResponse* response, + std::unique_ptr controller) override; private: Delegate* delegate_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9dc119e239d..330d48226dc 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -1458,7 +1458,7 @@ void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& it } void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) { - switch (event.type) { + switch (event.type()) { case blink::WebInputEvent::GestureScrollBegin: case blink::WebInputEvent::GestureScrollUpdate: case blink::WebInputEvent::GestureScrollEnd: diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 7e6f23947c2..ed524cbdcbc 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -86,7 +86,7 @@ bool IsAltKey(const content::NativeWebKeyboardEvent& event) { bool IsAltModifier(const content::NativeWebKeyboardEvent& event) { typedef content::NativeWebKeyboardEvent::Modifiers Modifiers; - int modifiers = event.modifiers; + int modifiers = event.modifiers(); modifiers &= ~Modifiers::NumLockOn; modifiers &= ~Modifiers::CapsLockOn; return (modifiers == Modifiers::AltKey) || @@ -767,13 +767,14 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { } void NativeWindowViews::SetHasShadow(bool has_shadow) { - wm::SetShadowType( + wm::SetShadowElevation( GetNativeWindow(), - has_shadow ? wm::SHADOW_TYPE_RECTANGULAR : wm::SHADOW_TYPE_NONE); + has_shadow ? wm::ShadowElevation::MEDIUM : wm::ShadowElevation::NONE); } bool NativeWindowViews::HasShadow() { - return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE; + return GetNativeWindow()->GetProperty(wm::kShadowElevationKey) + != wm::ShadowElevation::NONE; } void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) { @@ -1234,10 +1235,10 @@ void NativeWindowViews::HandleKeyboardEvent( // Show accelerator when "Alt" is pressed. if (menu_bar_visible_ && IsAltKey(event)) menu_bar_->SetAcceleratorVisibility( - event.type == blink::WebInputEvent::RawKeyDown); + event.type() == blink::WebInputEvent::RawKeyDown); // Show the submenu when "Alt+Key" is pressed. - if (event.type == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) && + if (event.type() == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) && IsAltModifier(event)) { if (!menu_bar_visible_ && (menu_bar_->GetAcceleratorIndex(event.windowsKeyCode) != -1)) @@ -1250,10 +1251,10 @@ void NativeWindowViews::HandleKeyboardEvent( return; // Toggle the menu bar only when a single Alt is released. - if (event.type == blink::WebInputEvent::RawKeyDown && IsAltKey(event)) { + if (event.type() == blink::WebInputEvent::RawKeyDown && IsAltKey(event)) { // When a single Alt is pressed: menu_bar_alt_pressed_ = true; - } else if (event.type == blink::WebInputEvent::KeyUp && IsAltKey(event) && + } else if (event.type() == blink::WebInputEvent::KeyUp && IsAltKey(event) && menu_bar_alt_pressed_) { // When a single Alt is released right after a Alt is pressed: menu_bar_alt_pressed_ = false; diff --git a/atom/browser/net/atom_url_request_job_factory.cc b/atom/browser/net/atom_url_request_job_factory.cc index 92c4eb40a97..d0488085f5f 100644 --- a/atom/browser/net/atom_url_request_job_factory.cc +++ b/atom/browser/net/atom_url_request_job_factory.cc @@ -50,15 +50,16 @@ bool AtomURLRequestJobFactory::InterceptProtocol( return false; ProtocolHandler* original_protocol_handler = protocol_handler_map_[scheme]; protocol_handler_map_[scheme] = protocol_handler.release(); - original_protocols_.set(scheme, base::WrapUnique(original_protocol_handler)); + original_protocols_[scheme].reset(original_protocol_handler); return true; } bool AtomURLRequestJobFactory::UninterceptProtocol(const std::string& scheme) { - if (!original_protocols_.contains(scheme)) + auto it = original_protocols_.find(scheme); + if (it == original_protocols_.end()) return false; - protocol_handler_map_[scheme] = - original_protocols_.take_and_erase(scheme).release(); + protocol_handler_map_[scheme] = it->second.release(); + original_protocols_.erase(it); return true; } @@ -78,7 +79,9 @@ bool AtomURLRequestJobFactory::HasProtocolHandler( } void AtomURLRequestJobFactory::Clear() { - base::STLDeleteValues(&protocol_handler_map_); + for (auto& it : protocol_handler_map_) + delete it.second; + protocol_handler_map_.clear(); } net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( diff --git a/atom/browser/net/atom_url_request_job_factory.h b/atom/browser/net/atom_url_request_job_factory.h index 5b439c2f9cd..16d1ed3b207 100644 --- a/atom/browser/net/atom_url_request_job_factory.h +++ b/atom/browser/net/atom_url_request_job_factory.h @@ -9,9 +9,9 @@ #include #include #include +#include #include -#include "base/containers/scoped_ptr_hash_map.h" #include "net/url_request/url_request_job_factory.h" namespace atom { @@ -64,7 +64,7 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory { ProtocolHandlerMap protocol_handler_map_; // Map that stores the original protocols of schemes. - using OriginalProtocolsMap = base::ScopedPtrHashMap< + using OriginalProtocolsMap = std::unordered_map< std::string, std::unique_ptr>; // Can only be accessed in IO thread. OriginalProtocolsMap original_protocols_; diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index 67fb578650f..0df6bb5c37d 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -59,11 +59,11 @@ void AskForOptions(v8::Isolate* isolate, } bool IsErrorOptions(base::Value* value, int* error) { - if (value->IsType(base::Value::TYPE_DICTIONARY)) { + if (value->IsType(base::Value::Type::DICTIONARY)) { base::DictionaryValue* dict = static_cast(value); if (dict->GetInteger("error", error)) return true; - } else if (value->IsType(base::Value::TYPE_INTEGER)) { + } else if (value->IsType(base::Value::Type::INTEGER)) { if (value->GetAsInteger(error)) return true; } diff --git a/atom/browser/net/url_request_async_asar_job.cc b/atom/browser/net/url_request_async_asar_job.cc index 942f06233e3..86aa7c55067 100644 --- a/atom/browser/net/url_request_async_asar_job.cc +++ b/atom/browser/net/url_request_async_asar_job.cc @@ -7,6 +7,7 @@ #include #include "atom/common/atom_constants.h" +#include "base/threading/sequenced_worker_pool.h" namespace atom { @@ -18,10 +19,10 @@ URLRequestAsyncAsarJob::URLRequestAsyncAsarJob( void URLRequestAsyncAsarJob::StartAsync(std::unique_ptr options) { base::FilePath::StringType file_path; - if (options->IsType(base::Value::TYPE_DICTIONARY)) { + if (options->IsType(base::Value::Type::DICTIONARY)) { static_cast(options.get())->GetString( "path", &file_path); - } else if (options->IsType(base::Value::TYPE_STRING)) { + } else if (options->IsType(base::Value::Type::STRING)) { options->GetAsString(&file_path); } diff --git a/atom/browser/net/url_request_buffer_job.cc b/atom/browser/net/url_request_buffer_job.cc index 70f46030817..fa848862bb2 100644 --- a/atom/browser/net/url_request_buffer_job.cc +++ b/atom/browser/net/url_request_buffer_job.cc @@ -34,13 +34,13 @@ URLRequestBufferJob::URLRequestBufferJob( void URLRequestBufferJob::StartAsync(std::unique_ptr options) { const base::BinaryValue* binary = nullptr; - if (options->IsType(base::Value::TYPE_DICTIONARY)) { + if (options->IsType(base::Value::Type::DICTIONARY)) { base::DictionaryValue* dict = static_cast(options.get()); dict->GetString("mimeType", &mime_type_); dict->GetString("charset", &charset_); dict->GetBinary("data", &binary); - } else if (options->IsType(base::Value::TYPE_BINARY)) { + } else if (options->IsType(base::Value::Type::BINARY)) { options->GetAsBinary(&binary); } diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index a8c13483e6a..ff426dd08c8 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -112,7 +112,7 @@ void URLRequestFetchJob::BeforeStartInUI( } void URLRequestFetchJob::StartAsync(std::unique_ptr options) { - if (!options->IsType(base::Value::TYPE_DICTIONARY)) { + if (!options->IsType(base::Value::Type::DICTIONARY)) { NotifyStartError(net::URLRequestStatus( net::URLRequestStatus::FAILED, net::ERR_NOT_IMPLEMENTED)); return; diff --git a/atom/browser/net/url_request_string_job.cc b/atom/browser/net/url_request_string_job.cc index abec345e63d..60dc323d8ad 100644 --- a/atom/browser/net/url_request_string_job.cc +++ b/atom/browser/net/url_request_string_job.cc @@ -17,13 +17,13 @@ URLRequestStringJob::URLRequestStringJob( } void URLRequestStringJob::StartAsync(std::unique_ptr options) { - if (options->IsType(base::Value::TYPE_DICTIONARY)) { + if (options->IsType(base::Value::Type::DICTIONARY)) { base::DictionaryValue* dict = static_cast(options.get()); dict->GetString("mimeType", &mime_type_); dict->GetString("charset", &charset_); dict->GetString("data", &data_); - } else if (options->IsType(base::Value::TYPE_STRING)) { + } else if (options->IsType(base::Value::Type::STRING)) { options->GetAsString(&data_); } net::URLRequestSimpleJob::Start(); diff --git a/atom/browser/osr/osr_output_device.cc b/atom/browser/osr/osr_output_device.cc index 5f605f668c9..49c4191e21e 100644 --- a/atom/browser/osr/osr_output_device.cc +++ b/atom/browser/osr/osr_output_device.cc @@ -4,7 +4,7 @@ #include "atom/browser/osr/osr_output_device.h" -#include "third_party/skia/include/core/SkDevice.h" +#include "third_party/skia/src/core/SkDevice.h" #include "ui/gfx/skia_util.h" namespace atom { diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 2003118f389..c41a6805c06 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -16,10 +16,11 @@ #include "components/display_compositor/gl_helper.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_view_frame_subscriber.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/context_factory.h" -#include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "media/base/video_frame.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_type.h" @@ -337,6 +338,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( bool transparent, const OnPaintCallback& callback, content::RenderWidgetHost* host, + bool is_guest_view_hack, NativeWindow* native_window) : render_widget_host_(content::RenderWidgetHostImpl::From(host)), native_window_(native_window), @@ -355,19 +357,23 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( render_widget_host_->SetView(this); #if !defined(OS_MACOSX) - content::ImageTransportFactory* factory = - content::ImageTransportFactory::GetInstance(); delegated_frame_host_ = base::MakeUnique( - factory->GetContextFactory()->AllocateFrameSinkId(), this); + AllocateFrameSinkId(is_guest_view_hack), this); root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); #endif #if defined(OS_MACOSX) - CreatePlatformWidget(); + CreatePlatformWidget(is_guest_view_hack); #else + // On macOS the ui::Compositor is created/owned by the platform view. + content::ImageTransportFactory* factory = + content::ImageTransportFactory::GetInstance(); + ui::ContextFactoryPrivate* context_factory_private = + factory->GetContextFactoryPrivate(); compositor_.reset( - new ui::Compositor(content::GetContextFactory(), + new ui::Compositor(context_factory_private->AllocateFrameSinkId(), + content::GetContextFactory(), context_factory_private, base::ThreadTaskRunnerHandle::Get())); compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget()); compositor_->SetRootLayer(root_layer_.get()); @@ -399,6 +405,17 @@ OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() { #endif } +void OffScreenRenderWidgetHostView::OnWindowResize() { + // In offscreen mode call RenderWidgetHostView's SetSize explicitly + auto size = native_window_->GetSize(); + SetSize(size); +} + +void OffScreenRenderWidgetHostView::OnWindowClosed() { + native_window_->RemoveObserver(this); + native_window_ = nullptr; +} + void OffScreenRenderWidgetHostView::OnBeginFrameTimerTick() { const base::TimeTicks frame_time = base::TimeTicks::Now(); const base::TimeDelta vsync_period = @@ -416,10 +433,17 @@ void OffScreenRenderWidgetHostView::SendBeginFrame( base::TimeTicks deadline = display_time - estimated_browser_composite_time; + const cc::BeginFrameArgs& begin_frame_args = + cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, + begin_frame_source_.source_id(), + begin_frame_number_, frame_time, deadline, + vsync_period, cc::BeginFrameArgs::NORMAL); + DCHECK(begin_frame_args.IsValid()); + begin_frame_number_++; + render_widget_host_->Send(new ViewMsg_BeginFrame( render_widget_host_->GetRoutingID(), - cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, - vsync_period, cc::BeginFrameArgs::NORMAL))); + begin_frame_args)); } bool OffScreenRenderWidgetHostView::OnMessageReceived( @@ -481,7 +505,7 @@ bool OffScreenRenderWidgetHostView::HasFocus() const { } bool OffScreenRenderWidgetHostView::IsSurfaceAvailableForCopy() const { - return GetDelegatedFrameHost()->CanCopyToBitmap(); + return GetDelegatedFrameHost()->CanCopyFromCompositingSurface(); } void OffScreenRenderWidgetHostView::Show() { @@ -561,7 +585,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( last_scroll_offset_ = frame.metadata.root_scroll_offset; } - if (frame.delegated_frame_data) { + if (!frame.render_pass_list.empty()) { if (software_output_device_) { if (!begin_frame_timer_.get()) { software_output_device_->SetActive(painting_); @@ -569,13 +593,11 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( // The compositor will draw directly to the SoftwareOutputDevice which // then calls OnPaint. -#if defined(OS_MACOSX) - browser_compositor_->SwapCompositorFrame(output_surface_id, - std::move(frame)); -#else - delegated_frame_host_->SwapDelegatedFrame(output_surface_id, - std::move(frame)); -#endif + // We would normally call BrowserCompositorMac::SwapCompositorFrame on + // macOS, however it contains compositor resize logic that we don't want. + // Consequently we instead call the SwapDelegatedFrame method directly. + GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id, + std::move(frame)); } else { if (!copy_frame_generator_.get()) { copy_frame_generator_.reset( @@ -584,20 +606,17 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( // Determine the damage rectangle for the current frame. This is the same // calculation that SwapDelegatedFrame uses. - cc::RenderPass* root_pass = - frame.delegated_frame_data->render_pass_list.back().get(); + cc::RenderPass* root_pass = frame.render_pass_list.back().get(); gfx::Size frame_size = root_pass->output_rect.size(); gfx::Rect damage_rect = gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); damage_rect.Intersect(gfx::Rect(frame_size)); -#if defined(OS_MACOSX) - browser_compositor_->SwapCompositorFrame(output_surface_id, - std::move(frame)); -#else - delegated_frame_host_->SwapDelegatedFrame(output_surface_id, - std::move(frame)); -#endif + // We would normally call BrowserCompositorMac::SwapCompositorFrame on + // macOS, however it contains compositor resize logic that we don't want. + // Consequently we instead call the SwapDelegatedFrame method directly. + GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id, + std::move(frame)); // Request a copy of the last compositor frame which will eventually call // OnPaint asynchronously. @@ -647,7 +666,7 @@ void OffScreenRenderWidgetHostView::SelectionBoundsChanged( const ViewHostMsg_SelectionBounds_Params &) { } -void OffScreenRenderWidgetHostView::CopyFromCompositingSurface( +void OffScreenRenderWidgetHostView::CopyFromSurface( const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, @@ -656,18 +675,14 @@ void OffScreenRenderWidgetHostView::CopyFromCompositingSurface( src_subrect, dst_size, callback, preferred_color_type); } -void OffScreenRenderWidgetHostView::CopyFromCompositingSurfaceToVideoFrame( +void OffScreenRenderWidgetHostView::CopyFromSurfaceToVideoFrame( const gfx::Rect& src_subrect, - const scoped_refptr& target, + scoped_refptr target, const base::Callback& callback) { GetDelegatedFrameHost()->CopyFromCompositingSurfaceToVideoFrame( src_subrect, target, callback); } -bool OffScreenRenderWidgetHostView::CanCopyToVideoFrame() const { - return GetDelegatedFrameHost()->CanCopyToVideoFrame(); -} - void OffScreenRenderWidgetHostView::BeginFrameSubscription( std::unique_ptr subscriber) { GetDelegatedFrameHost()->BeginFrameSubscription(std::move(subscriber)); @@ -685,12 +700,6 @@ gfx::Rect OffScreenRenderWidgetHostView::GetBoundsInRootWindow() { return gfx::Rect(size_); } -void OffScreenRenderWidgetHostView::LockCompositingSurface() { -} - -void OffScreenRenderWidgetHostView::UnlockCompositingSurface() { -} - void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged( const gfx::Range &, const std::vector&) { } @@ -752,6 +761,40 @@ void OffScreenRenderWidgetHostView::SetBeginFrameSource( #endif // !defined(OS_MACOSX) +bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpace( + const gfx::Point& point, + const cc::SurfaceId& original_surface, + gfx::Point* transformed_point) { + // Transformations use physical pixels rather than DIP, so conversion + // is necessary. + gfx::Point point_in_pixels = + gfx::ConvertPointToPixel(scale_factor_, point); + if (!GetDelegatedFrameHost()->TransformPointToLocalCoordSpace( + point_in_pixels, original_surface, transformed_point)) { + return false; + } + + *transformed_point = + gfx::ConvertPointToDIP(scale_factor_, *transformed_point); + return true; +} + +bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView( + const gfx::Point& point, + RenderWidgetHostViewBase* target_view, + gfx::Point* transformed_point) { + if (target_view == this) { + *transformed_point = point; + return true; + } + + // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion, + // but it is not necessary here because the final target view is responsible + // for converting before computing the final transform. + return GetDelegatedFrameHost()->TransformPointToCoordSpaceForView( + point, target_view, transformed_point); +} + std::unique_ptr OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice( ui::Compositor* compositor) { @@ -894,15 +937,20 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer() { GetCompositor()->SetScaleAndSize(scale_factor_, size_in_pixels); } -void OffScreenRenderWidgetHostView::OnWindowResize() { - // In offscreen mode call RenderWidgetHostView's SetSize explicitly - auto size = native_window_->GetSize(); - SetSize(size); -} - -void OffScreenRenderWidgetHostView::OnWindowClosed() { - native_window_->RemoveObserver(this); - native_window_ = nullptr; +cc::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId( + bool is_guest_view_hack) { + // GuestViews have two RenderWidgetHostViews and so we need to make sure + // we don't have FrameSinkId collisions. + // The FrameSinkId generated here must be unique with FrameSinkId allocated + // in ContextFactoryPrivate. + content::ImageTransportFactory* factory = + content::ImageTransportFactory::GetInstance(); + return is_guest_view_hack + ? factory->GetContextFactoryPrivate()->AllocateFrameSinkId() + : cc::FrameSinkId(base::checked_cast( + render_widget_host_->GetProcess()->GetID()), + base::checked_cast( + render_widget_host_->GetRoutingID())); } } // namespace atom diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index 7380476bee6..d215d73ab9c 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -69,6 +69,7 @@ class OffScreenRenderWidgetHostView OffScreenRenderWidgetHostView(bool transparent, const OnPaintCallback& callback, content::RenderWidgetHost* render_widget_host, + bool is_guest_view_hack, NativeWindow* native_window); ~OffScreenRenderWidgetHostView() override; @@ -126,23 +127,20 @@ class OffScreenRenderWidgetHostView #endif void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params &) override; - void CopyFromCompositingSurface(const gfx::Rect &, - const gfx::Size &, - const content::ReadbackRequestCallback &, - const SkColorType) override; - void CopyFromCompositingSurfaceToVideoFrame( - const gfx::Rect &, - const scoped_refptr &, - const base::Callback &) override; - bool CanCopyToVideoFrame(void) const override; + void CopyFromSurface( + const gfx::Rect& src_subrect, + const gfx::Size& dst_size, + const content::ReadbackRequestCallback& callback, + const SkColorType color_type) override; + void CopyFromSurfaceToVideoFrame( + const gfx::Rect& src_subrect, + scoped_refptr target, + const base::Callback& callback) override; void BeginFrameSubscription( std::unique_ptr) override; void EndFrameSubscription() override; bool HasAcceleratedSurface(const gfx::Size &) override; gfx::Rect GetBoundsInRootWindow(void) override; - void LockCompositingSurface(void) override; - void UnlockCompositingSurface(void) override; void ImeCompositionRangeChanged( const gfx::Range &, const std::vector&) override; gfx::Size GetPhysicalBackingSize() const override; @@ -166,6 +164,15 @@ class OffScreenRenderWidgetHostView void SetBeginFrameSource(cc::BeginFrameSource* source) override; #endif // !defined(OS_MACOSX) + bool TransformPointToLocalCoordSpace( + const gfx::Point& point, + const cc::SurfaceId& original_surface, + gfx::Point* transformed_point) override; + bool TransformPointToCoordSpaceForView( + const gfx::Point& point, + RenderWidgetHostViewBase* target_view, + gfx::Point* transformed_point) override; + // ui::CompositorDelegate: std::unique_ptr CreateSoftwareOutputDevice( ui::Compositor* compositor) override; @@ -182,7 +189,7 @@ class OffScreenRenderWidgetHostView base::TimeDelta vsync_period); #if defined(OS_MACOSX) - void CreatePlatformWidget(); + void CreatePlatformWidget(bool is_guest_view_hack); void DestroyPlatformWidget(); #endif @@ -210,6 +217,8 @@ class OffScreenRenderWidgetHostView void SetupFrameRate(bool force); void ResizeRootLayer(); + cc::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack); + // Weak ptrs. content::RenderWidgetHostImpl* render_widget_host_; NativeWindow* native_window_; @@ -236,6 +245,10 @@ class OffScreenRenderWidgetHostView std::unique_ptr copy_frame_generator_; std::unique_ptr begin_frame_timer_; + // Provides |source_id| for BeginFrameArgs that we create. + cc::StubBeginFrameSource begin_frame_source_; + uint64_t begin_frame_number_ = cc::BeginFrameArgs::kStartingFrameNumber; + #if defined(OS_MACOSX) CALayer* background_layer_; std::unique_ptr browser_compositor_; diff --git a/atom/browser/osr/osr_render_widget_host_view_mac.mm b/atom/browser/osr/osr_render_widget_host_view_mac.mm index 7cf010ff8e2..8e13c2c577d 100644 --- a/atom/browser/osr/osr_render_widget_host_view_mac.mm +++ b/atom/browser/osr/osr_render_widget_host_view_mac.mm @@ -121,10 +121,12 @@ void OffScreenRenderWidgetHostView::SelectionChanged( RenderWidgetHostViewBase::SelectionChanged(text, offset, range); } -void OffScreenRenderWidgetHostView::CreatePlatformWidget() { +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(), true)); + mac_helper_, mac_helper_, render_widget_host_->is_hidden(), true, + AllocateFrameSinkId(is_guest_view_hack))); } void OffScreenRenderWidgetHostView::DestroyPlatformWidget() { diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 0d9c52743bc..8d95017b0e6 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -79,7 +79,8 @@ content::RenderWidgetHostViewBase* content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) { auto relay = NativeWindowRelay::FromWebContents(web_contents_); view_ = new OffScreenRenderWidgetHostView( - transparent_, callback_, render_widget_host, relay->window.get()); + transparent_, callback_, render_widget_host, + is_guest_view_hack, relay->window.get()); return view_; } @@ -88,7 +89,7 @@ content::RenderWidgetHostViewBase* content::RenderWidgetHost* render_widget_host) { auto relay = NativeWindowRelay::FromWebContents(web_contents_); view_ = new OffScreenRenderWidgetHostView( - transparent_, callback_, render_widget_host, relay->window.get()); + transparent_, callback_, render_widget_host, false, relay->window.get()); return view_; } diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index ecd6a28b5cd..989d0410476 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 1.6.7 + 1.7.0 CFBundleShortVersionString - 1.6.7 + 1.7.0 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index f7a9b32351b..af65704a2ea 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,6,7,0 - PRODUCTVERSION 1,6,7,0 + FILEVERSION 1,7,0,0 + PRODUCTVERSION 1,7,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "1.6.7" + VALUE "FileVersion", "1.7.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "1.6.7" + VALUE "ProductVersion", "1.7.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/browser/ui/certificate_trust_mac.mm b/atom/browser/ui/certificate_trust_mac.mm index e0888dd3ea2..be6e6963f46 100644 --- a/atom/browser/ui/certificate_trust_mac.mm +++ b/atom/browser/ui/certificate_trust_mac.mm @@ -69,7 +69,7 @@ auto cert_db = net::CertDatabase::GetInstance(); // This forces Chromium to reload the certificate since it might be trusted // now. - cert_db->NotifyObserversCertDBChanged(cert_.get()); + cert_db->NotifyObserversCertDBChanged(); callback_.Run(); diff --git a/atom/browser/ui/certificate_trust_win.cc b/atom/browser/ui/certificate_trust_win.cc new file mode 100644 index 00000000000..dd26291a2e4 --- /dev/null +++ b/atom/browser/ui/certificate_trust_win.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/ui/certificate_trust.h" + +#include +#include + +#include "base/callback.h" +#include "net/cert/cert_database.h" + +namespace certificate_trust { + +// Add the provided certificate to the Trusted Root Certificate Authorities +// store for the current user. +// +// This requires prompting the user to confirm they trust the certificate. +BOOL AddToTrustedRootStore(const PCCERT_CONTEXT cert_context, + const scoped_refptr& cert) { + auto root_cert_store = CertOpenStore( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_CURRENT_USER, + L"Root"); + + if (root_cert_store == NULL) { + return false; + } + + auto result = CertAddCertificateContextToStore( + root_cert_store, + cert_context, + CERT_STORE_ADD_REPLACE_EXISTING, + NULL); + + if (result) { + // force Chromium to reload it's database for this certificate + auto cert_db = net::CertDatabase::GetInstance(); + cert_db->NotifyObserversCertDBChanged(); + } + + CertCloseStore(root_cert_store, CERT_CLOSE_STORE_FORCE_FLAG); + + return result; +} + +CERT_CHAIN_PARA GetCertificateChainParameters() { + CERT_ENHKEY_USAGE enhkey_usage; + enhkey_usage.cUsageIdentifier = 0; + enhkey_usage.rgpszUsageIdentifier = NULL; + + CERT_USAGE_MATCH cert_usage; + // ensure the rules are applied to the entire chain + cert_usage.dwType = USAGE_MATCH_TYPE_AND; + cert_usage.Usage = enhkey_usage; + + CERT_CHAIN_PARA params = { sizeof(CERT_CHAIN_PARA) }; + params.RequestedUsage = cert_usage; + + return params; +} + +void ShowCertificateTrust(atom::NativeWindow* parent_window, + const scoped_refptr& cert, + const std::string& message, + const ShowTrustCallback& callback) { + PCCERT_CHAIN_CONTEXT chain_context; + + auto cert_context = cert->CreateOSCertChainForCert(); + + auto params = GetCertificateChainParameters(); + + if (CertGetCertificateChain(NULL, + cert_context, + NULL, + NULL, + ¶ms, + NULL, + NULL, + &chain_context)) { + auto error_status = chain_context->TrustStatus.dwErrorStatus; + if (error_status == CERT_TRUST_IS_SELF_SIGNED || + error_status == CERT_TRUST_IS_UNTRUSTED_ROOT) { + // these are the only scenarios we're interested in supporting + AddToTrustedRootStore(cert_context, cert); + } + + CertFreeCertificateChain(chain_context); + } + + CertFreeCertificateContext(cert_context); + + callback.Run(); +} + +} // namespace certificate_trust diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index a21fbc5497a..30a3e6643fb 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -224,6 +224,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSSegmentedControl*)sender).tag]; base::DictionaryValue details; details.SetInteger("selectedIndex", ((NSSegmentedControl*)sender).selectedSegment); + details.SetBoolean("isSelected", [((NSSegmentedControl*)sender) isSelectedForSegment:((NSSegmentedControl*)sender).selectedSegment]); window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); } @@ -520,6 +521,15 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; else control.segmentStyle = NSSegmentStyleAutomatic; + std::string segmentMode; + settings.Get("mode", &segmentMode); + if (segmentMode == "multiple") + control.trackingMode = NSSegmentSwitchTrackingSelectAny; + else if (segmentMode == "buttons") + control.trackingMode = NSSegmentSwitchTrackingMomentary; + else + control.trackingMode = NSSegmentSwitchTrackingSelectOne; + std::vector segments; settings.Get("segments", &segments); diff --git a/atom/browser/ui/message_box_gtk.cc b/atom/browser/ui/message_box_gtk.cc index a7bbe51ecf1..ffaa0a76cd7 100644 --- a/atom/browser/ui/message_box_gtk.cc +++ b/atom/browser/ui/message_box_gtk.cc @@ -41,7 +41,7 @@ class GtkMessageBox : public NativeWindowObserver { const gfx::ImageSkia& icon) : cancel_id_(cancel_id), checkbox_checked_(false), - parent_(static_cast(parent_window)) { + parent_(static_cast(parent_window)) { // Create dialog. dialog_ = gtk_message_dialog_new( nullptr, // parent @@ -94,7 +94,7 @@ class GtkMessageBox : public NativeWindowObserver { // Parent window. if (parent_) { parent_->AddObserver(this); - parent_->SetEnabled(false); + static_cast(parent_)->SetEnabled(false); libgtkui::SetGtkTransientForAura(dialog_, parent_->GetNativeWindow()); gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE); } @@ -104,7 +104,7 @@ class GtkMessageBox : public NativeWindowObserver { gtk_widget_destroy(dialog_); if (parent_) { parent_->RemoveObserver(this); - parent_->SetEnabled(true); + static_cast(parent_)->SetEnabled(true); } } @@ -179,7 +179,7 @@ class GtkMessageBox : public NativeWindowObserver { bool checkbox_checked_; - NativeWindowViews* parent_; + NativeWindow* parent_; GtkWidget* dialog_; MessageBoxCallback callback_; diff --git a/atom/browser/ui/views/global_menu_bar_x11.cc b/atom/browser/ui/views/global_menu_bar_x11.cc index 266d10b96db..d48d86961ba 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.cc +++ b/atom/browser/ui/views/global_menu_bar_x11.cc @@ -9,8 +9,10 @@ // This conflicts with mate::Converter, #undef True #undef False -// and V8. +// and V8, #undef None +// and url_request_status.h, +#undef Status #include #include diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index 617dd3346da..aabed323d2b 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -36,7 +36,7 @@ SubmenuButton::SubmenuButton(const base::string16& title, if (GetUnderlinePosition(title, &accelerator_, &underline_start_, &underline_end_)) - gfx::Canvas::SizeStringInt(GetText(), GetFontList(), &text_width_, + gfx::Canvas::SizeStringInt(GetText(), gfx::FontList(), &text_width_, &text_height_, 0, 0); SetInkDropMode(InkDropMode::ON); @@ -107,8 +107,8 @@ bool SubmenuButton::GetUnderlinePosition(const base::string16& text, void SubmenuButton::GetCharacterPosition( const base::string16& text, int index, int* pos) { int height = 0; - gfx::Canvas::SizeStringInt(text.substr(0, index), GetFontList(), pos, &height, - 0, 0); + gfx::Canvas::SizeStringInt(text.substr(0, index), gfx::FontList(), pos, + &height, 0, 0); } } // namespace atom diff --git a/atom/browser/ui/webui/pdf_viewer_handler.cc b/atom/browser/ui/webui/pdf_viewer_handler.cc index be2f3373055..5829b59f6d3 100644 --- a/atom/browser/ui/webui/pdf_viewer_handler.cc +++ b/atom/browser/ui/webui/pdf_viewer_handler.cc @@ -33,9 +33,8 @@ void CreateResponseHeadersDictionary(const net::HttpResponseHeaders* headers, while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) { base::Value* existing_value = nullptr; if (result->Get(header_name, &existing_value)) { - base::StringValue* existing_string_value = - static_cast(existing_value); - existing_string_value->GetString()->append(", ").append(header_value); + std::string src = existing_value->GetString(); + result->SetString(header_name, src + ", " + header_value); } else { result->SetString(header_name, header_value); } @@ -131,7 +130,7 @@ void PdfViewerHandler::GetDefaultZoom(const base::ListValue* args) { double zoom_level = host_zoom_map->GetDefaultZoomLevel(); ResolveJavascriptCallback( *callback_id, - base::FundamentalValue(content::ZoomLevelToZoomFactor(zoom_level))); + base::Value(content::ZoomLevelToZoomFactor(zoom_level))); } void PdfViewerHandler::GetInitialZoom(const base::ListValue* args) { @@ -145,7 +144,7 @@ void PdfViewerHandler::GetInitialZoom(const base::ListValue* args) { content::HostZoomMap::GetZoomLevel(web_ui()->GetWebContents()); ResolveJavascriptCallback( *callback_id, - base::FundamentalValue(content::ZoomLevelToZoomFactor(zoom_level))); + base::Value(content::ZoomLevelToZoomFactor(zoom_level))); } void PdfViewerHandler::SetZoom(const base::ListValue* args) { @@ -159,7 +158,7 @@ void PdfViewerHandler::SetZoom(const base::ListValue* args) { content::HostZoomMap::SetZoomLevel(web_ui()->GetWebContents(), zoom_level); - ResolveJavascriptCallback(*callback_id, base::FundamentalValue(zoom_level)); + ResolveJavascriptCallback(*callback_id, base::Value(zoom_level)); } void PdfViewerHandler::GetStrings(const base::ListValue* args) { @@ -204,7 +203,7 @@ void PdfViewerHandler::OnZoomLevelChanged( if (change.host == kPdfViewerUIHost) { CallJavascriptFunction( "cr.webUIListenerCallback", base::StringValue("onZoomLevelChanged"), - base::FundamentalValue( + base::Value( content::ZoomLevelToZoomFactor(change.zoom_level))); } } diff --git a/atom/browser/ui/webui/pdf_viewer_ui.cc b/atom/browser/ui/webui/pdf_viewer_ui.cc index 580d1831e58..b6073f8409a 100644 --- a/atom/browser/ui/webui/pdf_viewer_ui.cc +++ b/atom/browser/ui/webui/pdf_viewer_ui.cc @@ -134,7 +134,8 @@ class PdfViewerUI::ResourceRequester content::ResourceDispatcherHostImpl::Get()->InitializeURLRequest( request.get(), content::Referrer(url, blink::WebReferrerPolicyDefault), false, // download. - render_process_id, render_view_id, render_frame_id, resource_context); + render_process_id, render_view_id, render_frame_id, + content::PREVIEWS_OFF, resource_context); content::ResourceRequestInfoImpl* info = content::ResourceRequestInfoImpl::ForRequest(request.get()); @@ -202,7 +203,8 @@ PdfViewerUI::PdfViewerUI(content::BrowserContext* browser_context, content::WebContentsObserver(web_ui->GetWebContents()), src_(src) { pdf_handler_ = new PdfViewerHandler(src); - web_ui->AddMessageHandler(pdf_handler_); + web_ui->AddMessageHandler( + std::unique_ptr(pdf_handler_)); content::URLDataSource::Add(browser_context, new BundledDataSource); } diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 3151da6f171..ef27850370f 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -6,17 +6,17 @@ #include -#include "atom_natives.h" // NOLINT: This file is generated with coffee2c. - #include "atom/common/asar/archive.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" -#include "atom/common/node_includes.h" #include "native_mate/arguments.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" #include "native_mate/wrappable.h" +#include "atom/common/node_includes.h" +#include "atom_natives.h" // NOLINT: This file is generated with js2c. + namespace { class Archive : public mate::Wrappable { @@ -130,7 +130,7 @@ class Archive : public mate::Wrappable { void InitAsarSupport(v8::Isolate* isolate, v8::Local process, v8::Local require) { - // Evaluate asar_init.coffee. + // Evaluate asar_init.js. const char* asar_init_native = reinterpret_cast( static_cast(node::asar_init_data)); v8::Local asar_init = v8::Script::Compile(v8::String::NewFromUtf8( diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index c82589d6b19..f4a64531529 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -13,7 +13,7 @@ #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/node_includes.h" #include "base/logging.h" -#include "base/process/process_metrics.h" +#include "base/sys_info.h" #include "native_mate/dictionary.h" namespace atom { @@ -23,51 +23,6 @@ namespace { // Dummy class type that used for crashing the program. struct DummyClass { bool crash; }; -void Hang() { - for (;;) - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); -} - -v8::Local GetProcessMemoryInfo(v8::Isolate* isolate) { - std::unique_ptr metrics( - base::ProcessMetrics::CreateCurrentProcessMetrics()); - - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("workingSetSize", - static_cast(metrics->GetWorkingSetSize() >> 10)); - dict.Set("peakWorkingSetSize", - static_cast(metrics->GetPeakWorkingSetSize() >> 10)); - - size_t private_bytes, shared_bytes; - if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) { - dict.Set("privateBytes", static_cast(private_bytes >> 10)); - dict.Set("sharedBytes", static_cast(shared_bytes >> 10)); - } - - return dict.GetHandle(); -} - -v8::Local GetSystemMemoryInfo(v8::Isolate* isolate, - mate::Arguments* args) { - base::SystemMemoryInfoKB mem_info; - if (!base::GetSystemMemoryInfo(&mem_info)) { - args->ThrowError("Unable to retrieve system memory information"); - return v8::Undefined(isolate); - } - - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("total", mem_info.total); - dict.Set("free", mem_info.free); - - // NB: These return bogus values on macOS -#if !defined(OS_MACOSX) - dict.Set("swapTotal", mem_info.swap_total); - dict.Set("swapFree", mem_info.swap_free); -#endif - - return dict.GetHandle(); -} - // Called when there is a fatal error in V8, we just crash the process here so // we can get the stack trace. void FatalErrorCallback(const char* location, const char* message) { @@ -81,6 +36,7 @@ void FatalErrorCallback(const char* location, const char* message) { AtomBindings::AtomBindings(uv_loop_t* loop) { uv_async_init(loop, &call_next_tick_async_, OnCallNextTick); call_next_tick_async_.data = this; + metrics_ = base::ProcessMetrics::CreateCurrentProcessMetrics(); } AtomBindings::~AtomBindings() { @@ -97,6 +53,9 @@ void AtomBindings::BindTo(v8::Isolate* isolate, dict.SetMethod("log", &Log); dict.SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo); dict.SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo); + dict.SetMethod("getCPUUsage", + base::Bind(&AtomBindings::GetCPUUsage, base::Unretained(this))); + dict.SetMethod("getIOCounters", &GetIOCounters); #if defined(OS_POSIX) dict.SetMethod("setFdLimit", &base::SetFdLimit); #endif @@ -168,4 +127,81 @@ void AtomBindings::Crash() { static_cast(nullptr)->crash = true; } +// static +void AtomBindings::Hang() { + for (;;) + base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); +} + +// static +v8::Local AtomBindings::GetProcessMemoryInfo(v8::Isolate* isolate) { + std::unique_ptr metrics( + base::ProcessMetrics::CreateCurrentProcessMetrics()); + + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("workingSetSize", + static_cast(metrics->GetWorkingSetSize() >> 10)); + dict.Set("peakWorkingSetSize", + static_cast(metrics->GetPeakWorkingSetSize() >> 10)); + + size_t private_bytes, shared_bytes; + if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes)) { + dict.Set("privateBytes", static_cast(private_bytes >> 10)); + dict.Set("sharedBytes", static_cast(shared_bytes >> 10)); + } + + return dict.GetHandle(); +} + +// static +v8::Local AtomBindings::GetSystemMemoryInfo(v8::Isolate* isolate, + mate::Arguments* args) { + base::SystemMemoryInfoKB mem_info; + if (!base::GetSystemMemoryInfo(&mem_info)) { + args->ThrowError("Unable to retrieve system memory information"); + return v8::Undefined(isolate); + } + + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + dict.Set("total", mem_info.total); + dict.Set("free", mem_info.free); + + // NB: These return bogus values on macOS +#if !defined(OS_MACOSX) + dict.Set("swapTotal", mem_info.swap_total); + dict.Set("swapFree", mem_info.swap_free); +#endif + + return dict.GetHandle(); +} + +v8::Local AtomBindings::GetCPUUsage(v8::Isolate* isolate) { + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + int processor_count = base::SysInfo::NumberOfProcessors(); + dict.Set("percentCPUUsage", + metrics_->GetPlatformIndependentCPUUsage() / processor_count); + dict.Set("idleWakeupsPerSecond", metrics_->GetIdleWakeupsPerSecond()); + + return dict.GetHandle(); +} + +// static +v8::Local AtomBindings::GetIOCounters(v8::Isolate* isolate) { + std::unique_ptr metrics( + base::ProcessMetrics::CreateCurrentProcessMetrics()); + base::IoCounters io_counters; + mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); + + if (metrics->GetIOCounters(&io_counters)) { + dict.Set("readOperationCount", io_counters.ReadOperationCount); + dict.Set("writeOperationCount", io_counters.WriteOperationCount); + dict.Set("otherOperationCount", io_counters.OtherOperationCount); + dict.Set("readTransferCount", io_counters.ReadTransferCount); + dict.Set("writeTransferCount", io_counters.WriteTransferCount); + dict.Set("otherTransferCount", io_counters.OtherTransferCount); + } + + return dict.GetHandle(); +} + } // namespace atom diff --git a/atom/common/api/atom_bindings.h b/atom/common/api/atom_bindings.h index 81574171503..a37497ccc5b 100644 --- a/atom/common/api/atom_bindings.h +++ b/atom/common/api/atom_bindings.h @@ -8,7 +8,9 @@ #include #include "base/macros.h" +#include "base/process/process_metrics.h" #include "base/strings/string16.h" +#include "native_mate/arguments.h" #include "v8/include/v8.h" #include "vendor/node/deps/uv/include/uv.h" @@ -32,6 +34,12 @@ class AtomBindings { static void Log(const base::string16& message); static void Crash(); + static void Hang(); + static v8::Local GetProcessMemoryInfo(v8::Isolate* isolate); + static v8::Local GetSystemMemoryInfo(v8::Isolate* isolate, + mate::Arguments* args); + v8::Local GetCPUUsage(v8::Isolate* isolate); + static v8::Local GetIOCounters(v8::Isolate* isolate); private: void ActivateUVLoop(v8::Isolate* isolate); @@ -40,6 +48,7 @@ class AtomBindings { uv_async_t call_next_tick_async_; std::list pending_next_ticks_; + std::unique_ptr metrics_; DISALLOW_COPY_AND_ASSIGN(AtomBindings); }; diff --git a/atom/common/api/object_life_monitor.cc b/atom/common/api/object_life_monitor.cc index cd5537e8874..cc68130d34b 100644 --- a/atom/common/api/object_life_monitor.cc +++ b/atom/common/api/object_life_monitor.cc @@ -12,8 +12,7 @@ namespace atom { ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate, v8::Local target) - : context_(isolate, isolate->GetCurrentContext()), - target_(isolate, target), + : target_(isolate, target), weak_ptr_factory_(this) { target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter); } diff --git a/atom/common/api/object_life_monitor.h b/atom/common/api/object_life_monitor.h index 73030864b93..e047960e813 100644 --- a/atom/common/api/object_life_monitor.h +++ b/atom/common/api/object_life_monitor.h @@ -22,7 +22,6 @@ class ObjectLifeMonitor { static void OnObjectGC(const v8::WeakCallbackInfo& data); static void Free(const v8::WeakCallbackInfo& data); - v8::Global context_; v8::Global target_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index a3a02996d40..8f75c8fbb57 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -181,7 +181,7 @@ bool Archive::Init() { std::string error; base::JSONReader reader; std::unique_ptr value(reader.ReadToValue(header)); - if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) { + if (!value || !value->IsType(base::Value::Type::DICTIONARY)) { LOG(ERROR) << "Failed to parse header: " << error; return false; } @@ -269,8 +269,9 @@ bool Archive::Realpath(const base::FilePath& path, base::FilePath* realpath) { } bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { - if (external_files_.contains(path)) { - *out = external_files_.get(path)->path(); + auto it = external_files_.find(path.value()); + if (it != external_files_.end()) { + *out = it->second->path(); return true; } @@ -296,7 +297,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { #endif *out = temp_file->path(); - external_files_.set(path, std::move(temp_file)); + external_files_[path.value()] = std::move(temp_file); return true; } diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index 9e3abc3434d..4796d1014b7 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -6,9 +6,9 @@ #define ATOM_COMMON_ASAR_ARCHIVE_H_ #include +#include #include -#include "base/containers/scoped_ptr_hash_map.h" #include "base/files/file.h" #include "base/files/file_path.h" @@ -75,8 +75,8 @@ class Archive { std::unique_ptr header_; // Cached external temporary files. - base::ScopedPtrHashMap> - external_files_; + std::unordered_map> external_files_; DISALLOW_COPY_AND_ASSIGN(Archive); }; diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 79ece65408b..92b79c0c14d 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_COMMON_ATOM_VERSION_H_ #define ATOM_MAJOR_VERSION 1 -#define ATOM_MINOR_VERSION 6 -#define ATOM_PATCH_VERSION 7 +#define ATOM_MINOR_VERSION 7 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index 4838875354a..e25591c3bf8 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "56.0.2924.87" +#define CHROME_VERSION_STRING "58.0.3029.110" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ diff --git a/atom/common/common_message_generator.cc b/atom/common/common_message_generator.cc index 854fc8778e9..6b14637cf3c 100644 --- a/atom/common/common_message_generator.cc +++ b/atom/common/common_message_generator.cc @@ -31,4 +31,3 @@ namespace IPC { namespace IPC { #include "atom/common/common_message_generator.h" } // namespace IPC - diff --git a/atom/common/common_message_generator.h b/atom/common/common_message_generator.h index a63c40b9623..8b41a17f29b 100644 --- a/atom/common/common_message_generator.h +++ b/atom/common/common_message_generator.h @@ -9,4 +9,5 @@ #include "chrome/common/tts_messages.h" #include "chrome/common/widevine_cdm_messages.h" #include "chrome/common/chrome_utility_messages.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "components/pdf/common/pdf_messages.h" diff --git a/atom/common/crash_reporter/crash_reporter_mac.mm b/atom/common/crash_reporter/crash_reporter_mac.mm index 4b59be5dfca..990e1b3b195 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.mm +++ b/atom/common/crash_reporter/crash_reporter_mac.mm @@ -43,11 +43,16 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name, base::FilePath handler_path = framework_bundle_path.Append("Resources").Append("crashpad_handler"); + std::vector args = { + "--no-rate-limit", + "--no-upload-gzip", // not all servers accept gzip + }; + crashpad::CrashpadClient crashpad_client; crashpad_client.StartHandler(handler_path, crashes_dir, crashes_dir, submit_url, StringMap(), - std::vector(), + args, true, false); } // @autoreleasepool diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index d4ee1e44891..5acfe545e49 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -14,7 +14,8 @@ #include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" -#include "third_party/WebKit/public/web/WebCache.h" +#include "third_party/WebKit/public/platform/WebMouseEvent.h" +#include "third_party/WebKit/public/platform/WebMouseWheelEvent.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "ui/base/clipboard/clipboard.h" @@ -149,12 +150,14 @@ bool Converter::FromV8( mate::Dictionary dict; if (!ConvertFromV8(isolate, val, &dict)) return false; - if (!dict.Get("type", &out->type)) + blink::WebInputEvent::Type type; + if (!dict.Get("type", &type)) return false; + out->setType(type); std::vector modifiers; if (dict.Get("modifiers", &modifiers)) - out->modifiers = VectorToBitArray(modifiers); - out->timeStampSeconds = base::Time::Now().ToDoubleT(); + out->setModifiers(VectorToBitArray(modifiers)); + out->setTimeStampSeconds(base::Time::Now().ToDoubleT()); return true; } @@ -175,19 +178,19 @@ bool Converter::FromV8( ui::KeyboardCode keyCode = atom::KeyboardCodeFromStr(str, &shifted); out->windowsKeyCode = keyCode; if (shifted) - out->modifiers |= blink::WebInputEvent::ShiftKey; + out->setModifiers(out->modifiers() | blink::WebInputEvent::ShiftKey); ui::DomCode domCode = ui::UsLayoutKeyboardCodeToDomCode(keyCode); out->domCode = static_cast(domCode); ui::DomKey domKey; ui::KeyboardCode dummy_code; - int flags = atom::WebEventModifiersToEventFlags(out->modifiers); + int flags = atom::WebEventModifiersToEventFlags(out->modifiers()); if (ui::DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &dummy_code)) out->domKey = static_cast(domKey); - if ((out->type == blink::WebInputEvent::Char || - out->type == blink::WebInputEvent::RawKeyDown)) { + if ((out->type() == blink::WebInputEvent::Char || + out->type() == blink::WebInputEvent::RawKeyDown)) { // Make sure to not read beyond the buffer in case some bad code doesn't // NULL-terminate it (this is called from plugins). size_t text_length_cap = blink::WebKeyboardEvent::textLengthCap; @@ -219,20 +222,20 @@ v8::Local Converter::ToV8( v8::Isolate* isolate, const content::NativeWebKeyboardEvent& in) { mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - if (in.type == blink::WebInputEvent::Type::RawKeyDown) + if (in.type() == blink::WebInputEvent::Type::RawKeyDown) dict.Set("type", "keyDown"); - else if (in.type == blink::WebInputEvent::Type::KeyUp) + else if (in.type() == blink::WebInputEvent::Type::KeyUp) dict.Set("type", "keyUp"); dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.domKey)); dict.Set("code", ui::KeycodeConverter::DomCodeToCodeString( static_cast(in.domCode))); using Modifiers = blink::WebInputEvent::Modifiers; - dict.Set("isAutoRepeat", (in.modifiers & Modifiers::IsAutoRepeat) != 0); - dict.Set("shift", (in.modifiers & Modifiers::ShiftKey) != 0); - dict.Set("control", (in.modifiers & Modifiers::ControlKey) != 0); - dict.Set("alt", (in.modifiers & Modifiers::AltKey) != 0); - dict.Set("meta", (in.modifiers & Modifiers::MetaKey) != 0); + dict.Set("isAutoRepeat", (in.modifiers() & Modifiers::IsAutoRepeat) != 0); + dict.Set("shift", (in.modifiers() & Modifiers::ShiftKey) != 0); + dict.Set("control", (in.modifiers() & Modifiers::ControlKey) != 0); + dict.Set("alt", (in.modifiers() & Modifiers::AltKey) != 0); + dict.Set("meta", (in.modifiers() & Modifiers::MetaKey) != 0); return dict.GetHandle(); } @@ -277,7 +280,7 @@ bool Converter::FromV8( bool can_scroll = true; if (dict.Get("canScroll", &can_scroll) && !can_scroll) { out->hasPreciseScrollingDeltas = false; - out->modifiers &= ~blink::WebInputEvent::ControlKey; + out->setModifiers(out->modifiers() & ~blink::WebInputEvent::ControlKey); } #endif return true; @@ -444,7 +447,7 @@ v8::Local Converter::ToV8( mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); dict.Set("count", static_cast(stat.count)); dict.Set("size", static_cast(stat.size)); - dict.Set("liveSize", static_cast(stat.liveSize)); + dict.Set("liveSize", static_cast(stat.decodedSize)); return dict.GetHandle(); } diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index 34156f313e5..7b3a14e8307 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,7 +6,7 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" -#include "third_party/WebKit/public/web/WebCache.h" +#include "third_party/WebKit/public/platform/WebCache.h" #include "third_party/WebKit/public/web/WebContextMenuData.h" namespace blink { diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index 3ba30e14ff4..65620bdb8ba 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -167,42 +167,42 @@ base::Value* V8ValueConverter::FromV8Value( v8::Local V8ValueConverter::ToV8ValueImpl( v8::Isolate* isolate, const base::Value* value) const { switch (value->GetType()) { - case base::Value::TYPE_NULL: + case base::Value::Type::NONE: return v8::Null(isolate); - case base::Value::TYPE_BOOLEAN: { + case base::Value::Type::BOOLEAN: { bool val = false; value->GetAsBoolean(&val); return v8::Boolean::New(isolate, val); } - case base::Value::TYPE_INTEGER: { + case base::Value::Type::INTEGER: { int val = 0; value->GetAsInteger(&val); return v8::Integer::New(isolate, val); } - case base::Value::TYPE_DOUBLE: { + case base::Value::Type::DOUBLE: { double val = 0.0; value->GetAsDouble(&val); return v8::Number::New(isolate, val); } - case base::Value::TYPE_STRING: { + case base::Value::Type::STRING: { std::string val; value->GetAsString(&val); return v8::String::NewFromUtf8( isolate, val.c_str(), v8::String::kNormalString, val.length()); } - case base::Value::TYPE_LIST: + case base::Value::Type::LIST: return ToV8Array(isolate, static_cast(value)); - case base::Value::TYPE_DICTIONARY: + case base::Value::Type::DICTIONARY: return ToV8Object(isolate, static_cast(value)); - case base::Value::TYPE_BINARY: + case base::Value::Type::BINARY: return ToArrayBuffer(isolate, static_cast(value)); @@ -314,13 +314,13 @@ base::Value* V8ValueConverter::FromV8ValueImpl( return base::Value::CreateNullValue().release(); if (val->IsBoolean()) - return new base::FundamentalValue(val->ToBoolean()->Value()); + return new base::Value(val->ToBoolean()->Value()); if (val->IsInt32()) - return new base::FundamentalValue(val->ToInt32()->Value()); + return new base::Value(val->ToInt32()->Value()); if (val->IsNumber()) - return new base::FundamentalValue(val->ToNumber()->Value()); + return new base::Value(val->ToNumber()->Value()); if (val->IsString()) { v8::String::Utf8Value utf8(val->ToString()); @@ -490,7 +490,7 @@ base::Value* V8ValueConverter::FromV8Object( // there *is* a "windowId" property, but since it should be an int, code // on the browser which doesn't additionally check for null will fail. // We can avoid all bugs related to this by stripping null. - if (strip_null_from_objects_ && child->IsType(base::Value::TYPE_NULL)) + if (strip_null_from_objects_ && child->IsType(base::Value::Type::NONE)) continue; result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), diff --git a/atom/common/native_mate_converters/v8_value_converter.h b/atom/common/native_mate_converters/v8_value_converter.h index 2b8dcf85964..ae6113cfeb0 100644 --- a/atom/common/native_mate_converters/v8_value_converter.h +++ b/atom/common/native_mate_converters/v8_value_converter.h @@ -10,10 +10,10 @@ #include "v8/include/v8.h" namespace base { -class BinaryValue; class DictionaryValue; class ListValue; class Value; +using BinaryValue = Value; } namespace atom { diff --git a/atom/common/native_mate_converters/value_converter.cc b/atom/common/native_mate_converters/value_converter.cc index c3c7ae0383c..3ed68136709 100644 --- a/atom/common/native_mate_converters/value_converter.cc +++ b/atom/common/native_mate_converters/value_converter.cc @@ -15,7 +15,7 @@ bool Converter::FromV8(v8::Isolate* isolate, std::unique_ptr converter(new atom::V8ValueConverter); std::unique_ptr value(converter->FromV8Value( val, isolate->GetCurrentContext())); - if (value && value->IsType(base::Value::TYPE_DICTIONARY)) { + if (value && value->IsType(base::Value::Type::DICTIONARY)) { out->Swap(static_cast(value.get())); return true; } else { @@ -36,7 +36,7 @@ bool Converter::FromV8(v8::Isolate* isolate, std::unique_ptr converter(new atom::V8ValueConverter); std::unique_ptr value(converter->FromV8Value( val, isolate->GetCurrentContext())); - if (value->IsType(base::Value::TYPE_LIST)) { + if (value->IsType(base::Value::Type::LIST)) { out->Swap(static_cast(value.get())); return true; } else { diff --git a/atom/node/osfhandle.cc b/atom/node/osfhandle.cc index b0ac8c1ce3b..e9ec03a5c81 100644 --- a/atom/node/osfhandle.cc +++ b/atom/node/osfhandle.cc @@ -7,6 +7,8 @@ #include #define U_I18N_IMPLEMENTATION +#define U_COMMON_IMPLEMENTATION +#define U_COMBINED_IMPLEMENTATION #include "third_party/icu/source/common/unicode/ubidi.h" #include "third_party/icu/source/common/unicode/uchar.h" @@ -15,6 +17,7 @@ #include "third_party/icu/source/common/unicode/unorm.h" #include "third_party/icu/source/common/unicode/urename.h" #include "third_party/icu/source/common/unicode/ustring.h" +#include "third_party/icu/source/i18n/unicode/dtitvfmt.h" #include "third_party/icu/source/i18n/unicode/measfmt.h" #include "third_party/icu/source/i18n/unicode/translit.h" #include "third_party/icu/source/i18n/unicode/ucsdet.h" @@ -22,6 +25,7 @@ #include "third_party/icu/source/i18n/unicode/uregex.h" #include "third_party/icu/source/i18n/unicode/uspoof.h" #include "third_party/icu/source/i18n/unicode/usearch.h" +#include "util-inl.h" #include "v8-profiler.h" #include "v8-inspector.h" @@ -35,6 +39,18 @@ int close(int fd) { return _close(fd); } +void* ArrayBufferCalloc(size_t length) { + return UncheckedCalloc(length); +} + +void* ArrayBufferMalloc(size_t length) { + return UncheckedMalloc(length); +} + +void ArrayBufferFree(void* data, size_t length) { + return ::free(data); +} + void ReferenceSymbols() { // Following symbols are used by electron.exe but got stripped by compiler, // by using the symbols we can force compiler to keep the objects in node.dll, @@ -60,6 +76,9 @@ void ReferenceSymbols() { UMeasureFormatWidth width = UMEASFMT_WIDTH_WIDE; UErrorCode status = U_ZERO_ERROR; icu::MeasureFormat format(icu::Locale::getRoot(), width, status); + icu::DateInterval internal(0, 0); + icu::DateIntervalFormat::createInstance(UnicodeString(), + icu::Locale::getRoot(), status); reinterpret_cast(nullptr)->clone(); } diff --git a/atom/node/osfhandle.h b/atom/node/osfhandle.h index 1427bb89511..58f87198ae2 100644 --- a/atom/node/osfhandle.h +++ b/atom/node/osfhandle.h @@ -21,6 +21,12 @@ namespace node { __declspec(dllexport) int open_osfhandle(intptr_t osfhandle, int flags); __declspec(dllexport) int close(int fd); +// Memory allocation functions from Node's module, used by ArrayBuffer allocator +// to make sure memories are allocated and freed with the same allocator. +__declspec(dllexport) void* ArrayBufferCalloc(size_t length); +__declspec(dllexport) void* ArrayBufferMalloc(size_t length); +__declspec(dllexport) void ArrayBufferFree(void* data, size_t length); + // A trick to force referencing symbols. __declspec(dllexport) void ReferenceSymbols(); diff --git a/atom/renderer/api/atom_api_spell_check_client.cc b/atom/renderer/api/atom_api_spell_check_client.cc index 9a07cbf6eaa..8d434f1aa0c 100644 --- a/atom/renderer/api/atom_api_spell_check_client.cc +++ b/atom/renderer/api/atom_api_spell_check_client.cc @@ -51,13 +51,13 @@ SpellCheckClient::SpellCheckClient(const std::string& language, SpellCheckClient::~SpellCheckClient() {} -void SpellCheckClient::spellCheck( +void SpellCheckClient::checkSpelling( const blink::WebString& text, int& misspelling_start, int& misspelling_len, blink::WebVector* optional_suggestions) { std::vector results; - SpellCheckText(base::string16(text), true, &results); + SpellCheckText(text.utf16(), true, &results); if (results.size() == 1) { misspelling_start = results[0].location; misspelling_len = results[0].length; @@ -66,10 +66,8 @@ void SpellCheckClient::spellCheck( void SpellCheckClient::requestCheckingOfText( const blink::WebString& textToCheck, - const blink::WebVector& markersInText, - const blink::WebVector& markerOffsets, blink::WebTextCheckingCompletion* completionCallback) { - base::string16 text(textToCheck); + base::string16 text(textToCheck.utf16()); if (text.empty() || !HasWordCharacters(text, 0)) { completionCallback->didCancelCheckingText(); return; diff --git a/atom/renderer/api/atom_api_spell_check_client.h b/atom/renderer/api/atom_api_spell_check_client.h index aa6abb0f56b..cb4a36aadf0 100644 --- a/atom/renderer/api/atom_api_spell_check_client.h +++ b/atom/renderer/api/atom_api_spell_check_client.h @@ -13,6 +13,10 @@ #include "native_mate/scoped_persistent.h" #include "third_party/WebKit/public/web/WebSpellCheckClient.h" +namespace blink { +struct WebTextCheckingResult; +} + namespace atom { namespace api { @@ -27,15 +31,13 @@ class SpellCheckClient : public blink::WebSpellCheckClient { private: // blink::WebSpellCheckClient: - void spellCheck( + void checkSpelling( const blink::WebString& text, int& misspelledOffset, int& misspelledLength, blink::WebVector* optionalSuggestions) override; void requestCheckingOfText( const blink::WebString& textToCheck, - const blink::WebVector& markersInText, - const blink::WebVector& markerOffsets, blink::WebTextCheckingCompletion* completionCallback) override; void showSpellingUI(bool show) override; bool isShowingSpellingUI() override; diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index f103b89391d..ac12f974791 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -16,15 +16,15 @@ #include "content/public/renderer/render_view.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" -#include "third_party/WebKit/public/web/WebCache.h" +#include "third_party/WebKit/public/platform/WebCache.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrameWidget.h" #include "third_party/WebKit/public/web/WebInputMethodController.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" #include "third_party/WebKit/public/web/WebScriptSource.h" -#include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/WebKit/public/web/WebView.h" +#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h" #include "atom/common/node_includes.h" @@ -110,7 +110,8 @@ void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) { v8::Local WebFrame::RegisterEmbedderCustomElement( const base::string16& name, v8::Local options) { blink::WebExceptionCode c = 0; - return web_frame_->document().registerEmbedderCustomElement(name, options, c); + return web_frame_->document().registerEmbedderCustomElement( + blink::WebString::fromUTF16(name), options, c); } void WebFrame::RegisterElementResizeCallback( @@ -145,15 +146,14 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args, void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { // TODO(pfrazee): Remove 2.0 - // Register scheme to secure list (https, wss, data). - blink::WebSecurityPolicy::registerURLSchemeAsSecure( - blink::WebString::fromUTF8(scheme)); + blink::SchemeRegistry::registerURLSchemeAsSecure( + WTF::String::fromUTF8(scheme.data(), scheme.length())); } void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) { // Register scheme to bypass pages's Content Security Policy. - blink::WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy( - blink::WebString::fromUTF8(scheme)); + blink::SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy( + WTF::String::fromUTF8(scheme.data(), scheme.length())); } void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme, @@ -175,32 +175,36 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme, } } // Register scheme to privileged list (https, wss, data, chrome-extension) - blink::WebString privileged_scheme(blink::WebString::fromUTF8(scheme)); + WTF::String privileged_scheme( + WTF::String::fromUTF8(scheme.data(), scheme.length())); if (secure) { // TODO(pfrazee): Remove 2.0 - blink::WebSecurityPolicy::registerURLSchemeAsSecure(privileged_scheme); + blink::SchemeRegistry::registerURLSchemeAsSecure(privileged_scheme); } if (bypassCSP) { - blink::WebSecurityPolicy::registerURLSchemeAsBypassingContentSecurityPolicy( + blink::SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy( privileged_scheme); } if (allowServiceWorkers) { - blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers( + blink::SchemeRegistry::registerURLSchemeAsAllowingServiceWorkers( privileged_scheme); } if (supportFetchAPI) { - blink::WebSecurityPolicy::registerURLSchemeAsSupportingFetchAPI( + blink::SchemeRegistry::registerURLSchemeAsSupportingFetchAPI( privileged_scheme); } if (corsEnabled) { - blink::WebSecurityPolicy::registerURLSchemeAsCORSEnabled(privileged_scheme); + blink::SchemeRegistry::registerURLSchemeAsCORSEnabled(privileged_scheme); } } void WebFrame::InsertText(const std::string& text) { web_frame_->frameWidget() ->getActiveWebInputMethodController() - ->commitText(blink::WebString::fromUTF8(text), 0); + ->commitText(blink::WebString::fromUTF8(text), + blink::WebVector(), + blink::WebRange(), + 0); } void WebFrame::InsertCSS(const std::string& css) { @@ -216,7 +220,7 @@ void WebFrame::ExecuteJavaScript(const base::string16& code, std::unique_ptr callback( new ScriptExecutionCallback(completion_callback)); web_frame_->requestExecuteScriptAndReturnValue( - blink::WebScriptSource(code), + blink::WebScriptSource(blink::WebString::fromUTF16(code)), has_user_gesture, callback.release()); } diff --git a/atom/renderer/api/atom_api_web_frame.h b/atom/renderer/api/atom_api_web_frame.h index a35b86cacfa..6c6d0b19f98 100644 --- a/atom/renderer/api/atom_api_web_frame.h +++ b/atom/renderer/api/atom_api_web_frame.h @@ -11,7 +11,7 @@ #include "atom/renderer/guest_view_container.h" #include "native_mate/handle.h" #include "native_mate/wrappable.h" -#include "third_party/WebKit/public/web/WebCache.h" +#include "third_party/WebKit/public/platform/WebCache.h" namespace blink { class WebLocalFrame; diff --git a/atom/renderer/atom_render_frame_observer.cc b/atom/renderer/atom_render_frame_observer.cc index d9a41a48d4a..3912a7bcc6d 100644 --- a/atom/renderer/atom_render_frame_observer.cc +++ b/atom/renderer/atom_render_frame_observer.cc @@ -24,7 +24,6 @@ void AtomRenderFrameObserver::DidClearWindowObject() { void AtomRenderFrameObserver::DidCreateScriptContext( v8::Handle context, - int extension_group, int world_id) { if (ShouldNotifyClient(world_id)) renderer_client_->DidCreateScriptContext(context, render_frame_); @@ -62,8 +61,7 @@ void AtomRenderFrameObserver::CreateIsolatedWorldContext() { // Create initial script context in isolated world blink::WebScriptSource source("void 0"); - frame->executeScriptInIsolatedWorld( - World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP); + frame->executeScriptInIsolatedWorld(World::ISOLATED_WORLD, &source, 1); } bool AtomRenderFrameObserver::IsMainWorld(int world_id) { diff --git a/atom/renderer/atom_render_frame_observer.h b/atom/renderer/atom_render_frame_observer.h index 51cb21b3b0e..6eeb32aac03 100644 --- a/atom/renderer/atom_render_frame_observer.h +++ b/atom/renderer/atom_render_frame_observer.h @@ -17,10 +17,6 @@ enum World { ISOLATED_WORLD = 999 }; -enum ExtensionGroup { - MAIN_GROUP = 1 -}; - // Helper class to forward the messages to the client. class AtomRenderFrameObserver : public content::RenderFrameObserver { public: @@ -30,7 +26,6 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { // content::RenderFrameObserver: void DidClearWindowObject() override; void DidCreateScriptContext(v8::Handle context, - int extension_group, int world_id) override; void WillReleaseScriptContext(v8::Local context, int world_id) override; diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 1471fcac6a0..393b864031a 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -7,8 +7,6 @@ #include #include -#include "atom_natives.h" // NOLINT: This file is generated with js2c - #include "atom/common/api/atom_bindings.h" #include "atom/common/api/event_emitter_caller.h" #include "atom/common/asar/asar_util.h" @@ -27,6 +25,7 @@ #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "atom/common/node_includes.h" +#include "atom_natives.h" // NOLINT: This file is generated with js2c namespace atom { @@ -172,8 +171,7 @@ void AtomRendererClient::WillDestroyWorkerContextOnWorkerThread( v8::Local AtomRendererClient::GetContext( blink::WebFrame* frame, v8::Isolate* isolate) { if (isolated_world()) - return frame->worldScriptContext( - isolate, World::ISOLATED_WORLD, ExtensionGroup::MAIN_GROUP); + return frame->worldScriptContext(isolate, World::ISOLATED_WORLD); else return frame->mainWorldScriptContext(); } diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index 4fe9bd449dd..2768f072cd6 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -6,14 +6,11 @@ #include -#include "atom_natives.h" // NOLINT: This file is generated with js2c - #include "atom/common/api/api_messages.h" #include "atom/common/api/atom_bindings.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/v8_value_converter.h" #include "atom/common/native_mate_converters/value_converter.h" -#include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "atom/renderer/api/atom_api_renderer_ipc.h" #include "atom/renderer/atom_render_view_observer.h" @@ -31,6 +28,9 @@ #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" +#include "atom/common/node_includes.h" +#include "atom_natives.h" // NOLINT: This file is generated with js2c + namespace atom { namespace { @@ -86,6 +86,9 @@ void InitializeBindings(v8::Local binding, mate::Dictionary b(isolate, binding); b.SetMethod("get", GetBinding); b.SetMethod("crash", AtomBindings::Crash); + b.SetMethod("hang", AtomBindings::Hang); + b.SetMethod("getProcessMemoryInfo", &AtomBindings::GetProcessMemoryInfo); + b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo); } class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver { diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index 4d3675e2f6f..1219dfb5dcf 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -30,6 +30,7 @@ #include "third_party/WebKit/public/web/WebPluginParams.h" #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" +#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h" #if defined(OS_MACOSX) #include "base/mac/mac_util.h" @@ -85,6 +86,13 @@ void RendererClientBase::RenderThreadStarted() { blink::WebCustomElement::addEmbedderCustomElementName("webview"); blink::WebCustomElement::addEmbedderCustomElementName("browserplugin"); + // Parse --secure-schemes=scheme1,scheme2 + std::vector secure_schemes_list = + ParseSchemesCLISwitch(switches::kSecureSchemes); + for (const std::string& scheme : secure_schemes_list) + blink::SchemeRegistry::registerURLSchemeAsSecure( + WTF::String::fromUTF8(scheme.data(), scheme.length())); + preferences_manager_.reset(new PreferencesManager); #if defined(OS_WIN) @@ -126,13 +134,6 @@ void RendererClientBase::RenderFrameCreated( // Allow access to file scheme from pdf viewer. blink::WebSecurityPolicy::addOriginAccessWhitelistEntry( GURL(kPdfViewerUIOrigin), "file", "", true); - - // Parse --secure-schemes=scheme1,scheme2 - std::vector secure_schemes_list = - ParseSchemesCLISwitch(switches::kSecureSchemes); - for (const std::string& secure_scheme : secure_schemes_list) - blink::WebSecurityPolicy::registerURLSchemeAsSecure( - blink::WebString::fromUTF8(secure_scheme)); } void RendererClientBase::RenderViewCreated(content::RenderView* render_view) { diff --git a/chromium_src/chrome/browser/certificate_manager_model.cc b/chromium_src/chrome/browser/certificate_manager_model.cc index 2274c09e341..5f073478cdc 100644 --- a/chromium_src/chrome/browser/certificate_manager_model.cc +++ b/chromium_src/chrome/browser/certificate_manager_model.cc @@ -92,12 +92,12 @@ CertificateManagerModel::CertificateManagerModel( CertificateManagerModel::~CertificateManagerModel() { } -int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, +int CertificateManagerModel::ImportFromPKCS12(PK11SlotInfo* slot_info, const std::string& data, const base::string16& password, bool is_extractable, net::CertificateList* imported_certs) { - return cert_db_->ImportFromPKCS12(module, data, password, + return cert_db_->ImportFromPKCS12(slot_info, data, password, is_extractable, imported_certs); } diff --git a/chromium_src/chrome/browser/certificate_manager_model.h b/chromium_src/chrome/browser/certificate_manager_model.h index 7646da5b9b4..eb84b69f733 100644 --- a/chromium_src/chrome/browser/certificate_manager_model.h +++ b/chromium_src/chrome/browser/certificate_manager_model.h @@ -44,7 +44,7 @@ class CertificateManagerModel { // |data|, using the given |password|. If |is_extractable| is false, // mark the private key as unextractable from the module. // Returns a net error code on failure. - int ImportFromPKCS12(net::CryptoModule* module, + int ImportFromPKCS12(PK11SlotInfo* slot_info, const std::string& data, const base::string16& password, bool is_extractable, diff --git a/chromium_src/chrome/browser/media/native_desktop_media_list.cc b/chromium_src/chrome/browser/media/native_desktop_media_list.cc index 391bdd50a31..4a9c0e03c8b 100644 --- a/chromium_src/chrome/browser/media/native_desktop_media_list.cc +++ b/chromium_src/chrome/browser/media/native_desktop_media_list.cc @@ -8,6 +8,8 @@ #include #include +using base::PlatformThreadRef; + #include "base/hash.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc index b06c3a06409..a35e80cea23 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc @@ -18,10 +18,9 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/common/chrome_utility_messages.h" -#include "chrome/common/print_messages.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/utility_process_host.h" @@ -30,13 +29,13 @@ #include "printing/pdf_render_settings.h" #include "ui/base/l10n/l10n_util.h" +using content::BrowserThread; + namespace printing { namespace { -using content::BrowserThread; - -class PdfToEmfConverterImpl; +class PdfConverterImpl; // Allows to delete temporary directory after all temporary files created inside // are closed. Windows cannot delete directory with opened files. Directory is @@ -59,8 +58,8 @@ class RefCountedTempDir DISALLOW_COPY_AND_ASSIGN(RefCountedTempDir); }; -typedef std::unique_ptr - ScopedTempFile; +using ScopedTempFile = + std::unique_ptr; // Wrapper for Emf to keep only file handle in memory, and load actual data only // on playback. Emf::InitFromFile() can play metafile directly from disk, but it @@ -74,21 +73,39 @@ class LazyEmf : public MetafilePlayer { } ~LazyEmf() override { Close(); } + protected: + // MetafilePlayer: bool SafePlayback(HDC hdc) const override; - bool GetDataAsVector(std::vector* buffer) const override; - bool SaveTo(base::File* file) const override; - private: void Close() const; bool LoadEmf(Emf* emf) const; + private: mutable scoped_refptr temp_dir_; mutable ScopedTempFile file_; // Mutable because of consts in base class. + bool GetDataAsVector(std::vector* buffer) const override; + bool SaveTo(base::File* file) const override; + DISALLOW_COPY_AND_ASSIGN(LazyEmf); }; -// Converts PDF into EMF. +// Postscript metafile subclass to override SafePlayback. +class PostScriptMetaFile : public LazyEmf { + public: + PostScriptMetaFile(const scoped_refptr& temp_dir, + ScopedTempFile file) + : LazyEmf(temp_dir, std::move(file)) {} + ~PostScriptMetaFile() override; + + protected: + // MetafilePlayer: + bool SafePlayback(HDC hdc) const override; + + DISALLOW_COPY_AND_ASSIGN(PostScriptMetaFile); +}; + +// Class for converting PDF to another format for printing (Emf, Postscript). // Class uses 3 threads: UI, IO and FILE. // Internal workflow is following: // 1. Create instance on the UI thread. (files_, settings_,) @@ -101,36 +118,33 @@ class LazyEmf : public MetafilePlayer { // // All these steps work sequentially, so no data should be accessed // simultaneously by several threads. -class PdfToEmfUtilityProcessHostClient +class PdfConverterUtilityProcessHostClient : public content::UtilityProcessHostClient { public: - PdfToEmfUtilityProcessHostClient( - base::WeakPtr converter, + PdfConverterUtilityProcessHostClient( + base::WeakPtr converter, const PdfRenderSettings& settings); void Start(const scoped_refptr& data, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback); + const PdfConverter::StartCallback& start_callback); void GetPage(int page_number, - const PdfToEmfConverter::GetPageCallback& get_page_callback); + const PdfConverter::GetPageCallback& get_page_callback); void Stop(); + // UtilityProcessHostClient implementation. + void OnProcessCrashed(int exit_code) override; + void OnProcessLaunchFailed(int exit_code) override; + // Needs to be public to handle ChromeUtilityHostMsg_PreCacheFontCharacters // sync message replies. bool Send(IPC::Message* msg); - // UtilityProcessHostClient implementation. - void OnProcessCrashed(int exit_code) override; - void OnProcessLaunchFailed(int exit_code) override; - bool OnMessageReceived(const IPC::Message& message) override; - - private: + protected: class GetPageCallbackData { public: - GetPageCallbackData(int page_number, - PdfToEmfConverter::GetPageCallback callback) + GetPageCallbackData(int page_number, PdfConverter::GetPageCallback callback) : page_number_(page_number), callback_(callback) {} GetPageCallbackData(GetPageCallbackData&& other) { @@ -140,45 +154,62 @@ class PdfToEmfUtilityProcessHostClient GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { page_number_ = rhs.page_number_; callback_ = rhs.callback_; - emf_ = std::move(rhs.emf_); + file_ = std::move(rhs.file_); return *this; } int page_number() const { return page_number_; } - const PdfToEmfConverter::GetPageCallback& callback() const { - return callback_; - } - ScopedTempFile TakeEmf() { return std::move(emf_); } - void set_emf(ScopedTempFile emf) { emf_ = std::move(emf); } + const PdfConverter::GetPageCallback& callback() const { return callback_; } + ScopedTempFile TakeFile() { return std::move(file_); } + void set_file(ScopedTempFile file) { file_ = std::move(file); } private: int page_number_; - PdfToEmfConverter::GetPageCallback callback_; - ScopedTempFile emf_; + + PdfConverter::GetPageCallback callback_; + ScopedTempFile file_; DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); }; - ~PdfToEmfUtilityProcessHostClient() override; + ~PdfConverterUtilityProcessHostClient() override; - // Message handlers. + bool OnMessageReceived(const IPC::Message& message) override; + + // Helper functions: must be overridden by subclasses + // Set the process name + virtual base::string16 GetName() const; + // Create a metafileplayer subclass file from a temporary file. + virtual std::unique_ptr GetFileFromTemp( + std::unique_ptr + temp_file); + // Send the messages to Start, GetPage, and Stop. + virtual void SendStartMessage(IPC::PlatformFileForTransit transit); + virtual void SendGetPageMessage(int page_number, + IPC::PlatformFileForTransit transit); + virtual void SendStopMessage(); + + // Message handlers: void OnPageCount(int page_count); void OnPageDone(bool success, float scale_factor); + + void OnFailed(); + void OnTempPdfReady(ScopedTempFile pdf); + void OnTempFileReady(GetPageCallbackData* callback_data, + ScopedTempFile temp_file); + + // Additional message handler needed for Pdf to Emf void OnPreCacheFontCharacters(const LOGFONT& log_font, const base::string16& characters); - void OnFailed(); - void OnTempPdfReady(bool print_text_with_gdi, ScopedTempFile pdf); - void OnTempEmfReady(GetPageCallbackData* callback_data, ScopedTempFile emf); - scoped_refptr temp_dir_; - // Used to suppress callbacks after PdfToEmfConverterImpl is deleted. - base::WeakPtr converter_; + // Used to suppress callbacks after PdfConverter is deleted. + base::WeakPtr converter_; PdfRenderSettings settings_; // Document loaded callback. - PdfToEmfConverter::StartCallback start_callback_; + PdfConverter::StartCallback start_callback_; // Process host for IPC. base::WeakPtr utility_process_host_; @@ -186,22 +217,37 @@ class PdfToEmfUtilityProcessHostClient // Queue of callbacks for GetPage() requests. Utility process should reply // with PageDone in the same order as requests were received. // Use containers that keeps element pointers valid after push() and pop(). - typedef std::queue GetPageCallbacks; + using GetPageCallbacks = std::queue; GetPageCallbacks get_page_callbacks_; - DISALLOW_COPY_AND_ASSIGN(PdfToEmfUtilityProcessHostClient); + DISALLOW_COPY_AND_ASSIGN(PdfConverterUtilityProcessHostClient); }; -class PdfToEmfConverterImpl : public PdfToEmfConverter { - public: - PdfToEmfConverterImpl(); +std::unique_ptr +PdfConverterUtilityProcessHostClient::GetFileFromTemp( + std::unique_ptr + temp_file) { + if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 || + settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3) { + return base::MakeUnique(temp_dir_, + std::move(temp_file)); + } + return base::MakeUnique(temp_dir_, std::move(temp_file)); +} - ~PdfToEmfConverterImpl() override; +class PdfConverterImpl : public PdfConverter { + public: + PdfConverterImpl(); + + ~PdfConverterImpl() override; + + base::WeakPtr GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } void Start(const scoped_refptr& data, const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const StartCallback& start_callback) override; + const StartCallback& start_callback); void GetPage(int page_number, const GetPageCallback& get_page_callback) override; @@ -209,11 +255,17 @@ class PdfToEmfConverterImpl : public PdfToEmfConverter { // Helps to cancel callbacks if this object is destroyed. void RunCallback(const base::Closure& callback); - private: - scoped_refptr utility_client_; - base::WeakPtrFactory weak_ptr_factory_; + void Start( + const scoped_refptr& utility_client, + const scoped_refptr& data, + const StartCallback& start_callback); - DISALLOW_COPY_AND_ASSIGN(PdfToEmfConverterImpl); + private: + scoped_refptr utility_client_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PdfConverterImpl); }; ScopedTempFile CreateTempFile(scoped_refptr* temp_dir) { @@ -260,10 +312,10 @@ ScopedTempFile CreateTempPdfFile( bool LazyEmf::SafePlayback(HDC hdc) const { Emf emf; bool result = LoadEmf(&emf) && emf.SafePlayback(hdc); - // TODO(vitalybuka): Fix destruction of metafiles. For some reasons - // instances of Emf are not deleted. crbug.com/411683 + // TODO(thestig): Fix destruction of metafiles. For some reasons + // instances of Emf are not deleted. https://crbug.com/260806 // It's known that the Emf going to be played just once to a printer. So just - // release file here. + // release |file_| here. Close(); return result; } @@ -280,7 +332,7 @@ bool LazyEmf::SaveTo(base::File* file) const { void LazyEmf::Close() const { file_.reset(); - temp_dir_ = NULL; + temp_dir_ = nullptr; } bool LazyEmf::LoadEmf(Emf* emf) const { @@ -294,24 +346,55 @@ bool LazyEmf::LoadEmf(Emf* emf) const { return emf->InitFromData(data.data(), data.size()); } -PdfToEmfUtilityProcessHostClient::PdfToEmfUtilityProcessHostClient( - base::WeakPtr converter, +PostScriptMetaFile::~PostScriptMetaFile() { +} + +bool PostScriptMetaFile::SafePlayback(HDC hdc) const { + // TODO(thestig): Fix destruction of metafiles. For some reasons + // instances of Emf are not deleted. https://crbug.com/260806 + // It's known that the Emf going to be played just once to a printer. So just + // release |file_| before returning. + Emf emf; + if (!LoadEmf(&emf)) { + Close(); + return false; + } + + { + // Ensure enumerator destruction before calling Close() below. + Emf::Enumerator emf_enum(emf, nullptr, nullptr); + for (const Emf::Record& record : emf_enum) { + auto* emf_record = record.record(); + if (emf_record->iType != EMR_GDICOMMENT) + continue; + + const EMRGDICOMMENT* comment = + reinterpret_cast(emf_record); + const char* data = reinterpret_cast(comment->Data); + const uint16_t* ptr = reinterpret_cast(data); + int ret = ExtEscape(hdc, PASSTHROUGH, 2 + *ptr, data, 0, nullptr); + DCHECK_EQ(*ptr, ret); + } + } + Close(); + return true; +} + +PdfConverterUtilityProcessHostClient::PdfConverterUtilityProcessHostClient( + base::WeakPtr converter, const PdfRenderSettings& settings) - : converter_(converter), settings_(settings) { -} + : converter_(converter), settings_(settings) {} -PdfToEmfUtilityProcessHostClient::~PdfToEmfUtilityProcessHostClient() { -} +PdfConverterUtilityProcessHostClient::~PdfConverterUtilityProcessHostClient() {} -void PdfToEmfUtilityProcessHostClient::Start( +void PdfConverterUtilityProcessHostClient::Start( const scoped_refptr& data, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback) { + const PdfConverter::StartCallback& start_callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::Start, this, data, - print_text_with_gdi, start_callback)); + base::Bind(&PdfConverterUtilityProcessHostClient::Start, this, data, + start_callback)); return; } @@ -324,50 +407,41 @@ void PdfToEmfUtilityProcessHostClient::Start( utility_process_host_ = content::UtilityProcessHost::Create( this, base::ThreadTaskRunnerHandle::Get()) ->AsWeakPtr(); - utility_process_host_->SetName(base::ASCIIToUTF16( - "IDS_UTILITY_PROCESS_EMF_CONVERTOR_NAME")); + utility_process_host_->SetName(GetName()); BrowserThread::PostTaskAndReplyWithResult( BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempPdfFile, data, &temp_dir_), - base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempPdfReady, this, - print_text_with_gdi)); + base::Bind(&PdfConverterUtilityProcessHostClient::OnTempPdfReady, this)); } -void PdfToEmfUtilityProcessHostClient::OnTempPdfReady(bool print_text_with_gdi, - ScopedTempFile pdf) { +void PdfConverterUtilityProcessHostClient::OnTempPdfReady(ScopedTempFile pdf) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!utility_process_host_ || !pdf) return OnFailed(); // Should reply with OnPageCount(). - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles( - IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false), settings_, - print_text_with_gdi)); + SendStartMessage( + IPC::GetPlatformFileForTransit(pdf->GetPlatformFile(), false)); } -void PdfToEmfUtilityProcessHostClient::OnPageCount(int page_count) { +void PdfConverterUtilityProcessHostClient::OnPageCount(int page_count) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (start_callback_.is_null()) return OnFailed(); - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&PdfToEmfConverterImpl::RunCallback, - converter_, + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&PdfConverterImpl::RunCallback, converter_, base::Bind(start_callback_, page_count))); start_callback_.Reset(); } -void PdfToEmfUtilityProcessHostClient::GetPage( +void PdfConverterUtilityProcessHostClient::GetPage( int page_number, - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + const PdfConverter::GetPageCallback& get_page_callback) { if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::GetPage, - this, - page_number, - get_page_callback)); + BrowserThread::IO, FROM_HERE, + base::Bind(&PdfConverterUtilityProcessHostClient::GetPage, this, + page_number, get_page_callback)); return; } @@ -378,55 +452,84 @@ void PdfToEmfUtilityProcessHostClient::GetPage( return OnFailed(); BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::FILE, - FROM_HERE, - base::Bind(&CreateTempFile, &temp_dir_), - base::Bind(&PdfToEmfUtilityProcessHostClient::OnTempEmfReady, - this, + BrowserThread::FILE, FROM_HERE, base::Bind(&CreateTempFile, &temp_dir_), + base::Bind(&PdfConverterUtilityProcessHostClient::OnTempFileReady, this, &get_page_callbacks_.back())); } -void PdfToEmfUtilityProcessHostClient::OnTempEmfReady( +void PdfConverterUtilityProcessHostClient::OnTempFileReady( GetPageCallbackData* callback_data, - ScopedTempFile emf) { + ScopedTempFile temp_file) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!utility_process_host_ || !emf) + if (!utility_process_host_ || !temp_file) return OnFailed(); IPC::PlatformFileForTransit transit = - IPC::GetPlatformFileForTransit(emf->GetPlatformFile(), false); - callback_data->set_emf(std::move(emf)); + IPC::GetPlatformFileForTransit(temp_file->GetPlatformFile(), false); + callback_data->set_file(std::move(temp_file)); // Should reply with OnPageDone(). - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage( - callback_data->page_number(), transit)); + SendGetPageMessage(callback_data->page_number(), transit); } -void PdfToEmfUtilityProcessHostClient::OnPageDone(bool success, - float scale_factor) { +void PdfConverterUtilityProcessHostClient::OnPageDone(bool success, + float scale_factor) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (get_page_callbacks_.empty()) return OnFailed(); GetPageCallbackData& data = get_page_callbacks_.front(); - std::unique_ptr emf; + std::unique_ptr file; if (success) { - ScopedTempFile temp_emf = data.TakeEmf(); - if (!temp_emf) // Unexpected message from utility process. + ScopedTempFile temp_file = data.TakeFile(); + if (!temp_file) // Unexpected message from utility process. return OnFailed(); - emf = base::MakeUnique(temp_dir_, std::move(temp_emf)); + file = GetFileFromTemp(std::move(temp_file)); } - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - base::Bind(&PdfToEmfConverterImpl::RunCallback, - converter_, - base::Bind(data.callback(), - data.page_number(), - scale_factor, - base::Passed(&emf)))); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&PdfConverterImpl::RunCallback, converter_, + base::Bind(data.callback(), data.page_number(), scale_factor, + base::Passed(&file)))); get_page_callbacks_.pop(); } -void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( +void PdfConverterUtilityProcessHostClient::Stop() { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PdfConverterUtilityProcessHostClient::Stop, this)); + return; + } + SendStopMessage(); +} + +void PdfConverterUtilityProcessHostClient::OnProcessCrashed(int exit_code) { + OnFailed(); +} + +void PdfConverterUtilityProcessHostClient::OnProcessLaunchFailed( + int exit_code) { + OnFailed(); +} + +bool PdfConverterUtilityProcessHostClient::Send(IPC::Message* msg) { + if (utility_process_host_) + return utility_process_host_->Send(msg); + delete msg; + return false; +} + +void PdfConverterUtilityProcessHostClient::OnFailed() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!start_callback_.is_null()) + OnPageCount(0); + while (!get_page_callbacks_.empty()) + OnPageDone(false, 0.0f); + utility_process_host_.reset(); +} + + +void PdfConverterUtilityProcessHostClient::OnPreCacheFontCharacters( const LOGFONT& font, const base::string16& str) { // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache @@ -458,29 +561,10 @@ void PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters( DeleteEnhMetaFile(metafile); } -void PdfToEmfUtilityProcessHostClient::Stop() { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&PdfToEmfUtilityProcessHostClient::Stop, this)); - return; - } - Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); -} - -void PdfToEmfUtilityProcessHostClient::OnProcessCrashed(int exit_code) { - OnFailed(); -} - -void PdfToEmfUtilityProcessHostClient::OnProcessLaunchFailed(int exit_code) { - OnFailed(); -} - -bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( +bool PdfConverterUtilityProcessHostClient::OnMessageReceived( const IPC::Message& message) { bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PdfToEmfUtilityProcessHostClient, message) + IPC_BEGIN_MESSAGE_MAP(PdfConverterUtilityProcessHostClient, message) IPC_MESSAGE_HANDLER( ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, OnPageCount) IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, @@ -492,59 +576,69 @@ bool PdfToEmfUtilityProcessHostClient::OnMessageReceived( return handled; } -bool PdfToEmfUtilityProcessHostClient::Send(IPC::Message* msg) { - if (utility_process_host_) - return utility_process_host_->Send(msg); - delete msg; - return false; +base::string16 PdfConverterUtilityProcessHostClient::GetName() const { + return L"ChromeUtilityProcessPDFConvertor"; } -void PdfToEmfUtilityProcessHostClient::OnFailed() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!start_callback_.is_null()) - OnPageCount(0); - while (!get_page_callbacks_.empty()) - OnPageDone(false, 0.0f); - utility_process_host_.reset(); +void PdfConverterUtilityProcessHostClient::SendGetPageMessage( + int page_number, + IPC::PlatformFileForTransit transit) { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage(page_number, + transit)); } -PdfToEmfConverterImpl::PdfToEmfConverterImpl() : weak_ptr_factory_(this) { +void PdfConverterUtilityProcessHostClient::SendStartMessage( + IPC::PlatformFileForTransit transit) { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles(transit, settings_)); } -PdfToEmfConverterImpl::~PdfToEmfConverterImpl() { +void PdfConverterUtilityProcessHostClient::SendStopMessage() { + Send(new ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop()); +} + +// Pdf Converter Impl and subclasses +PdfConverterImpl::PdfConverterImpl() : weak_ptr_factory_(this) {} + +PdfConverterImpl::~PdfConverterImpl() { if (utility_client_.get()) utility_client_->Stop(); } -void PdfToEmfConverterImpl::Start( - const scoped_refptr& data, - const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const StartCallback& start_callback) { - DCHECK(!utility_client_.get()); - utility_client_ = new PdfToEmfUtilityProcessHostClient( - weak_ptr_factory_.GetWeakPtr(), conversion_settings); - utility_client_->Start(data, print_text_with_gdi, start_callback); +void PdfConverterImpl::Start( + const scoped_refptr& utility_client, + const scoped_refptr& data, + const StartCallback& start_callback) { + DCHECK(!utility_client_); + utility_client_ = utility_client; + utility_client_->Start(data, start_callback); } -void PdfToEmfConverterImpl::GetPage(int page_number, - const GetPageCallback& get_page_callback) { +void PdfConverterImpl::GetPage(int page_number, + const GetPageCallback& get_page_callback) { utility_client_->GetPage(page_number, get_page_callback); } -void PdfToEmfConverterImpl::RunCallback(const base::Closure& callback) { +void PdfConverterImpl::RunCallback(const base::Closure& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); callback.Run(); } } // namespace -PdfToEmfConverter::~PdfToEmfConverter() { -} +PdfConverter::~PdfConverter() {} // static -std::unique_ptr PdfToEmfConverter::CreateDefault() { - return std::unique_ptr(new PdfToEmfConverterImpl()); +std::unique_ptr PdfConverter::StartPdfConverter( + const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback) { + std::unique_ptr converter = + base::MakeUnique(); + converter->Start( + new PdfConverterUtilityProcessHostClient(converter->GetWeakPtr(), + conversion_settings), + data, start_callback); + return std::move(converter); } } // namespace printing diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h index 1f527152740..9990400a7bc 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.h @@ -15,24 +15,21 @@ namespace printing { class MetafilePlayer; struct PdfRenderSettings; -class PdfToEmfConverter { +class PdfConverter { public: - typedef base::Callback StartCallback; - typedef base::Callback emf)> - GetPageCallback; - - virtual ~PdfToEmfConverter(); - - static std::unique_ptr CreateDefault(); + using StartCallback = base::Callback; + using GetPageCallback = + base::Callback file)>; + virtual ~PdfConverter(); // Starts conversion of PDF provided as |data|. Calls |start_callback| // with positive |page_count|. |page_count| is 0 if initialization failed. - virtual void Start(const scoped_refptr& data, - const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const StartCallback& start_callback) = 0; + static std::unique_ptr StartPdfConverter( + const scoped_refptr& data, + const PdfRenderSettings& conversion_settings, + const StartCallback& start_callback); // Requests conversion of the page. |page_number| is 0-base page number in // PDF provided in Start() call. @@ -41,7 +38,6 @@ class PdfToEmfConverter { virtual void GetPage(int page_number, const GetPageCallback& get_page_callback) = 0; }; - } // namespace printing #endif // CHROME_BROWSER_PRINTING_PDF_TO_EMF_CONVERTER_H_ diff --git a/chromium_src/chrome/browser/printing/print_job.cc b/chromium_src/chrome/browser/printing/print_job.cc index 70bdb900458..c5038f370de 100644 --- a/chromium_src/chrome/browser/printing/print_job.cc +++ b/chromium_src/chrome/browser/printing/print_job.cc @@ -14,6 +14,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/threading/worker_pool.h" @@ -222,27 +223,23 @@ PrintedDocument* PrintJob::document() const { } #if defined(OS_WIN) - -class PrintJob::PdfToEmfState { +class PrintJob::PdfConversionState { public: - PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area) + PdfConversionState(gfx::Size page_size, gfx::Rect content_area) : page_count_(0), current_page_(0), pages_in_progress_(0), page_size_(page_size), - content_area_(content_area), - converter_(PdfToEmfConverter::CreateDefault()) {} + content_area_(content_area) {} void Start(const scoped_refptr& data, const PdfRenderSettings& conversion_settings, - bool print_text_with_gdi, - const PdfToEmfConverter::StartCallback& start_callback) { - converter_->Start(data, conversion_settings, print_text_with_gdi, - start_callback); + const PdfConverter::StartCallback& start_callback) { + converter_ = PdfConverter::StartPdfConverter( + data, conversion_settings, start_callback); } - void GetMorePages( - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + void GetMorePages(const PdfConverter::GetPageCallback& get_page_callback) { const int kMaxNumberOfTempFilesPerDocument = 3; while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument && current_page_ < page_count_) { @@ -251,8 +248,7 @@ class PrintJob::PdfToEmfState { } } - void OnPageProcessed( - const PdfToEmfConverter::GetPageCallback& get_page_callback) { + void OnPageProcessed(const PdfConverter::GetPageCallback& get_page_callback) { --pages_in_progress_; GetMorePages(get_page_callback); // Release converter if we don't need this any more. @@ -270,7 +266,7 @@ class PrintJob::PdfToEmfState { int pages_in_progress_; gfx::Size page_size_; gfx::Rect content_area_; - std::unique_ptr converter_; + std::unique_ptr converter_; }; void PrintJob::AppendPrintedPage(int page_number) { @@ -282,46 +278,67 @@ void PrintJob::StartPdfToEmfConversion( const gfx::Size& page_size, const gfx::Rect& content_area, bool print_text_with_gdi) { - DCHECK(!pdf_to_emf_state_); - pdf_to_emf_state_ = base::MakeUnique(page_size, content_area); + DCHECK(!pdf_conversion_state_); + pdf_conversion_state_ = + base::MakeUnique(page_size, content_area); const int kPrinterDpi = settings().dpi(); - pdf_to_emf_state_->Start( - bytes, PdfRenderSettings(content_area, kPrinterDpi, true), - print_text_with_gdi, base::Bind(&PrintJob::OnPdfToEmfStarted, this)); + PdfRenderSettings settings( + content_area, gfx::Point(0, 0), kPrinterDpi, /*autorotate=*/true, + print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT + : PdfRenderSettings::Mode::NORMAL); + pdf_conversion_state_->Start( + bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this)); } -void PrintJob::OnPdfToEmfStarted(int page_count) { +void PrintJob::OnPdfConversionStarted(int page_count) { if (page_count <= 0) { - pdf_to_emf_state_.reset(); + pdf_conversion_state_.reset(); Cancel(); return; } - pdf_to_emf_state_->set_page_count(page_count); - pdf_to_emf_state_->GetMorePages( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + pdf_conversion_state_->set_page_count(page_count); + pdf_conversion_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfPageConverted, this)); } -void PrintJob::OnPdfToEmfPageConverted(int page_number, - float scale_factor, - std::unique_ptr emf) { - DCHECK(pdf_to_emf_state_); - if (!document_.get() || !emf || page_number < 0 || +void PrintJob::OnPdfPageConverted(int page_number, + float scale_factor, + std::unique_ptr metafile) { + DCHECK(pdf_conversion_state_); + if (!document_.get() || !metafile || page_number < 0 || static_cast(page_number) >= pdf_page_mapping_.size()) { - pdf_to_emf_state_.reset(); + pdf_conversion_state_.reset(); Cancel(); return; } // Update the rendered document. It will send notifications to the listener. - document_->SetPage(pdf_page_mapping_[page_number], std::move(emf), - scale_factor, pdf_to_emf_state_->page_size(), - pdf_to_emf_state_->content_area()); + document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile), + scale_factor, pdf_conversion_state_->page_size(), + pdf_conversion_state_->content_area()); - pdf_to_emf_state_->GetMorePages( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + pdf_conversion_state_->GetMorePages( + base::Bind(&PrintJob::OnPdfPageConverted, this)); } -#endif // OS_WIN +void PrintJob::StartPdfToPostScriptConversion( + const scoped_refptr& bytes, + const gfx::Rect& content_area, + const gfx::Point& physical_offsets, + bool ps_level2) { + DCHECK(!pdf_conversion_state_); + pdf_conversion_state_ = base::MakeUnique( + gfx::Size(), gfx::Rect()); + const int kPrinterDpi = settings().dpi(); + PdfRenderSettings settings( + content_area, physical_offsets, kPrinterDpi, true /* autorotate? */, + ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 + : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); + pdf_conversion_state_->Start( + bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this)); +} + +#endif // defined(OS_WIN) void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) { if (document_.get() == new_document) @@ -372,8 +389,10 @@ void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { } case JobEventDetails::PAGE_DONE: #if defined(OS_WIN) - pdf_to_emf_state_->OnPageProcessed( - base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); + if (pdf_conversion_state_) { + pdf_conversion_state_->OnPageProcessed( + base::Bind(&PrintJob::OnPdfPageConverted, this)); + } #endif // defined(OS_WIN) break; default: { diff --git a/chromium_src/chrome/browser/printing/print_job.h b/chromium_src/chrome/browser/printing/print_job.h index e5c77aeb234..bca518f6fcd 100644 --- a/chromium_src/chrome/browser/printing/print_job.h +++ b/chromium_src/chrome/browser/printing/print_job.h @@ -100,6 +100,12 @@ class PrintJob : public PrintJobWorkerOwner, const gfx::Size& page_size, const gfx::Rect& content_area, bool print_text_with_gdi); + + void StartPdfToPostScriptConversion( + const scoped_refptr& bytes, + const gfx::Rect& content_area, + const gfx::Point& physical_offset, + bool ps_level2); #endif // defined(OS_WIN) protected: @@ -126,10 +132,10 @@ class PrintJob : public PrintJobWorkerOwner, void HoldUntilStopIsCalled(); #if defined(OS_WIN) - void OnPdfToEmfStarted(int page_count); - void OnPdfToEmfPageConverted(int page_number, - float scale_factor, - std::unique_ptr emf); + void OnPdfConversionStarted(int page_count); + void OnPdfPageConverted(int page_number, + float scale_factor, + std::unique_ptr emf); #endif // defined(OS_WIN) content::NotificationRegistrar registrar_; @@ -157,8 +163,8 @@ class PrintJob : public PrintJobWorkerOwner, bool is_canceling_; #if defined(OS_WIN) - class PdfToEmfState; - std::unique_ptr pdf_to_emf_state_; + class PdfConversionState; + std::unique_ptr pdf_conversion_state_; std::vector pdf_page_mapping_; #endif // defined(OS_WIN) diff --git a/chromium_src/chrome/browser/process_singleton_posix.cc b/chromium_src/chrome/browser/process_singleton_posix.cc index 7d5677031f4..e1e25cf91de 100644 --- a/chromium_src/chrome/browser/process_singleton_posix.cc +++ b/chromium_src/chrome/browser/process_singleton_posix.cc @@ -49,25 +49,34 @@ #include #include +#include #include #include +#include + #include "atom/common/atom_command_line.h" + #include "base/base_paths.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/files/file_descriptor_watcher_posix.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/location.h" #include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/posix/eintr_wrapper.h" #include "base/posix/safe_strerror.h" #include "base/rand_util.h" #include "base/sequenced_task_runner_helpers.h" #include "base/single_thread_task_runner.h" -#include "base/stl_util.h" +#include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -78,6 +87,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "build/build_config.h" #include "content/public/browser/browser_thread.h" #include "net/base/network_interfaces.h" #include "ui/base/l10n/l10n_util.h" @@ -222,9 +232,8 @@ int SetupSocketOnly() { int sock = socket(PF_UNIX, SOCK_STREAM, 0); PCHECK(sock >= 0) << "socket() failed"; - int rv = base::SetNonBlocking(sock); - DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; - rv = SetCloseOnExec(sock); + DCHECK(base::SetNonBlocking(sock)) << "Failed to make non-blocking socket."; + int rv = SetCloseOnExec(sock); DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket."; return sock; @@ -305,7 +314,6 @@ bool ParseLockPath(const base::FilePath& path, bool DisplayProfileInUseError(const base::FilePath& lock_path, const std::string& hostname, int pid) { - // TODO: yolo return true; } @@ -455,44 +463,38 @@ bool ReplaceOldSingletonLock(const base::FilePath& symlink_content, // This class sets up a listener on the singleton socket and handles parsing // messages that come in on the singleton socket. class ProcessSingleton::LinuxWatcher - : public base::MessageLoopForIO::Watcher, - public base::MessageLoop::DestructionObserver, - public base::RefCountedThreadSafe { public: // A helper class to read message from an established socket. - class SocketReader : public base::MessageLoopForIO::Watcher { + class SocketReader { public: SocketReader(ProcessSingleton::LinuxWatcher* parent, - base::MessageLoop* ui_message_loop, + scoped_refptr ui_task_runner, int fd) : parent_(parent), - ui_message_loop_(ui_message_loop), + ui_task_runner_(ui_task_runner), fd_(fd), bytes_read_(0) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Wait for reads. - base::MessageLoopForIO::current()->WatchFileDescriptor( - fd, true, base::MessageLoopForIO::WATCH_READ, &fd_reader_, this); + fd_watch_controller_ = base::FileDescriptorWatcher::WatchReadable( + fd, base::Bind(&SocketReader::OnSocketCanReadWithoutBlocking, + base::Unretained(this))); // If we haven't completed in a reasonable amount of time, give up. timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kTimeoutInSeconds), this, &SocketReader::CleanupAndDeleteSelf); } - ~SocketReader() override { CloseSocket(fd_); } - - // MessageLoopForIO::Watcher impl. - void OnFileCanReadWithoutBlocking(int fd) override; - void OnFileCanWriteWithoutBlocking(int fd) override { - // SocketReader only watches for accept (read) events. - NOTREACHED(); - } + ~SocketReader() { CloseSocket(fd_); } // Finish handling the incoming message by optionally sending back an ACK // message and removing this SocketReader. void FinishWithACK(const char *message, size_t length); private: + void OnSocketCanReadWithoutBlocking(); + void CleanupAndDeleteSelf() { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -500,13 +502,15 @@ class ProcessSingleton::LinuxWatcher // We're deleted beyond this point. } - base::MessageLoopForIO::FileDescriptorWatcher fd_reader_; + // Controls watching |fd_|. + std::unique_ptr + fd_watch_controller_; // The ProcessSingleton::LinuxWatcher that owns us. ProcessSingleton::LinuxWatcher* const parent_; - // A reference to the UI message loop. - base::MessageLoop* const ui_message_loop_; + // A reference to the UI task runner. + scoped_refptr ui_task_runner_; // The file descriptor we're reading. const int fd_; @@ -525,9 +529,7 @@ class ProcessSingleton::LinuxWatcher // We expect to only be constructed on the UI thread. explicit LinuxWatcher(ProcessSingleton* parent) - : ui_message_loop_(base::MessageLoop::current()), - parent_(parent) { - } + : ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), parent_(parent) {} // Start listening for connections on the socket. This method should be // called from the IO thread. @@ -540,79 +542,63 @@ class ProcessSingleton::LinuxWatcher const std::vector& argv, SocketReader* reader); - // MessageLoopForIO::Watcher impl. These run on the IO thread. - void OnFileCanReadWithoutBlocking(int fd) override; - void OnFileCanWriteWithoutBlocking(int fd) override { - // ProcessSingleton only watches for accept (read) events. - NOTREACHED(); - } - - // MessageLoop::DestructionObserver - void WillDestroyCurrentMessageLoop() override { - fd_watcher_.StopWatchingFileDescriptor(); - } - private: friend struct BrowserThread::DeleteOnThread; friend class base::DeleteHelper; - ~LinuxWatcher() override { + ~LinuxWatcher() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - STLDeleteElements(&readers_); - - base::MessageLoopForIO* ml = base::MessageLoopForIO::current(); - ml->RemoveDestructionObserver(this); } + void OnSocketCanReadWithoutBlocking(int socket); + // Removes and deletes the SocketReader. void RemoveSocketReader(SocketReader* reader); - base::MessageLoopForIO::FileDescriptorWatcher fd_watcher_; + std::unique_ptr socket_watcher_; // A reference to the UI message loop (i.e., the message loop we were // constructed on). - base::MessageLoop* ui_message_loop_; + scoped_refptr ui_task_runner_; // The ProcessSingleton that owns us. ProcessSingleton* const parent_; - std::set readers_; + std::set> readers_; DISALLOW_COPY_AND_ASSIGN(LinuxWatcher); }; -void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) { +void ProcessSingleton::LinuxWatcher::OnSocketCanReadWithoutBlocking( + int socket) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Accepting incoming client. sockaddr_un from; socklen_t from_len = sizeof(from); - int connection_socket = HANDLE_EINTR(accept( - fd, reinterpret_cast(&from), &from_len)); + int connection_socket = HANDLE_EINTR( + accept(socket, reinterpret_cast(&from), &from_len)); if (-1 == connection_socket) { PLOG(ERROR) << "accept() failed"; return; } - int rv = base::SetNonBlocking(connection_socket); - DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; - SocketReader* reader = new SocketReader(this, - ui_message_loop_, - connection_socket); - readers_.insert(reader); + DCHECK(base::SetNonBlocking(connection_socket)) + << "Failed to make non-blocking socket."; + readers_.insert( + base::MakeUnique(this, ui_task_runner_, connection_socket)); } void ProcessSingleton::LinuxWatcher::StartListening(int socket) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Watch for client connections on this socket. - base::MessageLoopForIO* ml = base::MessageLoopForIO::current(); - ml->AddDestructionObserver(this); - ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ, - &fd_watcher_, this); + socket_watcher_ = base::FileDescriptorWatcher::WatchReadable( + socket, base::Bind(&LinuxWatcher::OnSocketCanReadWithoutBlocking, + base::Unretained(this), socket)); } void ProcessSingleton::LinuxWatcher::HandleMessage( const std::string& current_dir, const std::vector& argv, SocketReader* reader) { - DCHECK(ui_message_loop_ == base::MessageLoop::current()); + DCHECK(ui_task_runner_->BelongsToCurrentThread()); DCHECK(reader); if (parent_->notification_callback_.Run(argv, @@ -632,25 +618,27 @@ void ProcessSingleton::LinuxWatcher::HandleMessage( void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(reader); - readers_.erase(reader); - delete reader; + auto it = std::find_if(readers_.begin(), readers_.end(), + [reader](const std::unique_ptr& ptr) { + return ptr.get() == reader; + }); + readers_.erase(it); } /////////////////////////////////////////////////////////////////////////////// // ProcessSingleton::LinuxWatcher::SocketReader // -void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking( - int fd) { +void ProcessSingleton::LinuxWatcher::SocketReader:: + OnSocketCanReadWithoutBlocking() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK_EQ(fd, fd_); while (bytes_read_ < sizeof(buf_)) { - ssize_t rv = HANDLE_EINTR( - read(fd, buf_ + bytes_read_, sizeof(buf_) - bytes_read_)); + ssize_t rv = + HANDLE_EINTR(read(fd_, buf_ + bytes_read_, sizeof(buf_) - bytes_read_)); if (rv < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { PLOG(ERROR) << "read() failed"; - CloseSocket(fd); + CloseSocket(fd_); return; } else { // It would block, so we just return and continue to watch for the next @@ -696,10 +684,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::OnFileCanReadWithoutBlocking( tokens.erase(tokens.begin()); // Return to the UI thread to handle opening a new browser tab. - ui_message_loop_->task_runner()->PostTask( + ui_task_runner_->PostTask( FROM_HERE, base::Bind(&ProcessSingleton::LinuxWatcher::HandleMessage, parent_, current_dir, tokens, this)); - fd_reader_.StopWatchingFileDescriptor(); + fd_watch_controller_.reset(); // LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader // object by invoking SocketReader::FinishWithACK(). @@ -731,7 +719,8 @@ ProcessSingleton::ProcessSingleton( const base::FilePath& user_data_dir, const NotificationCallback& notification_callback) : notification_callback_(notification_callback), - current_pid_(base::GetCurrentProcId()) { + current_pid_(base::GetCurrentProcId()), + watcher_(new LinuxWatcher(this)) { // The user_data_dir may have not been created yet. base::CreateDirectoryAndGetError(user_data_dir, nullptr); @@ -897,12 +886,26 @@ ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate( const base::CommandLine& command_line, int retry_attempts, const base::TimeDelta& timeout) { + const base::TimeTicks begin_ticks = base::TimeTicks::Now(); NotifyResult result = NotifyOtherProcessWithTimeout( command_line, retry_attempts, timeout, true); - if (result != PROCESS_NONE) + if (result != PROCESS_NONE) { + if (result == PROCESS_NOTIFIED) { + UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToNotify", + base::TimeTicks::Now() - begin_ticks); + } else { + UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure", + base::TimeTicks::Now() - begin_ticks); + } return result; - if (Create()) + } + + if (Create()) { + UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToCreate", + base::TimeTicks::Now() - begin_ticks); return PROCESS_NONE; + } + // If the Create() failed, try again to notify. (It could be that another // instance was starting at the same time and managed to grab the lock before // we did.) @@ -910,6 +913,15 @@ ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate( // aren't going to try to take over the lock ourselves. result = NotifyOtherProcessWithTimeout( command_line, retry_attempts, timeout, false); + + if (result == PROCESS_NOTIFIED) { + UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToNotify", + base::TimeTicks::Now() - begin_ticks); + } else { + UMA_HISTOGRAM_MEDIUM_TIMES("Chrome.ProcessSingleton.TimeToFailure", + base::TimeTicks::Now() - begin_ticks); + } + if (result != PROCESS_NONE) return result; @@ -1019,15 +1031,13 @@ bool ProcessSingleton::Create() { if (listen(sock, 5) < 0) NOTREACHED() << "listen failed: " << base::safe_strerror(errno); - // In Electron the ProcessSingleton is created earlier than the IO - // thread gets created, so we have to postpone the call until message - // loop is up an running. - scoped_refptr task_runner = - base::ThreadTaskRunnerHandle::Get(); - task_runner->PostTask( + DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, - base::Bind(&ProcessSingleton::StartListening, - base::Unretained(this), sock)); + base::Bind(&ProcessSingleton::LinuxWatcher::StartListening, + watcher_, + sock)); return true; } @@ -1038,17 +1048,6 @@ void ProcessSingleton::Cleanup() { UnlinkPath(lock_path_); } -void ProcessSingleton::StartListening(int sock) { - watcher_ = new LinuxWatcher(this); - DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO)); - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&ProcessSingleton::LinuxWatcher::StartListening, - watcher_.get(), - sock)); -} - bool ProcessSingleton::IsSameChromeInstance(pid_t pid) { pid_t cur_pid = current_pid_; while (pid != cur_pid) { diff --git a/chromium_src/chrome/common/chrome_utility_printing_messages.h b/chromium_src/chrome/common/chrome_utility_printing_messages.h new file mode 100644 index 00000000000..fc71f0bd05f --- /dev/null +++ b/chromium_src/chrome/common/chrome_utility_printing_messages.h @@ -0,0 +1,111 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Multiply-included message file, so no include guard. + +#include +#include + +#include "base/strings/string16.h" +#include "build/build_config.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_param_traits.h" +#include "ipc/ipc_platform_file.h" +#include "printing/backend/print_backend.h" +#include "printing/features/features.h" +#include "printing/page_range.h" +#include "printing/pdf_render_settings.h" +#include "printing/pwg_raster_settings.h" + +#if defined(OS_WIN) +#include +#endif + +#define IPC_MESSAGE_START ChromeUtilityPrintingMsgStart + +IPC_ENUM_TRAITS_MAX_VALUE(printing::PdfRenderSettings::Mode, + printing::PdfRenderSettings::Mode::LAST) + +IPC_STRUCT_TRAITS_BEGIN(printing::PdfRenderSettings) + IPC_STRUCT_TRAITS_MEMBER(area) + IPC_STRUCT_TRAITS_MEMBER(offsets) + IPC_STRUCT_TRAITS_MEMBER(dpi) + IPC_STRUCT_TRAITS_MEMBER(autorotate) + IPC_STRUCT_TRAITS_MEMBER(mode) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterCapsAndDefaults) + IPC_STRUCT_TRAITS_MEMBER(printer_capabilities) + IPC_STRUCT_TRAITS_MEMBER(caps_mime_type) + IPC_STRUCT_TRAITS_MEMBER(printer_defaults) + IPC_STRUCT_TRAITS_MEMBER(defaults_mime_type) +IPC_STRUCT_TRAITS_END() + +IPC_ENUM_TRAITS_MAX_VALUE(printing::ColorModel, printing::PROCESSCOLORMODEL_RGB) + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults::Paper) + IPC_STRUCT_TRAITS_MEMBER(display_name) + IPC_STRUCT_TRAITS_MEMBER(vendor_id) + IPC_STRUCT_TRAITS_MEMBER(size_um) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults) + IPC_STRUCT_TRAITS_MEMBER(collate_capable) + IPC_STRUCT_TRAITS_MEMBER(collate_default) + IPC_STRUCT_TRAITS_MEMBER(copies_capable) + IPC_STRUCT_TRAITS_MEMBER(duplex_capable) + IPC_STRUCT_TRAITS_MEMBER(duplex_default) + IPC_STRUCT_TRAITS_MEMBER(color_changeable) + IPC_STRUCT_TRAITS_MEMBER(color_default) + IPC_STRUCT_TRAITS_MEMBER(color_model) + IPC_STRUCT_TRAITS_MEMBER(bw_model) + IPC_STRUCT_TRAITS_MEMBER(papers) + IPC_STRUCT_TRAITS_MEMBER(default_paper) + IPC_STRUCT_TRAITS_MEMBER(dpis) + IPC_STRUCT_TRAITS_MEMBER(default_dpi) +IPC_STRUCT_TRAITS_END() + +IPC_ENUM_TRAITS_MAX_VALUE(printing::PwgRasterTransformType, + printing::TRANSFORM_TYPE_LAST) + +IPC_STRUCT_TRAITS_BEGIN(printing::PwgRasterSettings) + IPC_STRUCT_TRAITS_MEMBER(odd_page_transform) + IPC_STRUCT_TRAITS_MEMBER(rotate_all_pages) + IPC_STRUCT_TRAITS_MEMBER(reverse_page_order) +IPC_STRUCT_TRAITS_END() + +#if defined(OS_WIN) +// Reply when the utility process loaded PDF. |page_count| is 0, if loading +// failed. +IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, + int /* page_count */) + +// Reply when the utility process rendered the PDF page. +IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, + bool /* success */, + float /* scale_factor */) + +// Request that the given font characters be loaded by the browser so it's +// cached by the OS. Please see +// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details. +IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters, + LOGFONT /* font_data */, + base::string16 /* characters */) + +// Tell the utility process to start rendering the given PDF into a metafile. +// Utility process would be alive until +// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles, + IPC::PlatformFileForTransit /* input_file */, + printing::PdfRenderSettings /* settings */) + +// Requests conversion of the next page. +IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, + int /* page_number */, + IPC::PlatformFileForTransit /* output_file */) + +// Requests utility process to stop conversion and exit. +IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop) + +#endif // OS_WIN diff --git a/chromium_src/chrome/common/print_messages.h b/chromium_src/chrome/common/print_messages.h index e74dfafa71a..196d8be508c 100644 --- a/chromium_src/chrome/common/print_messages.h +++ b/chromium_src/chrome/common/print_messages.h @@ -74,6 +74,9 @@ struct PrintMsg_PrintPages_Params { IPC_ENUM_TRAITS_MAX_VALUE(printing::MarginType, printing::MARGIN_TYPE_LAST) +IPC_ENUM_TRAITS_MIN_MAX_VALUE(printing::DuplexMode, + printing::UNKNOWN_DUPLEX_MODE, + printing::SHORT_EDGE) IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPrintScalingOption, blink::WebPrintScalingOptionLast) @@ -310,39 +313,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_MetafileReadyForPrinting, IPC_MESSAGE_ROUTED2(PrintHostMsg_PrintPreviewFailed, int /* document cookie */, int /* request_id */); - -#if defined(OS_WIN) -// Tell the utility process to start rendering the given PDF into a metafile. -// Utility process would be alive until -// ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop message. -IPC_MESSAGE_CONTROL3(ChromeUtilityMsg_RenderPDFPagesToMetafiles, - IPC::PlatformFileForTransit /* input_file */, - printing::PdfRenderSettings /* settings */, - bool /* print_text_with_gdi */) - -// Requests conversion of the next page. -IPC_MESSAGE_CONTROL2(ChromeUtilityMsg_RenderPDFPagesToMetafiles_GetPage, - int /* page_number */, - IPC::PlatformFileForTransit /* output_file */) - -// Requests utility process to stop conversion and exit. -IPC_MESSAGE_CONTROL0(ChromeUtilityMsg_RenderPDFPagesToMetafiles_Stop) - -// Reply when the utility process loaded PDF. |page_count| is 0, if loading -// failed. -IPC_MESSAGE_CONTROL1(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount, - int /* page_count */) - -// Reply when the utility process rendered the PDF page. -IPC_MESSAGE_CONTROL2(ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone, - bool /* success */, - float /* scale_factor */) - -// Request that the given font characters be loaded by the browser so it's -// cached by the OS. Please see -// PdfToEmfUtilityProcessHostClient::OnPreCacheFontCharacters for details. -IPC_SYNC_MESSAGE_CONTROL2_0(ChromeUtilityHostMsg_PreCacheFontCharacters, - LOGFONT /* font_data */, - base::string16 /* characters */) - -#endif diff --git a/chromium_src/chrome/renderer/media/chrome_key_systems.cc b/chromium_src/chrome/renderer/media/chrome_key_systems.cc index 206ac400fba..87b5c43e7fb 100644 --- a/chromium_src/chrome/renderer/media/chrome_key_systems.cc +++ b/chromium_src/chrome/renderer/media/chrome_key_systems.cc @@ -66,11 +66,11 @@ class ExternalClearKeyProperties : public KeySystemProperties { return true; case media::EmeInitDataType::CENC: -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) return true; #else return false; -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) case media::EmeInitDataType::UNKNOWN: return false; @@ -80,7 +80,7 @@ class ExternalClearKeyProperties : public KeySystemProperties { } SupportedCodecs GetSupportedCodecs() const override { -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL; #else return media::EME_CODEC_WEBM_ALL; @@ -224,21 +224,21 @@ static void AddPepperBasedWidevine( // as those may offer a higher level of protection. supported_codecs |= media::EME_CODEC_WEBM_OPUS; supported_codecs |= media::EME_CODEC_WEBM_VORBIS; -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) supported_codecs |= media::EME_CODEC_MP4_AAC; -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) for (size_t i = 0; i < codecs.size(); ++i) { if (codecs[i] == kCdmSupportedCodecVp8) supported_codecs |= media::EME_CODEC_WEBM_VP8; if (codecs[i] == kCdmSupportedCodecVp9) supported_codecs |= media::EME_CODEC_WEBM_VP9; -#if defined(USE_PROPRIETARY_CODECS) +#if BUILDFLAG(USE_PROPRIETARY_CODECS) if (codecs[i] == kCdmSupportedCodecAvc1) supported_codecs |= media::EME_CODEC_MP4_AVC1; if (codecs[i] == kCdmSupportedCodecVp9) supported_codecs |= media::EME_CODEC_MP4_VP9; -#endif // defined(USE_PROPRIETARY_CODECS) +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) } using Robustness = cdm::WidevineKeySystemProperties::Robustness; diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc index c1097093335..450f9f89398 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc @@ -15,7 +15,8 @@ #include "ppapi/proxy/serialized_structs.h" #if defined(OS_LINUX) || defined(OS_OPENBSD) -#include "content/public/common/child_process_sandbox_support_linux.h" +#include "content/public/child/child_process_sandbox_support_linux.h" +#include "content/public/common/common_sandbox_support_linux.h" #elif defined(OS_WIN) #include "third_party/skia/include/ports/SkFontMgr.h" #endif diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc index 5e41c5b8a65..09e5b46df6f 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc @@ -8,7 +8,8 @@ #include #include "base/lazy_instance.h" -#include "base/metrics/histogram.h" +#include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/render_thread.h" diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc index d93cdea8312..adac07cb7ce 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc @@ -12,7 +12,7 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" -#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -32,6 +32,7 @@ #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" #include "third_party/WebKit/public/web/WebFrameClient.h" +#include "third_party/WebKit/public/web/WebFrameWidget.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPlugin.h" #include "third_party/WebKit/public/web/WebPluginDocument.h" @@ -484,12 +485,9 @@ void PrepareFrameAndViewForPrint::ResizeForPrinting() { // Backup size and offset if it's a local frame. blink::WebView* web_view = frame_.view(); - // Backup size and offset. - if (blink::WebFrame* web_frame = web_view->mainFrame()) - prev_scroll_offset_ = web_frame->scrollOffset(); if (blink::WebFrame* web_frame = web_view->mainFrame()) { if (web_frame->isWebLocalFrame()) - prev_scroll_offset_ = web_frame->scrollOffset(); + prev_scroll_offset_ = web_frame->getScrollOffset(); } prev_view_size_ = web_view->size(); @@ -535,8 +533,10 @@ void PrepareFrameAndViewForPrint::CopySelection( blink::WebView::create(this, blink::WebPageVisibilityStateVisible); owns_web_view_ = true; content::RenderView::ApplyWebPreferences(prefs, web_view); - web_view->setMainFrame( - blink::WebLocalFrame::create(blink::WebTreeScopeType::Document, this)); + blink::WebLocalFrame* main_frame = blink::WebLocalFrame::create( + blink::WebTreeScopeType::Document, this, nullptr, nullptr); + web_view->setMainFrame(main_frame); + blink::WebFrameWidget::create(this, web_view, main_frame); frame_.Reset(web_view->mainFrame()->toWebLocalFrame()); node_to_print_.reset(); @@ -565,7 +565,8 @@ blink::WebLocalFrame* PrepareFrameAndViewForPrint::createChildFrame( const blink::WebString& unique_name, blink::WebSandboxFlags sandbox_flags, const blink::WebFrameOwnerProperties& frame_owner_properties) { - blink::WebLocalFrame* frame = blink::WebLocalFrame::create(scope, this); + blink::WebLocalFrame* frame = blink::WebLocalFrame::create( + scope, this, nullptr, nullptr); parent->appendChild(frame); return frame; } diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc index 197baedc2f1..4bc37f4da97 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc @@ -126,12 +126,12 @@ void PrintWebViewHelper::PrintPageInternal( &content_area); gfx::Rect canvas_area = content_area; - SkCanvas* canvas = metafile->GetVectorCanvasForNewPage( - page_size, canvas_area, scale_factor); + cc::PaintCanvas* canvas = + metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor); if (!canvas) return; - MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); + MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile); RenderPageContent(frame, params.page_number, canvas_area, content_area, scale_factor, canvas); diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm index 341b89717be..6332df49af5 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm @@ -14,7 +14,6 @@ #include "printing/page_size_margins.h" #include "third_party/WebKit/public/platform/WebCanvas.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/skia/include/core/SkCanvas.h" namespace printing { @@ -112,13 +111,13 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params, gfx::Rect canvas_area = content_area; { - SkCanvas* canvas = metafile->GetVectorCanvasForNewPage( + cc::PaintCanvas* canvas = metafile->GetVectorCanvasForNewPage( *page_size, canvas_area, scale_factor); if (!canvas) return; - MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); - skia::SetIsPreviewMetafile(*canvas, is_preview); + MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile); + cc::SetIsPreviewMetafile(canvas, is_preview); RenderPageContent(frame, page_number, canvas_area, content_area, scale_factor, static_cast(canvas)); } diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index e96a2b8339a..abac5543003 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -14,7 +14,6 @@ #include "printing/page_size_margins.h" #include "printing/pdf_metafile_skia.h" #include "printing/units.h" -#include "skia/ext/platform_device.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -161,12 +160,12 @@ void PrintWebViewHelper::PrintPageInternal( frame->getPrintPageShrink(params.page_number); float scale_factor = css_scale_factor * webkit_page_shrink_factor; - SkCanvas* canvas = metafile->GetVectorCanvasForNewPage( - page_size, canvas_area, scale_factor); + cc::PaintCanvas* canvas = + metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor); if (!canvas) return; - MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); + MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile); #if 0 if (params.params.display_header_footer) { diff --git a/chromium_src/chrome/utility/printing_handler_win.cc b/chromium_src/chrome/utility/printing_handler_win.cc index 4265991272a..cd01a09601a 100644 --- a/chromium_src/chrome/utility/printing_handler_win.cc +++ b/chromium_src/chrome/utility/printing_handler_win.cc @@ -8,6 +8,7 @@ #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/scoped_native_library.h" +#include "chrome/common/chrome_utility_printing_messages.h" #include "chrome/common/print_messages.h" #include "content/public/utility/utility_thread.h" #include "pdf/pdf.h" @@ -59,13 +60,25 @@ bool PrintingHandlerWin::OnMessageReceived(const IPC::Message& message) { void PrintingHandlerWin::OnRenderPDFPagesToMetafile( IPC::PlatformFileForTransit pdf_transit, - const PdfRenderSettings& settings, - bool print_text_with_gdi) { + const PdfRenderSettings& settings) { pdf_rendering_settings_ = settings; - chrome_pdf::SetPDFUseGDIPrinting(print_text_with_gdi); + chrome_pdf::SetPDFUseGDIPrinting(pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::GDI_TEXT); + int postscript_level; + switch (pdf_rendering_settings_.mode) { + case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2: + postscript_level = 2; + break; + case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3: + postscript_level = 3; + break; + default: + postscript_level = 0; // Not using postscript. + } + chrome_pdf::SetPDFPostscriptPrintingLevel(postscript_level); + base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); int page_count = LoadPDF(std::move(pdf_file)); - //int page_count = 1; Send( new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageCount(page_count)); } @@ -75,8 +88,12 @@ void PrintingHandlerWin::OnRenderPDFPagesToMetafileGetPage( IPC::PlatformFileForTransit output_file) { base::File emf_file = IPC::PlatformFileForTransitToFile(output_file); float scale_factor = 1.0f; - bool success = - RenderPdfPageToMetafile(page_number, std::move(emf_file), &scale_factor); + bool postscript = pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 || + pdf_rendering_settings_.mode == + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3; + bool success = RenderPdfPageToMetafile(page_number, std::move(emf_file), + &scale_factor, postscript); Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_PageDone( success, scale_factor)); } @@ -105,7 +122,8 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) { bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, base::File output_file, - float* scale_factor) { + float* scale_factor, + bool postscript) { Emf metafile; metafile.Init(); @@ -116,18 +134,30 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, // original coordinates and we'll be able to print in full resolution. // Before playback we'll need to counter the scaling up that will happen // in the service (print_system_win.cc). - *scale_factor = gfx::CalculatePageScale( - metafile.context(), pdf_rendering_settings_.area.right(), - pdf_rendering_settings_.area.bottom()); - gfx::ScaleDC(metafile.context(), *scale_factor); + // + // The postscript driver does not use the metafile size since it outputs + // postscript rather than a metafile. Instead it uses the printable area + // sent to RenderPDFPageToDC to determine the area to render. Therefore, + // don't scale the DC to match the metafile, and send the printer physical + // offsets to the driver. + if (!postscript) { + *scale_factor = gfx::CalculatePageScale( + metafile.context(), pdf_rendering_settings_.area.right(), + pdf_rendering_settings_.area.bottom()); + gfx::ScaleDC(metafile.context(), *scale_factor); + } // The underlying metafile is of type Emf and ignores the arguments passed // to StartPage. metafile.StartPage(gfx::Size(), gfx::Rect(), 1); + int offset_x = postscript ? pdf_rendering_settings_.offsets.x() : 0; + int offset_y = postscript ? pdf_rendering_settings_.offsets.y() : 0; + if (!chrome_pdf::RenderPDFPageToDC( &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(), - pdf_rendering_settings_.dpi, pdf_rendering_settings_.area.x(), - pdf_rendering_settings_.area.y(), + pdf_rendering_settings_.dpi, + pdf_rendering_settings_.area.x() - offset_x, + pdf_rendering_settings_.area.y() - offset_y, pdf_rendering_settings_.area.width(), pdf_rendering_settings_.area.height(), true, false, true, true, pdf_rendering_settings_.autorotate)) { @@ -138,4 +168,4 @@ bool PrintingHandlerWin::RenderPdfPageToMetafile(int page_number, return metafile.SaveTo(&output_file); } -} // printing +} // namespace printing diff --git a/chromium_src/chrome/utility/printing_handler_win.h b/chromium_src/chrome/utility/printing_handler_win.h index b4a1902dc71..d058e7e5055 100644 --- a/chromium_src/chrome/utility/printing_handler_win.h +++ b/chromium_src/chrome/utility/printing_handler_win.h @@ -29,8 +29,7 @@ class PrintingHandlerWin : public UtilityMessageHandler { private: // IPC message handlers. void OnRenderPDFPagesToMetafile(IPC::PlatformFileForTransit pdf_transit, - const PdfRenderSettings& settings, - bool print_text_with_gdi); + const PdfRenderSettings& settings); void OnRenderPDFPagesToMetafileGetPage( int page_number, IPC::PlatformFileForTransit output_file); @@ -39,7 +38,8 @@ class PrintingHandlerWin : public UtilityMessageHandler { int LoadPDF(base::File pdf_file); bool RenderPdfPageToMetafile(int page_number, base::File output_file, - float* scale_factor); + float* scale_factor, + bool postscript); std::vector pdf_data_; PdfRenderSettings pdf_rendering_settings_; diff --git a/chromium_src/components/pdf/renderer/pepper_pdf_host.cc b/chromium_src/components/pdf/renderer/pepper_pdf_host.cc index 5f0e9afe548..28f046c13ce 100644 --- a/chromium_src/components/pdf/renderer/pepper_pdf_host.cc +++ b/chromium_src/components/pdf/renderer/pepper_pdf_host.cc @@ -47,7 +47,7 @@ int32_t PepperPDFHost::OnHostMsgDidStartLoading( if (!render_frame) return PP_ERROR_FAILED; - render_frame->DidStartLoading(); + render_frame->PluginDidStartLoading(); return PP_OK; } @@ -57,7 +57,7 @@ int32_t PepperPDFHost::OnHostMsgDidStopLoading( if (!render_frame) return PP_ERROR_FAILED; - render_frame->DidStopLoading(); + render_frame->PluginDidStopLoading(); return PP_OK; } diff --git a/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc b/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc index 0b16c1395eb..6cdc1e6ea93 100644 --- a/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc +++ b/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc @@ -57,6 +57,9 @@ const int StreamListenSocket::kSocketError = -1; StreamListenSocket::StreamListenSocket(SocketDescriptor s, StreamListenSocket::Delegate* del) : socket_delegate_(del), +#if defined(OS_POSIX) + watcher_(FROM_HERE), +#endif socket_(s), reads_paused_(false), has_pending_reads_(false) { diff --git a/common.gypi b/common.gypi index 7c1bf366aa6..d4b7646c28e 100644 --- a/common.gypi +++ b/common.gypi @@ -240,6 +240,7 @@ 4302, # (atldlgs.h) 'type cast': truncation from 'LPCTSTR' to 'WORD' 4458, # (atldlgs.h) declaration of 'dwCommonButtons' hides class member 4503, # decorated name length exceeded, name was truncated + 4714, # (atomicstring.h) function marked as __forceinline not inlined 4800, # (v8.h) forcing value to bool 'true' or 'false' 4819, # The file contains a character that cannot be represented in the current code page 4838, # (atlgdi.h) conversion from 'int' to 'UINT' requires a narrowing conversion diff --git a/docs-translations/es/project/README.md b/docs-translations/es/project/README.md index 1aac1d3c780..ed38803d42a 100644 --- a/docs-translations/es/project/README.md +++ b/docs-translations/es/project/README.md @@ -7,12 +7,12 @@ :memo: Traducciones disponibles: [Koreano](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Chino Simplificado](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Portugués Brasileño](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Chino Tradicional](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) -Electron es un framework que permite escribir aplicaciones de escritorio multiplataforma -usando JavaScript, HTML y CSS. Está basado en [Node.js](https://nodejs.org/) con +Electron es un framework que permite escribir aplicaciones de escritorio multiplataforma +usando JavaScript, HTML y CSS. Está basado en [Node.js](https://nodejs.org/) con [Chromium](http://www.chromium.org). Es usado por [Atom editor](https://github.com/atom/atom) y muchas otras [aplicaciones](https://electron.atom.io/apps). -Sigue a [@ElectronJS](https://twitter.com/electronjs) en Twitter para estar informado de anuncios +Sigue a [@ElectronJS](https://twitter.com/electronjs) en Twitter para estar informado de anuncios importantes. Este proyecto se adhiere al [Código de Conducta convenido para Colaboradores](CODE_OF_CONDUCT.md). @@ -41,7 +41,7 @@ los prebuilt binaries, debug symbols, y más. ## Documentación -Las guías y API de referencia están disponibles en el directorio +Las guías y API de referencia están disponibles en el directorio [docs](https://github.com/electron/electron/tree/master/docs). Ahí también puedes encontrar documentos que describen cómo construir y contribuir en Electron. @@ -67,14 +67,14 @@ para ver una aplicación mínima en acción. ## Comunidad Puedes preguntar y interactuar con la comunidad en los siguientes lugares: -- [`electron`](http://discuss.atom.io/c/electron) Categoría en los Foros de +- [`electron`](http://discuss.atom.io/c/electron) Categoría en los Foros de Atom. - `#atom-shell` canal de IRC en Freenode - [`Atom`](http://atom-slack.herokuapp.com/) canales en Slack - [`electron-br`](https://electron-br.slack.com) *(Portugués Brasileño)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Koreano)* - [`electron-jp`](https://electron-jp.slack.com) *(Japonés)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turco)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turco)* - [`electron-id`](https://electron-id.slack.com) *(Indonés* Mira [awesome-electron](https://github.com/sindresorhus/awesome-electron) diff --git a/docs-translations/ko-KR/project/README.md b/docs-translations/ko-KR/project/README.md index a9db702d02f..23c233518d6 100644 --- a/docs-translations/ko-KR/project/README.md +++ b/docs-translations/ko-KR/project/README.md @@ -73,7 +73,7 @@ npm install electron --save-dev - [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티 - [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티 - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티 -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(터키)* 커뮤니티 +- [`electron-tr`](http://electron-tr.herokuapp.com) *(터키)* 커뮤니티 - [`electron-id`](https://electron-id.slack.com) *(인도네시아)* 커뮤니티 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 diff --git a/docs-translations/pt-BR/project/README.md b/docs-translations/pt-BR/project/README.md index d986549f4db..b2e8807a36e 100644 --- a/docs-translations/pt-BR/project/README.md +++ b/docs-translations/pt-BR/project/README.md @@ -61,7 +61,7 @@ Você pode fazer perguntas e interagir com a comunidade nos seguintes locais: - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)* - [`electron-id`](https://electron-id.slack.com) *(Indonesia)* Confira [awesome-electron](https://github.com/sindresorhus/awesome-electron) para uma lista mantida pela comunidade de exemplos de aplicativos úteis, ferramentas e recursos. diff --git a/docs-translations/tr-TR/project/README.md b/docs-translations/tr-TR/project/README.md index d5be7773932..f1998ba09bd 100644 --- a/docs-translations/tr-TR/project/README.md +++ b/docs-translations/tr-TR/project/README.md @@ -72,7 +72,7 @@ Asağıdaki sayfalardan sorular sorabilir ve topluluk ile etkileşime geçebilir - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* - [`electron-jp`](https://electron-jp.slack.com) *(Japanese)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)* - [`electron-id`](https://electron-id.slack.com) *(Indonesia)* Topluluk tarafından sağlanan örnek uygulamaları, aracları ve kaynaklara ulaşmak için diff --git a/docs-translations/zh-CN/project/README.md b/docs-translations/zh-CN/project/README.md index 711dece2fcf..bdd5d06dd84 100644 --- a/docs-translations/zh-CN/project/README.md +++ b/docs-translations/zh-CN/project/README.md @@ -73,7 +73,7 @@ ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/ npm install electron -g - [`electron-br`](https://electron-br.slack.com) *(葡萄牙语-巴西)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(韩语)* - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(日语)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(土耳其)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(土耳其)* - [`electron-id`](https://electron-id.slack.com) *(印度尼西亚)* 查看 [awesome-electron](https://github.com/sindresorhus/awesome-electron) diff --git a/docs-translations/zh-TW/project/README.md b/docs-translations/zh-TW/project/README.md index 4a5d4c602be..7225b26c6f9 100644 --- a/docs-translations/zh-TW/project/README.md +++ b/docs-translations/zh-TW/project/README.md @@ -66,12 +66,12 @@ Clone 並使用 [`electron/electron-quick-start`](https://github.com/electron/el - [`electron-br`](https://electron-br.slack.com) *(葡萄牙語-巴西)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(韓語)* - [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(日語)* -- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(土耳其)* +- [`electron-tr`](http://electron-tr.herokuapp.com) *(土耳其)* - [`electron-id`](https://electron-id.slack.com) *(印度尼西亞)* 在 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 查看由社群維護的清單,包括實用的應用程式、工具以及資源。 -## 憑證 +## 授權條款 MIT © 2016 Github diff --git a/docs/README.md b/docs/README.md index e36eef9dd26..dbb1421ab74 100644 --- a/docs/README.md +++ b/docs/README.md @@ -40,6 +40,7 @@ an issue: * [Desktop Environment Integration](tutorial/desktop-environment-integration.md) * [Online/Offline Event Detection](tutorial/online-offline-events.md) * [REPL](tutorial/repl.md) +* [Native Notifications](tutorial/notifications.md) ## API References diff --git a/docs/api/app.md b/docs/api/app.md index e3160e9053f..cf537474af2 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -760,6 +760,10 @@ Disables hardware acceleration for current app. This method can only be called before app is ready. +### `app.getAppMemoryInfo()` + +Returns [ProcessMemoryInfo[]](structures/process-memory-info.md): Array of `ProcessMemoryInfo` objects that correspond to memory usage statistics of all the processes associated with the app. + ### `app.setBadgeCount(count)` _Linux_ _macOS_ * `count` Integer diff --git a/docs/api/browser-view.md b/docs/api/browser-view.md index 3b7e6f9b9bf..7b722db45e4 100644 --- a/docs/api/browser-view.md +++ b/docs/api/browser-view.md @@ -44,7 +44,7 @@ Objects created with `new BrowserView` have the following properties: #### `view.webContents` _Experimental_ -A [`webContents`](web-contents.md) object owned by this view. +A [`WebContents`](web-contents.md) object owned by this view. #### `win.id` _Experimental_ @@ -57,10 +57,10 @@ Objects created with `new BrowserWindow` have the following instance methods: #### `win.setAutoResize(options)` _Experimental_ * `options` Object - * `width`: If `true`, the view's width will grow and shrink together with - the window. `false` by default. - * `height`: If `true`, the view's height will grow and shrink together with - the window. `false` by default. + * `width` Boolean - If `true`, the view's width will grow and shrink together + with the window. `false` by default. + * `height` Boolean - If `true`, the view's height will grow and shrink + together with the window. `false` by default. #### `win.setBounds(bounds)` _Experimental_ diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 615e3b2c6f9..68cfa7fcea9 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -176,7 +176,7 @@ it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. -### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_ +### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_ _Windows_ * `browserWindow` BrowserWindow (optional) * `options` Object @@ -184,11 +184,17 @@ and no GUI dialog will appear. * `message` String - The message to display to the user. * `callback` Function -Displays a modal dialog that shows a message and certificate information, and -gives the user the option of trusting/importing the certificate. +On macOS, this displays a modal dialog that shows a message and certificate +information, and gives the user the option of trusting/importing the +certificate. If you provide a `browserWindow` argument the dialog will be +attached to the parent window, making it modal. -The `browserWindow` argument allows the dialog to attach itself to a parent -window, making it modal. +On Windows the options are more limited, due to the Win32 APIs used: + + - The `message` argument is not used, as the OS provides its own confirmation + dialog. + - The `browserWindow` argument is ignored since it is not possible to make + this confirmation dialog modal. ## Sheets diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 57c57b5a4e5..f6e24e9f63c 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -16,8 +16,8 @@ It is also possible to send messages from the main process to the renderer process, see [webContents.send][web-contents-send] for more information. * When sending a message, the event name is the `channel`. -* To reply a synchronous message, you need to set `event.returnValue`. -* To send an asynchronous back to the sender, you can use +* To reply to a synchronous message, you need to set `event.returnValue`. +* To send an asynchronous message back to the sender, you can use `event.sender.send(...)`. An example of sending and handling messages between the render and main diff --git a/docs/api/locales.md b/docs/api/locales.md index e8af957b267..a45fdbcbe57 100644 --- a/docs/api/locales.md +++ b/docs/api/locales.md @@ -8,132 +8,135 @@ values are listed below: | Language Code | Language Name | |---------------|---------------| | af | Afrikaans | -| an | Aragonese | -| ar-AE | Arabic (U.A.E.) | -| ar-IQ | Arabic (Iraq) | -| ar | Arabic (Standard) | -| ar-BH | Arabic (Bahrain) | -| ar-DZ | Arabic (Algeria) | -| ar-EG | Arabic (Egypt) | -| ar-JO | Arabic (Jordan) | -| ar-KW | Arabic (Kuwait) | -| ar-LB | Arabic (Lebanon) | -| ar-LY | Arabic (Libya) | -| ar-MA | Arabic (Morocco) | -| ar-OM | Arabic (Oman) | -| ar-QA | Arabic (Qatar) | -| ar-SA | Arabic (Saudi Arabia) | -| ar-SY | Arabic (Syria) | -| ar-TN | Arabic (Tunisia) | -| ar-YE | Arabic (Yemen) | -| as | Assamese | -| ast | Asturian | +| am | Amharic | +| ar | Arabic | | az | Azerbaijani | | be | Belarusian | | bg | Bulgarian | -| bg | Bulgarian | +| bh | Bihari | | bn | Bengali | | br | Breton | | bs | Bosnian | | ca | Catalan | -| ce | Chechen | -| ch | Chamorro | | co | Corsican | -| cr | Cree | | cs | Czech | -| cv | Chuvash | +| cy | Welsh | | da | Danish | -| de | German (Standard) | +| de | German | | de-AT | German (Austria) | | de-CH | German (Switzerland) | | de-DE | German (Germany) | -| de-LI | German (Liechtenstein) | -| de-LU | German (Luxembourg) | | el | Greek | -| en-AU | English (Australia) | -| en-BZ | English (Belize) | | en | English | +| en-AU | English (Australia) | | en-CA | English (Canada) | -| en-GB | English (United Kingdom) | -| en-IE | English (Ireland) | -| en-JM | English (Jamaica) | +| en-GB | English (UK) | | en-NZ | English (New Zealand) | -| en-PH | English (Philippines) | -| en-TT | English (Trinidad & Tobago) | -| en-US | English (United States) | +| en-US | English (US) | | en-ZA | English (South Africa) | -| en-ZW | English (Zimbabwe) | | eo | Esperanto | +| es | Spanish | +| es-419 | Spanish (Latin America) | | et | Estonian | | eu | Basque | | fa | Persian | -| fa | Farsi | -| fa-IR | Persian/Iran | | fi | Finnish | -| fj | Fijian | -| fo | Faeroese | +| fil | Filipino | +| fo | Faroese | +| fr | French | +| fr-CA | French (Canada) | | fr-CH | French (Switzerland) | | fr-FR | French (France) | -| fr-LU | French (Luxembourg) | -| fr-MC | French (Monaco) | -| fr | French (Standard) | -| fr-BE | French (Belgium) | -| fr-CA | French (Canada) | -| fur | Friulian | | fy | Frisian | | ga | Irish | -| gd-IE | Gaelic (Irish) | -| gd | Gaelic (Scots) | -| gl | Galacian | -| gu | Gujurati | +| gd | Scots Gaelic | +| gl | Galician | +| gn | Guarani | +| gu | Gujarati | +| ha | Hausa | +| haw | Hawaiian | | he | Hebrew | | hi | Hindi | | hr | Croatian | -| ht | Haitian | | hu | Hungarian | | hy | Armenian | +| ia | Interlingua | | id | Indonesian | | is | Icelandic | +| it | Italian | | it-CH | Italian (Switzerland) | -| it | Italian (Standard) | -| iu | Inuktitut | +| it-IT | Italian (Italy) | | ja | Japanese | +| jw | Javanese | | ka | Georgian | | kk | Kazakh | -| km | Khmer | +| km | Cambodian | | kn | Kannada | | ko | Korean | -| ko-KP | Korean (North Korea) | -| ko-KR | Korean (South Korea) | -| ks | Kashmiri | -| ky | Kirghiz | +| ku | Kurdish | +| ky | Kyrgyz | | la | Latin | -| lb | Luxembourgish | +| ln | Lingala | +| lo | Laothian | | lt | Lithuanian | | lv | Latvian | -| mi | Maori | -| mk | FYRO Macedonian | +| mk | Macedonian | | ml | Malayalam | +| mn | Mongolian | | mo | Moldavian | | mr | Marathi | | ms | Malay | | mt | Maltese | -| my | Burmese | | nb | Norwegian (Bokmal) | | ne | Nepali | -| ng | Ndonga | -| nl | Dutch (Standard) | -| nl-BE | Dutch (Belgian) | +| nl | Dutch | | nn | Norwegian (Nynorsk) | | no | Norwegian | -| nv | Navajo | | oc | Occitan | | om | Oromo | | or | Oriya | +| pa | Punjabi | +| pl | Polish | +| ps | Pashto | +| pt | Portuguese | +| pt-BR | Portuguese (Brazil) | +| pt-PT | Portuguese (Portugal) | +| qu | Quechua | +| rm | Romansh | +| ro | Romanian | +| ru | Russian | +| sd | Sindhi | +| sh | Serbo-Croatian | +| si | Sinhalese | +| sk | Slovak | +| sl | Slovenian | +| sn | Shona | +| so | Somali | | sq | Albanian | -| tlh | Klingon | -| zh-TW | Chinese (Taiwan) | +| sr | Serbian | +| st | Sesotho | +| su | Sundanese | +| sv | Swedish | +| sw | Swahili | +| ta | Tamil | +| te | Telugu | +| tg | Tajik | +| th | Thai | +| ti | Tigrinya | +| tk | Turkmen | +| to | Tonga | +| tr | Turkish | +| tt | Tatar | +| tw | Twi | +| ug | Uighur | +| uk | Ukrainian | +| ur | Urdu | +| uz | Uzbek | +| vi | Vietnamese | +| xh | Xhosa | +| yi | Yiddish | +| yo | Yoruba | | zh | Chinese | -| zh-CN | Chinese (PRC) | -| zh-HK | Chinese (Hong Kong) | -| zh-SG | Chinese (Singapore) | +| zh-CN | Chinese (Simplified) | +| zh-TW | Chinese (Traditional) | +| zu | Zulu | diff --git a/docs/api/menu.md b/docs/api/menu.md index beceb2059c6..6a30d49b1d6 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -241,7 +241,7 @@ Linux. Here are some notes on making your app's menu more native-like. On macOS there are many system-defined standard menus, like the `Services` and `Windows` menus. To make your menu a standard menu, you should set your menu's -`role` to one of following and Electron will recognize them and make them +`role` to one of the following and Electron will recognize them and make them become standard menus: * `window` diff --git a/docs/api/process.md b/docs/api/process.md index 84320ca98bb..59f80963d81 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -116,3 +116,15 @@ Returns `Object`: Returns an object giving memory usage statistics about the entire system. Note that all statistics are reported in Kilobytes. + +### `process.getCPUUsage()` + +Returns: + +* `CPUUsage` [CPUUsage](structures/cpu-usage.md) + +### `process.getIOCounters()` _Windows_ _Linux_ + +Returns: + +* `IOCounters` [IOCounters](structures/io-counters.md) \ No newline at end of file diff --git a/docs/api/structures/cpu-usage.md b/docs/api/structures/cpu-usage.md new file mode 100644 index 00000000000..b700d4945f0 --- /dev/null +++ b/docs/api/structures/cpu-usage.md @@ -0,0 +1,6 @@ +# CPUUsage Object + +* `percentCPUUsage` Number - Percentage of CPU used since the last call to getCPUUsage. + First call returns 0. +* `idleWakeupsPerSecond` Number - The number of average idle cpu wakeups per second + since the last call to getCPUUsage. First call returns 0. diff --git a/docs/api/structures/io-counters.md b/docs/api/structures/io-counters.md new file mode 100644 index 00000000000..62ad39a90b0 --- /dev/null +++ b/docs/api/structures/io-counters.md @@ -0,0 +1,8 @@ +# IOCounters Object + +* `readOperationCount` Number - The number of I/O read operations. +* `writeOperationCount` Number - The number of I/O write operations. +* `otherOperationCount` Number - Then number of I/O other operations. +* `readTransferCount` Number - The number of I/O read transfers. +* `writeTransferCount` Number - The number of I/O write transfers. +* `otherTransferCount` Number - Then number of I/O other transfers. diff --git a/docs/api/structures/memory-info.md b/docs/api/structures/memory-info.md new file mode 100644 index 00000000000..f6b9d17aaa1 --- /dev/null +++ b/docs/api/structures/memory-info.md @@ -0,0 +1,12 @@ +# MemoryInfo Object + +* `pid` Integer - Process id of the process. +* `workingSetSize` Integer - The amount of memory currently pinned to actual physical RAM. +* `peakWorkingSetSize` Integer - The maximum amount of memory that has ever been pinned + to actual physical RAM. +* `privateBytes` Integer - The amount of memory not shared by other processes, such as + JS heap or HTML content. +* `sharedBytes` Integer - The amount of memory shared between processes, typically + memory consumed by the Electron code itself + +Note that all statistics are reported in Kilobytes. diff --git a/docs/api/structures/process-memory-info.md b/docs/api/structures/process-memory-info.md new file mode 100644 index 00000000000..68198f2d454 --- /dev/null +++ b/docs/api/structures/process-memory-info.md @@ -0,0 +1,4 @@ +# ProcessMemoryInfo Object + +* `pid` Integer - Process id of the process. +* `memory` [MemoryInfo](memory-info.md) - Memory information of the process. diff --git a/docs/api/touch-bar-segmented-control.md b/docs/api/touch-bar-segmented-control.md index 42be0907908..986fee4929f 100644 --- a/docs/api/touch-bar-segmented-control.md +++ b/docs/api/touch-bar-segmented-control.md @@ -21,10 +21,15 @@ Process: [Main](../tutorial/quick-start.md#main-process) * `small-square` - The control is displayed using the small square style. * `separated` - The segments in the control are displayed very close to each other but not touching. - * `segments` [SegmentedControlSegment[]](structures/segmented-control-segment.md) - An array of segments to place in this control - * `selectedIndex` Integer (Optional) - The index of the currently selected segment, will update automatically with user interaction + * `mode` String - (Optional) The selection mode of the control: + * `single` - Default. One item selected at a time, selecting one deselects the previously selected item. + * `multiple` - Multiple items can be selected at a time. + * `buttons` - Make the segments act as buttons, each segment can be pressed and released but never marked as active. + * `segments` [SegmentedControlSegment[]](structures/segmented-control-segment.md) - An array of segments to place in this control. + * `selectedIndex` Integer (Optional) - The index of the currently selected segment, will update automatically with user interaction. When the mode is multiple it will be the last selected item. * `change` Function - Called when the user selects a new segment - * `selectedIndex` Integer - The index of the segment the user selected + * `selectedIndex` Integer - The index of the segment the user selected. + * `isSelected` Boolean - Whether as a result of user selection the segment is selected or not. ### Instance Properties diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index 0a0827a2b2f..8f1b8732f8b 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -138,3 +138,13 @@ app.once('ready', () => { window.setTouchBar(touchBar) }) ``` + +### Running the above example + +To run the example above, you'll need to (assuming you've got a terminal open in the dirtectory you want to run the example): + +1. Save the above file to your computer as `touchbar.js` +2. Install Electron via `npm install electron` +3. Run the example inside Electron: `./node_modules/.bin/electron touchbar.js` + +You should then see a new Electron window and the app running in your touch bar (or touch bar emulator). diff --git a/docs/glossary.md b/docs/glossary.md index 6019bddeee2..b923037f9f0 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -127,7 +127,7 @@ available in "core". ### V8 V8 is Google's open source JavaScript engine. It is written in C++ and is -used in Google Chrome, the open source browser from Google. V8 can run +used in Google Chrome. V8 can run standalone, or can be embedded into any C++ application. ### webview diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 1c82e360e8e..96e56362b2d 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -8,55 +8,9 @@ applications can put a custom menu in the dock menu. This guide explains how to integrate your application into those desktop environments with Electron APIs. -## Notifications (Windows, Linux, macOS) +## Notifications -All three operating systems provide means for applications to send notifications -to the user. Electron conveniently allows developers to send notifications with -the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using -the currently running operating system's native notification APIs to display it. - -**Note:** Since this is an HTML5 API it is only available in the renderer process. - -```javascript -let myNotification = new Notification('Title', { - body: 'Lorem Ipsum Dolor Sit Amet' -}) - -myNotification.onclick = () => { - console.log('Notification clicked') -} -``` - -While code and user experience across operating systems are similar, there -are fine differences. - -### Windows - -* On Windows 10, notifications "just work". -* On Windows 8.1 and Windows 8, a shortcut to your app, with a [Application User -Model ID][app-user-model-id], must be installed to the Start screen. Note, -however, that it does not need to be pinned to the Start screen. -* On Windows 7, notifications work via a custom implemetation which visually -resembles the native one on newer systems. - -Furthermore, the maximum length for the notification body is 250 characters, -with the Windows team recommending that notifications should be kept to 200 -characters. - -### Linux - -Notifications are sent using `libnotify`, it can show notifications on any -desktop environment that follows [Desktop Notifications -Specification][notification-spec], including Cinnamon, Enlightenment, Unity, -GNOME, KDE. - -### macOS - -Notifications are straight-forward on macOS, you should however be aware of -[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). - -Note that notifications are limited to 256 bytes in size - and will be truncated -if you exceed that limit. +See [Notifications](notifications.md) ## Recent documents (Windows & macOS) diff --git a/docs/tutorial/notifications.md b/docs/tutorial/notifications.md new file mode 100644 index 00000000000..34c64ad9bb4 --- /dev/null +++ b/docs/tutorial/notifications.md @@ -0,0 +1,85 @@ +# Notifications (Windows, Linux, macOS) + +All three operating systems provide means for applications to send notifications +to the user. Electron conveniently allows developers to send notifications with +the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using +the currently running operating system's native notification APIs to display it. + +**Note:** Since this is an HTML5 API it is only available in the renderer process. + +```javascript +let myNotification = new Notification('Title', { + body: 'Lorem Ipsum Dolor Sit Amet' +}) + +myNotification.onclick = () => { + console.log('Notification clicked') +} +``` + +While code and user experience across operating systems are similar, there +are subtle differences. + +## Windows + +* On Windows 10, notifications "just work". +* On Windows 8.1 and Windows 8, a shortcut to your app, with an [Application User +Model ID][app-user-model-id], must be installed to the Start screen. Note, +however, that it does not need to be pinned to the Start screen. +* On Windows 7, notifications work via a custom implementation which visually + resembles the native one on newer systems. + +Furthermore, in Windows 8, the maximum length for the notification body is 250 +characters, with the Windows team recommending that notifications should be kept +to 200 characters. That said, that limitation has been removed in Windows 10, with +the Windows team asking developers to be reasonable. Attempting to send gigantic +amounts of text to the API (thousands of characters) might result in instability. + +### Advanced Notifications + +Later versions of Windows allow for advanced notifications, with custom templates, +images, and other flexible elements. To send those notifications (from either the +main process or the renderer process), use the userland module +[electron-windows-notifications](https://github.com/felixrieseberg/electron-windows-notifications), +which uses native Node addons to send `ToastNotification` and `TileNotification` objects. + +While notifications including buttons work with just `electron-windows-notifications`, +handling replies requires the use of [`electron-windows-interactive-notifications`](https://github.com/felixrieseberg/electron-windows-interactive-notifications), which +helps with registering the required COM components and calling your Electron app with +the entered user data. + +### Quiet Hours / Presentation Mode + +To detect whether or not you're allowed to send a notification, use the userland module +[electron-notification-state](https://github.com/felixrieseberg/electron-notification-state). + +This allows you to determine ahead of time whether or not Windows will silently throw +the notification away. + +## macOS + +Notifications are straight-forward on macOS, but you should be aware of +[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). + +Note that notifications are limited to 256 bytes in size and will be truncated +if you exceed that limit. + +### Advanced Notifications + +Later versions of macOS allow for notifications with an input field, allowing the user +to quickly reply to a notification. In order to send notifications with an input field, +use the userland module [node-mac-notifier](https://github.com/CharlieHess/node-mac-notifier). + +### Do not disturb / Session State + +To detect whether or not you're allowed to send a notification, use the userland module +[electron-notification-state](https://github.com/felixrieseberg/electron-notification-state). + +This will allow you to detect ahead of time whether or not the notification will be displayed. + +## Linux + +Notifications are sent using `libnotify` which can show notifications on any +desktop environment that follows [Desktop Notifications +Specification][notification-spec], including Cinnamon, Enlightenment, Unity, +GNOME, KDE. diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index f490b738891..9a13715fad6 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -192,10 +192,10 @@ $ .\node_modules\.bin\electron . If you downloaded Electron manually, you can also use the included binary to execute your app directly. -#### Windows +#### macOS ```bash -$ .\electron\electron.exe your-app\ +$ ./Electron.app/Contents/MacOS/Electron your-app/ ``` #### Linux @@ -204,10 +204,10 @@ $ .\electron\electron.exe your-app\ $ ./electron/electron your-app/ ``` -#### macOS +#### Windows ```bash -$ ./Electron.app/Contents/MacOS/Electron your-app/ +$ .\electron\electron.exe your-app\ ``` `Electron.app` here is part of the Electron's release package, you can download diff --git a/electron.gyp b/electron.gyp index ce3673abf11..dd40842bb86 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '1.6.7', + 'version%': '1.7.0', 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', }, 'includes': [ @@ -237,9 +237,6 @@ 'USING_V8_SHARED', 'USING_V8_PLATFORM_SHARED', 'USING_V8_BASE_SHARED', - # Remove this after enable_plugins becomes a feature flag. - 'ENABLE_PLUGINS', - 'USE_PROPRIETARY_CODECS', ], 'sources': [ '<@(lib_sources)', diff --git a/filenames.gypi b/filenames.gypi index 86ed08daf2d..54ddf4dde19 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -293,6 +293,7 @@ 'atom/browser/ui/atom_menu_model.h', 'atom/browser/ui/certificate_trust.h', 'atom/browser/ui/certificate_trust_mac.mm', + 'atom/browser/ui/certificate_trust_win.cc', 'atom/browser/ui/cocoa/atom_menu_controller.h', 'atom/browser/ui/cocoa/atom_menu_controller.mm', 'atom/browser/ui/cocoa/atom_touch_bar.h', diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 4b3f70139f0..49a134f3941 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -76,13 +76,9 @@ BrowserWindow.prototype._init = function () { // Change window title to page title. this.webContents.on('page-title-updated', (event, title) => { - // The page-title-updated event is not emitted immediately (see #3645), so - // when the callback is called the BrowserWindow might have been closed. - if (this.isDestroyed()) return - // Route the event to BrowserWindow. this.emit('page-title-updated', event, title) - if (!event.defaultPrevented) this.setTitle(title) + if (!this.isDestroyed() && !event.defaultPrevented) this.setTitle(title) }) // Sometimes the webContents doesn't get focus when window is shown, so we diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 4bb129449eb..ae0c1f1428b 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -264,16 +264,17 @@ TouchBar.TouchBarSegmentedControl = class TouchBarSegmentedControl extends Touch constructor (config) { super() if (config == null) config = {} - const {segmentStyle, segments, selectedIndex, change} = config + const {segmentStyle, segments, selectedIndex, change, mode} = config this.type = 'segmented_control' this._addLiveProperty('segmentStyle', segmentStyle) this._addLiveProperty('segments', segments || []) this._addLiveProperty('selectedIndex', selectedIndex) + this._addLiveProperty('mode', mode) if (typeof change === 'function') { this.onInteraction = (details) => { this._selectedIndex = details.selectedIndex - change(details.selectedIndex) + change(details.selectedIndex, details.isSelected) } } } diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 6af96e17571..c49c1be8ba6 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -268,13 +268,6 @@ WebContents.prototype._init = function () { this.reload() }) - // Delays the page-title-updated event to next tick. - this.on('-page-title-updated', function (...args) { - setImmediate(() => { - this.emit('page-title-updated', ...args) - }) - }) - app.emit('web-contents-created', {}, this) } diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index aff73ebe6f6..305da92f9e6 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -314,7 +314,7 @@ ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event, // The W3C does not seem to have word on how postMessage should work when the // origins do not match, so we do not do |canAccessWindow| check here since // postMessage across origins is useful and not harmful. - if (guestContents.getURL().indexOf(targetOrigin) === 0 || targetOrigin === '*') { + if (targetOrigin === '*' || isSameOrigin(guestContents.getURL(), targetOrigin)) { const sourceId = event.sender.id guestContents.send('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin) } diff --git a/lib/sandboxed_renderer/init.js b/lib/sandboxed_renderer/init.js index 5194f951544..1aec0bc0bfd 100644 --- a/lib/sandboxed_renderer/init.js +++ b/lib/sandboxed_renderer/init.js @@ -38,6 +38,9 @@ const preloadSrc = fs.readFileSync(preloadPath).toString() // access to things like `process.atomBinding`). const preloadProcess = new events.EventEmitter() preloadProcess.crash = () => binding.crash() +preloadProcess.hang = () => binding.hang() +preloadProcess.getProcessMemoryInfo = () => binding.getProcessMemoryInfo() +preloadProcess.getSystemMemoryInfo = () => binding.getSystemMemoryInfo() process.platform = preloadProcess.platform = electron.remote.process.platform process.execPath = preloadProcess.execPath = electron.remote.process.execPath process.on('exit', () => preloadProcess.emit('exit')) diff --git a/package.json b/package.json index bfb35f29689..d6215fd2f43 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "electron", - "version": "1.6.7", + "version": "1.7.0", "devDependencies": { "asar": "^0.11.0", "browserify": "^13.1.0", "electabul": "~0.0.4", "electron-docs-linter": "^2.1.0", + "electron-typescript-definitions": "^1.2.0", "request": "*", "standard": "^8.4.0", "standard-markdown": "^2.1.1" diff --git a/script/bootstrap.py b/script/bootstrap.py index 1fd3fd83906..08d84cff28e 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -63,6 +63,7 @@ def main(): create_chrome_version_h() touch_config_gypi() run_update(defines, args.msvs) + create_node_headers() update_electron_modules('spec', args.target_arch) @@ -176,17 +177,21 @@ def update_node_modules(dirname, env=None): if os.environ.has_key('CI'): try: execute_stdout(args, env) + execute_stdout([NPM, 'rebuild'], env) except subprocess.CalledProcessError: pass else: execute_stdout(args, env) + execute_stdout([NPM, 'rebuild'], env) def update_electron_modules(dirname, target_arch): env = os.environ.copy() + version = get_electron_version() env['npm_config_arch'] = target_arch - env['npm_config_target'] = get_electron_version() - env['npm_config_disturl'] = 'https://atom.io/download/electron' + env['npm_config_target'] = version + env['npm_config_nodedir'] = os.path.join(SOURCE_ROOT, 'dist', + 'node-{0}'.format(version)) update_node_modules(dirname, env) @@ -260,5 +265,11 @@ def run_update(defines, msvs): execute_stdout(args) +def create_node_headers(): + execute_stdout([sys.executable, + os.path.join(SOURCE_ROOT, 'script', 'create-node-headers.py'), + '--version', get_electron_version()]) + + if __name__ == '__main__': sys.exit(main()) diff --git a/script/cibuild b/script/cibuild index 419404fca8a..f523fa1af5f 100755 --- a/script/cibuild +++ b/script/cibuild @@ -81,6 +81,7 @@ def main(): sys.stderr.write('\nRunning `npm run lint`\n') sys.stderr.flush() execute([npm, 'run', 'lint']) + if is_release: run_script('build.py', ['-c', 'R']) run_script('create-dist.py') diff --git a/script/create-dist.py b/script/create-dist.py index 27032400f3d..2602a9f943d 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -91,6 +91,7 @@ def main(): if PLATFORM != 'win32' and not args.no_api_docs: create_api_json_schema() + create_typescript_definitions() if PLATFORM == 'linux': strip_binaries() @@ -143,6 +144,15 @@ def create_api_json_schema(): '--version={}'.format(ELECTRON_VERSION.replace('v', ''))], env=env) +def create_typescript_definitions(): + node_bin_dir = os.path.join(SOURCE_ROOT, 'node_modules', '.bin') + env = os.environ.copy() + env['PATH'] = os.path.pathsep.join([node_bin_dir, env['PATH']]) + infile = os.path.relpath(os.path.join(DIST_DIR, 'electron-api.json')) + outfile = os.path.relpath(os.path.join(DIST_DIR, 'electron.d.ts')) + execute(['electron-typescript-definitions', '--in={0}'.format(infile), + '--out={0}'.format(outfile)], env=env) + def strip_binaries(): for binary in TARGET_BINARIES[PLATFORM]: if binary.endswith('.so') or '.' not in binary: diff --git a/script/create-node-headers.py b/script/create-node-headers.py new file mode 100755 index 00000000000..baf9c86aba3 --- /dev/null +++ b/script/create-node-headers.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +import argparse +import os +import shutil +import sys +import tarfile + +from lib.util import safe_mkdir, scoped_cwd + + +SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') +NODE_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'node') +OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R') + +HEADERS_SUFFIX = [ + '.h', + '.gypi', +] +HEADERS_DIRS = [ + 'src', + 'deps/http_parser', + 'deps/zlib', + 'deps/uv', + 'deps/npm', + 'deps/mdb_v8', +] +HEADERS_FILES = [ + 'common.gypi', + 'config.gypi', +] + + +def main(): + safe_mkdir(DIST_DIR) + + args = parse_args() + node_headers_dir = os.path.join(DIST_DIR, 'node-{0}'.format(args.version)) + iojs_headers_dir = os.path.join(DIST_DIR, 'iojs-{0}'.format(args.version)) + iojs2_headers_dir = os.path.join(DIST_DIR, + 'iojs-{0}-headers'.format(args.version)) + + copy_headers(node_headers_dir) + create_header_tarball(node_headers_dir) + copy_headers(iojs_headers_dir) + create_header_tarball(iojs_headers_dir) + copy_headers(iojs2_headers_dir) + create_header_tarball(iojs2_headers_dir) + + +def parse_args(): + parser = argparse.ArgumentParser(description='create node header tarballs') + parser.add_argument('-v', '--version', help='Specify the version', + required=True) + return parser.parse_args() + + +def copy_headers(dist_headers_dir): + safe_mkdir(dist_headers_dir) + + # Copy standard node headers from node. repository. + for include_path in HEADERS_DIRS: + abs_path = os.path.join(NODE_DIR, include_path) + for dirpath, _, filenames in os.walk(abs_path): + for filename in filenames: + extension = os.path.splitext(filename)[1] + if extension not in HEADERS_SUFFIX: + continue + copy_source_file(os.path.join(dirpath, filename), NODE_DIR, + dist_headers_dir) + for other_file in HEADERS_FILES: + copy_source_file(os.path.join(NODE_DIR, other_file), NODE_DIR, + dist_headers_dir) + + # Copy V8 headers from chromium's repository. + src = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', 'download', + 'libchromiumcontent', 'src') + for dirpath, _, filenames in os.walk(os.path.join(src, 'v8')): + for filename in filenames: + extension = os.path.splitext(filename)[1] + if extension not in HEADERS_SUFFIX: + continue + copy_source_file(os.path.join(dirpath, filename), src, + os.path.join(dist_headers_dir, 'deps')) + + +def create_header_tarball(dist_headers_dir): + target = dist_headers_dir + '.tar.gz' + with scoped_cwd(DIST_DIR): + tarball = tarfile.open(name=target, mode='w:gz') + tarball.add(os.path.relpath(dist_headers_dir)) + tarball.close() + + +def copy_source_file(source, start, destination): + relative = os.path.relpath(source, start=start) + final_destination = os.path.join(destination, relative) + safe_mkdir(os.path.dirname(final_destination)) + shutil.copy2(source, final_destination) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/script/lib/config.py b/script/lib/config.py index 5818571089f..c920f2acc22 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -9,7 +9,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ - '4a0e32606e52c12c50c2e3a0973d015d8cdff494' + '44a803957cb27610c38f7e859016ac257959aeb5' PLATFORM = { 'cygwin': 'win32', diff --git a/script/upload-node-headers.py b/script/upload-node-headers.py index 230b08ed5ac..6c5163f7629 100755 --- a/script/upload-node-headers.py +++ b/script/upload-node-headers.py @@ -5,50 +5,17 @@ import glob import os import shutil import sys -import tarfile from lib.config import PLATFORM, get_target_arch, s3_config -from lib.util import execute, safe_mkdir, scoped_cwd, s3put +from lib.util import safe_mkdir, scoped_cwd, s3put SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) DIST_DIR = os.path.join(SOURCE_ROOT, 'dist') -NODE_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'node') OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R') -HEADERS_SUFFIX = [ - '.h', - '.gypi', -] -HEADERS_DIRS = [ - 'src', - 'deps/http_parser', - 'deps/zlib', - 'deps/uv', - 'deps/npm', - 'deps/mdb_v8', -] -HEADERS_FILES = [ - 'common.gypi', - 'config.gypi', -] - - def main(): - safe_mkdir(DIST_DIR) - args = parse_args() - node_headers_dir = os.path.join(DIST_DIR, 'node-{0}'.format(args.version)) - iojs_headers_dir = os.path.join(DIST_DIR, 'iojs-{0}'.format(args.version)) - iojs2_headers_dir = os.path.join(DIST_DIR, - 'iojs-{0}-headers'.format(args.version)) - - copy_headers(node_headers_dir) - create_header_tarball(node_headers_dir) - copy_headers(iojs_headers_dir) - create_header_tarball(iojs_headers_dir) - copy_headers(iojs2_headers_dir) - create_header_tarball(iojs2_headers_dir) # Upload node's headers to S3. bucket, access_key, secret_key = s3_config() @@ -62,50 +29,6 @@ def parse_args(): return parser.parse_args() -def copy_headers(dist_headers_dir): - safe_mkdir(dist_headers_dir) - - # Copy standard node headers from node. repository. - for include_path in HEADERS_DIRS: - abs_path = os.path.join(NODE_DIR, include_path) - for dirpath, _, filenames in os.walk(abs_path): - for filename in filenames: - extension = os.path.splitext(filename)[1] - if extension not in HEADERS_SUFFIX: - continue - copy_source_file(os.path.join(dirpath, filename), NODE_DIR, - dist_headers_dir) - for other_file in HEADERS_FILES: - copy_source_file(os.path.join(NODE_DIR, other_file), NODE_DIR, - dist_headers_dir) - - # Copy V8 headers from chromium's repository. - src = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', 'download', - 'libchromiumcontent', 'src') - for dirpath, _, filenames in os.walk(os.path.join(src, 'v8')): - for filename in filenames: - extension = os.path.splitext(filename)[1] - if extension not in HEADERS_SUFFIX: - continue - copy_source_file(os.path.join(dirpath, filename), src, - os.path.join(dist_headers_dir, 'deps')) - - -def create_header_tarball(dist_headers_dir): - target = dist_headers_dir + '.tar.gz' - with scoped_cwd(DIST_DIR): - tarball = tarfile.open(name=target, mode='w:gz') - tarball.add(os.path.relpath(dist_headers_dir)) - tarball.close() - - -def copy_source_file(source, start, destination): - relative = os.path.relpath(source, start=start) - final_destination = os.path.join(destination, relative) - safe_mkdir(os.path.dirname(final_destination)) - shutil.copy2(source, final_destination) - - def upload_node(bucket, access_key, secret_key, version): with scoped_cwd(DIST_DIR): s3put(bucket, access_key, secret_key, DIST_DIR, diff --git a/script/upload.py b/script/upload.py index 8b4cdfcbdf0..ea5e8eca3c2 100755 --- a/script/upload.py +++ b/script/upload.py @@ -81,6 +81,7 @@ def main(): if PLATFORM == 'darwin': upload_electron(github, release, os.path.join(DIST_DIR, 'electron-api.json')) + upload_electron(github, release, os.path.join(DIST_DIR, 'electron.d.ts')) upload_electron(github, release, os.path.join(DIST_DIR, DSYM_NAME)) elif PLATFORM == 'win32': upload_electron(github, release, os.path.join(DIST_DIR, PDB_NAME)) @@ -101,6 +102,7 @@ def main(): run_python_script('upload-windows-pdb.py') # Upload node headers. + run_python_script('create-node-headers.py', '-v', args.version) run_python_script('upload-node-headers.py', '-v', args.version) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 9a9b4334bce..1bcc1a5c622 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -533,4 +533,17 @@ describe('app module', function () { }) }) }) + + describe('getAppMemoryInfo() API', function () { + it('returns the process memory of all running electron processes', function () { + const appMemoryInfo = app.getAppMemoryInfo() + assert.ok(appMemoryInfo.length > 0, 'App memory info object is not > 0') + for (const {memory, pid} of appMemoryInfo) { + assert.ok(memory.workingSetSize > 0, 'working set size is not > 0') + assert.ok(memory.privateBytes > 0, 'private bytes is not > 0') + assert.ok(memory.sharedBytes > 0, 'shared bytes is not > 0') + assert.ok(pid > 0, 'pid is not > 0') + } + }) + }) }) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 9576fd5d22b..8d5f329a14c 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -86,6 +86,42 @@ describe('BrowserWindow module', function () { }) describe('BrowserWindow.close()', function () { + let server + + before(function (done) { + server = http.createServer((request, response) => { + switch (request.url) { + case '/404': + response.statusCode = '404' + response.end() + break + case '/301': + response.statusCode = '301' + response.setHeader('Location', '/200') + response.end() + break + case '/200': + response.statusCode = '200' + response.end('hello') + break + case '/title': + response.statusCode = '200' + response.end('Hello') + break + default: + done('unsupported endpoint') + } + }).listen(0, '127.0.0.1', () => { + server.url = 'http://127.0.0.1:' + server.address().port + done() + }) + }) + + after(function () { + server.close() + server = null + }) + it('should emit unload handler', function (done) { w.webContents.on('did-finish-load', function () { w.close() @@ -109,6 +145,38 @@ describe('BrowserWindow module', function () { }) w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false.html')) }) + + it('should not crash when invoked synchronously inside navigation observer', function (done) { + const events = [ + { name: 'did-start-loading', url: `${server.url}/200` }, + { name: 'did-get-redirect-request', url: `${server.url}/301` }, + { name: 'did-get-response-details', url: `${server.url}/200` }, + { name: 'dom-ready', url: `${server.url}/200` }, + { name: 'page-title-updated', url: `${server.url}/title` }, + { name: 'did-stop-loading', url: `${server.url}/200` }, + { name: 'did-finish-load', url: `${server.url}/200` }, + { name: 'did-frame-finish-load', url: `${server.url}/200` }, + { name: 'did-fail-load', url: `${server.url}/404` } + ] + const responseEvent = 'window-webContents-destroyed' + + function* genNavigationEvent () { + let eventOptions = null + while ((eventOptions = events.shift()) && events.length) { + let w = new BrowserWindow({show: false}) + eventOptions.id = w.id + eventOptions.responseEvent = responseEvent + ipcRenderer.send('test-webcontents-navigation-observer', eventOptions) + yield 1 + } + } + + let gen = genNavigationEvent() + ipcRenderer.on(responseEvent, function () { + if (!gen.next().value) done() + }) + gen.next() + }) }) describe('window.close()', function () { @@ -1082,6 +1150,29 @@ describe('BrowserWindow module', function () { }) w.loadURL('file://' + path.join(fixtures, 'pages', 'window-open.html')) }) + + it('releases memory after popup is closed', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + preload: preload, + sandbox: true + } + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?allocate-memory')) + w.webContents.openDevTools({mode: 'detach'}) + ipcMain.once('answer', function (event, {bytesBeforeOpen, bytesAfterOpen, bytesAfterClose}) { + const memoryIncreaseByOpen = bytesAfterOpen - bytesBeforeOpen + const memoryDecreaseByClose = bytesAfterOpen - bytesAfterClose + // decreased memory should be less than increased due to factors we + // can't control, but given the amount of memory allocated in the + // fixture, we can reasonably expect decrease to be at least 70% of + // increase + assert(memoryDecreaseByClose > memoryIncreaseByOpen * 0.7) + done() + }) + }) }) describe('nativeWindowOpen option', () => { @@ -1170,6 +1261,60 @@ describe('BrowserWindow module', function () { }) w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')) }) + + it('emits for each close attempt', function (done) { + var beforeUnloadCount = 0 + w.on('onbeforeunload', function () { + beforeUnloadCount++ + if (beforeUnloadCount < 3) { + w.close() + } else if (beforeUnloadCount === 3) { + done() + } + }) + w.webContents.once('did-finish-load', function () { + w.close() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false-prevent3.html')) + }) + + it('emits for each reload attempt', function (done) { + var beforeUnloadCount = 0 + w.on('onbeforeunload', function () { + beforeUnloadCount++ + if (beforeUnloadCount < 3) { + w.reload() + } else if (beforeUnloadCount === 3) { + done() + } + }) + w.webContents.once('did-finish-load', function () { + w.webContents.once('did-finish-load', function () { + assert.fail('Reload was not prevented') + }) + w.reload() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false-prevent3.html')) + }) + + it('emits for each navigation attempt', function (done) { + var beforeUnloadCount = 0 + w.on('onbeforeunload', function () { + beforeUnloadCount++ + if (beforeUnloadCount < 3) { + w.loadURL('about:blank') + } else if (beforeUnloadCount === 3) { + done() + } + }) + w.webContents.once('did-finish-load', function () { + w.webContents.once('did-finish-load', function () { + assert.fail('Navigation was not prevented') + }) + w.loadURL('about:blank') + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false-prevent3.html')) + }) }) describe('new-window event', function () { diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index f8597c03409..83b114f7238 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -1,4 +1,5 @@ const assert = require('assert') +const http = require('http') const path = require('path') const {closeWindow} = require('./window-helpers') const BrowserWindow = require('electron').remote.BrowserWindow @@ -70,6 +71,15 @@ describe('debugger module', function () { }) describe('debugger.sendCommand', function () { + let server + + afterEach(function () { + if (server != null) { + server.close() + server = null + } + }) + it('retuns response', function (done) { w.webContents.loadURL('about:blank') try { @@ -125,5 +135,33 @@ describe('debugger module', function () { done() }) }) + + it('handles invalid unicode characters in message', function (done) { + try { + w.webContents.debugger.attach() + } catch (err) { + done('unexpected error : ' + err) + } + + w.webContents.debugger.on('message', (event, method, params) => { + if (method === 'Network.loadingFinished') { + w.webContents.debugger.sendCommand('Network.getResponseBody', { + requestId: params.requestId + }, () => { + done() + }) + } + }) + + server = http.createServer((req, res) => { + res.setHeader('Content-Type', 'text/plain; charset=utf-8') + res.end('\uFFFF') + }) + + server.listen(0, '127.0.0.1', () => { + w.webContents.debugger.sendCommand('Network.enable') + w.loadURL(`http://127.0.0.1:${server.address().port}`) + }) + }) }) }) diff --git a/spec/api-process-spec.js b/spec/api-process-spec.js new file mode 100644 index 00000000000..5f4ad1730bc --- /dev/null +++ b/spec/api-process-spec.js @@ -0,0 +1,26 @@ +const assert = require('assert') + +describe('process module', function () { + describe('process.getCPUUsage()', function () { + it('returns a cpu usage object', function () { + const cpuUsage = process.getCPUUsage() + assert.equal(typeof cpuUsage.percentCPUUsage, 'number') + assert.equal(typeof cpuUsage.idleWakeupsPerSecond, 'number') + }) + }) + + describe('process.getIOCounters()', function () { + it('returns an io counters object', function () { + if (process.platform === 'darwin') { + return + } + const ioCounters = process.getIOCounters() + assert.equal(typeof ioCounters.readOperationCount, 'number') + assert.equal(typeof ioCounters.writeOperationCount, 'number') + assert.equal(typeof ioCounters.otherOperationCount, 'number') + assert.equal(typeof ioCounters.readTransferCount, 'number') + assert.equal(typeof ioCounters.writeTransferCount, 'number') + assert.equal(typeof ioCounters.otherTransferCount, 'number') + }) + }) +}) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index f081b390094..7eac9d3e0e9 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -542,4 +542,70 @@ describe('webContents module', function () { }) }) }) + + describe('destroy()', () => { + let server + + before(function (done) { + server = http.createServer((request, response) => { + switch (request.url) { + case '/404': + response.statusCode = '404' + response.end() + break + case '/301': + response.statusCode = '301' + response.setHeader('Location', '/200') + response.end() + break + case '/200': + response.statusCode = '200' + response.end('hello') + break + default: + done('unsupported endpoint') + } + }).listen(0, '127.0.0.1', () => { + server.url = 'http://127.0.0.1:' + server.address().port + done() + }) + }) + + after(function () { + server.close() + server = null + }) + + it('should not crash when invoked synchronously inside navigation observer', (done) => { + const events = [ + { name: 'did-start-loading', url: `${server.url}/200` }, + { name: 'did-get-redirect-request', url: `${server.url}/301` }, + { name: 'did-get-response-details', url: `${server.url}/200` }, + { name: 'dom-ready', url: `${server.url}/200` }, + { name: 'did-stop-loading', url: `${server.url}/200` }, + { name: 'did-finish-load', url: `${server.url}/200` }, + // FIXME: Multiple Emit calls inside an observer assume that object + // will be alive till end of the observer. Synchronous `destroy` api + // violates this contract and crashes. + // { name: 'did-frame-finish-load', url: `${server.url}/200` }, + { name: 'did-fail-load', url: `${server.url}/404` } + ] + const responseEvent = 'webcontents-destroyed' + + function* genNavigationEvent () { + let eventOptions = null + while ((eventOptions = events.shift()) && events.length) { + eventOptions.responseEvent = responseEvent + ipcRenderer.send('test-webcontents-navigation-observer', eventOptions) + yield 1 + } + } + + let gen = genNavigationEvent() + ipcRenderer.on(responseEvent, () => { + if (!gen.next().value) done() + }) + gen.next() + }) + }) }) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index d5d1b3f4782..1302fbbc433 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -1,4 +1,5 @@ const assert = require('assert') +const fs = require('fs') const http = require('http') const path = require('path') const ws = require('ws') @@ -618,6 +619,39 @@ describe('chromium feature', function () { }) document.body.appendChild(webview) }) + + describe('targetOrigin argument', function () { + let serverURL + let server + + beforeEach(function (done) { + server = http.createServer(function (req, res) { + res.writeHead(200) + const filePath = path.join(fixtures, 'pages', 'window-opener-targetOrigin.html') + res.end(fs.readFileSync(filePath, 'utf8')) + }) + server.listen(0, '127.0.0.1', function () { + serverURL = `http://127.0.0.1:${server.address().port}` + done() + }) + }) + + afterEach(function () { + server.close() + }) + + it('delivers messages that match the origin', function (done) { + let b + listener = function (event) { + window.removeEventListener('message', listener) + b.close() + assert.equal(event.data, 'deliver') + done() + } + window.addEventListener('message', listener) + b = window.open(serverURL, '', 'show=no') + }) + }) }) describe('creating a Uint8Array under browser side', function () { diff --git a/spec/fixtures/api/allocate-memory.html b/spec/fixtures/api/allocate-memory.html new file mode 100644 index 00000000000..ce3140ab0cd --- /dev/null +++ b/spec/fixtures/api/allocate-memory.html @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/spec/fixtures/api/beforeunload-false-prevent3.html b/spec/fixtures/api/beforeunload-false-prevent3.html new file mode 100644 index 00000000000..6ed2a7d1aa4 --- /dev/null +++ b/spec/fixtures/api/beforeunload-false-prevent3.html @@ -0,0 +1,17 @@ + + + + + diff --git a/spec/fixtures/api/sandbox.html b/spec/fixtures/api/sandbox.html index a74a1d5d600..f8d7aa7921d 100644 --- a/spec/fixtures/api/sandbox.html +++ b/spec/fixtures/api/sandbox.html @@ -1,5 +1,18 @@ + + diff --git a/spec/static/main.js b/spec/static/main.js index 7e56da623bf..ba31b61ae07 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -338,6 +338,27 @@ ipcMain.on('crash-service-pid', (event, pid) => { event.returnValue = null }) +ipcMain.on('test-webcontents-navigation-observer', (event, options) => { + let contents = null + let destroy = () => {} + if (options.id) { + const w = BrowserWindow.fromId(options.id) + contents = w.webContents + destroy = () => w.close() + } else { + contents = webContents.create() + destroy = () => contents.destroy() + } + + contents.once(options.name, () => destroy()) + + contents.once('destroyed', () => { + event.sender.send(options.responseEvent) + }) + + contents.loadURL(options.url) +}) + // Suspend listeners until the next event and then restore them const suspendListeners = (emitter, eventName, callback) => { const listeners = emitter.listeners(eventName) diff --git a/vendor/brightray b/vendor/brightray index 909c4926549..3d9ebb54999 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 909c49265493bd095c27cefd999567be2107899a +Subproject commit 3d9ebb549990d50ab67b705b8ff16433a3dbc546 diff --git a/vendor/crashpad b/vendor/crashpad index eeac857dfb5..2871326543e 160000 --- a/vendor/crashpad +++ b/vendor/crashpad @@ -1 +1 @@ -Subproject commit eeac857dfb5b255c899c8763d62654863b4c8890 +Subproject commit 2871326543ea0e01488f034bb660bf5a39f55c0c diff --git a/vendor/node b/vendor/node index 3fe90cfcf54..df227c3a5db 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 3fe90cfcf54dd946980e59daf550a7cdb2317c8f +Subproject commit df227c3a5db7aa8eab64c86f54588c6cd2d6c623