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

Side by Side Diff: chrome/browser/notifications/notification_platform_bridge_linux.cc

Issue 2803873003: Linux native notifications: Support closing and updating notifications (Closed)
Patch Set: Address thestig@'s comments Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/notifications/notification_platform_bridge_linux.h" 5 #include "chrome/browser/notifications/notification_platform_bridge_linux.h"
6 6
7 #include <algorithm>
8
7 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
8 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/notifications/notification.h" 11 #include "chrome/browser/notifications/notification.h"
10 12
11 namespace { 13 namespace {
12 14
13 const char kFreedesktopNotificationsName[] = "org.freedesktop.Notifications"; 15 const char kFreedesktopNotificationsName[] = "org.freedesktop.Notifications";
14 const char kFreedesktopNotificationsPath[] = "/org/freedesktop/Notifications"; 16 const char kFreedesktopNotificationsPath[] = "/org/freedesktop/Notifications";
15 17
16 } // namespace 18 } // namespace
17 19
18 // static 20 // static
19 NotificationPlatformBridge* NotificationPlatformBridge::Create() { 21 NotificationPlatformBridge* NotificationPlatformBridge::Create() {
20 GDBusProxy* notification_proxy = g_dbus_proxy_new_for_bus_sync( 22 GDBusProxy* notification_proxy = g_dbus_proxy_new_for_bus_sync(
21 G_BUS_TYPE_SESSION, 23 G_BUS_TYPE_SESSION,
22 static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | 24 static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
23 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | 25 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
24 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START), 26 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
25 nullptr, kFreedesktopNotificationsName, kFreedesktopNotificationsPath, 27 nullptr, kFreedesktopNotificationsName, kFreedesktopNotificationsPath,
26 kFreedesktopNotificationsName, nullptr, nullptr); 28 kFreedesktopNotificationsName, nullptr, nullptr);
27 if (!notification_proxy) 29 if (!notification_proxy)
28 return nullptr; 30 return nullptr;
29 return new NotificationPlatformBridgeLinux(notification_proxy); 31 return new NotificationPlatformBridgeLinux(notification_proxy);
30 } 32 }
31 33
34 NotificationPlatformBridgeLinux::NotificationData::NotificationData(
35 const std::string& notification_id,
36 const std::string& profile_id,
37 bool is_incognito,
38 NotificationPlatformBridgeLinux* platform_bridge)
39 : notification_id(notification_id),
40 profile_id(profile_id),
41 is_incognito(is_incognito),
42 platform_bridge(platform_bridge) {}
43
44 NotificationPlatformBridgeLinux::NotificationData::~NotificationData() {
45 if (cancellable)
46 g_cancellable_cancel(cancellable);
47 }
48
49 void OnNotifyComplete(GObject* source_object,
Peter Beverloo 2017/04/06 17:56:57 nit: maybe move to the anonymous namespace around
Tom (Use chromium acct) 2017/04/06 18:25:38 Done.
50 GAsyncResult* result,
51 gpointer user_data) {
52 GDBusProxy* proxy = G_DBUS_PROXY(source_object);
53 GVariant* value = g_dbus_proxy_call_finish(proxy, result, nullptr);
54 if (!value) {
55 // The message might have been cancelled, in which case
56 // |user_data| points to a destroyed NotificationData.
57 return;
58 }
59 auto* data =
60 reinterpret_cast<NotificationPlatformBridgeLinux::NotificationData*>(
61 user_data);
Peter Beverloo 2017/04/06 17:56:57 We're putting quite some trust here in the data th
Tom (Use chromium acct) 2017/04/06 18:25:37 Done.
62 data->platform_bridge->OnNotifyComplete(data, value);
63 }
64
32 NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux( 65 NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux(
33 GDBusProxy* notification_proxy) 66 GDBusProxy* notification_proxy)
34 : notification_proxy_(notification_proxy) {} 67 : notification_proxy_(notification_proxy) {}
35 68
36 NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() { 69 NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() {}
37 g_object_unref(notification_proxy_);
38 }
39 70
40 void NotificationPlatformBridgeLinux::Display( 71 void NotificationPlatformBridgeLinux::Display(
41 NotificationCommon::Type notification_type, 72 NotificationCommon::Type notification_type,
42 const std::string& notification_id, 73 const std::string& notification_id,
43 const std::string& profile_id, 74 const std::string& profile_id,
44 bool is_incognito, 75 bool is_incognito,
45 const Notification& notification) { 76 const Notification& notification) {
46 // TODO(thomasanderson): Add a complete implementation. 77 NotificationData* data = FindNotificationData(notification_id, profile_id);
47 g_dbus_proxy_call( 78 if (data) {
48 notification_proxy_, "Notify", 79 // Update an existing notification.
49 g_variant_new("(susssasa{sv}i)", "", 0, "", 80 if (data->dbus_id) {
50 base::UTF16ToUTF8(notification.title()).c_str(), 81 NotifyNow(data->dbus_id, notification_type, notification, nullptr,
51 base::UTF16ToUTF8(notification.message()).c_str(), nullptr, 82 nullptr, nullptr);
52 nullptr, -1), 83 } else {
53 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr, nullptr); 84 data->update_type = notification_type;
85 data->update_data.reset(new Notification(notification));
Peter Beverloo 2017/04/06 17:56:57 nit (from base/memory/ptr_util.h): data->update_d
Tom (Use chromium acct) 2017/04/06 18:25:37 Done.
86 }
87 } else {
88 // Send the notification for the first time.
89 data =
90 new NotificationData(notification_id, profile_id, is_incognito, this);
91 data->cancellable.reset(g_cancellable_new());
92 notifications_.emplace(data, std::unique_ptr<NotificationData>(data));
Peter Beverloo 2017/04/06 17:56:57 base::WrapUnique(data)
Tom (Use chromium acct) 2017/04/06 18:25:37 Done.
93 NotifyNow(0, notification_type, notification, data->cancellable,
94 ::OnNotifyComplete, data);
Peter Beverloo 2017/04/06 17:56:57 It's rather confusing that we have two OnNotifyCom
Tom (Use chromium acct) 2017/04/06 18:25:37 Done.
95 }
54 } 96 }
55 97
56 void NotificationPlatformBridgeLinux::Close( 98 void NotificationPlatformBridgeLinux::Close(
57 const std::string& profile_id, 99 const std::string& profile_id,
58 const std::string& notification_id) { 100 const std::string& notification_id) {
59 NOTIMPLEMENTED(); 101 NotificationData* data = FindNotificationData(notification_id, profile_id);
102 if (!data)
103 return;
104 if (data->dbus_id) {
105 CloseNow(data->dbus_id);
106 notifications_.erase(data);
107 } else {
108 data->should_close = true;
109 }
60 } 110 }
61 111
62 void NotificationPlatformBridgeLinux::GetDisplayed( 112 void NotificationPlatformBridgeLinux::GetDisplayed(
63 const std::string& profile_id, 113 const std::string& profile_id,
64 bool incognito, 114 bool incognito,
65 const DisplayedNotificationsCallback& callback) const { 115 const DisplayedNotificationsCallback& callback) const {
66 callback.Run(base::MakeUnique<std::set<std::string>>(), false); 116 callback.Run(base::MakeUnique<std::set<std::string>>(), false);
67 } 117 }
118
119 void NotificationPlatformBridgeLinux::OnNotifyComplete(NotificationData* data,
120 GVariant* value) {
121 data->cancellable.reset(nullptr);
Peter Beverloo 2017/04/06 17:56:57 nit: no need for `nullptr`
Tom (Use chromium acct) 2017/04/06 18:25:38 Done.
Lei Zhang 2017/04/06 19:59:33 Well, only with the newest ScopedGObject.
122 if (value && g_variant_is_of_type(value, G_VARIANT_TYPE("(u)")))
123 g_variant_get(value, "(u)", &data->dbus_id);
124
125 if (!data->dbus_id) {
126 // There was some sort of error with creating the notification.
127 notifications_.erase(data);
128 } else if (data->should_close) {
129 CloseNow(data->dbus_id);
130 notifications_.erase(data);
131 } else if (data->update_data) {
132 NotifyNow(data->dbus_id, data->update_type, *data->update_data, nullptr,
133 nullptr, nullptr);
134 data->update_data.reset();
135 }
136 }
137
138 void NotificationPlatformBridgeLinux::NotifyNow(
139 uint32_t dbus_id,
140 NotificationCommon::Type notification_type,
141 const Notification& notification,
142 GCancellable* cancellable,
143 GAsyncReadyCallback callback,
144 gpointer user_data) {
145 // TODO(thomasanderson): Add a complete implementation.
146 GVariant* parameters = g_variant_new(
147 "(susssasa{sv}i)", "", dbus_id, "",
148 base::UTF16ToUTF8(notification.title()).c_str(),
149 base::UTF16ToUTF8(notification.message()).c_str(), nullptr, nullptr, -1);
Peter Beverloo 2017/04/06 17:56:57 I know that you're just moving this, but are these
Tom (Use chromium acct) 2017/04/06 18:25:37 Done.
150 g_dbus_proxy_call(notification_proxy_, "Notify", parameters,
151 G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback,
152 user_data);
153 }
154
155 void NotificationPlatformBridgeLinux::CloseNow(uint32_t dbus_id) {
156 g_dbus_proxy_call(notification_proxy_, "CloseNotification",
157 g_variant_new("(u)", dbus_id), G_DBUS_CALL_FLAGS_NONE, -1,
158 nullptr, nullptr, nullptr);
159 }
160
161 NotificationPlatformBridgeLinux::NotificationData*
162 NotificationPlatformBridgeLinux::FindNotificationData(
163 const std::string& notification_id,
164 const std::string& profile_id) {
165 auto it = std::find_if(
166 notifications_.begin(), notifications_.end(),
167 [&](std::pair<NotificationData* const, std::unique_ptr<NotificationData>>&
168 data) {
169 return data.first->notification_id == notification_id &&
170 data.first->profile_id == profile_id;
171
172 });
Peter Beverloo 2017/04/06 17:56:57 nit: while I'm a fan of STL, we're tied to a looku
Tom (Use chromium acct) 2017/04/06 18:25:38 Done.
173 if (it == notifications_.end())
174 return nullptr;
175 return it->first;
176 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698