Chromium Code Reviews| 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 |