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> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/strings/nullable_string16.h" | 12 #include "base/strings/nullable_string16.h" |
13 #include "base/strings/string_number_conversions.h" | |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "base/task_scheduler/post_task.h" | 15 #include "base/task_scheduler/post_task.h" |
15 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
16 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
17 #include "chrome/browser/notifications/native_notification_display_service.h" | 18 #include "chrome/browser/notifications/native_notification_display_service.h" |
18 #include "chrome/browser/notifications/notification.h" | 19 #include "chrome/browser/notifications/notification.h" |
19 #include "chrome/browser/notifications/notification_display_service_factory.h" | 20 #include "chrome/browser/notifications/notification_display_service_factory.h" |
20 #include "chrome/browser/profiles/profile_manager.h" | 21 #include "chrome/browser/profiles/profile_manager.h" |
21 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
22 | 23 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 NotificationCommon::Type notification_type; | 169 NotificationCommon::Type notification_type; |
169 const std::string notification_id; | 170 const std::string notification_id; |
170 const std::string profile_id; | 171 const std::string profile_id; |
171 const bool is_incognito; | 172 const bool is_incognito; |
172 | 173 |
173 // A copy of the origin_url from the underlying | 174 // A copy of the origin_url from the underlying |
174 // message_center::Notification. Used to pass back to | 175 // message_center::Notification. Used to pass back to |
175 // NativeNotificationDisplayService. | 176 // NativeNotificationDisplayService. |
176 const GURL origin_url; | 177 const GURL origin_url; |
177 | 178 |
179 // Used to keep track of the IDs of the buttons currently displayed | |
180 // on this notification. The valid range of action IDs is | |
181 // [action_start, action_end). | |
182 size_t action_start = 0; | |
183 size_t action_end = 0; | |
184 | |
178 // Temporary resource files associated with the notification that | 185 // Temporary resource files associated with the notification that |
179 // should be cleaned up when the notification is closed or on | 186 // should be cleaned up when the notification is closed or on |
180 // shutdown. | 187 // shutdown. |
181 std::vector<base::FilePath> resource_files; | 188 std::vector<base::FilePath> resource_files; |
182 | 189 |
183 // Used to cancel the initial "Notify" message so we don't call | 190 // Used to cancel the initial "Notify" message so we don't call |
184 // NotificationPlatformBridgeLinux::NotifyCompleteInternal() with a | 191 // NotificationPlatformBridgeLinux::NotifyCompleteInternal() with a |
185 // destroyed Notification. | 192 // destroyed Notification. |
186 ScopedGObject<GCancellable> cancellable; | 193 ScopedGObject<GCancellable> cancellable; |
187 | 194 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 | 350 |
344 if (data->dbus_id) | 351 if (data->dbus_id) |
345 DCHECK(!data->cancellable); | 352 DCHECK(!data->cancellable); |
346 | 353 |
347 data->ResetResourceFiles(); | 354 data->ResetResourceFiles(); |
348 | 355 |
349 GVariantBuilder actions_builder; | 356 GVariantBuilder actions_builder; |
350 // Even-indexed elements in this array are action IDs passed back to | 357 // Even-indexed elements in this array are action IDs passed back to |
351 // us in GSignalReceiver. Odd-indexed ones contain the button text. | 358 // us in GSignalReceiver. Odd-indexed ones contain the button text. |
352 g_variant_builder_init(&actions_builder, G_VARIANT_TYPE("as")); | 359 g_variant_builder_init(&actions_builder, G_VARIANT_TYPE("as")); |
360 data->action_start = data->action_end; | |
361 for (const auto& button_info : notification.buttons()) { | |
362 // FDO notification buttons can contain either an icon or a label, | |
363 // but not both, and the type of all buttons must be the same (all | |
364 // labels or all icons), so always use labels. | |
365 std::string id = base::SizeTToString(data->action_end++); | |
366 const std::string label = base::UTF16ToUTF8(button_info.title); | |
367 AddActionToNotification(&actions_builder, id.c_str(), label.c_str()); | |
368 } | |
353 if (notification.clickable()) { | 369 if (notification.clickable()) { |
354 // Special case: the pair ("default", "") will not add a button, | 370 // Special case: the pair ("default", "") will not add a button, |
355 // but instead makes the entire notification clickable. | 371 // but instead makes the entire notification clickable. |
356 AddActionToNotification(&actions_builder, "default", ""); | 372 AddActionToNotification(&actions_builder, "default", ""); |
357 } | 373 } |
358 // Always add a settings button. | 374 // Always add a settings button. |
359 AddActionToNotification(&actions_builder, "settings", "Settings"); | 375 AddActionToNotification(&actions_builder, "settings", "Settings"); |
360 | 376 |
361 GVariantBuilder hints_builder; | 377 GVariantBuilder hints_builder; |
362 g_variant_builder_init(&hints_builder, G_VARIANT_TYPE("a{sv}")); | 378 g_variant_builder_init(&hints_builder, G_VARIANT_TYPE("a{sv}")); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 ForwardNotificationOperation(dbus_id, NotificationCommon::CLOSE, -1); | 466 ForwardNotificationOperation(dbus_id, NotificationCommon::CLOSE, -1); |
451 // std::unordered_map::erase(nullptr) is safe here. | 467 // std::unordered_map::erase(nullptr) is safe here. |
452 notifications_.erase(FindNotificationData(dbus_id)); | 468 notifications_.erase(FindNotificationData(dbus_id)); |
453 } else if (strcmp("ActionInvoked", sender_signal) == 0 && | 469 } else if (strcmp("ActionInvoked", sender_signal) == 0 && |
454 g_variant_is_of_type(parameters, G_VARIANT_TYPE("(us)"))) { | 470 g_variant_is_of_type(parameters, G_VARIANT_TYPE("(us)"))) { |
455 const gchar* action = nullptr; | 471 const gchar* action = nullptr; |
456 g_variant_get(parameters, "(u&s)", &dbus_id, &action); | 472 g_variant_get(parameters, "(u&s)", &dbus_id, &action); |
457 DCHECK(action); | 473 DCHECK(action); |
458 | 474 |
459 if (strcmp(action, "default") == 0) { | 475 if (strcmp(action, "default") == 0) { |
460 ForwardNotificationOperation(dbus_id, NotificationCommon::CLICK, 0); | 476 ForwardNotificationOperation(dbus_id, NotificationCommon::CLICK, -1); |
461 } else if (strcmp(action, "settings") == 0) { | 477 } else if (strcmp(action, "settings") == 0) { |
462 ForwardNotificationOperation(dbus_id, NotificationCommon::SETTINGS, -1); | 478 ForwardNotificationOperation(dbus_id, NotificationCommon::SETTINGS, -1); |
463 } else { | 479 } else { |
464 NOTIMPLEMENTED() << "No custom buttons just yet!"; | 480 size_t id; |
481 if (!base::StringToSizeT(action, &id)) | |
482 return; | |
483 NotificationData* data = FindNotificationData(dbus_id); | |
484 if (!data) | |
485 return; | |
486 size_t n_buttons = data->action_end - data->action_start; | |
487 size_t id_zero_based = id - data->action_start; | |
Lei Zhang
2017/04/18 00:05:57
Just as a FYI, if |id| is 0, this actually underfl
Tom (Use chromium acct)
2017/04/18 00:11:48
Ack.
I tried to design this with overflows in min
| |
488 if (id_zero_based >= n_buttons) | |
489 return; | |
490 ForwardNotificationOperation(dbus_id, NotificationCommon::CLICK, | |
491 id_zero_based); | |
465 } | 492 } |
466 } | 493 } |
467 } | 494 } |
OLD | NEW |