| 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 <unordered_map> | 10 #include <unordered_map> |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 const content::NotificationSource& source, | 331 const content::NotificationSource& source, |
| 332 const content::NotificationDetails& details) override { | 332 const content::NotificationDetails& details) override { |
| 333 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 333 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 334 DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type); | 334 DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type); |
| 335 // The browser process is about to exit. Post the CleanUp() task | 335 // The browser process is about to exit. Post the CleanUp() task |
| 336 // while we still can. | 336 // while we still can. |
| 337 CleanUp(); | 337 CleanUp(); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void PostTaskToUiThread(base::OnceClosure closure) const { | 340 void PostTaskToUiThread(base::OnceClosure closure) const { |
| 341 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 341 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 342 bool success = content::BrowserThread::PostTask( | 342 bool success = content::BrowserThread::PostTask( |
| 343 content::BrowserThread::UI, FROM_HERE, std::move(closure)); | 343 content::BrowserThread::UI, FROM_HERE, std::move(closure)); |
| 344 DCHECK(success); | 344 DCHECK(success); |
| 345 } | 345 } |
| 346 | 346 |
| 347 void PostTaskToTaskRunnerThread(base::OnceClosure closure) const { | 347 void PostTaskToTaskRunnerThread(base::OnceClosure closure) const { |
| 348 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 348 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 349 DCHECK(task_runner_); | 349 DCHECK(task_runner_); |
| 350 bool success = task_runner_->PostTask(FROM_HERE, std::move(closure)); | 350 bool success = task_runner_->PostTask(FROM_HERE, std::move(closure)); |
| 351 DCHECK(success); | 351 DCHECK(success); |
| 352 } | 352 } |
| 353 | 353 |
| 354 // Sets up the D-Bus connection. | 354 // Sets up the D-Bus connection. |
| 355 void InitOnTaskRunner() { | 355 void InitOnTaskRunner() { |
| 356 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 356 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 357 // |bus_| may be non-null in unit testing where a fake bus is used. | 357 // |bus_| may be non-null in unit testing where a fake bus is used. |
| 358 if (!bus_) { | 358 if (!bus_) { |
| 359 dbus::Bus::Options bus_options; | 359 dbus::Bus::Options bus_options; |
| 360 bus_options.bus_type = dbus::Bus::SESSION; | 360 bus_options.bus_type = dbus::Bus::SESSION; |
| 361 bus_options.connection_type = dbus::Bus::PRIVATE; | 361 bus_options.connection_type = dbus::Bus::PRIVATE; |
| 362 bus_options.dbus_task_runner = task_runner_; | 362 bus_options.dbus_task_runner = task_runner_; |
| 363 bus_ = make_scoped_refptr(new dbus::Bus(bus_options)); | 363 bus_ = make_scoped_refptr(new dbus::Bus(bus_options)); |
| 364 } | 364 } |
| 365 | 365 |
| 366 notification_proxy_ = | 366 notification_proxy_ = |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 this)); | 422 this)); |
| 423 notification_proxy_->ConnectToSignal( | 423 notification_proxy_->ConnectToSignal( |
| 424 kFreedesktopNotificationsName, kSignalNotificationClosed, | 424 kFreedesktopNotificationsName, kSignalNotificationClosed, |
| 425 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnNotificationClosed, | 425 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnNotificationClosed, |
| 426 this), | 426 this), |
| 427 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnSignalConnected, | 427 base::Bind(&NotificationPlatformBridgeLinuxImpl::OnSignalConnected, |
| 428 this)); | 428 this)); |
| 429 } | 429 } |
| 430 | 430 |
| 431 void CleanUpOnTaskRunner() { | 431 void CleanUpOnTaskRunner() { |
| 432 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 432 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 433 if (bus_) | 433 if (bus_) |
| 434 bus_->ShutdownAndBlock(); | 434 bus_->ShutdownAndBlock(); |
| 435 bus_ = nullptr; | 435 bus_ = nullptr; |
| 436 notification_proxy_ = nullptr; | 436 notification_proxy_ = nullptr; |
| 437 notifications_.clear(); | 437 notifications_.clear(); |
| 438 } | 438 } |
| 439 | 439 |
| 440 // Makes the "Notify" call to D-Bus. | 440 // Makes the "Notify" call to D-Bus. |
| 441 void DisplayOnTaskRunner(NotificationCommon::Type notification_type, | 441 void DisplayOnTaskRunner(NotificationCommon::Type notification_type, |
| 442 const std::string& notification_id, | 442 const std::string& notification_id, |
| 443 const std::string& profile_id, | 443 const std::string& profile_id, |
| 444 bool is_incognito, | 444 bool is_incognito, |
| 445 std::unique_ptr<Notification> notification) { | 445 std::unique_ptr<Notification> notification) { |
| 446 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 446 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 447 NotificationData* data = | 447 NotificationData* data = |
| 448 FindNotificationData(notification_id, profile_id, is_incognito); | 448 FindNotificationData(notification_id, profile_id, is_incognito); |
| 449 if (data) { | 449 if (data) { |
| 450 // Update an existing notification. | 450 // Update an existing notification. |
| 451 data->notification_type = notification_type; | 451 data->notification_type = notification_type; |
| 452 data->resource_files.clear(); | 452 data->resource_files.clear(); |
| 453 } else { | 453 } else { |
| 454 // Send the notification for the first time. | 454 // Send the notification for the first time. |
| 455 data = | 455 data = |
| 456 new NotificationData(notification_type, notification_id, profile_id, | 456 new NotificationData(notification_type, notification_id, profile_id, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 } | 560 } |
| 561 if (!data->dbus_id) { | 561 if (!data->dbus_id) { |
| 562 // There was some sort of error with creating the notification. | 562 // There was some sort of error with creating the notification. |
| 563 notifications_.erase(data); | 563 notifications_.erase(data); |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 | 566 |
| 567 // Makes the "CloseNotification" call to D-Bus. | 567 // Makes the "CloseNotification" call to D-Bus. |
| 568 void CloseOnTaskRunner(const std::string& profile_id, | 568 void CloseOnTaskRunner(const std::string& profile_id, |
| 569 const std::string& notification_id) { | 569 const std::string& notification_id) { |
| 570 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 570 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 571 std::vector<NotificationData*> to_erase; | 571 std::vector<NotificationData*> to_erase; |
| 572 for (const auto& pair : notifications_) { | 572 for (const auto& pair : notifications_) { |
| 573 NotificationData* data = pair.first; | 573 NotificationData* data = pair.first; |
| 574 if (data->notification_id == notification_id && | 574 if (data->notification_id == notification_id && |
| 575 data->profile_id == profile_id) { | 575 data->profile_id == profile_id) { |
| 576 dbus::MethodCall method_call(kFreedesktopNotificationsName, | 576 dbus::MethodCall method_call(kFreedesktopNotificationsName, |
| 577 kMethodCloseNotification); | 577 kMethodCloseNotification); |
| 578 dbus::MessageWriter writer(&method_call); | 578 dbus::MessageWriter writer(&method_call); |
| 579 writer.AppendUint32(data->dbus_id); | 579 writer.AppendUint32(data->dbus_id); |
| 580 notification_proxy_->CallMethodAndBlock( | 580 notification_proxy_->CallMethodAndBlock( |
| 581 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); | 581 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); |
| 582 to_erase.push_back(data); | 582 to_erase.push_back(data); |
| 583 } | 583 } |
| 584 } | 584 } |
| 585 for (NotificationData* data : to_erase) | 585 for (NotificationData* data : to_erase) |
| 586 notifications_.erase(data); | 586 notifications_.erase(data); |
| 587 } | 587 } |
| 588 | 588 |
| 589 void GetDisplayedOnTaskRunner( | 589 void GetDisplayedOnTaskRunner( |
| 590 const std::string& profile_id, | 590 const std::string& profile_id, |
| 591 bool incognito, | 591 bool incognito, |
| 592 const GetDisplayedNotificationsCallback& callback) const { | 592 const GetDisplayedNotificationsCallback& callback) const { |
| 593 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 593 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 594 auto displayed = base::MakeUnique<std::set<std::string>>(); | 594 auto displayed = base::MakeUnique<std::set<std::string>>(); |
| 595 for (const auto& pair : notifications_) { | 595 for (const auto& pair : notifications_) { |
| 596 NotificationData* data = pair.first; | 596 NotificationData* data = pair.first; |
| 597 if (data->profile_id == profile_id && data->is_incognito == incognito) | 597 if (data->profile_id == profile_id && data->is_incognito == incognito) |
| 598 displayed->insert(data->notification_id); | 598 displayed->insert(data->notification_id); |
| 599 } | 599 } |
| 600 PostTaskToUiThread(base::BindOnce(callback, std::move(displayed), true)); | 600 PostTaskToUiThread(base::BindOnce(callback, std::move(displayed), true)); |
| 601 } | 601 } |
| 602 | 602 |
| 603 NotificationData* FindNotificationData(const std::string& notification_id, | 603 NotificationData* FindNotificationData(const std::string& notification_id, |
| 604 const std::string& profile_id, | 604 const std::string& profile_id, |
| 605 bool is_incognito) { | 605 bool is_incognito) { |
| 606 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 606 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 607 for (const auto& pair : notifications_) { | 607 for (const auto& pair : notifications_) { |
| 608 NotificationData* data = pair.first; | 608 NotificationData* data = pair.first; |
| 609 if (data->notification_id == notification_id && | 609 if (data->notification_id == notification_id && |
| 610 data->profile_id == profile_id && | 610 data->profile_id == profile_id && |
| 611 data->is_incognito == is_incognito) { | 611 data->is_incognito == is_incognito) { |
| 612 return data; | 612 return data; |
| 613 } | 613 } |
| 614 } | 614 } |
| 615 | 615 |
| 616 return nullptr; | 616 return nullptr; |
| 617 } | 617 } |
| 618 | 618 |
| 619 NotificationData* FindNotificationDataWithDBusId(uint32_t dbus_id) { | 619 NotificationData* FindNotificationDataWithDBusId(uint32_t dbus_id) { |
| 620 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 620 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 621 DCHECK(dbus_id); | 621 DCHECK(dbus_id); |
| 622 for (const auto& pair : notifications_) { | 622 for (const auto& pair : notifications_) { |
| 623 NotificationData* data = pair.first; | 623 NotificationData* data = pair.first; |
| 624 if (data->dbus_id == dbus_id) | 624 if (data->dbus_id == dbus_id) |
| 625 return data; | 625 return data; |
| 626 } | 626 } |
| 627 | 627 |
| 628 return nullptr; | 628 return nullptr; |
| 629 } | 629 } |
| 630 | 630 |
| 631 void ForwardNotificationOperation(NotificationData* data, | 631 void ForwardNotificationOperation(NotificationData* data, |
| 632 NotificationCommon::Operation operation, | 632 NotificationCommon::Operation operation, |
| 633 int action_index) { | 633 int action_index) { |
| 634 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 634 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 635 PostTaskToUiThread(base::BindOnce( | 635 PostTaskToUiThread(base::BindOnce( |
| 636 ForwardNotificationOperationOnUiThread, operation, | 636 ForwardNotificationOperationOnUiThread, operation, |
| 637 data->notification_type, data->origin_url.spec(), data->notification_id, | 637 data->notification_type, data->origin_url.spec(), data->notification_id, |
| 638 action_index, data->profile_id, data->is_incognito)); | 638 action_index, data->profile_id, data->is_incognito)); |
| 639 } | 639 } |
| 640 | 640 |
| 641 void OnActionInvoked(dbus::Signal* signal) { | 641 void OnActionInvoked(dbus::Signal* signal) { |
| 642 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 642 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 643 dbus::MessageReader reader(signal); | 643 dbus::MessageReader reader(signal); |
| 644 uint32_t dbus_id; | 644 uint32_t dbus_id; |
| 645 if (!reader.PopUint32(&dbus_id) || !dbus_id) | 645 if (!reader.PopUint32(&dbus_id) || !dbus_id) |
| 646 return; | 646 return; |
| 647 std::string action; | 647 std::string action; |
| 648 if (!reader.PopString(&action)) | 648 if (!reader.PopString(&action)) |
| 649 return; | 649 return; |
| 650 | 650 |
| 651 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); | 651 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); |
| 652 if (!data) | 652 if (!data) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 663 size_t n_buttons = data->action_end - data->action_start; | 663 size_t n_buttons = data->action_end - data->action_start; |
| 664 size_t id_zero_based = id - data->action_start; | 664 size_t id_zero_based = id - data->action_start; |
| 665 if (id_zero_based >= n_buttons) | 665 if (id_zero_based >= n_buttons) |
| 666 return; | 666 return; |
| 667 ForwardNotificationOperation(data, NotificationCommon::CLICK, | 667 ForwardNotificationOperation(data, NotificationCommon::CLICK, |
| 668 id_zero_based); | 668 id_zero_based); |
| 669 } | 669 } |
| 670 } | 670 } |
| 671 | 671 |
| 672 void OnNotificationClosed(dbus::Signal* signal) { | 672 void OnNotificationClosed(dbus::Signal* signal) { |
| 673 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 673 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 674 dbus::MessageReader reader(signal); | 674 dbus::MessageReader reader(signal); |
| 675 uint32_t dbus_id; | 675 uint32_t dbus_id; |
| 676 if (!reader.PopUint32(&dbus_id) || !dbus_id) | 676 if (!reader.PopUint32(&dbus_id) || !dbus_id) |
| 677 return; | 677 return; |
| 678 | 678 |
| 679 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); | 679 NotificationData* data = FindNotificationDataWithDBusId(dbus_id); |
| 680 if (!data) | 680 if (!data) |
| 681 return; | 681 return; |
| 682 | 682 |
| 683 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1); | 683 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1); |
| 684 notifications_.erase(data); | 684 notifications_.erase(data); |
| 685 } | 685 } |
| 686 | 686 |
| 687 // Called once the connection has been set up (or not). |success| | 687 // Called once the connection has been set up (or not). |success| |
| 688 // indicates the connection is ready to use. | 688 // indicates the connection is ready to use. |
| 689 void OnConnectionInitializationFinishedOnUiThread(bool success) { | 689 void OnConnectionInitializationFinishedOnUiThread(bool success) { |
| 690 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 690 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 691 connected_ = success; | 691 connected_ = success; |
| 692 for (auto& callback : on_connected_callbacks_) | 692 for (auto& callback : on_connected_callbacks_) |
| 693 std::move(callback).Run(success); | 693 std::move(callback).Run(success); |
| 694 on_connected_callbacks_.clear(); | 694 on_connected_callbacks_.clear(); |
| 695 if (!success) | 695 if (!success) |
| 696 CleanUp(); | 696 CleanUp(); |
| 697 } | 697 } |
| 698 | 698 |
| 699 void OnConnectionInitializationFinishedOnTaskRunner( | 699 void OnConnectionInitializationFinishedOnTaskRunner( |
| 700 ConnectionInitializationStatusCode status) { | 700 ConnectionInitializationStatusCode status) { |
| 701 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 701 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 702 UMA_HISTOGRAM_ENUMERATION( | 702 UMA_HISTOGRAM_ENUMERATION( |
| 703 "Notifications.Linux.BridgeInitializationStatus", | 703 "Notifications.Linux.BridgeInitializationStatus", |
| 704 static_cast<int>(status), | 704 static_cast<int>(status), |
| 705 static_cast<int>(ConnectionInitializationStatusCode::NUM_ITEMS)); | 705 static_cast<int>(ConnectionInitializationStatusCode::NUM_ITEMS)); |
| 706 PostTaskToUiThread(base::BindOnce( | 706 PostTaskToUiThread(base::BindOnce( |
| 707 &NotificationPlatformBridgeLinuxImpl:: | 707 &NotificationPlatformBridgeLinuxImpl:: |
| 708 OnConnectionInitializationFinishedOnUiThread, | 708 OnConnectionInitializationFinishedOnUiThread, |
| 709 this, status == ConnectionInitializationStatusCode::SUCCESS)); | 709 this, status == ConnectionInitializationStatusCode::SUCCESS)); |
| 710 } | 710 } |
| 711 | 711 |
| 712 void OnSignalConnected(const std::string& interface_name, | 712 void OnSignalConnected(const std::string& interface_name, |
| 713 const std::string& signal_name, | 713 const std::string& signal_name, |
| 714 bool success) { | 714 bool success) { |
| 715 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 715 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 716 if (!success) { | 716 if (!success) { |
| 717 OnConnectionInitializationFinishedOnTaskRunner( | 717 OnConnectionInitializationFinishedOnTaskRunner( |
| 718 ConnectionInitializationStatusCode::COULD_NOT_CONNECT_TO_SIGNALS); | 718 ConnectionInitializationStatusCode::COULD_NOT_CONNECT_TO_SIGNALS); |
| 719 return; | 719 return; |
| 720 } | 720 } |
| 721 connected_signals_barrier_.Run(); | 721 connected_signals_barrier_.Run(); |
| 722 } | 722 } |
| 723 | 723 |
| 724 void RecordMetricsForCapabilities() { | 724 void RecordMetricsForCapabilities() { |
| 725 // Histogram macros must be called with the same name for each | 725 // Histogram macros must be called with the same name for each |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 } | 824 } |
| 825 | 825 |
| 826 void NotificationPlatformBridgeLinux::SetReadyCallback( | 826 void NotificationPlatformBridgeLinux::SetReadyCallback( |
| 827 NotificationBridgeReadyCallback callback) { | 827 NotificationBridgeReadyCallback callback) { |
| 828 impl_->SetReadyCallback(std::move(callback)); | 828 impl_->SetReadyCallback(std::move(callback)); |
| 829 } | 829 } |
| 830 | 830 |
| 831 void NotificationPlatformBridgeLinux::CleanUp() { | 831 void NotificationPlatformBridgeLinux::CleanUp() { |
| 832 impl_->CleanUp(); | 832 impl_->CleanUp(); |
| 833 } | 833 } |
| OLD | NEW |