Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3163)

Unified Diff: chrome/browser/notifications/notification_platform_bridge_mac.mm

Issue 2158463003: Initial client side implementation of the XPC service (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: flag change Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/notifications/notification_platform_bridge_mac.mm
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm
index 08fefce8bcc7e130114c3ca7f3e03986004b5f58..8e05003c2ef4f12c2a96dbc1c3624ed86ee269a7 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -6,8 +6,12 @@
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
+#include "base/mac/scoped_nsobject.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/browser_process.h"
@@ -20,10 +24,14 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
+#import "chrome/browser/ui/cocoa/notifications/notification_delivery.h"
#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
#import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h"
+#include "chrome/common/features.h"
+#include "chrome/grit/generated_resources.h"
#include "components/url_formatter/elide_url.h"
#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h"
+#include "ui/base/l10n/l10n_util_mac.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -71,6 +79,23 @@ void ProfileLoadedCallback(NotificationCommon::Operation operation,
notification_id, action_index);
}
+// Loads the profile and process the Notification response
+void DoProcessNotificationResponse(NotificationCommon::Operation operation,
+ NotificationCommon::Type type,
+ const std::string& profile_id,
+ bool incognito,
+ const std::string& origin,
+ const std::string& notification_id,
+ int32_t button_index) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ ProfileManager* profileManager = g_browser_process->profile_manager();
+ DCHECK(profileManager);
+
+ profileManager->LoadProfile(
+ profile_id, incognito, base::Bind(&ProfileLoadedCallback, operation, type,
+ origin, notification_id, button_index));
+}
+
} // namespace
// static
@@ -86,19 +111,34 @@ NotificationPlatformBridge* NotificationPlatformBridge::Create() {
}
@end
+// Interface to communicate with the Alert XPC service.
+@interface NotificationRemoteDispatcher : NSObject
+
+- (void)dispatchNotification:(NSDictionary*)data;
+
+@end
+
// /////////////////////////////////////////////////////////////////////////////
NotificationPlatformBridgeMac::NotificationPlatformBridgeMac(
NSUserNotificationCenter* notification_center)
: delegate_([NotificationCenterDelegate alloc]),
- notification_center_(notification_center) {
+ notification_center_(notification_center),
+#if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
+ notification_remote_dispatcher_(
+ [[NotificationRemoteDispatcher alloc] init])
+#else
+ notification_remote_dispatcher_(nullptr)
+#endif // ENABLE_XPC_NOTIFICATIONS
+{
[notification_center_ setDelegate:delegate_.get()];
}
NotificationPlatformBridgeMac::~NotificationPlatformBridgeMac() {
[notification_center_ setDelegate:nil];
- // TODO(miguelg) lift this restriction if possible.
+ // TODO(miguelg) remove only alerts shown by the XPC service.
+ // TODO(miguelg) do not remove banners if possible.
[notification_center_ removeAllDeliveredNotifications];
}
@@ -139,6 +179,7 @@ void NotificationPlatformBridgeMac::Display(
// Tag
if (!notification.tag().empty()) {
[builder setTag:base::SysUTF8ToNSString(notification.tag())];
+
// If renotify is needed, delete the notification with the same tag
// from the notification center before displaying this one.
// TODO(miguelg): This will need to work for alerts as well via XPC
@@ -166,8 +207,21 @@ void NotificationPlatformBridgeMac::Display(
[builder setIncognito:incognito];
[builder setNotificationType:[NSNumber numberWithInteger:notification_type]];
+#if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
+ // Send persistent notifications to the XPC service so they
+ // can be displayed as alerts. Chrome itself can only display
+ // banners.
+ if (notification.never_timeout()) {
+ NSDictionary* dict = [builder buildDictionary];
+ [notification_remote_dispatcher_ dispatchNotification:dict];
+ } else {
+ NSUserNotification* toast = [builder buildUserNotification];
+ [notification_center_ deliverNotification:toast];
+ }
+#else
NSUserNotification* toast = [builder buildUserNotification];
[notification_center_ deliverNotification:toast];
+#endif // ENABLE_XPC_NOTIFICATIONS
}
void NotificationPlatformBridgeMac::Close(const std::string& profile_id,
@@ -214,6 +268,39 @@ bool NotificationPlatformBridgeMac::SupportsNotificationCenter() const {
}
// static
+void NotificationPlatformBridgeMac::ProcessNotificationResponse(
+ NSDictionary* response) {
+ if (!NotificationPlatformBridgeMac::VerifyNotificationData(response))
+ return;
+
+ NSNumber* button_index =
+ [response objectForKey:notification_constants::kNotificationButtonIndex];
+ NSNumber* operation =
+ [response objectForKey:notification_constants::kNotificationOperation];
+
+ std::string notification_origin = base::SysNSStringToUTF8(
+ [response objectForKey:notification_constants::kNotificationOrigin]);
+ std::string notification_id = base::SysNSStringToUTF8(
+ [response objectForKey:notification_constants::kNotificationId]);
+ std::string profile_id = base::SysNSStringToUTF8(
+ [response objectForKey:notification_constants::kNotificationProfileId]);
+ NSNumber* is_incognito =
+ [response objectForKey:notification_constants::kNotificationIncognito];
+ NSNumber* notification_type =
+ [response objectForKey:notification_constants::kNotificationType];
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(DoProcessNotificationResponse,
+ static_cast<NotificationCommon::Operation>(
+ operation.unsignedIntValue),
+ static_cast<NotificationCommon::Type>(
+ notification_type.unsignedIntValue),
+ profile_id, [is_incognito boolValue], notification_origin,
+ notification_id, button_index.intValue));
+}
+
+// static
bool NotificationPlatformBridgeMac::VerifyNotificationData(
NSDictionary* response) {
if (![response
@@ -282,44 +369,13 @@ bool NotificationPlatformBridgeMac::VerifyNotificationData(
}
// /////////////////////////////////////////////////////////////////////////////
-
@implementation NotificationCenterDelegate
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
didActivateNotification:(NSUserNotification*)notification {
- NSDictionary* response =
+ NSDictionary* notificationResponse =
[NotificationResponseBuilder buildDictionary:notification];
- if (!NotificationPlatformBridgeMac::VerifyNotificationData(response))
- return;
-
- NSNumber* buttonIndex =
- [response objectForKey:notification_constants::kNotificationButtonIndex];
- NSNumber* operation =
- [response objectForKey:notification_constants::kNotificationOperation];
-
- std::string notificationOrigin = base::SysNSStringToUTF8(
- [response objectForKey:notification_constants::kNotificationOrigin]);
- NSString* notificationId =
- [response objectForKey:notification_constants::kNotificationId];
- std::string persistentNotificationId =
- base::SysNSStringToUTF8(notificationId);
- std::string profileId = base::SysNSStringToUTF8(
- [response objectForKey:notification_constants::kNotificationProfileId]);
- NSNumber* isIncognito =
- [response objectForKey:notification_constants::kNotificationIncognito];
- NSNumber* notificationType =
- [response objectForKey:notification_constants::kNotificationType];
-
- ProfileManager* profileManager = g_browser_process->profile_manager();
- DCHECK(profileManager);
-
- profileManager->LoadProfile(
- profileId, [isIncognito boolValue],
- base::Bind(
- &ProfileLoadedCallback, static_cast<NotificationCommon::Operation>(
- operation.unsignedIntValue),
- static_cast<NotificationCommon::Type>(
- notificationType.unsignedIntValue),
- notificationOrigin, persistentNotificationId, buttonIndex.intValue));
+ NotificationPlatformBridgeMac::ProcessNotificationResponse(
+ notificationResponse);
}
- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
@@ -329,3 +385,52 @@ bool NotificationPlatformBridgeMac::VerifyNotificationData(
}
@end
+
+@implementation NotificationRemoteDispatcher {
+ // The connection to the XPC server in charge of delivering alerts.
+ base::scoped_nsobject<NSXPCConnection> xpcConnection_;
+}
+
+- (instancetype)init {
+ if ((self = [super init])) {
+ xpcConnection_.reset([[NSXPCConnection alloc]
+ initWithServiceName:
+ [NSString
+ stringWithFormat:notification_constants::kAlertXPCServiceName,
+ [base::mac::OuterBundle() bundleIdentifier]]]);
+ xpcConnection_.get().remoteObjectInterface =
+ [NSXPCInterface interfaceWithProtocol:@protocol(NotificationDelivery)];
+
+ xpcConnection_.get().interruptionHandler = ^{
+ LOG(WARNING) << "connection interrupted: interruptionHandler: ";
+ // TODO(miguelg): perhaps add some UMA here.
+ // We will be getting this handler both when the XPC server crashes or
+ // when it decides to close the connection.
+ };
+ xpcConnection_.get().invalidationHandler = ^{
+ LOG(WARNING) << "connection invalidationHandler received";
+ // This means that the connection should be recreated if it needs
+ // to be used again. It should not really happen.
+ DCHECK(false) << "XPC Connection invalidated";
+ };
+
+ xpcConnection_.get().exportedInterface =
+ [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)];
+ xpcConnection_.get().exportedObject = self;
+ [xpcConnection_ resume];
+ }
+
+ return self;
+}
+
+- (void)dispatchNotification:(NSDictionary*)data {
+ [[xpcConnection_ remoteObjectProxy] deliverNotification:data];
+}
+
+// NotificationReply implementation
+- (void)notificationClick:(NSDictionary*)notificationResponseData {
+ NotificationPlatformBridgeMac::ProcessNotificationResponse(
+ notificationResponseData);
+}
+
+@end
« no previous file with comments | « chrome/browser/notifications/notification_platform_bridge_mac.h ('k') | chrome/browser/ui/cocoa/notifications/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698