diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index 62bcb8c2828b..a332a5a379ba 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -1,7 +1,7 @@ { 'variables': { # The libraries brightray will be compiled to. - 'linux_system_libraries': 'gtk+-2.0 libnotify dbus-1 x11 xi xrandr xext gconf-2.0 gmodule-2.0 nss' + 'linux_system_libraries': 'gtk+-2.0 libnotify dbus-1 x11 xi xcursor xdamage xrandr xcomposite xext xfixes xrender xtst gconf-2.0 gmodule-2.0 nss' }, 'includes': [ 'filenames.gypi', @@ -87,6 +87,14 @@ '<(libchromiumcontent_dir)/libdevtools_discovery.a', '<(libchromiumcontent_dir)/libdevtools_http_handler.a', '<(libchromiumcontent_dir)/libhttp_server.a', + '<(libchromiumcontent_dir)/libdesktop_capture.a', + '<(libchromiumcontent_dir)/libdesktop_capture_differ_sse2.a', + '<(libchromiumcontent_dir)/libsystem_wrappers.a', + '<(libchromiumcontent_dir)/librtc_base.a', + '<(libchromiumcontent_dir)/librtc_base_approved.a', + '<(libchromiumcontent_dir)/libwebrtc_common.a', + '<(libchromiumcontent_dir)/libyuv.a', + '<(libchromiumcontent_dir)/libcdm_renderer.a', ], }, }, { @@ -101,17 +109,29 @@ '-lresolv', '-lfontconfig', '-lfreetype', - '-lX11 -lXcursor -lXext -lXfixes -lXrender -lXcomposite -lXdamage -lXtst -lXrandr', '-lexpat', ], }, }], + ['target_arch=="arm"', { + 'link_settings': { + 'libraries': [ + '<(libchromiumcontent_dir)/libyuv_neon.a', + ], + 'libraries!': [ + '<(libchromiumcontent_dir)/libdesktop_capture_differ_sse2.a', + ], + }, + }], ], }], # OS=="linux" ['OS=="mac"', { 'link_settings': { 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', + # Required by webrtc: + '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', + '$(SDKROOT)/System/Library/Frameworks/IOKit.framework', ], }, 'conditions': [ @@ -122,6 +142,14 @@ '<(libchromiumcontent_dir)/libdevtools_discovery.a', '<(libchromiumcontent_dir)/libdevtools_http_handler.a', '<(libchromiumcontent_dir)/libhttp_server.a', + '<(libchromiumcontent_dir)/libdesktop_capture.a', + '<(libchromiumcontent_dir)/libdesktop_capture_differ_sse2.a', + '<(libchromiumcontent_dir)/librtc_base.a', + '<(libchromiumcontent_dir)/librtc_base_approved.a', + '<(libchromiumcontent_dir)/libsystem_wrappers.a', + '<(libchromiumcontent_dir)/libwebrtc_common.a', + '<(libchromiumcontent_dir)/libyuv.a', + '<(libchromiumcontent_dir)/libcdm_renderer.a', ], }, }, { @@ -141,7 +169,6 @@ '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework', '$(SDKROOT)/System/Library/Frameworks/CoreMIDI.framework', '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework', - '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', # surface.gyp: '$(SDKROOT)/System/Library/Frameworks/IOSurface.framework', # content_common.gypi: @@ -150,9 +177,10 @@ '$(SDKROOT)/System/Library/Frameworks/ApplicationServices.framework', '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', '$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework', - '$(SDKROOT)/System/Library/Frameworks/IOKit.framework', # content_browser.gypi: '-lbsm', + # content_common.gypi: + '-lsandbox', # bluetooth.gyp: '$(SDKROOT)/System/Library/Frameworks/IOBluetooth.framework', ], @@ -172,6 +200,14 @@ '<(libchromiumcontent_dir)/devtools_discovery.lib', '<(libchromiumcontent_dir)/devtools_http_handler.lib', '<(libchromiumcontent_dir)/http_server.lib', + '<(libchromiumcontent_dir)/desktop_capture.lib', + '<(libchromiumcontent_dir)/desktop_capture_differ_sse2.lib', + '<(libchromiumcontent_dir)/rtc_base.lib', + '<(libchromiumcontent_dir)/rtc_base_approved.lib', + '<(libchromiumcontent_dir)/system_wrappers.lib', + '<(libchromiumcontent_dir)/webrtc_common.lib', + '<(libchromiumcontent_dir)/libyuv.lib', + '<(libchromiumcontent_dir)/cdm_renderer.lib', ], }, }, { diff --git a/brightray/brightray.gypi b/brightray/brightray.gypi index a71009c8334e..4513fa95db6b 100644 --- a/brightray/brightray.gypi +++ b/brightray/brightray.gypi @@ -131,6 +131,8 @@ 'SK_SUPPORT_LEGACY_SETCONFIG', 'SK_IGNORE_ETC1_SUPPORT', 'SK_IGNORE_GPU_DITHER', + # NACL is not enabled: + 'DISABLE_NACL', ], 'conditions': [ ['OS!="mac"', { @@ -162,6 +164,13 @@ '-fno-rtti', ], }], # OS=="linux" + ['OS=="mac"', { + 'defines': [ + # The usage of "webrtc/modules/desktop_capture/desktop_capture_options.h" + # is required to see this macro. + 'WEBRTC_MAC', + ], + }], # OS=="mac" ['OS=="win"', { 'include_dirs': [ '<(libchromiumcontent_src_dir)/third_party/wtl/include', @@ -178,6 +187,9 @@ 'WIN32_LEAN_AND_MEAN', '_ATL_NO_OPENGL', '_SECURE_ATL', + # The usage of "webrtc/modules/desktop_capture/desktop_capture_options.h" + # is required to see this macro. + 'WEBRTC_WIN', ], 'conditions': [ ['target_arch=="x64"', { diff --git a/brightray/browser/brightray_paths.h b/brightray/browser/brightray_paths.h index 91e95f9791be..14c51ca8f229 100644 --- a/brightray/browser/brightray_paths.h +++ b/brightray/browser/brightray_paths.h @@ -20,7 +20,7 @@ namespace brightray { enum { - PATH_START = 1000, + PATH_START = 11000, DIR_USER_DATA = PATH_START, // Directory where user data can be written. DIR_USER_CACHE, // Directory where user cache can be written. diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index 18b5fd855e25..465cbce43904 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -4,15 +4,19 @@ #include "browser/browser_client.h" +#include "base/path_service.h" #include "browser/browser_context.h" #include "browser/browser_main_parts.h" #include "browser/devtools_manager_delegate.h" #include "browser/media/media_capture_devices_dispatcher.h" -#include "browser/platform_notification_service_impl.h" - -#include "base/path_service.h" +#include "browser/notification_presenter.h" +#include "browser/platform_notification_service.h" #include "content/public/common/url_constants.h" +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif + namespace brightray { namespace { @@ -38,6 +42,20 @@ BrowserContext* BrowserClient::browser_context() { return browser_main_parts_->browser_context(); } +NotificationPresenter* BrowserClient::GetNotificationPresenter() { + #if defined(OS_WIN) + // Bail out if on Windows 7 or even lower, no operating will follow + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return nullptr; + #endif + + if (!notification_presenter_) { + // Create a new presenter if on OS X, Linux, or Windows 8+ + notification_presenter_.reset(NotificationPresenter::Create()); + } + return notification_presenter_.get(); +} + BrowserMainParts* BrowserClient::OverrideCreateBrowserMainParts( const content::MainFunctionParams&) { return new BrowserMainParts; @@ -65,7 +83,9 @@ content::MediaObserver* BrowserClient::GetMediaObserver() { } content::PlatformNotificationService* BrowserClient::GetPlatformNotificationService() { - return PlatformNotificationServiceImpl::GetInstance(); + if (!notification_service_) + notification_service_.reset(new PlatformNotificationService(this)); + return notification_service_.get(); } void BrowserClient::GetAdditionalAllowedSchemesForFileSystem( diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h index 0612e56d2552..bb6575c9b2b6 100644 --- a/brightray/browser/browser_client.h +++ b/brightray/browser/browser_client.h @@ -13,6 +13,8 @@ namespace brightray { class BrowserContext; class BrowserMainParts; class NetLog; +class NotificationPresenter; +class PlatformNotificationService; class BrowserClient : public content::ContentBrowserClient { public: @@ -24,6 +26,8 @@ class BrowserClient : public content::ContentBrowserClient { BrowserContext* browser_context(); BrowserMainParts* browser_main_parts() { return browser_main_parts_; } + NotificationPresenter* GetNotificationPresenter(); + protected: // Subclasses should override this to provide their own BrowserMainParts // implementation. The lifetime of the returned instance is managed by the @@ -51,6 +55,9 @@ class BrowserClient : public content::ContentBrowserClient { NetLog net_log_; private: + scoped_ptr notification_service_; + scoped_ptr notification_presenter_; + DISALLOW_COPY_AND_ASSIGN(BrowserClient); }; diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc index 4bf558d4293b..67ad5c8d540a 100644 --- a/brightray/browser/browser_context.cc +++ b/brightray/browser/browser_context.cc @@ -40,7 +40,7 @@ namespace { // Convert string to lower case and escape it. std::string MakePartitionName(const std::string& input) { - return net::EscapePath(base::StringToLowerASCII(input)); + return net::EscapePath(base::ToLowerASCII(input)); } } // namespace diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc index b0a7e72b5f24..279eff9b8180 100644 --- a/brightray/browser/browser_main_parts.cc +++ b/brightray/browser/browser_main_parts.cc @@ -7,6 +7,7 @@ #include "browser/browser_context.h" #include "browser/devtools_manager_delegate.h" #include "browser/web_ui_controller_factory.h" +#include "common/main_delegate.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" @@ -14,6 +15,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "net/proxy/proxy_resolver_v8.h" +#include "ui/base/l10n/l10n_util.h" #if defined(USE_AURA) #include "ui/gfx/screen.h" @@ -39,7 +41,6 @@ #if defined(OS_WIN) #include "ui/base/cursor/cursor_loader_win.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_win.h" #include "ui/gfx/platform_font_win.h" #endif @@ -169,6 +170,10 @@ void BrowserMainParts::ToolkitInitialized() { } void BrowserMainParts::PreMainMessageLoopStart() { +#if defined(OS_MACOSX) + l10n_util::OverrideLocaleWithCocoaLocale(); +#endif + InitializeResourceBundle(""); #if defined(OS_MACOSX) InitializeMainNib(); #endif diff --git a/brightray/browser/devtools_manager_delegate.cc b/brightray/browser/devtools_manager_delegate.cc index 95b6fb3b5b28..ca8f1cf2d84b 100644 --- a/brightray/browser/devtools_manager_delegate.cc +++ b/brightray/browser/devtools_manager_delegate.cc @@ -18,6 +18,7 @@ #include "components/devtools_discovery/basic_target_descriptor.h" #include "components/devtools_discovery/devtools_discovery_manager.h" #include "components/devtools_http_handler/devtools_http_handler.h" +#include "content/grit/shell_resources.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_frontend_host.h" #include "content/public/browser/favicon_status.h" @@ -35,11 +36,6 @@ namespace brightray { namespace { -// A hack here: -// Copy from grit/shell_resources.h of chromium repository -// since libcontentchromium doesn't expose content_shell resources. -const int kIDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE = 25500; - class TCPServerSocketFactory : public devtools_http_handler::DevToolsHttpHandler::ServerSocketFactory { public: @@ -99,6 +95,8 @@ class DevToolsDelegate : std::string GetDiscoveryPageHTML() override; std::string GetFrontendResource(const std::string& path) override; std::string GetPageThumbnailData(const GURL& url) override; + content::DevToolsExternalAgentProxyDelegate* HandleWebSocketConnection( + const std::string& path) override; private: DISALLOW_COPY_AND_ASSIGN(DevToolsDelegate); @@ -111,8 +109,9 @@ DevToolsDelegate::~DevToolsDelegate() { } std::string DevToolsDelegate::GetDiscoveryPageHTML() { + LOG(WARNING) << IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE; return ResourceBundle::GetSharedInstance().GetRawDataResource( - kIDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string(); + IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string(); } @@ -125,6 +124,11 @@ std::string DevToolsDelegate::GetPageThumbnailData(const GURL& url) { return std::string(); } +content::DevToolsExternalAgentProxyDelegate* +DevToolsDelegate::HandleWebSocketConnection(const std::string& path) { + return nullptr; +} + } // namespace // DevToolsManagerDelegate --------------------------------------------------- diff --git a/brightray/browser/devtools_ui.cc b/brightray/browser/devtools_ui.cc index 390a2dbf216b..6f5bdc7bfa5b 100644 --- a/brightray/browser/devtools_ui.cc +++ b/brightray/browser/devtools_ui.cc @@ -30,19 +30,25 @@ std::string PathWithoutParams(const std::string& path) { std::string GetMimeTypeForPath(const std::string& path) { std::string filename = PathWithoutParams(path); - if (base::EndsWith(filename, ".html", false)) { + if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) { return "text/html"; - } else if (base::EndsWith(filename, ".css", false)) { + } else if (base::EndsWith(filename, ".css", + base::CompareCase::INSENSITIVE_ASCII)) { return "text/css"; - } else if (base::EndsWith(filename, ".js", false)) { + } else if (base::EndsWith(filename, ".js", + base::CompareCase::INSENSITIVE_ASCII)) { return "application/javascript"; - } else if (base::EndsWith(filename, ".png", false)) { + } else if (base::EndsWith(filename, ".png", + base::CompareCase::INSENSITIVE_ASCII)) { return "image/png"; - } else if (base::EndsWith(filename, ".gif", false)) { + } else if (base::EndsWith(filename, ".gif", + base::CompareCase::INSENSITIVE_ASCII)) { return "image/gif"; - } else if (base::EndsWith(filename, ".svg", false)) { + } else if (base::EndsWith(filename, ".svg", + base::CompareCase::INSENSITIVE_ASCII)) { return "image/svg+xml"; - } else if (base::EndsWith(filename, ".manifest", false)) { + } else if (base::EndsWith(filename, ".manifest", + base::CompareCase::INSENSITIVE_ASCII)) { return "text/cache-manifest"; } return "text/html"; diff --git a/brightray/browser/linux/libnotify_loader.cc b/brightray/browser/linux/libnotify_loader.cc new file mode 100644 index 000000000000..ede4eeec670c --- /dev/null +++ b/brightray/browser/linux/libnotify_loader.cc @@ -0,0 +1,113 @@ +// This is generated file. Do not modify directly. +// Path to the code generator: tools/generate_library_loader/generate_library_loader.py . + +#include "browser/linux/libnotify_loader.h" + +#include + +LibNotifyLoader::LibNotifyLoader() : loaded_(false) { +} + +LibNotifyLoader::~LibNotifyLoader() { + CleanUp(loaded_); +} + +bool LibNotifyLoader::Load(const std::string& library_name) { + if (loaded_) + return false; + + library_ = dlopen(library_name.c_str(), RTLD_LAZY); + if (!library_) + return false; + + notify_is_initted = + reinterpret_castnotify_is_initted)>( + dlsym(library_, "notify_is_initted")); + notify_is_initted = &::notify_is_initted; + if (!notify_is_initted) { + CleanUp(true); + return false; + } + + notify_init = + reinterpret_castnotify_init)>( + dlsym(library_, "notify_init")); + notify_init = &::notify_init; + if (!notify_init) { + CleanUp(true); + return false; + } + + notify_notification_new = + reinterpret_castnotify_notification_new)>( + dlsym(library_, "notify_notification_new")); + notify_notification_new = &::notify_notification_new; + if (!notify_notification_new) { + CleanUp(true); + return false; + } + + notify_notification_add_action = + reinterpret_castnotify_notification_add_action)>( + dlsym(library_, "notify_notification_add_action")); + notify_notification_add_action = &::notify_notification_add_action; + if (!notify_notification_add_action) { + CleanUp(true); + return false; + } + + notify_notification_set_image_from_pixbuf = + reinterpret_castnotify_notification_set_image_from_pixbuf)>( + dlsym(library_, "notify_notification_set_image_from_pixbuf")); + notify_notification_set_image_from_pixbuf = &::notify_notification_set_image_from_pixbuf; + if (!notify_notification_set_image_from_pixbuf) { + CleanUp(true); + return false; + } + + notify_notification_set_timeout = + reinterpret_castnotify_notification_set_timeout)>( + dlsym(library_, "notify_notification_set_timeout")); + notify_notification_set_timeout = &::notify_notification_set_timeout; + if (!notify_notification_set_timeout) { + CleanUp(true); + return false; + } + + notify_notification_show = + reinterpret_castnotify_notification_show)>( + dlsym(library_, "notify_notification_show")); + notify_notification_show = &::notify_notification_show; + if (!notify_notification_show) { + CleanUp(true); + return false; + } + + notify_notification_close = + reinterpret_castnotify_notification_close)>( + dlsym(library_, "notify_notification_close")); + notify_notification_close = &::notify_notification_close; + if (!notify_notification_close) { + CleanUp(true); + return false; + } + + loaded_ = true; + return true; +} + +void LibNotifyLoader::CleanUp(bool unload) { + if (unload) { + dlclose(library_); + library_ = NULL; + } + loaded_ = false; + notify_is_initted = NULL; + notify_init = NULL; + notify_notification_new = NULL; + notify_notification_add_action = NULL; + notify_notification_set_image_from_pixbuf = NULL; + notify_notification_set_timeout = NULL; + notify_notification_show = NULL; + notify_notification_close = NULL; +} diff --git a/brightray/browser/linux/libnotify_loader.h b/brightray/browser/linux/libnotify_loader.h new file mode 100644 index 000000000000..6cf2853af2c6 --- /dev/null +++ b/brightray/browser/linux/libnotify_loader.h @@ -0,0 +1,41 @@ +// This is generated file. Do not modify directly. +// Path to the code generator: tools/generate_library_loader/generate_library_loader.py . + +#ifndef BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_ +#define BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_ + +#include + +#include + +class LibNotifyLoader { + public: + LibNotifyLoader(); + ~LibNotifyLoader(); + + bool Load(const std::string& library_name) + __attribute__((warn_unused_result)); + + bool loaded() const { return loaded_; } + + decltype(&::notify_is_initted) notify_is_initted; + decltype(&::notify_init) notify_init; + decltype(&::notify_notification_new) notify_notification_new; + decltype(&::notify_notification_add_action) notify_notification_add_action; + decltype(&::notify_notification_set_image_from_pixbuf) notify_notification_set_image_from_pixbuf; + decltype(&::notify_notification_set_timeout) notify_notification_set_timeout; + decltype(&::notify_notification_show) notify_notification_show; + decltype(&::notify_notification_close) notify_notification_close; + + private: + void CleanUp(bool unload); + + void* library_; + bool loaded_; + + // Disallow copy constructor and assignment operator. + LibNotifyLoader(const LibNotifyLoader&); + void operator=(const LibNotifyLoader&); +}; + +#endif // BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_ diff --git a/brightray/browser/linux/libnotify_notification.cc b/brightray/browser/linux/libnotify_notification.cc new file mode 100644 index 000000000000..98aa3ffd8a7d --- /dev/null +++ b/brightray/browser/linux/libnotify_notification.cc @@ -0,0 +1,157 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/linux/libnotify_notification.h" + +#include "base/files/file_enumerator.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "browser/notification_delegate.h" +#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" +#include "common/application_info.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace brightray { + +namespace { + +bool unity_has_result = false; +bool unity_result = false; + +bool UnityIsRunning() { + if (getenv("ELECTRON_USE_UBUNTU_NOTIFIER")) + return true; + + if (unity_has_result) + return unity_result; + + unity_has_result = true; + + // Look for the presence of libunity as our hint that we're under Ubuntu. + base::FileEnumerator enumerator(base::FilePath("/usr/lib"), + false, base::FileEnumerator::FILES); + base::FilePath haystack; + while (!((haystack = enumerator.Next()).empty())) { + if (base::StartsWith(haystack.value(), "/usr/lib/libunity-", + base::CompareCase::SENSITIVE)) { + unity_result = true; + break; + } + } + + return unity_result; +} + +void log_and_clear_error(GError* error, const char* context) { + LOG(ERROR) << context + << ": domain=" << error->domain + << " code=" << error->code + << " message=\"" << error->message << '"'; + g_error_free(error); +} + +} // namespace + +// static +Notification* Notification::Create(NotificationDelegate* delegate, + NotificationPresenter* presenter) { + return new LibnotifyNotification(delegate, presenter); +} + +// static +LibNotifyLoader LibnotifyNotification::libnotify_loader_; + +// static +bool LibnotifyNotification::Initialize() { + if (!libnotify_loader_.Load("libnotify.so.4") && + !libnotify_loader_.Load("libnotify.so.1") && + !libnotify_loader_.Load("libnotify.so")) { + return false; + } + if (!libnotify_loader_.notify_is_initted() && + !libnotify_loader_.notify_init(GetApplicationName().c_str())) { + return false; + } + return true; +} + +LibnotifyNotification::LibnotifyNotification(NotificationDelegate* delegate, + NotificationPresenter* presenter) + : Notification(delegate, presenter), + notification_(nullptr) { +} + +LibnotifyNotification::~LibnotifyNotification() { + g_object_unref(notification_); +} + +void LibnotifyNotification::Show(const base::string16& title, + const base::string16& body, + const GURL& icon_url, + const SkBitmap& icon) { + notification_ = libnotify_loader_.notify_notification_new( + base::UTF16ToUTF8(title).c_str(), + base::UTF16ToUTF8(body).c_str(), + nullptr); + + g_signal_connect( + notification_, "closed", G_CALLBACK(OnNotificationClosedThunk), this); + + // NB: On Unity, adding a notification action will cause the notification + // to display as a modal dialog box. Testing for distros that have "Unity + // Zen Nature" is difficult, we will test for the presence of the indicate + // dbus service + if (!UnityIsRunning()) { + libnotify_loader_.notify_notification_add_action( + notification_, "default", "View", OnNotificationViewThunk, this, + nullptr); + } + + if (!icon.drawsNothing()) { + GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon); + libnotify_loader_.notify_notification_set_image_from_pixbuf( + notification_, pixbuf); + libnotify_loader_.notify_notification_set_timeout( + notification_, NOTIFY_EXPIRES_DEFAULT); + g_object_unref(pixbuf); + } + + GError* error = nullptr; + libnotify_loader_.notify_notification_show(notification_, &error); + if (error) { + log_and_clear_error(error, "notify_notification_show"); + NotificationFailed(); + return; + } + + delegate()->NotificationDisplayed(); +} + +void LibnotifyNotification::Dismiss() { + GError* error = nullptr; + libnotify_loader_.notify_notification_close(notification_, &error); + if (error) { + log_and_clear_error(error, "notify_notification_close"); + Destroy(); + } +} + +void LibnotifyNotification::OnNotificationClosed( + NotifyNotification* notification) { + delegate()->NotificationClosed(); + Destroy(); +} + +void LibnotifyNotification::OnNotificationView( + NotifyNotification* notification, char* action) { + delegate()->NotificationClick(); + Destroy(); +} + +void LibnotifyNotification::NotificationFailed() { + delegate()->NotificationFailed(); + Destroy(); +} + +} // namespace brightray diff --git a/brightray/browser/linux/libnotify_notification.h b/brightray/browser/linux/libnotify_notification.h new file mode 100644 index 000000000000..be2f4280bc4f --- /dev/null +++ b/brightray/browser/linux/libnotify_notification.h @@ -0,0 +1,46 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_ +#define BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_ + +#include "browser/linux/libnotify_loader.h" +#include "browser/notification.h" +#include "ui/base/glib/glib_signal.h" + +namespace brightray { + +class LibnotifyNotification : public Notification { + public: + LibnotifyNotification(NotificationDelegate* delegate, + NotificationPresenter* presenter); + virtual ~LibnotifyNotification(); + + static bool Initialize(); + + // Notification: + void Show(const base::string16& title, + const base::string16& msg, + const GURL& icon_url, + const SkBitmap& icon) override; + void Dismiss() override; + + private: + CHROMEG_CALLBACK_0(LibnotifyNotification, void, OnNotificationClosed, + NotifyNotification*); + CHROMEG_CALLBACK_1(LibnotifyNotification, void, OnNotificationView, + NotifyNotification*, char*); + + void NotificationFailed(); + + static LibNotifyLoader libnotify_loader_; + + NotifyNotification* notification_; + + DISALLOW_COPY_AND_ASSIGN(LibnotifyNotification); +}; + +} // namespace brightray + +#endif // BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_ diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 10e8dec765f7..c846fca6659e 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -5,158 +5,21 @@ #include "browser/linux/notification_presenter_linux.h" -#include "base/bind.h" -#include "base/logging.h" -#include "base/files/file_enumerator.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h" -#include "content/public/browser/desktop_notification_delegate.h" -#include "content/public/common/platform_notification_data.h" -#include "common/application_info.h" -#include -#include "third_party/skia/include/core/SkBitmap.h" +#include "browser/linux/libnotify_notification.h" namespace brightray { -namespace { - -bool unity_has_result = false; -bool unity_result = false; - -bool UnityIsRunning() { - if (getenv("ELECTRON_USE_UBUNTU_NOTIFIER")) - return true; - - if (unity_has_result) - return unity_result; - - unity_has_result = true; - - // Look for the presence of libunity as our hint that we're under Ubuntu. - base::FileEnumerator enumerator(base::FilePath("/usr/lib"), - false, base::FileEnumerator::FILES); - base::FilePath haystack; - while (!((haystack = enumerator.Next()).empty())) { - if (base::StartsWith(haystack.value(), "/usr/lib/libunity-", base::CompareCase::SENSITIVE)) { - unity_result = true; - break; - } - } - - return unity_result; -} - -void log_and_clear_error(GError* error, const char* context) { - LOG(ERROR) << context - << ": domain=" << error->domain - << " code=" << error->code - << " message=\"" << error->message << '"'; - g_error_free(error); -} - -content::DesktopNotificationDelegate* GetDelegateFromNotification( - NotifyNotification* notification) { - return static_cast( - g_object_get_data(G_OBJECT(notification), "delegate")); -} - -} // namespace - // static NotificationPresenter* NotificationPresenter::Create() { - if (!notify_is_initted()) { - notify_init(GetApplicationName().c_str()); - } + if (!LibnotifyNotification::Initialize()) + return nullptr; return new NotificationPresenterLinux; } -NotificationPresenterLinux::NotificationPresenterLinux() - : notifications_(nullptr) { +NotificationPresenterLinux::NotificationPresenterLinux() { } NotificationPresenterLinux::~NotificationPresenterLinux() { - // unref any outstanding notifications, and then free the list. - if (notifications_) - g_list_free_full(notifications_, g_object_unref); -} - -void NotificationPresenterLinux::ShowNotification( - const content::PlatformNotificationData& data, - const SkBitmap& icon, - scoped_ptr delegate_ptr, - base::Closure* cancel_callback) { - std::string title = base::UTF16ToUTF8(data.title); - std::string body = base::UTF16ToUTF8(data.body); - NotifyNotification* notification = notify_notification_new(title.c_str(), body.c_str(), nullptr); - - content::DesktopNotificationDelegate* delegate = delegate_ptr.release(); - - g_object_set_data_full(G_OBJECT(notification), "delegate", delegate, operator delete); - g_signal_connect(notification, "closed", G_CALLBACK(OnNotificationClosedThunk), this); - - // NB: On Unity, adding a notification action will cause the notification - // to display as a modal dialog box. Testing for distros that have "Unity - // Zen Nature" is difficult, we will test for the presence of the indicate - // dbus service - if (!UnityIsRunning()) { - notify_notification_add_action( - notification, "default", "View", OnNotificationViewThunk, this, nullptr); - } - - if (!icon.drawsNothing()) { - GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon); - notify_notification_set_image_from_pixbuf(notification, pixbuf); - notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT); - g_object_unref(pixbuf); - } - - GError* error = nullptr; - notify_notification_show(notification, &error); - if (error) { - log_and_clear_error(error, "notify_notification_show"); - g_object_unref(notification); - return; - } - - notifications_ = g_list_append(notifications_, notification); - delegate->NotificationDisplayed(); - - if (cancel_callback) - *cancel_callback = base::Bind( - &NotificationPresenterLinux::CancelNotification, - base::Unretained(this), - notification); -} - -void NotificationPresenterLinux::CancelNotification(NotifyNotification* notification) { - GError* error = nullptr; - notify_notification_close(notification, &error); - if (error) - log_and_clear_error(error, "notify_notification_close"); - - GetDelegateFromNotification(notification)->NotificationClosed(); - DeleteNotification(notification); -} - -void NotificationPresenterLinux::DeleteNotification(NotifyNotification* notification) { - notifications_ = g_list_remove(notifications_, notification); - g_object_unref(notification); -} - -void NotificationPresenterLinux::OnNotificationClosed(NotifyNotification* notification) { - if (!notification) - return; - GetDelegateFromNotification(notification)->NotificationClosed(); - DeleteNotification(notification); -} - -void NotificationPresenterLinux::OnNotificationView( - NotifyNotification* notification, char* action) { - if (!notification) - return; - GetDelegateFromNotification(notification)->NotificationClick(); - DeleteNotification(notification); } } // namespace brightray diff --git a/brightray/browser/linux/notification_presenter_linux.h b/brightray/browser/linux/notification_presenter_linux.h index ddd79e4c2e8d..ef4367994847 100644 --- a/brightray/browser/linux/notification_presenter_linux.h +++ b/brightray/browser/linux/notification_presenter_linux.h @@ -6,13 +6,7 @@ #ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_ #define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_ -#include - -#include - -#include "base/compiler_specific.h" #include "browser/notification_presenter.h" -#include "ui/base/glib/glib_signal.h" namespace brightray { @@ -21,31 +15,8 @@ class NotificationPresenterLinux : public NotificationPresenter { NotificationPresenterLinux(); ~NotificationPresenterLinux(); - void RemoveNotification(NotifyNotification *notification); - private: - // NotificationPresenter: - void ShowNotification( - const content::PlatformNotificationData&, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) override; - - void CancelNotification(NotifyNotification* notification); - void DeleteNotification(NotifyNotification* notification); - - CHROMEG_CALLBACK_0(NotificationPresenterLinux, void, OnNotificationClosed, NotifyNotification*); - CHROMEG_CALLBACK_1(NotificationPresenterLinux, void, OnNotificationView, NotifyNotification*, - char*); - - // A list of all open NotifyNotification objects. - // We do lookups here both by NotifyNotification object (when the user - // clicks a notification) and by the ID - // tuple (when the browser asks to dismiss a notification). So it's not - // a map. - // Entries in this list count as refs, so removal from this list should - // always go with g_object_unref(). - GList* notifications_; + DISALLOW_COPY_AND_ASSIGN(NotificationPresenterLinux); }; } // namespace brightray diff --git a/brightray/browser/mac/bry_inspectable_web_contents_view.mm b/brightray/browser/mac/bry_inspectable_web_contents_view.mm index 53afef7b6e54..a1b8dd3c0547 100644 --- a/brightray/browser/mac/bry_inspectable_web_contents_view.mm +++ b/brightray/browser/mac/bry_inspectable_web_contents_view.mm @@ -6,7 +6,7 @@ #include "content/public/browser/render_widget_host_view.h" #import "ui/base/cocoa/underlay_opengl_hosting_window.h" -#include "ui/gfx/mac/scoped_ns_disable_screen_updates.h" +#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h" using namespace brightray; @@ -89,7 +89,7 @@ using namespace brightray; // Focus on web view. devToolsWebContents->RestoreFocus(); } else { - gfx::ScopedNSDisableScreenUpdates disabler; + gfx::ScopedCocoaDisableScreenUpdates disabler; [devToolsView removeFromSuperview]; [self adjustSubviews]; } diff --git a/brightray/browser/mac/cocoa_notification.h b/brightray/browser/mac/cocoa_notification.h new file mode 100644 index 000000000000..b1709568210e --- /dev/null +++ b/brightray/browser/mac/cocoa_notification.h @@ -0,0 +1,42 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_MAC_COCOA_NOTIFICATION_H_ +#define BROWSER_MAC_COCOA_NOTIFICATION_H_ + +#import + +#include "base/mac/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" +#include "browser/notification.h" + +namespace brightray { + +class CocoaNotification : public Notification { + public: + CocoaNotification(NotificationDelegate* delegate, + NotificationPresenter* presenter); + ~CocoaNotification(); + + // Notification: + void Show(const base::string16& title, + const base::string16& msg, + const GURL& icon_url, + const SkBitmap& icon) override; + void Dismiss() override; + + void NotifyDisplayed(); + void NotifyClick(); + + NSUserNotification* notification() const { return notification_; } + + private: + base::scoped_nsobject notification_; + + DISALLOW_COPY_AND_ASSIGN(CocoaNotification); +}; + +} // namespace brightray + +#endif // BROWSER_MAC_COCOA_NOTIFICATION_H_ diff --git a/brightray/browser/mac/cocoa_notification.mm b/brightray/browser/mac/cocoa_notification.mm new file mode 100644 index 000000000000..24174e226a90 --- /dev/null +++ b/brightray/browser/mac/cocoa_notification.mm @@ -0,0 +1,66 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/mac/cocoa_notification.h" + +#include "base/mac/mac_util.h" +#include "base/strings/sys_string_conversions.h" +#include "browser/notification_delegate.h" +#include "browser/notification_presenter.h" +#include "skia/ext/skia_utils_mac.h" + +namespace brightray { + +// static +Notification* Notification::Create(NotificationDelegate* delegate, + NotificationPresenter* presenter) { + return new CocoaNotification(delegate, presenter); +} + +CocoaNotification::CocoaNotification(NotificationDelegate* delegate, + NotificationPresenter* presenter) + : Notification(delegate, presenter) { +} + +CocoaNotification::~CocoaNotification() { + [NSUserNotificationCenter.defaultUserNotificationCenter + removeDeliveredNotification:notification_]; +} + +void CocoaNotification::Show(const base::string16& title, + const base::string16& body, + const GURL& icon_url, + const SkBitmap& icon) { + notification_.reset([[NSUserNotification alloc] init]); + [notification_ setTitle:base::SysUTF16ToNSString(title)]; + [notification_ setInformativeText:base::SysUTF16ToNSString(body)]; + + if ([notification_ respondsToSelector:@selector(setContentImage:)] && + !icon.drawsNothing()) { + NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( + icon, base::mac::GetGenericRGBColorSpace()); + [notification_ setContentImage:image]; + } + + [NSUserNotificationCenter.defaultUserNotificationCenter + deliverNotification:notification_]; +} + +void CocoaNotification::Dismiss() { + [NSUserNotificationCenter.defaultUserNotificationCenter + removeDeliveredNotification:notification_]; + delegate()->NotificationClosed(); + Destroy(); +} + +void CocoaNotification::NotifyDisplayed() { + delegate()->NotificationDisplayed(); +} + +void CocoaNotification::NotifyClick() { + delegate()->NotificationClick(); + Destroy(); +} + +} // namespace brightray diff --git a/brightray/browser/mac/notification_center_delegate.h b/brightray/browser/mac/notification_center_delegate.h new file mode 100644 index 000000000000..6bee83d411b4 --- /dev/null +++ b/brightray/browser/mac/notification_center_delegate.h @@ -0,0 +1,22 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_MAC_NOTIFICATION_DELEGATE_H_ +#define BROWSER_MAC_NOTIFICATION_DELEGATE_H_ + +#import + +namespace brightray { +class NotificationPresenterMac; +} + +@interface NotificationCenterDelegate : + NSObject { + @private + brightray::NotificationPresenterMac* presenter_; +} +- (instancetype)initWithPresenter:(brightray::NotificationPresenterMac*)presenter; +@end + +#endif // BROWSER_MAC_NOTIFICATION_DELEGATE_H_ diff --git a/brightray/browser/mac/notification_center_delegate.mm b/brightray/browser/mac/notification_center_delegate.mm new file mode 100644 index 000000000000..53537bdc311a --- /dev/null +++ b/brightray/browser/mac/notification_center_delegate.mm @@ -0,0 +1,41 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/mac/notification_center_delegate.h" + +#include "browser/mac/cocoa_notification.h" +#include "browser/mac/notification_presenter_mac.h" + +@implementation NotificationCenterDelegate + +- (instancetype)initWithPresenter:(brightray::NotificationPresenterMac*)presenter { + self = [super init]; + if (!self) + return nil; + + presenter_ = presenter; + return self; +} + +- (void)userNotificationCenter:(NSUserNotificationCenter*)center + didDeliverNotification:(NSUserNotification*)notif { + auto notification = presenter_->GetNotification(notif); + if (notification) + notification->NotifyDisplayed(); +} + +- (void)userNotificationCenter:(NSUserNotificationCenter*)center + didActivateNotification:(NSUserNotification *)notif { + auto notification = presenter_->GetNotification(notif); + if (notification) + notification->NotifyClick(); +} + +- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center + shouldPresentNotification:(NSUserNotification*)notification { + // Display notifications even if the app is active. + return YES; +} + +@end diff --git a/brightray/browser/mac/notification_presenter_mac.h b/brightray/browser/mac/notification_presenter_mac.h new file mode 100644 index 000000000000..825a1dada233 --- /dev/null +++ b/brightray/browser/mac/notification_presenter_mac.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 Adam Roben . All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_ +#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_ + +#include "base/mac/scoped_nsobject.h" +#include "browser/mac/notification_center_delegate.h" +#include "browser/notification_presenter.h" + +namespace brightray { + +class CocoaNotification; + +class NotificationPresenterMac : public NotificationPresenter { + public: + CocoaNotification* GetNotification(NSUserNotification* notif); + + NotificationPresenterMac(); + ~NotificationPresenterMac(); + + private: + base::scoped_nsobject + notification_center_delegate_; + + DISALLOW_COPY_AND_ASSIGN(NotificationPresenterMac); +}; + +} // namespace brightray + +#endif diff --git a/brightray/browser/mac/notification_presenter_mac.mm b/brightray/browser/mac/notification_presenter_mac.mm new file mode 100644 index 000000000000..a37e9182fc6e --- /dev/null +++ b/brightray/browser/mac/notification_presenter_mac.mm @@ -0,0 +1,38 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/mac/notification_presenter_mac.h" + +#include "browser/mac/cocoa_notification.h" +#include "browser/mac/notification_center_delegate.h" + +namespace brightray { + +// static +NotificationPresenter* NotificationPresenter::Create() { + return new NotificationPresenterMac; +} + +CocoaNotification* NotificationPresenterMac::GetNotification( + NSUserNotification* ns_notification) { + for (Notification* notification : notifications()) { + auto native_notification = static_cast(notification); + if ([native_notification->notification() isEqual:ns_notification]) + return native_notification; + } + return nullptr; +} + +NotificationPresenterMac::NotificationPresenterMac() + : notification_center_delegate_( + [[NotificationCenterDelegate alloc] initWithPresenter:this]) { + NSUserNotificationCenter.defaultUserNotificationCenter.delegate = + notification_center_delegate_; +} + +NotificationPresenterMac::~NotificationPresenterMac() { + NSUserNotificationCenter.defaultUserNotificationCenter.delegate = nil; +} + +} // namespace brightray diff --git a/brightray/browser/media/media_capture_devices_dispatcher.cc b/brightray/browser/media/media_capture_devices_dispatcher.cc index 1c99d89765ae..09c71b82a495 100644 --- a/brightray/browser/media/media_capture_devices_dispatcher.cc +++ b/brightray/browser/media/media_capture_devices_dispatcher.cc @@ -37,7 +37,7 @@ const MediaStreamDevices& EmptyDevices() { } // namespace MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() { - return Singleton::get(); + return base::Singleton::get(); } MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher() diff --git a/brightray/browser/media/media_capture_devices_dispatcher.h b/brightray/browser/media/media_capture_devices_dispatcher.h index be369a2ff61f..c62a917572d2 100644 --- a/brightray/browser/media/media_capture_devices_dispatcher.h +++ b/brightray/browser/media/media_capture_devices_dispatcher.h @@ -64,7 +64,7 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver { int render_view_id) override; private: - friend struct DefaultSingletonTraits; + friend struct base::DefaultSingletonTraits; MediaCaptureDevicesDispatcher(); virtual ~MediaCaptureDevicesDispatcher(); diff --git a/brightray/browser/net/devtools_network_interceptor.h b/brightray/browser/net/devtools_network_interceptor.h index 330a7340bd57..60093d0ad633 100644 --- a/brightray/browser/net/devtools_network_interceptor.h +++ b/brightray/browser/net/devtools_network_interceptor.h @@ -68,7 +68,7 @@ class DevToolsNetworkInterceptor { // Transactions waiting certain amount of transfer to be accounted. std::vector throttled_transactions_; - base::OneShotTimer timer_; + base::OneShotTimer timer_; base::TimeTicks offset_; base::TimeDelta tick_length_; base::TimeDelta latency_length_; diff --git a/brightray/browser/net/devtools_network_transaction.cc b/brightray/browser/net/devtools_network_transaction.cc index c8c74a67999f..fa3343ef9879 100644 --- a/brightray/browser/net/devtools_network_transaction.cc +++ b/brightray/browser/net/devtools_network_transaction.cc @@ -15,12 +15,10 @@ namespace brightray { -namespace { - -const char kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; - -} // namespace +// static +const char + DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] = + "X-DevTools-Emulate-Network-Conditions-Client-Id"; DevToolsNetworkTransaction::DevToolsNetworkTransaction( DevToolsNetworkController* controller, @@ -151,6 +149,10 @@ int64_t DevToolsNetworkTransaction::GetTotalReceivedBytes() const { return transaction_->GetTotalReceivedBytes(); } +int64_t DevToolsNetworkTransaction::GetTotalSentBytes() const { + return transaction_->GetTotalSentBytes(); +} + void DevToolsNetworkTransaction::DoneReading() { transaction_->DoneReading(); } @@ -178,6 +180,11 @@ bool DevToolsNetworkTransaction::GetLoadTimingInfo( return transaction_->GetLoadTimingInfo(info); } +bool DevToolsNetworkTransaction::GetRemoteEndpoint( + net::IPEndPoint* endpoint) const { + return transaction_->GetRemoteEndpoint(endpoint); +} + void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) { transaction_->SetPriority(priority); } diff --git a/brightray/browser/net/devtools_network_transaction.h b/brightray/browser/net/devtools_network_transaction.h index 19295bf0dc76..3e16db0f2c2c 100644 --- a/brightray/browser/net/devtools_network_transaction.h +++ b/brightray/browser/net/devtools_network_transaction.h @@ -22,6 +22,8 @@ class DevToolsNetworkInterceptor; class DevToolsNetworkTransaction : public net::HttpTransaction { public: + static const char kDevToolsEmulateNetworkConditionsClientId[]; + DevToolsNetworkTransaction( DevToolsNetworkController* controller, scoped_ptr network_transaction); @@ -55,12 +57,14 @@ class DevToolsNetworkTransaction : public net::HttpTransaction { void StopCaching() override; bool GetFullRequestHeaders(net::HttpRequestHeaders* headers) const override; int64_t GetTotalReceivedBytes() const override; + int64_t GetTotalSentBytes() const override; void DoneReading() override; const net::HttpResponseInfo* GetResponseInfo() const override; net::LoadState GetLoadState() const override; net::UploadProgress GetUploadProgress() const override; void SetQuicServerInfo(net::QuicServerInfo* quic_server_info) override; bool GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; + bool GetRemoteEndpoint(net::IPEndPoint* endpoint) const override; void SetPriority(net::RequestPriority priority) override; void SetWebSocketHandshakeStreamCreateHelper( net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) override; diff --git a/brightray/browser/net/devtools_network_transaction_factory.cc b/brightray/browser/net/devtools_network_transaction_factory.cc index 72367112f8fb..d1676a34d56e 100644 --- a/brightray/browser/net/devtools_network_transaction_factory.cc +++ b/brightray/browser/net/devtools_network_transaction_factory.cc @@ -7,6 +7,7 @@ #include "browser/net/devtools_network_controller.h" #include "browser/net/devtools_network_transaction.h" +#include "content/public/browser/service_worker_context.h" #include "net/base/net_errors.h" #include "net/http/http_network_layer.h" #include "net/http/http_network_transaction.h" @@ -18,6 +19,10 @@ DevToolsNetworkTransactionFactory::DevToolsNetworkTransactionFactory( net::HttpNetworkSession* session) : controller_(controller), network_layer_(new net::HttpNetworkLayer(session)) { + std::set headers; + headers.insert( + DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId); + content::ServiceWorkerContext::AddExcludedHeadersForFetchEvent(headers); } DevToolsNetworkTransactionFactory::~DevToolsNetworkTransactionFactory() { diff --git a/brightray/browser/network_delegate.cc b/brightray/browser/network_delegate.cc index dbaeeeed3e2c..8a1f8ee828ce 100644 --- a/brightray/browser/network_delegate.cc +++ b/brightray/browser/network_delegate.cc @@ -26,7 +26,8 @@ NetworkDelegate::NetworkDelegate() { auto command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(kIgnoreConnectionsLimit)) { std::string value = command_line->GetSwitchValueASCII(kIgnoreConnectionsLimit); - base::SplitString(value, ',', &ignore_connections_limit_domains_); + ignore_connections_limit_domains_ = base::SplitString( + value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); } } @@ -38,7 +39,7 @@ int NetworkDelegate::OnBeforeURLRequest( const net::CompletionCallback& callback, GURL* new_url) { for (const auto& domain : ignore_connections_limit_domains_) { - if (request->url().DomainIs(domain.c_str(), domain.size())) { + if (request->url().DomainIs(domain)) { // Allow unlimited concurrent connections. request->SetPriority(net::MAXIMUM_PRIORITY); request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS); @@ -91,8 +92,15 @@ void NetworkDelegate::OnBeforeRedirect(net::URLRequest* request, void NetworkDelegate::OnResponseStarted(net::URLRequest* request) { } -void NetworkDelegate::OnRawBytesRead(const net::URLRequest& request, - int bytes_read) { +void NetworkDelegate::OnURLRequestJobOrphaned(net::URLRequest* request) { +} + +void NetworkDelegate::OnNetworkBytesReceived(const net::URLRequest& request, + int64_t bytes_read) { +} + +void NetworkDelegate::OnNetworkBytesSent(const net::URLRequest& request, + int64_t bytes_sent) { } void NetworkDelegate::OnCompleted(net::URLRequest* request, bool started) { diff --git a/brightray/browser/network_delegate.h b/brightray/browser/network_delegate.h index f281f663ffa2..b10cabadd229 100644 --- a/brightray/browser/network_delegate.h +++ b/brightray/browser/network_delegate.h @@ -43,8 +43,11 @@ class NetworkDelegate : public net::NetworkDelegate { void OnBeforeRedirect(net::URLRequest* request, const GURL& new_location) override; void OnResponseStarted(net::URLRequest* request) override; - void OnRawBytesRead(const net::URLRequest& request, - int bytes_read) override; + void OnURLRequestJobOrphaned(net::URLRequest* request) override; + void OnNetworkBytesReceived(const net::URLRequest& request, + int64_t bytes_read) override; + void OnNetworkBytesSent(const net::URLRequest& request, + int64_t bytes_sent) override; void OnCompleted(net::URLRequest* request, bool started) override; void OnURLRequestDestroyed(net::URLRequest* request) override; void OnPACScriptError(int line_number, diff --git a/brightray/browser/notification.cc b/brightray/browser/notification.cc new file mode 100644 index 000000000000..6384737c21bf --- /dev/null +++ b/brightray/browser/notification.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/notification.h" + +#include "browser/notification_delegate.h" +#include "browser/notification_presenter.h" + +namespace brightray { + +Notification::Notification(NotificationDelegate* delegate, + NotificationPresenter* presenter) + : delegate_(delegate), + presenter_(presenter), + weak_factory_(this) { +} + +Notification::~Notification() { + delegate()->NotificationDestroyed(); +} + +void Notification::Destroy() { + presenter()->RemoveNotification(this); +} + +} // namespace brightray diff --git a/brightray/browser/notification.h b/brightray/browser/notification.h new file mode 100644 index 000000000000..9d0deccbf451 --- /dev/null +++ b/brightray/browser/notification.h @@ -0,0 +1,63 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_NOTIFICATION_H_ +#define BROWSER_NOTIFICATION_H_ + +#include "base/memory/weak_ptr.h" +#include "base/strings/string16.h" + +class GURL; +class SkBitmap; + +namespace brightray { + +class NotificationDelegate; +class NotificationPresenter; + +class Notification { + public: + // Shows the notification. + virtual void Show(const base::string16& title, + const base::string16& msg, + const GURL& icon_url, + const SkBitmap& icon) = 0; + // Closes the notification, this instance will be destroyed after the + // notification gets closed. + virtual void Dismiss() = 0; + + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + + NotificationDelegate* delegate() const { return delegate_; } + NotificationPresenter* presenter() const { return presenter_; } + + protected: + Notification(NotificationDelegate* delegate, + NotificationPresenter* presenter); + virtual ~Notification(); + + // delete this. + void Destroy(); + + private: + friend class NotificationPresenter; + + // Can only be called by NotificationPresenter, the caller is responsible of + // freeing the returned instance. + static Notification* Create(NotificationDelegate* delegate, + NotificationPresenter* presenter); + + NotificationDelegate* delegate_; + NotificationPresenter* presenter_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(Notification); +}; + +} // namespace brightray + +#endif // BROWSER_NOTIFICATION_H_ diff --git a/brightray/browser/notification_delegate.h b/brightray/browser/notification_delegate.h new file mode 100644 index 000000000000..93512f71753d --- /dev/null +++ b/brightray/browser/notification_delegate.h @@ -0,0 +1,23 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_NOTIFICATION_DELEGATE_H_ +#define BROWSER_NOTIFICATION_DELEGATE_H_ + +#include "content/public/browser/desktop_notification_delegate.h" + +namespace brightray { + +class NotificationDelegate : public content::DesktopNotificationDelegate { + public: + // The native Notification object is destroyed. + virtual void NotificationDestroyed() {} + + // Failed to send the notification. + virtual void NotificationFailed() {} +}; + +} // namespace brightray + +#endif // BROWSER_NOTIFICATION_DELEGATE_H_ diff --git a/brightray/browser/notification_delegate_adapter.cc b/brightray/browser/notification_delegate_adapter.cc new file mode 100644 index 000000000000..da9a70aab391 --- /dev/null +++ b/brightray/browser/notification_delegate_adapter.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/notification_delegate_adapter.h" + +namespace brightray { + +NotificationDelegateAdapter::NotificationDelegateAdapter( + scoped_ptr delegate) + : delegate_(delegate.Pass()) { +} + +NotificationDelegateAdapter::~NotificationDelegateAdapter() { +} + +void NotificationDelegateAdapter::NotificationDestroyed() { + delete this; +} + +void NotificationDelegateAdapter::NotificationDisplayed() { + delegate_->NotificationDisplayed(); +} + +void NotificationDelegateAdapter::NotificationClosed() { + delegate_->NotificationClosed(); +} + +void NotificationDelegateAdapter::NotificationClick() { + delegate_->NotificationClick(); +} + +} // namespace brightray diff --git a/brightray/browser/notification_delegate_adapter.h b/brightray/browser/notification_delegate_adapter.h new file mode 100644 index 000000000000..b48c7376cb00 --- /dev/null +++ b/brightray/browser/notification_delegate_adapter.h @@ -0,0 +1,36 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_ +#define BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_ + +#include "base/memory/scoped_ptr.h" +#include "browser/notification_delegate.h" + +namespace brightray { + +// Adapt the content::DesktopNotificationDelegate to NotificationDelegate. +class NotificationDelegateAdapter : public NotificationDelegate { + public: + explicit NotificationDelegateAdapter( + scoped_ptr delegate); + ~NotificationDelegateAdapter() override; + + // NotificationDelegate: + void NotificationDestroyed() override; + + // content::DesktopNotificationDelegate: + void NotificationDisplayed() override; + void NotificationClosed() override; + void NotificationClick() override; + + private: + scoped_ptr delegate_; + + DISALLOW_COPY_AND_ASSIGN(NotificationDelegateAdapter); +}; + +} // namespace brightray + +#endif // BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_ diff --git a/brightray/browser/notification_presenter.cc b/brightray/browser/notification_presenter.cc new file mode 100644 index 000000000000..ad46e292a272 --- /dev/null +++ b/brightray/browser/notification_presenter.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "browser/notification_presenter.h" + +#include "browser/notification.h" + +namespace brightray { + +NotificationPresenter::NotificationPresenter() { +} + +NotificationPresenter::~NotificationPresenter() { + for (Notification* notification : notifications_) + delete notification; +} + +base::WeakPtr NotificationPresenter::CreateNotification( + NotificationDelegate* delegate) { + Notification* notification = Notification::Create(delegate, this); + notifications_.insert(notification); + return notification->GetWeakPtr(); +} + +void NotificationPresenter::RemoveNotification(Notification* notification) { + notifications_.erase(notification); + delete notification; +} + +} // namespace brightray diff --git a/brightray/browser/notification_presenter.h b/brightray/browser/notification_presenter.h index 6c1a66fc5931..b3dac3005dcb 100644 --- a/brightray/browser/notification_presenter.h +++ b/brightray/browser/notification_presenter.h @@ -1,29 +1,41 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + #ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ #define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ -#include "base/callback_forward.h" -#include "base/memory/scoped_ptr.h" +#include -class SkBitmap; - -namespace content { -class DesktopNotificationDelegate; -struct PlatformNotificationData; -} +#include "base/memory/weak_ptr.h" namespace brightray { +class Notification; +class NotificationDelegate; + class NotificationPresenter { public: - virtual ~NotificationPresenter() {} - static NotificationPresenter* Create(); - virtual void ShowNotification( - const content::PlatformNotificationData&, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) = 0; + virtual ~NotificationPresenter(); + + base::WeakPtr CreateNotification( + NotificationDelegate* delegate); + + std::set notifications() const { return notifications_; } + + protected: + NotificationPresenter(); + + private: + friend class Notification; + + void RemoveNotification(Notification* notification); + + std::set notifications_; + + DISALLOW_COPY_AND_ASSIGN(NotificationPresenter); }; } // namespace brightray diff --git a/brightray/browser/notification_presenter_mac.h b/brightray/browser/notification_presenter_mac.h deleted file mode 100644 index 768bf2b6f1a2..000000000000 --- a/brightray/browser/notification_presenter_mac.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Copyright (c) 2013 Adam Roben . All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE-CHROMIUM file. - -#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_ -#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_ - -#include "browser/notification_presenter.h" - -#include - -#import - -#include "base/mac/scoped_nsobject.h" - -@class BRYUserNotificationCenterDelegate; - -namespace brightray { - -class NotificationPresenterMac : public NotificationPresenter { - public: - NotificationPresenterMac(); - ~NotificationPresenterMac(); - - // NotificationPresenter: - void ShowNotification( - const content::PlatformNotificationData&, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) override; - - // Get the delegate accroding from the notification object. - content::DesktopNotificationDelegate* GetDelegateFromNotification( - NSUserNotification* notification); - - // Remove the notification object accroding to its delegate. - void RemoveNotification(content::DesktopNotificationDelegate* delegate); - - private: - void CancelNotification(content::DesktopNotificationDelegate* delegate); - - // The userInfo of NSUserNotification can not store pointers (because they are - // not in property list), so we have to track them in a C++ map. - // Also notice that the delegate acts as "ID" or "Key", because it is certain - // that each notification has a unique delegate. - typedef std::map> - NotificationsMap; - NotificationsMap notifications_map_; - - base::scoped_nsobject delegate_; -}; - -} // namespace brightray - -#endif diff --git a/brightray/browser/notification_presenter_mac.mm b/brightray/browser/notification_presenter_mac.mm deleted file mode 100644 index d7dfe0156634..000000000000 --- a/brightray/browser/notification_presenter_mac.mm +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Copyright (c) 2013 Adam Roben . All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE-CHROMIUM file. - -#import "browser/notification_presenter_mac.h" - -#include "base/bind.h" -#include "base/stl_util.h" -#include "base/mac/mac_util.h" -#include "base/strings/sys_string_conversions.h" -#include "content/public/common/platform_notification_data.h" -#include "content/public/browser/desktop_notification_delegate.h" -#include "skia/ext/skia_utils_mac.h" - -@interface BRYUserNotificationCenterDelegate : NSObject { - @private - brightray::NotificationPresenterMac* presenter_; -} -- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter; -@end - -namespace brightray { - -namespace { - -} // namespace - -NotificationPresenter* NotificationPresenter::Create() { - return new NotificationPresenterMac; -} - -NotificationPresenterMac::NotificationPresenterMac() - : delegate_([[BRYUserNotificationCenterDelegate alloc] initWithNotificationPresenter:this]) { - NSUserNotificationCenter.defaultUserNotificationCenter.delegate = delegate_; -} - -NotificationPresenterMac::~NotificationPresenterMac() { - NSUserNotificationCenter.defaultUserNotificationCenter.delegate = nil; -} - -void NotificationPresenterMac::ShowNotification( - const content::PlatformNotificationData& data, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) { - auto notification = [[NSUserNotification alloc] init]; - notification.title = base::SysUTF16ToNSString(data.title); - notification.informativeText = base::SysUTF16ToNSString(data.body); - - if ([notification respondsToSelector:@selector(setContentImage:)] && !icon.drawsNothing()) - notification.contentImage = gfx::SkBitmapToNSImageWithColorSpace(icon, base::mac::GetGenericRGBColorSpace()); - - notifications_map_[delegate.get()].reset(notification); - [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification]; - - if (cancel_callback) - *cancel_callback = base::Bind( - &NotificationPresenterMac::CancelNotification, - base::Unretained(this), - delegate.release()); -} - -content::DesktopNotificationDelegate* NotificationPresenterMac::GetDelegateFromNotification( - NSUserNotification* notification) { - for (NotificationsMap::const_iterator it = notifications_map_.begin(); - it != notifications_map_.end(); ++it) - if ([it->second isEqual:notification]) - return it->first; - return NULL; -} - -void NotificationPresenterMac::RemoveNotification(content::DesktopNotificationDelegate* delegate) { - if (ContainsKey(notifications_map_, delegate)) { - delete delegate; - notifications_map_.erase(delegate); - } -} - -void NotificationPresenterMac::CancelNotification(content::DesktopNotificationDelegate* delegate) { - if (!ContainsKey(notifications_map_, delegate)) - return; - - // Notifications in -deliveredNotifications aren't the same objects we passed to - // -deliverNotification:, but they will respond YES to -isEqual:. - auto notification = notifications_map_[delegate]; - auto center = NSUserNotificationCenter.defaultUserNotificationCenter; - for (NSUserNotification* deliveredNotification in center.deliveredNotifications) - if ([notification isEqual:deliveredNotification]) { - [center removeDeliveredNotification:deliveredNotification]; - delegate->NotificationClosed(); - break; - } - - RemoveNotification(delegate); -} - -} // namespace brightray - -@implementation BRYUserNotificationCenterDelegate - -- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter { - self = [super init]; - if (!self) - return nil; - - presenter_ = presenter; - return self; -} - -- (void)userNotificationCenter:(NSUserNotificationCenter*)center - didDeliverNotification:(NSUserNotification*)notification { - auto delegate = presenter_->GetDelegateFromNotification(notification); - if (delegate) - delegate->NotificationDisplayed(); -} - -- (void)userNotificationCenter:(NSUserNotificationCenter*)center - didActivateNotification:(NSUserNotification *)notification { - auto delegate = presenter_->GetDelegateFromNotification(notification); - if (delegate) { - delegate->NotificationClick(); - presenter_->RemoveNotification(delegate); - } -} - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center - shouldPresentNotification:(NSUserNotification*)notification { - // Display notifications even if the app is active. - return YES; -} - -@end diff --git a/brightray/browser/permission_manager.cc b/brightray/browser/permission_manager.cc index 24795ac279ee..c5d1ac9a9cd5 100644 --- a/brightray/browser/permission_manager.cc +++ b/brightray/browser/permission_manager.cc @@ -18,10 +18,9 @@ PermissionManager::PermissionManager() { PermissionManager::~PermissionManager() { } -void PermissionManager::RequestPermission( +int PermissionManager::RequestPermission( content::PermissionType permission, content::RenderFrameHost* render_frame_host, - int request_id, const GURL& requesting_origin, bool user_gesture, const base::Callback& callback) { @@ -30,13 +29,10 @@ void PermissionManager::RequestPermission( GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID()); } callback.Run(content::PERMISSION_STATUS_GRANTED); + return kNoPendingOperation; } -void PermissionManager::CancelPermissionRequest( - content::PermissionType permission, - content::RenderFrameHost* render_frame_host, - int request_id, - const GURL& requesting_origin) { +void PermissionManager::CancelPermissionRequest(int request_id) { } void PermissionManager::ResetPermission( diff --git a/brightray/browser/permission_manager.h b/brightray/browser/permission_manager.h index a0860dd39bdf..778605c51ec1 100644 --- a/brightray/browser/permission_manager.h +++ b/brightray/browser/permission_manager.h @@ -17,17 +17,13 @@ class PermissionManager : public content::PermissionManager { ~PermissionManager() override; // content::PermissionManager: - void RequestPermission( + int RequestPermission( content::PermissionType permission, content::RenderFrameHost* render_frame_host, - int request_id, const GURL& requesting_origin, bool user_gesture, const base::Callback& callback) override; - void CancelPermissionRequest(content::PermissionType permission, - content::RenderFrameHost* render_frame_host, - int request_id, - const GURL& requesting_origin) override; + void CancelPermissionRequest(int request_id) override; void ResetPermission(content::PermissionType permission, const GURL& requesting_origin, const GURL& embedding_origin) override; diff --git a/brightray/browser/platform_notification_service.cc b/brightray/browser/platform_notification_service.cc new file mode 100644 index 000000000000..7d91ce5f2e42 --- /dev/null +++ b/brightray/browser/platform_notification_service.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/platform_notification_service.h" + +#include "browser/browser_client.h" +#include "browser/notification.h" +#include "browser/notification_delegate_adapter.h" +#include "browser/notification_presenter.h" +#include "content/public/common/platform_notification_data.h" + +namespace brightray { + +namespace { + +void RemoveNotification(base::WeakPtr notification) { + if (notification) + notification->Dismiss(); +} + +} // namespace + +PlatformNotificationService::PlatformNotificationService( + BrowserClient* browser_client) + : browser_client_(browser_client) { +} + +PlatformNotificationService::~PlatformNotificationService() {} + +blink::WebNotificationPermission PlatformNotificationService::CheckPermissionOnUIThread( + content::BrowserContext* browser_context, + const GURL& origin, + int render_process_id) { + return blink::WebNotificationPermissionAllowed; +} + +blink::WebNotificationPermission PlatformNotificationService::CheckPermissionOnIOThread( + content::ResourceContext* resource_context, + const GURL& origin, + int render_process_id) { + return blink::WebNotificationPermissionAllowed; +} + +void PlatformNotificationService::DisplayNotification( + content::BrowserContext* browser_context, + const GURL& origin, + const SkBitmap& icon, + const content::PlatformNotificationData& data, + scoped_ptr delegate, + base::Closure* cancel_callback) { + auto presenter = browser_client_->GetNotificationPresenter(); + if (!presenter) + return; + scoped_ptr adapter( + new NotificationDelegateAdapter(delegate.Pass())); + auto notification = presenter->CreateNotification(adapter.get()); + if (notification) { + ignore_result(adapter.release()); // it will release itself automatically. + notification->Show(data.title, data.body, data.icon, icon); + *cancel_callback = base::Bind(&RemoveNotification, notification); + } +} + +void PlatformNotificationService::DisplayPersistentNotification( + content::BrowserContext* browser_context, + int64_t service_worker_registration_id, + const GURL& origin, + const SkBitmap& icon, + const content::PlatformNotificationData& notification_data) { +} + +void PlatformNotificationService::ClosePersistentNotification( + content::BrowserContext* browser_context, + int64_t persistent_notification_id) { +} + +bool PlatformNotificationService::GetDisplayedPersistentNotifications( + content::BrowserContext* browser_context, + std::set* displayed_notifications) { + return false; +} + +} // namespace brightray diff --git a/brightray/browser/platform_notification_service_impl.h b/brightray/browser/platform_notification_service.h similarity index 67% rename from brightray/browser/platform_notification_service_impl.h rename to brightray/browser/platform_notification_service.h index da1e2ad81eba..0c598965df4e 100644 --- a/brightray/browser/platform_notification_service_impl.h +++ b/brightray/browser/platform_notification_service.h @@ -2,31 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE-CHROMIUM file. -#ifndef BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_ -#define BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_ +#ifndef BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_ +#define BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_ -#include "base/memory/singleton.h" #include "content/public/browser/platform_notification_service.h" namespace brightray { -class NotificationPresenter; +class BrowserClient; -class PlatformNotificationServiceImpl +class PlatformNotificationService : public content::PlatformNotificationService { public: - // Returns the active instance of the service in the browser process. Safe to - // be called from any thread. - static PlatformNotificationServiceImpl* GetInstance(); - - NotificationPresenter* notification_presenter(); - - private: - friend struct DefaultSingletonTraits; - - PlatformNotificationServiceImpl(); - ~PlatformNotificationServiceImpl() override; + explicit PlatformNotificationService(BrowserClient* browser_client); + ~PlatformNotificationService() override; + protected: // content::PlatformNotificationService: blink::WebNotificationPermission CheckPermissionOnUIThread( content::BrowserContext* browser_context, @@ -56,11 +47,12 @@ class PlatformNotificationServiceImpl content::BrowserContext* browser_context, std::set* displayed_notifications) override; - scoped_ptr notification_presenter_; + private: + BrowserClient* browser_client_; - DISALLOW_COPY_AND_ASSIGN(PlatformNotificationServiceImpl); + DISALLOW_COPY_AND_ASSIGN(PlatformNotificationService); }; } // namespace brightray -#endif // BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_ +#endif // BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_ diff --git a/brightray/browser/platform_notification_service_impl.cc b/brightray/browser/platform_notification_service_impl.cc deleted file mode 100644 index e93408ebe108..000000000000 --- a/brightray/browser/platform_notification_service_impl.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE-CHROMIUM file. - -#include "browser/platform_notification_service_impl.h" - -#include "browser/notification_presenter.h" - -#include "content/public/browser/desktop_notification_delegate.h" - -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif - -namespace brightray { - -// static -PlatformNotificationServiceImpl* -PlatformNotificationServiceImpl::GetInstance() { - return Singleton::get(); -} - -PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() {} -PlatformNotificationServiceImpl::~PlatformNotificationServiceImpl() {} - -NotificationPresenter* PlatformNotificationServiceImpl::notification_presenter() { - #if defined(OS_WIN) - // Bail out if on Windows 7 or even lower, no operating will follow - if (base::win::GetVersion() < base::win::VERSION_WIN8) - return nullptr; - #endif - - if (!notification_presenter_) { - // Create a new presenter if on OS X, Linux, or Windows 8+ - notification_presenter_.reset(NotificationPresenter::Create()); - } - return notification_presenter_.get(); -} - -blink::WebNotificationPermission PlatformNotificationServiceImpl::CheckPermissionOnUIThread( - content::BrowserContext* browser_context, - const GURL& origin, - int render_process_id) { - return blink::WebNotificationPermissionAllowed; -} - -blink::WebNotificationPermission PlatformNotificationServiceImpl::CheckPermissionOnIOThread( - content::ResourceContext* resource_context, - const GURL& origin, - int render_process_id) { - return blink::WebNotificationPermissionAllowed; -} - -void PlatformNotificationServiceImpl::DisplayNotification( - content::BrowserContext* browser_context, - const GURL& origin, - const SkBitmap& icon, - const content::PlatformNotificationData& notification_data, - scoped_ptr delegate, - base::Closure* cancel_callback) { - auto presenter = notification_presenter(); - if (presenter) - presenter->ShowNotification(notification_data, icon, delegate.Pass(), cancel_callback); -} - -void PlatformNotificationServiceImpl::DisplayPersistentNotification( - content::BrowserContext* browser_context, - int64_t service_worker_registration_id, - const GURL& origin, - const SkBitmap& icon, - const content::PlatformNotificationData& notification_data) { -} - -void PlatformNotificationServiceImpl::ClosePersistentNotification( - content::BrowserContext* browser_context, - int64_t persistent_notification_id) { -} - -bool PlatformNotificationServiceImpl::GetDisplayedPersistentNotifications( - content::BrowserContext* browser_context, - std::set* displayed_notifications) { - return false; -} - -} // namespace brightray diff --git a/brightray/browser/special_storage_policy.cc b/brightray/browser/special_storage_policy.cc index f28e8e5caf3f..77a302bb1f8f 100644 --- a/brightray/browser/special_storage_policy.cc +++ b/brightray/browser/special_storage_policy.cc @@ -20,6 +20,10 @@ bool SpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) { return true; } +bool SpecialStoragePolicy::IsStorageDurable(const GURL& origin) { + return true; +} + bool SpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) { return false; } diff --git a/brightray/browser/special_storage_policy.h b/brightray/browser/special_storage_policy.h index 9e02a4ac28c9..265df536cf23 100644 --- a/brightray/browser/special_storage_policy.h +++ b/brightray/browser/special_storage_policy.h @@ -16,6 +16,7 @@ class SpecialStoragePolicy : public storage::SpecialStoragePolicy { // storage::SpecialStoragePolicy implementation. bool IsStorageProtected(const GURL& origin) override; bool IsStorageUnlimited(const GURL& origin) override; + bool IsStorageDurable(const GURL& origin) override; bool IsStorageSessionOnly(const GURL& origin) override; bool CanQueryDiskSize(const GURL& origin) override; bool HasIsolatedStorage(const GURL& origin) override; diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc index 3f552b314c89..5c0d7828a96f 100644 --- a/brightray/browser/url_request_context_getter.cc +++ b/brightray/browser/url_request_context_getter.cc @@ -26,6 +26,7 @@ #include "net/http/http_server_properties_impl.h" #include "net/log/net_log.h" #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" +#include "net/proxy/proxy_config.h" #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_script_fetcher_impl.h" #include "net/proxy/proxy_service.h" @@ -79,6 +80,10 @@ const char kNoProxyServer[] = "no-proxy-server"; // affects HTTP and HTTPS requests. const char kProxyServer[] = "proxy-server"; +// Bypass specified proxy for the given semi-colon-separated list of hosts. This +// flag has an effect only when --proxy-server is set. +const char kProxyBypassList[] = "proxy-bypass-list"; + // Uses the pac script at the given URL. const char kProxyPacUrl[] = "proxy-pac-url"; @@ -106,19 +111,24 @@ std::string URLRequestContextGetter::Delegate::GetUserAgent() { return base::EmptyString(); } -net::URLRequestJobFactory* URLRequestContextGetter::Delegate::CreateURLRequestJobFactory( +scoped_ptr +URLRequestContextGetter::Delegate::CreateURLRequestJobFactory( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector* protocol_interceptors) { scoped_ptr job_factory(new net::URLRequestJobFactoryImpl); for (auto it = protocol_handlers->begin(); it != protocol_handlers->end(); ++it) - job_factory->SetProtocolHandler(it->first, it->second.release()); + job_factory->SetProtocolHandler( + it->first, make_scoped_ptr(it->second.release())); protocol_handlers->clear(); - job_factory->SetProtocolHandler(url::kDataScheme, new net::DataProtocolHandler); - job_factory->SetProtocolHandler(url::kFileScheme, new net::FileProtocolHandler( - BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); + job_factory->SetProtocolHandler( + url::kDataScheme, make_scoped_ptr(new net::DataProtocolHandler)); + job_factory->SetProtocolHandler( + url::kFileScheme, + make_scoped_ptr(new net::FileProtocolHandler( + BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)))); // Set up interceptors in the reverse order. scoped_ptr top_job_factory = job_factory.Pass(); @@ -128,7 +138,7 @@ net::URLRequestJobFactory* URLRequestContextGetter::Delegate::CreateURLRequestJo top_job_factory.Pass(), make_scoped_ptr(*i))); protocol_interceptors->weak_clear(); - return top_job_factory.release(); + return top_job_factory.Pass(); } net::HttpCache::BackendFactory* @@ -142,7 +152,8 @@ URLRequestContextGetter::Delegate::CreateHttpCacheBackendFactory(const base::Fil BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); } -net::CertVerifier* URLRequestContextGetter::Delegate::CreateCertVerifier() { +scoped_ptr +URLRequestContextGetter::Delegate::CreateCertVerifier() { return net::CertVerifier::CreateDefault(); } @@ -186,8 +197,8 @@ URLRequestContextGetter::URLRequestContextGetter( // We must create the proxy config service on the UI loop on Linux because it // must synchronously run on the glib message loop. This will be passed to // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). - proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService( - io_loop_->task_runner(), file_loop_->task_runner())); + proxy_config_service_ = net::ProxyService::CreateSystemProxyConfigService( + io_loop_->task_runner(), file_loop_->task_runner()); } URLRequestContextGetter::~URLRequestContextGetter() { @@ -236,8 +247,10 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { base::WorkerPool::GetTaskRunner(true)))); std::string accept_lang = l10n_util::GetApplicationLocale(""); - storage_->set_http_user_agent_settings(new net::StaticHttpUserAgentSettings( - net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang), delegate_->GetUserAgent())); + storage_->set_http_user_agent_settings(make_scoped_ptr( + new net::StaticHttpUserAgentSettings( + net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang), + delegate_->GetUserAgent()))); scoped_ptr host_resolver(net::HostResolver::CreateDefaultResolver(nullptr)); @@ -255,8 +268,12 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { if (command_line.HasSwitch(kNoProxyServer)) { storage_->set_proxy_service(net::ProxyService::CreateDirect()); } else if (command_line.HasSwitch(kProxyServer)) { - storage_->set_proxy_service(net::ProxyService::CreateFixed( - command_line.GetSwitchValueASCII(kProxyServer))); + net::ProxyConfig proxy_config; + proxy_config.proxy_rules().ParseFromString( + command_line.GetSwitchValueASCII(kProxyServer)); + proxy_config.proxy_rules().bypass_rules.ParseFromString( + command_line.GetSwitchValueASCII(kProxyBypassList)); + storage_->set_proxy_service(net::ProxyService::CreateFixed(proxy_config)); } else if (command_line.HasSwitch(kProxyPacUrl)) { auto proxy_config = net::ProxyConfig::CreateFromCustomPacURL( GURL(command_line.GetSwitchValueASCII(kProxyPacUrl))); @@ -266,7 +283,7 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { } else { storage_->set_proxy_service( net::CreateProxyServiceUsingV8ProxyResolver( - proxy_config_service_.release(), + proxy_config_service_.Pass(), new net::ProxyScriptFetcherImpl(url_request_context_.get()), dhcp_factory.Create(url_request_context_.get()), host_resolver.get(), @@ -280,7 +297,7 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { schemes.push_back(std::string("ntlm")); schemes.push_back(std::string("negotiate")); - auto auth_handler_factory = + auto auth_handler_factory = make_scoped_ptr( net::HttpAuthHandlerRegistryFactory::Create( schemes, url_sec_mgr_.get(), @@ -288,12 +305,13 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { std::string(), // gssapi_library_name std::string(), // gssapi_library_nam false, // auth_android_negotiate_account_type - true); // negotiate_enable_port + true)); // negotiate_enable_port storage_->set_cert_verifier(delegate_->CreateCertVerifier()); - storage_->set_transport_security_state(new net::TransportSecurityState); + storage_->set_transport_security_state( + make_scoped_ptr(new net::TransportSecurityState)); storage_->set_ssl_config_service(delegate_->CreateSSLConfigService()); - storage_->set_http_auth_handler_factory(auth_handler_factory); + storage_->set_http_auth_handler_factory(auth_handler_factory.Pass()); scoped_ptr server_properties( new net::HttpServerPropertiesImpl); storage_->set_http_server_properties(server_properties.Pass()); @@ -312,6 +330,10 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { network_session_params.http_auth_handler_factory = url_request_context_->http_auth_handler_factory(); network_session_params.net_log = url_request_context_->net_log(); + net::NextProtoVector next_protos; + next_protos.push_back(net::kProtoHTTP2); + next_protos.push_back(net::kProtoHTTP11); + network_session_params.next_protos = next_protos; // --ignore-certificate-errors if (command_line.HasSwitch(switches::kIgnoreCertificateErrors)) @@ -335,10 +357,11 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { } else { backend = delegate_->CreateHttpCacheBackendFactory(base_path_); } - storage_->set_http_transaction_factory(new net::HttpCache( - new DevToolsNetworkTransactionFactory(controller_, session), - url_request_context_->net_log(), - backend)); + storage_->set_http_transaction_factory(make_scoped_ptr( + new net::HttpCache( + new DevToolsNetworkTransactionFactory(controller_, session), + url_request_context_->net_log(), + backend))); storage_->set_job_factory(delegate_->CreateURLRequestJobFactory( &protocol_handlers_, &protocol_interceptors_)); diff --git a/brightray/browser/url_request_context_getter.h b/brightray/browser/url_request_context_getter.h index c4e0f9208a17..cf647cf7b512 100644 --- a/brightray/browser/url_request_context_getter.h +++ b/brightray/browser/url_request_context_getter.h @@ -39,12 +39,12 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { virtual net::NetworkDelegate* CreateNetworkDelegate() { return NULL; } virtual std::string GetUserAgent(); - virtual net::URLRequestJobFactory* CreateURLRequestJobFactory( + virtual scoped_ptr CreateURLRequestJobFactory( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector* protocol_interceptors); virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( const base::FilePath& base_path); - virtual net::CertVerifier* CreateCertVerifier(); + virtual scoped_ptr CreateCertVerifier(); virtual net::SSLConfigService* CreateSSLConfigService(); virtual bool AllowNTLMCredentialsForDomain(const GURL& auth_origin); virtual bool CanDelegateURLSecurity(const GURL& auth_origin); diff --git a/brightray/browser/web_ui_controller_factory.cc b/brightray/browser/web_ui_controller_factory.cc index cacc2f8dc28f..3313d3a6c632 100644 --- a/brightray/browser/web_ui_controller_factory.cc +++ b/brightray/browser/web_ui_controller_factory.cc @@ -20,7 +20,7 @@ const char kChromeUIDevToolsBundledHost[] = "devtools"; // static WebUIControllerFactory* WebUIControllerFactory::GetInstance() { - return Singleton::get(); + return base::Singleton::get(); } WebUIControllerFactory::WebUIControllerFactory() { diff --git a/brightray/browser/web_ui_controller_factory.h b/brightray/browser/web_ui_controller_factory.h index 3367255bba35..44a77da5f1ea 100644 --- a/brightray/browser/web_ui_controller_factory.h +++ b/brightray/browser/web_ui_controller_factory.h @@ -9,7 +9,9 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller_factory.h" +namespace base { template struct DefaultSingletonTraits; +} namespace brightray { @@ -33,7 +35,7 @@ class WebUIControllerFactory : public content::WebUIControllerFactory { const GURL& url) const override; private: - friend struct DefaultSingletonTraits; + friend struct base::DefaultSingletonTraits; DISALLOW_COPY_AND_ASSIGN(WebUIControllerFactory); }; diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 8d4fe8bace04..d3d4f7dc2432 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -5,12 +5,15 @@ #include "browser/win/notification_presenter_win.h" +#include "base/files/file_util.h" +#include "base/md5.h" +#include "base/strings/utf_string_conversions.h" #include "base/win/windows_version.h" #include "browser/win/windows_toast_notification.h" -#include "common/application_info.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/codec/png_codec.h" #pragma comment(lib, "runtimeobject.lib") @@ -18,16 +21,26 @@ namespace brightray { namespace { -void RemoveNotification(base::WeakPtr notification) { - if (notification) - notification->DismissNotification(); +bool SaveIconToPath(const SkBitmap& bitmap, const base::FilePath& path) { + std::vector png_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data)) + return false; + + char* data = reinterpret_cast(&png_data[0]); + int size = static_cast(png_data.size()); + return base::WriteFile(path, data, size) == size; } } // namespace // static NotificationPresenter* NotificationPresenter::Create() { - return new NotificationPresenterWin; + if (!WindowsToastNotification::Initialize()) + return nullptr; + scoped_ptr presenter(new NotificationPresenterWin); + if (!presenter->Init()) + return nullptr; + return presenter.release(); } NotificationPresenterWin::NotificationPresenterWin() { @@ -36,19 +49,19 @@ NotificationPresenterWin::NotificationPresenterWin() { NotificationPresenterWin::~NotificationPresenterWin() { } -void NotificationPresenterWin::ShowNotification( - const content::PlatformNotificationData& data, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) { - // This class manages itself. - auto notification = new WindowsToastNotification(delegate.Pass()); - notification->ShowNotification(data.title, data.body, data.icon.spec()); +bool NotificationPresenterWin::Init() { + return temp_dir_.CreateUniqueTempDir(); +} - if (cancel_callback) { - *cancel_callback = base::Bind( - &RemoveNotification, notification->GetWeakPtr()); - } +base::string16 NotificationPresenterWin::SaveIconToFilesystem( + const SkBitmap& icon, const GURL& origin) { + std::string filename = base::MD5String(origin.spec()) + ".png"; + base::FilePath path = temp_dir_.path().Append(base::UTF8ToUTF16(filename)); + if (base::PathExists(path)) + return path.value(); + if (SaveIconToPath(icon, path)) + return path.value(); + return base::UTF8ToUTF16(origin.spec()); } } // namespace brightray diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index 5bc84feb92af..7bcf1a9909dd 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -16,8 +16,13 @@ #ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ #define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ +#include "base/files/scoped_temp_dir.h" +#include "base/strings/string16.h" #include "browser/notification_presenter.h" +class GURL; +class SkBitmap; + namespace brightray { class NotificationPresenterWin : public NotificationPresenter { @@ -25,13 +30,13 @@ class NotificationPresenterWin : public NotificationPresenter { NotificationPresenterWin(); ~NotificationPresenterWin(); - void ShowNotification( - const content::PlatformNotificationData&, - const SkBitmap& icon, - scoped_ptr delegate, - base::Closure* cancel_callback) override; + bool Init(); + + base::string16 SaveIconToFilesystem(const SkBitmap& icon, const GURL& origin); private: + base::ScopedTempDir temp_dir_; + DISALLOW_COPY_AND_ASSIGN(NotificationPresenterWin); }; diff --git a/brightray/browser/win/scoped_hstring.cc b/brightray/browser/win/scoped_hstring.cc index e3f5cbd29bbb..082ebe762270 100644 --- a/brightray/browser/win/scoped_hstring.cc +++ b/brightray/browser/win/scoped_hstring.cc @@ -8,26 +8,34 @@ ScopedHString::ScopedHString(const wchar_t* source) : str_(nullptr) { - Set(source); + Reset(source); } ScopedHString::ScopedHString(const std::wstring& source) : str_(nullptr) { - WindowsCreateString(source.c_str(), source.length(), &str_); + Reset(source); } ScopedHString::ScopedHString() : str_(nullptr) { } ScopedHString::~ScopedHString() { - if (str_) - WindowsDeleteString(str_); + Reset(); } -void ScopedHString::Set(const wchar_t* source) { +void ScopedHString::Reset() { if (str_) { WindowsDeleteString(str_); str_ = nullptr; } +} + +void ScopedHString::Reset(const wchar_t* source) { + Reset(); WindowsCreateString(source, wcslen(source), &str_); } + +void ScopedHString::Reset(const std::wstring& source) { + Reset(); + WindowsCreateString(source.c_str(), source.length(), &str_); +} diff --git a/brightray/browser/win/scoped_hstring.h b/brightray/browser/win/scoped_hstring.h index de03c0469b3a..5494df2fc5ce 100644 --- a/brightray/browser/win/scoped_hstring.h +++ b/brightray/browser/win/scoped_hstring.h @@ -22,7 +22,9 @@ class ScopedHString { ~ScopedHString(); // Sets to |source|. - void Set(const wchar_t* source); + void Reset(); + void Reset(const wchar_t* source); + void Reset(const std::wstring& source); // Returns string. operator HSTRING() const { return str_; } diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 60a20dc329f5..d08b888e4a8f 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -8,8 +8,10 @@ #include #include "base/strings/utf_string_conversions.h" +#include "browser/notification_delegate.h" #include "browser/win/scoped_hstring.h" -#include "content/public/browser/desktop_notification_delegate.h" +#include "browser/win/notification_presenter_win.h" +#include "common/application_info.h" using namespace ABI::Windows::Data::Xml::Dom; @@ -19,96 +21,137 @@ namespace { bool GetAppUserModelId(ScopedHString* app_id) { PWSTR current_app_id; - if (FAILED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) - return false; - - app_id->Set(current_app_id); - CoTaskMemFree(current_app_id); + if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) { + app_id->Reset(current_app_id); + CoTaskMemFree(current_app_id); + } else { + app_id->Reset(base::UTF8ToUTF16(GetApplicationName())); + } return app_id->success(); } } // namespace -WindowsToastNotification::WindowsToastNotification( - scoped_ptr delegate) - : delegate_(delegate.Pass()), - weak_factory_(this) { - // If it wasn't for Windows 7, we could do this statically - HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); +// static +Notification* Notification::Create(NotificationDelegate* delegate, + NotificationPresenter* presenter) { + return new WindowsToastNotification(delegate, presenter); +} + +// static +ComPtr + WindowsToastNotification::toast_manager_; + +// static +ComPtr + WindowsToastNotification::toast_notifier_; + +// static +bool WindowsToastNotification::Initialize() { + // Just initialize, don't care if it fails or already initialized. + Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); ScopedHString toast_manager_str( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager); if (!toast_manager_str.success()) - return; - HRESULT hr = Windows::Foundation::GetActivationFactory( - toast_manager_str, &toast_manager_); - if (FAILED(hr)) - return; + return false; + if (FAILED(Windows::Foundation::GetActivationFactory(toast_manager_str, + &toast_manager_))) + return false; ScopedHString app_id; if (!GetAppUserModelId(&app_id)) - return; + return false; - toast_manager_->CreateToastNotifierWithId(app_id, &toast_notifier_); + return SUCCEEDED( + toast_manager_->CreateToastNotifierWithId(app_id, &toast_notifier_)); +} + +WindowsToastNotification::WindowsToastNotification( + NotificationDelegate* delegate, + NotificationPresenter* presenter) + : Notification(delegate, presenter) { } WindowsToastNotification::~WindowsToastNotification() { + // Remove the notification on exit. + if (toast_notification_) { + RemoveCallbacks(toast_notification_.Get()); + Dismiss(); + } } -void WindowsToastNotification::ShowNotification( - const std::wstring& title, - const std::wstring& msg, - std::string icon_path) { +void WindowsToastNotification::Show( + const base::string16& title, + const base::string16& msg, + const GURL& icon_url, + const SkBitmap& icon) { + auto presenter_win = static_cast(presenter()); + std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url); + ComPtr toast_xml; - if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) + if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) { + NotificationFailed(); return; + } ScopedHString toast_str( RuntimeClass_Windows_UI_Notifications_ToastNotification); - if (!toast_str.success()) + if (!toast_str.success()) { + NotificationFailed(); return; + } ComPtr toast_factory; if (FAILED(Windows::Foundation::GetActivationFactory(toast_str, - &toast_factory))) + &toast_factory))) { + NotificationFailed(); return; + } if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(), - &toast_notification_))) + &toast_notification_))) { + NotificationFailed(); return; + } - if (FAILED(SetupCallbacks(toast_notification_.Get()))) + if (FAILED(SetupCallbacks(toast_notification_.Get()))) { + NotificationFailed(); return; + } - if (FAILED(toast_notifier_->Show(toast_notification_.Get()))) + if (FAILED(toast_notifier_->Show(toast_notification_.Get()))) { + NotificationFailed(); return; + } - delegate_->NotificationDisplayed(); + delegate()->NotificationDisplayed(); } -void WindowsToastNotification::DismissNotification() { +void WindowsToastNotification::Dismiss() { toast_notifier_->Hide(toast_notification_.Get()); } void WindowsToastNotification::NotificationClicked() { - delegate_->NotificationClick(); - delete this; + delegate()->NotificationClick(); + Destroy(); } void WindowsToastNotification::NotificationDismissed() { - delegate_->NotificationClosed(); - delete this; + delegate()->NotificationClosed(); + Destroy(); } void WindowsToastNotification::NotificationFailed() { - delete this; + delegate()->NotificationFailed(); + Destroy(); } bool WindowsToastNotification::GetToastXml( ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager, const std::wstring& title, const std::wstring& msg, - std::string icon_path, + const std::wstring& icon_path, IXmlDocument** toast_xml) { ABI::Windows::UI::Notifications::ToastTemplateType template_type; if (title.empty() || msg.empty()) { @@ -171,7 +214,7 @@ bool WindowsToastNotification::SetXmlText( } bool WindowsToastNotification::SetXmlImage( - IXmlDocument* doc, std::string icon_path) { + IXmlDocument* doc, const std::wstring& icon_path) { ScopedHString tag(L"image"); if (!tag.success()) return false; @@ -196,7 +239,7 @@ bool WindowsToastNotification::SetXmlImage( if (FAILED(attrs->GetNamedItem(src, &src_attr))) return false; - ScopedHString img_path(base::UTF8ToUTF16(icon_path).c_str()); + ScopedHString img_path(icon_path.c_str()); if (!img_path.success()) return false; @@ -217,7 +260,7 @@ bool WindowsToastNotification::GetTextNodeList( IXmlDocument* doc, IXmlNodeList** node_list, UINT32 req_length) { - tag->Set(L"text"); + tag->Reset(L"text"); if (!tag->success()) return false; @@ -249,16 +292,27 @@ bool WindowsToastNotification::AppendTextToXml( return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node)); } -bool WindowsToastNotification::SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast) { - EventRegistrationToken activatedToken, dismissedToken, failedToken; +bool WindowsToastNotification::SetupCallbacks( + ABI::Windows::UI::Notifications::IToastNotification* toast) { event_handler_ = Make(this); - if (FAILED(toast->add_Activated(event_handler_.Get(), &activatedToken))) + if (FAILED(toast->add_Activated(event_handler_.Get(), &activated_token_))) return false; - if (FAILED(toast->add_Dismissed(event_handler_.Get(), &dismissedToken))) + if (FAILED(toast->add_Dismissed(event_handler_.Get(), &dismissed_token_))) return false; - return SUCCEEDED(toast->add_Failed(event_handler_.Get(), &failedToken)); + return SUCCEEDED(toast->add_Failed(event_handler_.Get(), &failed_token_)); +} + +bool WindowsToastNotification::RemoveCallbacks( + ABI::Windows::UI::Notifications::IToastNotification* toast) { + if (FAILED(toast->remove_Activated(activated_token_))) + return false; + + if (FAILED(toast->remove_Dismissed(dismissed_token_))) + return false; + + return SUCCEEDED(toast->remove_Failed(failed_token_)); } /* diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 87dffae438b2..02e056669928 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -10,10 +10,7 @@ #include #include -#include "base/bind.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/desktop_notification_delegate.h" -#include "content/public/common/platform_notification_data.h" +#include "browser/notification.h" using namespace Microsoft::WRL; @@ -31,20 +28,22 @@ using DesktopToastFailedEventHandler = ABI::Windows::Foundation::ITypedEventHandler; -class WindowsToastNotification { +class WindowsToastNotification : public Notification { public: - WindowsToastNotification( - scoped_ptr delegate); + // Should only be called by NotificationPresenterWin. + static bool Initialize(); + + WindowsToastNotification(NotificationDelegate* delegate, + NotificationPresenter* presenter); ~WindowsToastNotification(); - void ShowNotification(const std::wstring& title, - const std::wstring& msg, - std::string icon_path); - void DismissNotification(); - - base::WeakPtr GetWeakPtr() { - return weak_factory_.GetWeakPtr(); - } + protected: + // Notification: + void Show(const base::string16& title, + const base::string16& msg, + const GURL& icon_url, + const SkBitmap& icon) override; + void Dismiss() override; private: friend class ToastEventHandler; @@ -56,7 +55,7 @@ class WindowsToastNotification { bool GetToastXml(ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager, const std::wstring& title, const std::wstring& msg, - std::string icon_path, + const std::wstring& icon_path, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const std::wstring& text); @@ -64,7 +63,7 @@ class WindowsToastNotification { const std::wstring& title, const std::wstring& body); bool SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, - std::string icon_path); + const std::wstring& icon_path); bool GetTextNodeList(ScopedHString* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, @@ -73,15 +72,18 @@ class WindowsToastNotification { ABI::Windows::Data::Xml::Dom::IXmlNode* node, const std::wstring& text); bool SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast); + bool RemoveCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast); + + static ComPtr toast_manager_; + static ComPtr toast_notifier_; + + EventRegistrationToken activated_token_; + EventRegistrationToken dismissed_token_; + EventRegistrationToken failed_token_; - scoped_ptr delegate_; ComPtr event_handler_; - ComPtr toast_manager_; - ComPtr toast_notifier_; ComPtr toast_notification_; - base::WeakPtrFactory weak_factory_; - DISALLOW_COPY_AND_ASSIGN(WindowsToastNotification); }; diff --git a/brightray/common/mac/main_application_bundle.mm b/brightray/common/mac/main_application_bundle.mm index 730eb36207b6..3e386b40dc58 100644 --- a/brightray/common/mac/main_application_bundle.mm +++ b/brightray/common/mac/main_application_bundle.mm @@ -5,20 +5,31 @@ #import "common/mac/main_application_bundle.h" -#import "common/mac/foundation_util.h" - -#import "base/files/file_path.h" -#import "base/path_service.h" +#include "base/files/file_path.h" +#include "base/mac/bundle_locations.h" +#include "base/mac/foundation_util.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" namespace brightray { +namespace { + +bool HasMainProcessKey() { + NSDictionary* info_dictionary = [base::mac::MainBundle() infoDictionary]; + return [[info_dictionary objectForKey:@"ElectronMainProcess"] boolValue] != NO; +} + +} // namespace + base::FilePath MainApplicationBundlePath() { // Start out with the path to the running executable. base::FilePath path; PathService::Get(base::FILE_EXE, &path); // Up to Contents. - if (base::mac::IsBackgroundOnlyProcess()) { + if (!HasMainProcessKey() && + base::EndsWith(path.value(), " Helper", base::CompareCase::SENSITIVE)) { // The running executable is the helper. Go up five steps: // Contents/Frameworks/Helper.app/Contents/MacOS/Helper // ^ to here ^ from here @@ -40,4 +51,4 @@ NSBundle* MainApplicationBundle() { return [NSBundle bundleWithPath:base::mac::FilePathToNSString(MainApplicationBundlePath())]; } -} +} // namespace brightray diff --git a/brightray/common/main_delegate.cc b/brightray/common/main_delegate.cc index cf0a16fb2732..74ec88791b96 100644 --- a/brightray/common/main_delegate.cc +++ b/brightray/common/main_delegate.cc @@ -11,9 +11,69 @@ #include "base/path_service.h" #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_switches.h" namespace brightray { +namespace { + +// Returns true if this subprocess type needs the ResourceBundle initialized +// and resources loaded. +bool SubprocessNeedsResourceBundle(const std::string& process_type) { + return +#if defined(OS_WIN) || defined(OS_MACOSX) + // Windows needs resources for the default/null plugin. + // Mac needs them for the plugin process name. + process_type == switches::kPluginProcess || +#endif +#if defined(OS_POSIX) && !defined(OS_MACOSX) + // The zygote process opens the resources for the renderers. + process_type == switches::kZygoteProcess || +#endif +#if defined(OS_MACOSX) + // Mac needs them too for scrollbar related images and for sandbox + // profiles. +#if !defined(DISABLE_NACL) + process_type == switches::kNaClLoaderProcess || +#endif + process_type == switches::kPpapiPluginProcess || + process_type == switches::kPpapiBrokerProcess || + process_type == switches::kGpuProcess || +#endif + process_type == switches::kRendererProcess || + process_type == switches::kUtilityProcess; +} + +} // namespace + +void InitializeResourceBundle(const std::string& locale) { + // Load locales. + ui::ResourceBundle::InitSharedInstanceWithLocale( + locale, nullptr, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES); + + // Load other resource files. + base::FilePath path; +#if defined(OS_MACOSX) + path = GetResourcesPakFilePath(); +#else + base::FilePath pak_dir; + PathService::Get(base::DIR_MODULE, &pak_dir); + path = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak")); +#endif + + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + bundle.AddDataPackFromPath(path, ui::GetSupportedScaleFactors()[0]); +#if defined(OS_WIN) + bundle.AddDataPackFromPath( + pak_dir.Append(FILE_PATH_LITERAL("ui_resources_200_percent.pak")), + ui::SCALE_FACTOR_200P); + bundle.AddDataPackFromPath( + pak_dir.Append(FILE_PATH_LITERAL("content_resources_200_percent.pak")), + ui::SCALE_FACTOR_200P); +#endif +} + + MainDelegate::MainDelegate() { } @@ -35,21 +95,16 @@ bool MainDelegate::BasicStartupComplete(int* exit_code) { } void MainDelegate::PreSandboxStartup() { - InitializeResourceBundle(); -} + auto cmd = *base::CommandLine::ForCurrentProcess(); + std::string process_type = cmd.GetSwitchValueASCII(switches::kProcessType); -void MainDelegate::InitializeResourceBundle() { - base::FilePath path; -#if defined(OS_MACOSX) - path = GetResourcesPakFilePath(); -#else - base::FilePath pak_dir; - PathService::Get(base::DIR_MODULE, &pak_dir); - path = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak")); -#endif - - ui::ResourceBundle::InitSharedInstanceWithPakPath(path); - AddDataPackFromPath(&ui::ResourceBundle::GetSharedInstance(), path.DirName()); + // Initialize ResourceBundle which handles files loaded from external + // sources. The language should have been passed in to us from the + // browser process as a command line flag. + if (SubprocessNeedsResourceBundle(process_type)) { + std::string locale = cmd.GetSwitchValueASCII(switches::kLang); + InitializeResourceBundle(locale); + } } content::ContentBrowserClient* MainDelegate::CreateContentBrowserClient() { diff --git a/brightray/common/main_delegate.h b/brightray/common/main_delegate.h index 58349944746d..2082a5228822 100644 --- a/brightray/common/main_delegate.h +++ b/brightray/common/main_delegate.h @@ -22,6 +22,9 @@ namespace brightray { class BrowserClient; class ContentClient; +void InitializeResourceBundle(const std::string& locale); +base::FilePath GetResourcesPakFilePath(); + class MainDelegate : public content::ContentMainDelegate { public: MainDelegate(); @@ -36,15 +39,9 @@ class MainDelegate : public content::ContentMainDelegate { // implementation. virtual scoped_ptr CreateBrowserClient(); - // Subclasses can override this to provide additional .pak files to be - // included in the ui::ResourceBundle. - virtual void AddDataPackFromPath( - ui::ResourceBundle* bundle, const base::FilePath& pak_dir) {} - #if defined(OS_MACOSX) // Subclasses can override this to custom the paths of child process and // framework bundle. - virtual base::FilePath GetResourcesPakFilePath(); virtual void OverrideChildProcessPath(); virtual void OverrideFrameworkBundlePath(); #endif @@ -55,8 +52,6 @@ class MainDelegate : public content::ContentMainDelegate { private: content::ContentBrowserClient* CreateContentBrowserClient() override; - void InitializeResourceBundle(); - scoped_ptr content_client_; scoped_ptr browser_client_; diff --git a/brightray/common/main_delegate_mac.mm b/brightray/common/main_delegate_mac.mm index 42f6e818e171..464cf68b50f0 100644 --- a/brightray/common/main_delegate_mac.mm +++ b/brightray/common/main_delegate_mac.mm @@ -27,7 +27,7 @@ base::FilePath GetFrameworksPath() { } -base::FilePath MainDelegate::GetResourcesPakFilePath() { +base::FilePath GetResourcesPakFilePath() { auto path = [base::mac::FrameworkBundle() pathForResource:@"content_shell" ofType:@"pak"]; return base::mac::NSStringToFilePath(path); } diff --git a/brightray/filenames.gypi b/brightray/filenames.gypi index 5b0fd733c998..26c02679c052 100644 --- a/brightray/filenames.gypi +++ b/brightray/filenames.gypi @@ -34,6 +34,12 @@ 'browser/mac/bry_application.mm', 'browser/mac/bry_inspectable_web_contents_view.h', 'browser/mac/bry_inspectable_web_contents_view.mm', + 'browser/mac/cocoa_notification.h', + 'browser/mac/cocoa_notification.mm', + 'browser/mac/notification_center_delegate.h', + 'browser/mac/notification_center_delegate.mm', + 'browser/mac/notification_presenter_mac.h', + 'browser/mac/notification_presenter_mac.mm', 'browser/media/media_capture_devices_dispatcher.cc', 'browser/media/media_capture_devices_dispatcher.h', 'browser/media/media_stream_devices_controller.cc', @@ -54,13 +60,21 @@ 'browser/net_log.h', 'browser/network_delegate.cc', 'browser/network_delegate.h', + 'browser/notification_delegate.h', + 'browser/notification_delegate_adapter.cc', + 'browser/notification_delegate_adapter.h', + 'browser/notification_presenter.cc', 'browser/notification_presenter.h', - 'browser/notification_presenter_mac.h', - 'browser/notification_presenter_mac.mm', + 'browser/notification.cc', + 'browser/notification.h', 'browser/permission_manager.cc', 'browser/permission_manager.h', - 'browser/platform_notification_service_impl.cc', - 'browser/platform_notification_service_impl.h', + 'browser/platform_notification_service.cc', + 'browser/platform_notification_service.h', + 'browser/linux/libnotify_loader.h', + 'browser/linux/libnotify_loader.cc', + 'browser/linux/libnotify_notification.h', + 'browser/linux/libnotify_notification.cc', 'browser/linux/notification_presenter_linux.h', 'browser/linux/notification_presenter_linux.cc', 'browser/win/notification_presenter_win.h', diff --git a/brightray/vendor/libchromiumcontent b/brightray/vendor/libchromiumcontent index f202592f932c..389d11b3bba3 160000 --- a/brightray/vendor/libchromiumcontent +++ b/brightray/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit f202592f932cfb8494cc6fa211f9b917f2457f3b +Subproject commit 389d11b3bba3bdd536075c4743dec9ff4e0965ff