OLD | NEW |
---|---|
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 } | |
OLD | NEW |