| 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 #include <memory> | 8 #include <memory> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 // while we still can. | 371 // while we still can. |
| 372 CleanUp(); | 372 CleanUp(); |
| 373 } | 373 } |
| 374 | 374 |
| 375 void SetBodyImagesSupported(bool body_images_supported) { | 375 void SetBodyImagesSupported(bool body_images_supported) { |
| 376 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 376 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 377 body_images_supported_ = body_images_supported; | 377 body_images_supported_ = body_images_supported; |
| 378 } | 378 } |
| 379 | 379 |
| 380 void PostTaskToUiThread(base::OnceClosure closure) const { | 380 void PostTaskToUiThread(base::OnceClosure closure) const { |
| 381 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 381 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 382 bool success = content::BrowserThread::PostTask( | 382 bool success = content::BrowserThread::PostTask( |
| 383 content::BrowserThread::UI, FROM_HERE, std::move(closure)); | 383 content::BrowserThread::UI, FROM_HERE, std::move(closure)); |
| 384 DCHECK(success); | 384 DCHECK(success); |
| 385 } | 385 } |
| 386 | 386 |
| 387 void PostTaskToTaskRunnerThread(base::OnceClosure closure) const { | 387 void PostTaskToTaskRunnerThread(base::OnceClosure closure) const { |
| 388 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 388 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 389 DCHECK(task_runner_); | 389 DCHECK(task_runner_); |
| 390 bool success = task_runner_->PostTask(FROM_HERE, std::move(closure)); | 390 bool success = task_runner_->PostTask(FROM_HERE, std::move(closure)); |
| 391 DCHECK(success); | 391 DCHECK(success); |
| 392 } | 392 } |
| 393 | 393 |
| 394 // Sets up the D-Bus connection. | 394 // Sets up the D-Bus connection. |
| 395 void InitOnTaskRunner() { | 395 void InitOnTaskRunner() { |
| 396 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 396 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 397 // |bus_| may be non-null in unit testing where a fake bus is used. | 397 // |bus_| may be non-null in unit testing where a fake bus is used. |
| 398 if (!bus_) { | 398 if (!bus_) { |
| 399 dbus::Bus::Options bus_options; | 399 dbus::Bus::Options bus_options; |
| 400 bus_options.bus_type = dbus::Bus::SESSION; | 400 bus_options.bus_type = dbus::Bus::SESSION; |
| 401 bus_options.connection_type = dbus::Bus::PRIVATE; | 401 bus_options.connection_type = dbus::Bus::PRIVATE; |
| 402 bus_options.dbus_task_runner = task_runner_; | 402 bus_options.dbus_task_runner = task_runner_; |
| 403 bus_ = make_scoped_refptr(new dbus::Bus(bus_options)); | 403 bus_ = make_scoped_refptr(new dbus::Bus(bus_options)); |
| 404 } | 404 } |
| 405 | 405 |
| 406 notification_proxy_ = | 406 notification_proxy_ = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 this)); | 465 this)); |
| 466 notification_proxy_->ConnectToSignal( | 466 notification_proxy_->ConnectToSignal( |
| 467 kFreedesktopNotificationsName, kSignalNotificationClosed, | 467 kFreedesktopNotificationsName, kSignalNotificationClosed, |
| 468 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnNotificationClosed, | 468 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnNotificationClosed, |
| 469 this), | 469 this), |
| 470 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnSignalConnected, | 470 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnSignalConnected, |
| 471 this)); | 471 this)); |
| 472 } | 472 } |
| 473 | 473 |
| 474 void CleanUpOnTaskRunner() { | 474 void CleanUpOnTaskRunner() { |
| 475 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 475 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 476 if (bus_) | 476 if (bus_) |
| 477 bus_->ShutdownAndBlock(); | 477 bus_->ShutdownAndBlock(); |
| 478 bus_ = nullptr; | 478 bus_ = nullptr; |
| 479 notification_proxy_ = nullptr; | 479 notification_proxy_ = nullptr; |
| 480 notifications_.clear(); | 480 notifications_.clear(); |
| 481 } | 481 } |
| 482 | 482 |
| 483 // Makes the "Notify" call to D-Bus. | 483 // Makes the "Notify" call to D-Bus. |
| 484 void DisplayOnTaskRunner(NotificationCommon::Type notification_type, | 484 void DisplayOnTaskRunner(NotificationCommon::Type notification_type, |
| 485 const std::string& notification_id, | 485 const std::string& notification_id, |
| 486 const std::string& profile_id, | 486 const std::string& profile_id, |
| 487 bool is_incognito, | 487 bool is_incognito, |
| 488 std::unique_ptr<Notification> notification) { | 488 std::unique_ptr<Notification> notification) { |
| 489 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 489 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 490 NotificationData* data = | 490 NotificationData* data = |
| 491 FindNotificationData(notification_id, profile_id, is_incognito); | 491 FindNotificationData(notification_id, profile_id, is_incognito); |
| 492 if (data) { | 492 if (data) { |
| 493 // Update an existing notification. | 493 // Update an existing notification. |
| 494 data->notification_type = notification_type; | 494 data->notification_type = notification_type; |
| 495 data->resource_files.clear(); | 495 data->resource_files.clear(); |
| 496 } else { | 496 } else { |
| 497 // Send the notification for the first time. | 497 // Send the notification for the first time. |
| 498 data = | 498 data = |
| 499 new NotificationData(notification_type, notification_id, profile_id, | 499 new NotificationData(notification_type, notification_id, profile_id, |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 } | 636 } |
| 637 if (!data->dbus_id) { | 637 if (!data->dbus_id) { |
| 638 // There was some sort of error with creating the notification. | 638 // There was some sort of error with creating the notification. |
| 639 notifications_.erase(data); | 639 notifications_.erase(data); |
| 640 } | 640 } |
| 641 } | 641 } |
| 642 | 642 |
| 643 // Makes the "CloseNotification" call to D-Bus. | 643 // Makes the "CloseNotification" call to D-Bus. |
| 644 void CloseOnTaskRunner(const std::string& profile_id, | 644 void CloseOnTaskRunner(const std::string& profile_id, |
| 645 const std::string& notification_id) { | 645 const std::string& notification_id) { |
| 646 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 646 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 647 std::vector<NotificationData*> to_erase; | 647 std::vector<NotificationData*> to_erase; |
| 648 for (const auto& pair : notifications_) { | 648 for (const auto& pair : notifications_) { |
| 649 NotificationData* data = pair.first; | 649 NotificationData* data = pair.first; |
| 650 if (data->notification_id == notification_id && | 650 if (data->notification_id == notification_id && |
| 651 data->profile_id == profile_id) { | 651 data->profile_id == profile_id) { |
| 652 dbus::MethodCall method_call(kFreedesktopNotificationsName, | 652 dbus::MethodCall method_call(kFreedesktopNotificationsName, |
| 653 kMethodCloseNotification); | 653 kMethodCloseNotification); |
| 654 dbus::MessageWriter writer(&method_call); | 654 dbus::MessageWriter writer(&method_call); |
| 655 writer.AppendUint32(data->dbus_id); | 655 writer.AppendUint32(data->dbus_id); |
| 656 notification_proxy_->CallMethodAndBlock( | 656 notification_proxy_->CallMethodAndBlock( |
| 657 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); | 657 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); |
| 658 to_erase.push_back(data); | 658 to_erase.push_back(data); |
| 659 } | 659 } |
| 660 } | 660 } |
| 661 for (NotificationData* data : to_erase) | 661 for (NotificationData* data : to_erase) |
| 662 notifications_.erase(data); | 662 notifications_.erase(data); |
| 663 } | 663 } |
| 664 | 664 |
| 665 void GetDisplayedOnTaskRunner( | 665 void GetDisplayedOnTaskRunner( |
| 666 const std::string& profile_id, | 666 const std::string& profile_id, |
| 667 bool incognito, | 667 bool incognito, |
| 668 const GetDisplayedNotificationsCallback& callback) const { | 668 const GetDisplayedNotificationsCallback& callback) const { |
| 669 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 669 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 670 auto displayed = base::MakeUnique<std::set<std::string>>(); | 670 auto displayed = base::MakeUnique<std::set<std::string>>(); |
| 671 for (const auto& pair : notifications_) { | 671 for (const auto& pair : notifications_) { |
| 672 NotificationData* data = pair.first; | 672 NotificationData* data = pair.first; |
| 673 if (data->profile_id == profile_id && data->is_incognito == incognito) | 673 if (data->profile_id == profile_id && data->is_incognito == incognito) |
| 674 displayed->insert(data->notification_id); | 674 displayed->insert(data->notification_id); |
| 675 } | 675 } |
| 676 PostTaskToUiThread(base::BindOnce(callback, std::move(displayed), true)); | 676 PostTaskToUiThread(base::BindOnce(callback, std::move(displayed), true)); |
| 677 } | 677 } |
| 678 | 678 |
| 679 NotificationData* FindNotificationData(const std::string& notification_id, | 679 NotificationData* FindNotificationData(const std::string& notification_id, |
| 680 const std::string& profile_id, | 680 const std::string& profile_id, |
| 681 bool is_incognito) { | 681 bool is_incognito) { |
| 682 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 682 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 683 for (const auto& pair : notifications_) { | 683 for (const auto& pair : notifications_) { |
| 684 NotificationData* data = pair.first; | 684 NotificationData* data = pair.first; |
| 685 if (data->notification_id == notification_id && | 685 if (data->notification_id == notification_id && |
| 686 data->profile_id == profile_id && | 686 data->profile_id == profile_id && |
| 687 data->is_incognito == is_incognito) { | 687 data->is_incognito == is_incognito) { |
| 688 return data; | 688 return data; |
| 689 } | 689 } |
| 690 } | 690 } |
| 691 | 691 |
| 692 return nullptr; | 692 return nullptr; |
| 693 } | 693 } |
| 694 | 694 |
| 695 NotificationData* FindNotificationDataWithDBusId(uint32_t dbus_id) { | 695 NotificationData* FindNotificationDataWithDBusId(uint32_t dbus_id) { |
| 696 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 696 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 697 DCHECK(dbus_id); | 697 DCHECK(dbus_id); |
| 698 for (const auto& pair : notifications_) { | 698 for (const auto& pair : notifications_) { |
| 699 NotificationData* data = pair.first; | 699 NotificationData* data = pair.first; |
| 700 if (data->dbus_id == dbus_id) | 700 if (data->dbus_id == dbus_id) |
| 701 return data; | 701 return data; |
| 702 } | 702 } |
| 703 | 703 |
| 704 return nullptr; | 704 return nullptr; |
| 705 } | 705 } |
| 706 | 706 |
| 707 void ForwardNotificationOperation(NotificationData* data, | 707 void ForwardNotificationOperation(NotificationData* data, |
| 708 NotificationCommon::Operation operation, | 708 NotificationCommon::Operation operation, |
| 709 int action_index) { | 709 int action_index) { |
| 710 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 710 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 711 PostTaskToUiThread(base::BindOnce( | 711 PostTaskToUiThread(base::BindOnce( |
| 712 ForwardNotificationOperationOnUiThread, operation, | 712 ForwardNotificationOperationOnUiThread, operation, |
| 713 data->notification_type, data->origin_url.spec(), data->notification_id, | 713 data->notification_type, data->origin_url.spec(), data->notification_id, |
| 714 action_index, data->profile_id, data->is_incognito)); | 714 action_index, data->profile_id, data->is_incognito)); |
| 715 } | 715 } |
| 716 | 716 |
| 717 void OnActionInvoked(dbus::Signal* signal) { | 717 void OnActionInvoked(dbus::Signal* signal) { |
| 718 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 718 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 719 dbus::MessageReader reader(signal); | 719 dbus::MessageReader reader(signal); |
| 720 uint32_t dbus_id; | 720 uint32_t dbus_id; |
| 721 if (!reader.PopUint32(&dbus_id) || !dbus_id) | 721 if (!reader.PopUint32(&dbus_id) || !dbus_id) |
| 722 return; | 722 return; |
| 723 std::string action; | 723 std::string action; |
| 724 if (!reader.PopString(&action)) | 724 if (!reader.PopString(&action)) |
| 725 return; | 725 return; |
| 726 | 726 |
| 727 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); | 727 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); |
| 728 if (!data) | 728 if (!data) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 739 size_t n_buttons = data->action_end - data->action_start; | 739 size_t n_buttons = data->action_end - data->action_start; |
| 740 size_t id_zero_based = id - data->action_start; | 740 size_t id_zero_based = id - data->action_start; |
| 741 if (id_zero_based >= n_buttons) | 741 if (id_zero_based >= n_buttons) |
| 742 return; | 742 return; |
| 743 ForwardNotificationOperation(data, NotificationCommon::CLICK, | 743 ForwardNotificationOperation(data, NotificationCommon::CLICK, |
| 744 id_zero_based); | 744 id_zero_based); |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 | 747 |
| 748 void OnNotificationClosed(dbus::Signal* signal) { | 748 void OnNotificationClosed(dbus::Signal* signal) { |
| 749 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 749 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 750 dbus::MessageReader reader(signal); | 750 dbus::MessageReader reader(signal); |
| 751 uint32_t dbus_id; | 751 uint32_t dbus_id; |
| 752 if (!reader.PopUint32(&dbus_id) || !dbus_id) | 752 if (!reader.PopUint32(&dbus_id) || !dbus_id) |
| 753 return; | 753 return; |
| 754 | 754 |
| 755 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); | 755 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); |
| 756 if (!data) | 756 if (!data) |
| 757 return; | 757 return; |
| 758 | 758 |
| 759 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1); | 759 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1); |
| 760 notifications_.erase(data); | 760 notifications_.erase(data); |
| 761 } | 761 } |
| 762 | 762 |
| 763 // Called once the connection has been set up (or not). |success| | 763 // Called once the connection has been set up (or not). |success| |
| 764 // indicates the connection is ready to use. | 764 // indicates the connection is ready to use. |
| 765 void OnConnectionInitializationFinishedOnUiThread(bool success) { | 765 void OnConnectionInitializationFinishedOnUiThread(bool success) { |
| 766 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 766 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 767 connected_ = success; | 767 connected_ = success; |
| 768 for (auto& callback : on_connected_callbacks_) | 768 for (auto& callback : on_connected_callbacks_) |
| 769 std::move(callback).Run(success); | 769 std::move(callback).Run(success); |
| 770 on_connected_callbacks_.clear(); | 770 on_connected_callbacks_.clear(); |
| 771 if (!success) | 771 if (!success) |
| 772 CleanUp(); | 772 CleanUp(); |
| 773 } | 773 } |
| 774 | 774 |
| 775 void OnConnectionInitializationFinishedOnTaskRunner( | 775 void OnConnectionInitializationFinishedOnTaskRunner( |
| 776 ConnectionInitializationStatusCode status) { | 776 ConnectionInitializationStatusCode status) { |
| 777 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 777 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 778 UMA_HISTOGRAM_ENUMERATION( | 778 UMA_HISTOGRAM_ENUMERATION( |
| 779 "Notifications.Linux.BridgeInitializationStatus", | 779 "Notifications.Linux.BridgeInitializationStatus", |
| 780 static_cast<int>(status), | 780 static_cast<int>(status), |
| 781 static_cast<int>(ConnectionInitializationStatusCode::NUM_ITEMS)); | 781 static_cast<int>(ConnectionInitializationStatusCode::NUM_ITEMS)); |
| 782 PostTaskToUiThread(base::BindOnce( | 782 PostTaskToUiThread(base::BindOnce( |
| 783 &NotificationPlatformBridgeLinuxImpl:: | 783 &NotificationPlatformBridgeLinuxImpl:: |
| 784 OnConnectionInitializationFinishedOnUiThread, | 784 OnConnectionInitializationFinishedOnUiThread, |
| 785 this, status == ConnectionInitializationStatusCode::SUCCESS)); | 785 this, status == ConnectionInitializationStatusCode::SUCCESS)); |
| 786 } | 786 } |
| 787 | 787 |
| 788 void OnSignalConnected(const std::string& interface_name, | 788 void OnSignalConnected(const std::string& interface_name, |
| 789 const std::string& signal_name, | 789 const std::string& signal_name, |
| 790 bool success) { | 790 bool success) { |
| 791 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 791 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 792 if (!success) { | 792 if (!success) { |
| 793 OnConnectionInitializationFinishedOnTaskRunner( | 793 OnConnectionInitializationFinishedOnTaskRunner( |
| 794 ConnectionInitializationStatusCode::COULD_NOT_CONNECT_TO_SIGNALS); | 794 ConnectionInitializationStatusCode::COULD_NOT_CONNECT_TO_SIGNALS); |
| 795 return; | 795 return; |
| 796 } | 796 } |
| 797 connected_signals_barrier_.Run(); | 797 connected_signals_barrier_.Run(); |
| 798 } | 798 } |
| 799 | 799 |
| 800 void RecordMetricsForCapabilities() { | 800 void RecordMetricsForCapabilities() { |
| 801 // Histogram macros must be called with the same name for each | 801 // Histogram macros must be called with the same name for each |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 } | 904 } |
| 905 | 905 |
| 906 void NotificationPlatformBridgeLinux::SetReadyCallback( | 906 void NotificationPlatformBridgeLinux::SetReadyCallback( |
| 907 NotificationBridgeReadyCallback callback) { | 907 NotificationBridgeReadyCallback callback) { |
| 908 impl_->SetReadyCallback(std::move(callback)); | 908 impl_->SetReadyCallback(std::move(callback)); |
| 909 } | 909 } |
| 910 | 910 |
| 911 void NotificationPlatformBridgeLinux::CleanUp() { | 911 void NotificationPlatformBridgeLinux::CleanUp() { |
| 912 impl_->CleanUp(); | 912 impl_->CleanUp(); |
| 913 } | 913 } |
| OLD | NEW |