diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index 63fb78257bf3..2d02e826dda4 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -48,4 +48,11 @@ void BrowserClient::ShowDesktopNotification( notification_presenter()->ShowNotification(params, render_process_id, render_view_id); } +void BrowserClient::CancelDesktopNotification( + int render_process_id, + int render_view_id, + int notification_id) { + notification_presenter()->CancelNotification(render_process_id, render_view_id, notification_id); +} + } diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h index 38983dd47fb8..33fea3dea320 100644 --- a/brightray/browser/browser_client.h +++ b/brightray/browser/browser_client.h @@ -35,6 +35,10 @@ private: 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; BrowserMainParts* browser_main_parts_; scoped_ptr notification_presenter_; diff --git a/brightray/browser/notification_presenter.h b/brightray/browser/notification_presenter.h index f2b6e7ea44cf..a106edab208d 100644 --- a/brightray/browser/notification_presenter.h +++ b/brightray/browser/notification_presenter.h @@ -17,6 +17,10 @@ class NotificationPresenter { 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; }; } diff --git a/brightray/browser/notification_presenter_mac.h b/brightray/browser/notification_presenter_mac.h index 77da8cf0766c..5cd2c87e40a4 100644 --- a/brightray/browser/notification_presenter_mac.h +++ b/brightray/browser/notification_presenter_mac.h @@ -1,9 +1,15 @@ +// 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_ #import "browser/notification_presenter.h" #import "base/memory/scoped_nsobject.h" +#import @class BRYUserNotificationCenterDelegate; @@ -18,8 +24,13 @@ class NotificationPresenterMac : public NotificationPresenter { 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; private: + std::map> notification_map_; scoped_nsobject delegate_; }; diff --git a/brightray/browser/notification_presenter_mac.mm b/brightray/browser/notification_presenter_mac.mm index 49a33561459b..02ca2927fe38 100644 --- a/brightray/browser/notification_presenter_mac.mm +++ b/brightray/browser/notification_presenter_mac.mm @@ -1,5 +1,11 @@ +// 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" +#import "base/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" @@ -19,12 +25,12 @@ NSString * const kNotificationIDKey = @"NotificationID"; struct NotificationID { NotificationID( - const content::ShowDesktopNotificationHostMsgParams& params, int render_process_id, - int render_view_id) + int render_view_id, + int notification_id) : render_process_id(render_process_id), render_view_id(render_view_id), - notification_id(params.notification_id) { + notification_id(notification_id) { } NotificationID(NSUserNotification* notification) @@ -33,6 +39,10 @@ struct NotificationID { 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), @@ -53,7 +63,7 @@ scoped_nsobject CreateUserNotification( auto notification = [[NSUserNotification alloc] init]; notification.title = base::SysUTF16ToNSString(params.title); notification.informativeText = base::SysUTF16ToNSString(params.body); - notification.userInfo = NotificationID(params, render_process_id, render_view_id).GetUserInfo(); + notification.userInfo = NotificationID(render_process_id, render_view_id, params.notification_id).GetUserInfo(); return scoped_nsobject(notification); } @@ -77,9 +87,39 @@ void NotificationPresenterMac::ShowNotification( 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)); [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification]; } +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()) + 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 center = NSUserNotificationCenter.defaultUserNotificationCenter; + for (NSUserNotification* deliveredNotification in center.deliveredNotifications) { + if (![notification isEqual:deliveredNotification]) + continue; + [center removeDeliveredNotification:deliveredNotification]; + } + + 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); +} + } @implementation BRYUserNotificationCenterDelegate