diff --git a/brightray/brightray.gypi b/brightray/brightray.gypi index 08ed02d4ff..c155782c7d 100644 --- a/brightray/brightray.gypi +++ b/brightray/brightray.gypi @@ -259,6 +259,7 @@ 'msvs_disabled_warnings': [ 4100, # unreferenced formal parameter 4127, # conditional expression is constant + 4189, # local variable is initialized but not referenced 4244, # 'initializing' : conversion from 'double' to 'size_t', possible loss of data 4245, # 'initializing' : conversion from 'int' to 'const net::QuicVersionTag', signed/unsigned mismatch 4251, # class 'std::xx' needs to have dll-interface. diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index f96e7f057e..3c7377d6d9 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -9,6 +9,8 @@ #include "browser/media/media_capture_devices_dispatcher.h" #include "browser/notification_presenter.h" +#include "base/base_paths.h" +#include "base/path_service.h" #include "content/public/common/url_constants.h" namespace brightray { @@ -66,24 +68,12 @@ net::URLRequestContextGetter* BrowserClient::CreateRequestContext( void BrowserClient::ShowDesktopNotification( const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id, - bool worker) { + content::RenderFrameHost* render_frame_host, + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) { auto presenter = notification_presenter(); - if (!presenter) - return; - presenter->ShowNotification(params, render_process_id, render_view_id); -} - -void BrowserClient::CancelDesktopNotification( - int render_process_id, - int render_view_id, - int notification_id) { - auto presenter = notification_presenter(); - if (!presenter) - return; - presenter->CancelNotification( - render_process_id, render_view_id, notification_id); + if (presenter) + presenter->ShowNotification(params, delegate, cancel_callback); } content::MediaObserver* BrowserClient::GetMediaObserver() { @@ -96,4 +86,13 @@ void BrowserClient::GetAdditionalAllowedSchemesForFileSystem( additional_schemes->push_back(content::kChromeUIScheme); } +base::FilePath BrowserClient::GetDefaultDownloadDirectory() { + // ~/Downloads + base::FilePath path; + if (PathService::Get(base::DIR_HOME, &path)) + path = path.Append(FILE_PATH_LITERAL("Downloads")); + + return path; +} + } // namespace brightray diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h index 41b15ea971..6d1944ca02 100644 --- a/brightray/browser/browser_client.h +++ b/brightray/browser/browser_client.h @@ -43,16 +43,13 @@ class BrowserClient : public content::ContentBrowserClient { const content::MainFunctionParams&) OVERRIDE; virtual void ShowDesktopNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id, - bool worker) OVERRIDE; - virtual void CancelDesktopNotification( - int render_process_id, - int render_view_id, - int notification_id) OVERRIDE; + content::RenderFrameHost* render_frame_host, + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) OVERRIDE; virtual content::MediaObserver* GetMediaObserver() OVERRIDE; virtual void GetAdditionalAllowedSchemesForFileSystem( std::vector* additional_schemes) OVERRIDE; + virtual base::FilePath GetDefaultDownloadDirectory() OVERRIDE; BrowserMainParts* browser_main_parts_; scoped_ptr notification_presenter_; diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc index d82f4bc256..9628dc6b38 100644 --- a/brightray/browser/browser_context.cc +++ b/brightray/browser/browser_context.cc @@ -204,4 +204,8 @@ quota::SpecialStoragePolicy* BrowserContext::GetSpecialStoragePolicy() { return nullptr; } +content::BrowserPluginGuestManagerDelegate* BrowserContext::GetGuestManagerDelegate() { + return nullptr; +} + } // namespace brightray diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h index a43d2380da..e59c72ab92 100644 --- a/brightray/browser/browser_context.h +++ b/brightray/browser/browser_context.h @@ -80,6 +80,8 @@ class BrowserContext : public content::BrowserContext { GetDownloadManagerDelegate() OVERRIDE; virtual content::GeolocationPermissionContext* GetGeolocationPermissionContext() OVERRIDE; + virtual content::BrowserPluginGuestManagerDelegate* + GetGuestManagerDelegate() OVERRIDE; virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE; diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc index 0dd21b4f66..f5153a7845 100644 --- a/brightray/browser/browser_main_parts.cc +++ b/brightray/browser/browser_main_parts.cc @@ -9,7 +9,6 @@ #include "net/proxy/proxy_resolver_v8.h" #if defined(USE_AURA) -#include "ui/aura/env.h" #include "ui/gfx/screen.h" #include "ui/views/widget/desktop_aura/desktop_screen.h" #endif @@ -61,6 +60,8 @@ void BrowserMainParts::PreEarlyInitialization() { #if defined(USE_AURA) && defined(USE_X11) views::LinuxUI::SetInstance(BuildGtk2UI()); #endif + + InitProxyResolverV8(); } void BrowserMainParts::ToolkitInitialized() { @@ -97,19 +98,14 @@ void BrowserMainParts::PreMainMessageLoopRun() { void BrowserMainParts::PostMainMessageLoopRun() { browser_context_.reset(); -#if defined(USE_AURA) - aura::Env::DeleteInstance(); -#endif } int BrowserMainParts::PreCreateThreads() { #if defined(USE_AURA) - aura::Env::CreateInstance(); gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); #endif - InitProxyResolverV8(); return 0; } @@ -118,11 +114,7 @@ BrowserContext* BrowserMainParts::CreateBrowserContext() { } void BrowserMainParts::InitProxyResolverV8() { -#if defined(OS_WIN) - net::ProxyResolverV8::CreateIsolate(); -#else - net::ProxyResolverV8::RememberDefaultIsolate(); -#endif + net::ProxyResolverV8::EnsureIsolateCreated(); } } // namespace brightray diff --git a/brightray/browser/inspectable_web_contents.cc b/brightray/browser/inspectable_web_contents.cc index 5090011a20..74aeac6711 100644 --- a/brightray/browser/inspectable_web_contents.cc +++ b/brightray/browser/inspectable_web_contents.cc @@ -2,18 +2,11 @@ #include "browser/inspectable_web_contents_impl.h" -#include "content/public/browser/web_contents_view.h" - namespace brightray { InspectableWebContents* InspectableWebContents::Create( const content::WebContents::CreateParams& create_params) { auto contents = content::WebContents::Create(create_params); -#if defined(OS_MACOSX) - // Work around http://crbug.com/279472. - contents->GetView()->SetAllowOverlappingViews(true); -#endif - return Create(contents); } diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 69eda18494..1449bde576 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -21,7 +21,6 @@ #include "content/public/browser/devtools_client_host.h" #include "content/public/browser/devtools_http_handler.h" #include "content/public/browser/devtools_manager.h" -#include "content/public/browser/web_contents_view.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" @@ -152,7 +151,7 @@ void InspectableWebContentsImpl::CloseDevTools() { if (devtools_web_contents_) { view_->CloseDevTools(); devtools_web_contents_.reset(); - web_contents_->GetView()->Focus(); + web_contents_->Focus(); } } @@ -176,7 +175,7 @@ void InspectableWebContentsImpl::ActivateWindow() { } void InspectableWebContentsImpl::CloseWindow() { - devtools_web_contents()->GetMainFrame()->DispatchBeforeUnload(false); + devtools_web_contents()->DispatchBeforeUnload(false); } void InspectableWebContentsImpl::SetContentsResizingStrategy( @@ -289,7 +288,7 @@ void InspectableWebContentsImpl::DidFinishLoad(int64 frame_id, view_->ShowDevTools(); } -void InspectableWebContentsImpl::WebContentsDestroyed(content::WebContents*) { +void InspectableWebContentsImpl::WebContentsDestroyed() { content::DevToolsManager::GetInstance()->ClientHostClosing( frontend_host_.get()); Observe(nullptr); diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h index dd115cdd1e..73ba40d7e4 100644 --- a/brightray/browser/inspectable_web_contents_impl.h +++ b/brightray/browser/inspectable_web_contents_impl.h @@ -103,7 +103,7 @@ class InspectableWebContentsImpl : const GURL& validated_url, bool is_main_frame, content::RenderViewHost*) OVERRIDE; - virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE; + virtual void WebContentsDestroyed() OVERRIDE; // content::WebContentsDelegate diff --git a/brightray/browser/inspectable_web_contents_view_mac.mm b/brightray/browser/inspectable_web_contents_view_mac.mm index 89eb8ec074..698e6883a4 100644 --- a/brightray/browser/inspectable_web_contents_view_mac.mm +++ b/brightray/browser/inspectable_web_contents_view_mac.mm @@ -5,8 +5,6 @@ #include "browser/inspectable_web_contents.h" #import "browser/mac/bry_inspectable_web_contents_view.h" -#include "content/public/browser/web_contents_view.h" - namespace brightray { InspectableWebContentsView* CreateInspectableContentsView(InspectableWebContentsImpl* inspectable_web_contents) { diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 06a9d0d42d..f734799809 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -3,13 +3,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE-CHROMIUM file. -#include - #include "browser/linux/notification_presenter_linux.h" -#include "base/strings/stringprintf.h" +#include "base/bind.h" +#include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "content/public/browser/render_view_host.h" +#include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/show_desktop_notification_params.h" #include "common/application_info.h" @@ -17,13 +16,7 @@ namespace brightray { namespace { -const char *kRenderProcessIDKey = "RenderProcessID"; -const char *kRenderViewIDKey = "RenderViewID"; -const char *kNotificationIDKey = "NotificationID"; - -void log_and_clear_error(GError *error, const char *context) { - if (!error) return; - +void log_and_clear_error(GError* error, const char* context) { LOG(ERROR) << context << ": domain=" << error->domain << " code=" << error->code @@ -31,38 +24,15 @@ void log_and_clear_error(GError *error, const char *context) { g_error_free(error); } -int GetObjectInt(NotifyNotification *noti, const char *key) { - return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(noti), key)); -} - -void SetObjectInt(NotifyNotification *noti, const char *key, int value) { - g_object_set_data(G_OBJECT(noti), key, GINT_TO_POINTER(value)); -} - - -void NotificationClosedCallback(NotifyNotification *noti, NotificationPresenterLinux *obj) { - int render_process_id = GetObjectInt(noti, kRenderProcessIDKey); - int render_view_id = GetObjectInt(noti, kRenderViewIDKey); - int notification_id = GetObjectInt(noti, kNotificationIDKey); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (host) host->DesktopNotificationPostClose(notification_id, false); - obj->RemoveNotification(noti); -} - -void NotificationViewCallback(NotifyNotification *noti, const char *action, - NotificationPresenterLinux *obj) { - int render_process_id = GetObjectInt(noti, kRenderProcessIDKey); - int render_view_id = GetObjectInt(noti, kRenderViewIDKey); - int notification_id = GetObjectInt(noti, kNotificationIDKey); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (host) host->DesktopNotificationPostClick(notification_id); - obj->RemoveNotification(noti); +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()); @@ -70,79 +40,71 @@ NotificationPresenter* NotificationPresenter::Create() { return new NotificationPresenterLinux; } -NotificationPresenterLinux::NotificationPresenterLinux() : notifications_(nullptr) { } +NotificationPresenterLinux::NotificationPresenterLinux() + : notifications_(nullptr) { +} NotificationPresenterLinux::~NotificationPresenterLinux() { // unref any outstanding notifications, and then free the list. - if (!notifications_) return; - - for (GList *p = notifications_; p != nullptr; p = p->next) { - g_object_unref(G_OBJECT(p->data)); - } - g_list_free(notifications_); + if (notifications_) + g_list_free_full(notifications_, g_object_unref); } void NotificationPresenterLinux::ShowNotification( const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id) { + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) { std::string title = base::UTF16ToUTF8(params.title); std::string body = base::UTF16ToUTF8(params.body); - NotifyNotification *noti = notify_notification_new(title.c_str(), body.c_str(), nullptr); - SetObjectInt(noti, kRenderProcessIDKey, render_process_id); - SetObjectInt(noti, kRenderViewIDKey, render_view_id); - SetObjectInt(noti, kNotificationIDKey, params.notification_id); - g_signal_connect(noti, "closed", - G_CALLBACK(NotificationClosedCallback), this); - notify_notification_add_action(noti, "default", "View", - (NotifyActionCallback)NotificationViewCallback, this, nullptr); + NotifyNotification* notification = notify_notification_new(title.c_str(), body.c_str(), nullptr); - notifications_ = g_list_append(notifications_, noti); + g_object_set_data(G_OBJECT(notification), "delegate", delegate); + g_signal_connect(notification, "closed", G_CALLBACK(OnNotificationClosedThunk), this); + notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, + nullptr); - GError *error = nullptr; - notify_notification_show(noti, &error); - log_and_clear_error(error, "notify_notification_show"); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (!host) + GError* error = nullptr; + notify_notification_show(notification, &error); + if (error) { + log_and_clear_error(error, "notify_notification_show"); + delegate->NotificationError(); return; - - host->DesktopNotificationPostDisplay(params.notification_id); -} - -void NotificationPresenterLinux::CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) { - NotifyNotification *noti = nullptr; - for (GList *p = notifications_; p != nullptr; p = p->next) { - int rpid = GetObjectInt(noti, kRenderProcessIDKey); - int rvid = GetObjectInt(noti, kRenderViewIDKey); - int nid = GetObjectInt(noti, kNotificationIDKey); - if (render_process_id == rpid && render_view_id == rvid && notification_id == nid) { - noti = reinterpret_cast(p->data); - notifications_ = g_list_delete_link(notifications_, p); - break; - } } - if (!noti) - return; - GError *error = nullptr; - notify_notification_close(noti, &error); - log_and_clear_error(error, "notify_notification_close"); - g_object_unref(noti); + notifications_ = g_list_append(notifications_, notification); + delegate->NotificationDisplayed(); - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (!host) - return; - - host->DesktopNotificationPostClose(notification_id, false); + if (cancel_callback) + *cancel_callback = base::Bind( + &NotificationPresenterLinux::CancelNotification, + base::Unretained(this), + notification); } -void NotificationPresenterLinux::RemoveNotification(NotifyNotification *noti) { - notifications_ = g_list_remove(notifications_, noti); - g_object_unref(noti); +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(false); + DeleteNotification(notification); +} + +void NotificationPresenterLinux::DeleteNotification(NotifyNotification* notification) { + notifications_ = g_list_remove(notifications_, notification); + g_object_unref(notification); +} + +void NotificationPresenterLinux::OnNotificationClosed(NotifyNotification* notification) { + GetDelegateFromNotification(notification)->NotificationClosed(false); + DeleteNotification(notification); +} + +void NotificationPresenterLinux::OnNotificationView( + NotifyNotification* notification, char* action) { + 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 dc868917e3..07e628e29a 100644 --- a/brightray/browser/linux/notification_presenter_linux.h +++ b/brightray/browser/linux/notification_presenter_linux.h @@ -7,10 +7,12 @@ #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 { @@ -22,14 +24,18 @@ class NotificationPresenterLinux : public NotificationPresenter { void RemoveNotification(NotifyNotification *notification); private: + // NotificationPresenter: virtual void ShowNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id) OVERRIDE; - virtual void CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) OVERRIDE; + content::DesktopNotificationDelegate* 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 @@ -38,7 +44,7 @@ class NotificationPresenterLinux : public NotificationPresenter { // a map. // Entries in this list count as refs, so removal from this list should // always go with g_object_unref(). - GList *notifications_; + GList* notifications_; }; } // 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 a070d8e405..084389dd92 100644 --- a/brightray/browser/mac/bry_inspectable_web_contents_view.mm +++ b/brightray/browser/mac/bry_inspectable_web_contents_view.mm @@ -4,7 +4,6 @@ #include "browser/inspectable_web_contents_view_mac.h" #include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents_view.h" #import "ui/base/cocoa/underlay_opengl_hosting_window.h" #include "ui/gfx/mac/scoped_ns_disable_screen_updates.h" @@ -22,10 +21,15 @@ using namespace brightray; devtools_docked_ = NO; auto contents = inspectableWebContentsView_->inspectable_web_contents()->GetWebContents(); - auto contentsView = contents->GetView()->GetNativeView(); + contents->SetAllowOverlappingViews(true); + + auto contentsView = contents->GetNativeView(); [contentsView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [self addSubview:contentsView]; + // See https://code.google.com/p/chromium/issues/detail?id=348490. + [self setWantsLayer:YES]; + return self; } @@ -42,7 +46,7 @@ using namespace brightray; return; auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents(); - auto devToolsView = devToolsWebContents->GetView()->GetNativeView(); + auto devToolsView = devToolsWebContents->GetNativeView(); devtools_visible_ = visible; if (devtools_docked_) { @@ -53,7 +57,7 @@ using namespace brightray; [self update]; } else { gfx::ScopedNSDisableScreenUpdates disabler; - devToolsWebContents->GetView()->RemoveOverlayView(); + devToolsWebContents->RemoveOverlayView(); [devToolsView removeFromSuperview]; [self adjustSubviews]; } @@ -79,7 +83,7 @@ using namespace brightray; devtools_docked_ = docked; if (!docked) { auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents(); - auto devToolsView = devToolsWebContents->GetView()->GetNativeView(); + auto devToolsView = devToolsWebContents->GetNativeView(); auto styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask | @@ -119,8 +123,8 @@ using namespace brightray; auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents(); gfx::ScopedNSDisableScreenUpdates disabler; - devToolsWebContents->GetView()->SetOverlayView( - contents->GetView(), + devToolsWebContents->SetOverlayView( + contents, gfx::Point(strategy_.insets().left(), strategy_.insets().top())); [self adjustSubviews]; } diff --git a/brightray/browser/notification_presenter.h b/brightray/browser/notification_presenter.h index db925f5e92..23420fb9cf 100644 --- a/brightray/browser/notification_presenter.h +++ b/brightray/browser/notification_presenter.h @@ -1,7 +1,10 @@ #ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ #define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ +#include "base/callback_forward.h" + namespace content { +class DesktopNotificationDelegate; struct ShowDesktopNotificationHostMsgParams; } @@ -15,12 +18,8 @@ class NotificationPresenter { virtual void ShowNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id) = 0; - virtual void CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) = 0; + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) = 0; }; } // namespace brightray diff --git a/brightray/browser/notification_presenter_mac.h b/brightray/browser/notification_presenter_mac.h index e4656b98f0..9c7a3a3c27 100644 --- a/brightray/browser/notification_presenter_mac.h +++ b/brightray/browser/notification_presenter_mac.h @@ -22,17 +22,27 @@ class NotificationPresenterMac : public NotificationPresenter { virtual void ShowNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id) OVERRIDE; - virtual void CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) OVERRIDE; + content::DesktopNotificationDelegate* 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: - typedef std::map> - NotificationMap; - NotificationMap notification_map_; + 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_; }; diff --git a/brightray/browser/notification_presenter_mac.mm b/brightray/browser/notification_presenter_mac.mm index dc2ad9231f..2bb595ed55 100644 --- a/brightray/browser/notification_presenter_mac.mm +++ b/brightray/browser/notification_presenter_mac.mm @@ -5,146 +5,121 @@ #import "browser/notification_presenter_mac.h" -#import "base/strings/stringprintf.h" -#import "base/strings/sys_string_conversions.h" -#import "content/public/browser/render_view_host.h" -#import "content/public/common/show_desktop_notification_params.h" +#include "base/bind.h" +#include "base/stl_util.h" +#include "base/strings/sys_string_conversions.h" +#include "content/public/browser/desktop_notification_delegate.h" +#include "content/public/common/show_desktop_notification_params.h" #import -@interface BRYUserNotificationCenterDelegate : NSObject +@interface BRYUserNotificationCenterDelegate : NSObject { + @private + brightray::NotificationPresenterMac* presenter_; +} +- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter; @end namespace brightray { namespace { -NSString * const kRenderProcessIDKey = @"RenderProcessID"; -NSString * const kRenderViewIDKey = @"RenderViewID"; -NSString * const kNotificationIDKey = @"NotificationID"; - -struct NotificationID { - NotificationID( - int render_process_id, - int render_view_id, - int notification_id) - : render_process_id(render_process_id), - render_view_id(render_view_id), - notification_id(notification_id) { - } - - NotificationID(NSUserNotification* notification) - : render_process_id([[notification.userInfo objectForKey:kRenderProcessIDKey] intValue]), - render_view_id([[notification.userInfo objectForKey:kRenderViewIDKey] intValue]), - notification_id([[notification.userInfo objectForKey:kNotificationIDKey] intValue]) { - } - - std::string GetID() { - return base::StringPrintf("%d:%d:%d", render_process_id, render_view_id, notification_id); - } - - NSDictionary* GetUserInfo() { - return @{ - kRenderProcessIDKey: @(render_process_id), - kRenderViewIDKey: @(render_view_id), - kNotificationIDKey: @(notification_id), - }; - } - - int render_process_id; - int render_view_id; - int notification_id; -}; - -base::scoped_nsobject CreateUserNotification( - const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id) { - auto notification = [[NSUserNotification alloc] init]; - notification.title = base::SysUTF16ToNSString(params.title); - notification.informativeText = base::SysUTF16ToNSString(params.body); - notification.userInfo = NotificationID(render_process_id, render_view_id, params.notification_id).GetUserInfo(); - - return base::scoped_nsobject(notification); -} - -} +} // namespace NotificationPresenter* NotificationPresenter::Create() { return new NotificationPresenterMac; } NotificationPresenterMac::NotificationPresenterMac() - : delegate_([[BRYUserNotificationCenterDelegate alloc] init]) { + : delegate_([[BRYUserNotificationCenterDelegate alloc] initWithNotificationPresenter:this]) { NSUserNotificationCenter.defaultUserNotificationCenter.delegate = delegate_; } NotificationPresenterMac::~NotificationPresenterMac() { + NSUserNotificationCenter.defaultUserNotificationCenter.delegate = nil; } void NotificationPresenterMac::ShowNotification( const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id) { - auto notification = CreateUserNotification(params, render_process_id, render_view_id); - notification_map_.insert(std::make_pair(NotificationID(notification).GetID(), notification)); + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) { + auto notification = [[NSUserNotification alloc] init]; + notification.title = base::SysUTF16ToNSString(params.title); + notification.informativeText = base::SysUTF16ToNSString(params.body); + + notifications_map_[delegate].reset(notification); [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification]; + + if (cancel_callback) + *cancel_callback = base::Bind( + &NotificationPresenterMac::CancelNotification, + base::Unretained(this), + delegate); } -void NotificationPresenterMac::CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) { - auto found = notification_map_.find(NotificationID(render_process_id, render_view_id, notification_id).GetID()); - if (found == notification_map_.end()) +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)) + notifications_map_.erase(delegate); +} + +void NotificationPresenterMac::CancelNotification(content::DesktopNotificationDelegate* delegate) { + if (!ContainsKey(notifications_map_, delegate)) return; - auto notification = found->second; - - notification_map_.erase(found); - // 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]) - continue; - [center removeDeliveredNotification:deliveredNotification]; - } + for (NSUserNotification* deliveredNotification in center.deliveredNotifications) + if ([notification isEqual:deliveredNotification]) { + [center removeDeliveredNotification:deliveredNotification]; + delegate->NotificationClosed(false); + break; + } - NotificationID ID(notification); - auto host = content::RenderViewHost::FromID(ID.render_process_id, ID.render_view_id); - if (!host) - return; - - host->DesktopNotificationPostClose(ID.notification_id, false); + RemoveNotification(delegate); } -} +} // namespace brightray @implementation BRYUserNotificationCenterDelegate -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification { - brightray::NotificationID ID(notification); +- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter { + self = [super init]; + if (!self) + return nil; - auto host = content::RenderViewHost::FromID(ID.render_process_id, ID.render_view_id); - if (!host) - return; - - host->DesktopNotificationPostDisplay(ID.notification_id); + presenter_ = presenter; + return self; } -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { - brightray::NotificationID ID(notification); - - auto host = content::RenderViewHost::FromID(ID.render_process_id, ID.render_view_id); - if (!host) - return; - - host->DesktopNotificationPostClick(ID.notification_id); +- (void)userNotificationCenter:(NSUserNotificationCenter*)center + didDeliverNotification:(NSUserNotification*)notification { + auto delegate = presenter_->GetDelegateFromNotification(notification); + if (delegate) + delegate->NotificationDisplayed(); } -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { +- (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; } diff --git a/brightray/browser/views/inspectable_web_contents_view_views.cc b/brightray/browser/views/inspectable_web_contents_view_views.cc index 4032ef08ec..e642c48e5b 100644 --- a/brightray/browser/views/inspectable_web_contents_view_views.cc +++ b/brightray/browser/views/inspectable_web_contents_view_views.cc @@ -3,7 +3,6 @@ #include "browser/inspectable_web_contents_impl.h" #include "base/strings/utf_string_conversions.h" -#include "content/public/browser/web_contents_view.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" diff --git a/brightray/vendor/libchromiumcontent b/brightray/vendor/libchromiumcontent index 4b4bcec11a..a88222442d 160000 --- a/brightray/vendor/libchromiumcontent +++ b/brightray/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit 4b4bcec11a02d1c7981562cf0b8a4670c338992b +Subproject commit a88222442d2a85345d9a208c23456956c208571d