| Index: chrome/browser/notifications/notification_platform_bridge_linux.cc
|
| diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc
|
| index e873b6a7c30f73e181c1fdfbd7493e7077f4b0af..7d0ab50387f60d58d9cc39910263400a08bd7a35 100644
|
| --- a/chrome/browser/notifications/notification_platform_bridge_linux.cc
|
| +++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
|
| @@ -11,12 +11,13 @@
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| +#include "base/synchronization/lock.h"
|
| #include "base/task_scheduler/post_task.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/notifications/native_notification_display_service.h"
|
| #include "chrome/browser/notifications/notification.h"
|
| #include "chrome/browser/notifications/notification_display_service_factory.h"
|
| +#include "chrome/browser/notifications/notification_display_service_proxy.h"
|
| #include "chrome/browser/profiles/profile_manager.h"
|
| #include "chrome/browser/shell_integration_linux.h"
|
| #include "content/public/browser/browser_thread.h"
|
| @@ -70,7 +71,8 @@ void ProfileLoadedCallback(NotificationCommon::Operation operation,
|
| NotificationDisplayService* display_service =
|
| NotificationDisplayServiceFactory::GetForProfile(profile);
|
|
|
| - static_cast<NativeNotificationDisplayService*>(display_service)
|
| + static_cast<NotificationDisplayServiceProxy*>(display_service)
|
| + ->native_notification_display_service()
|
| ->ProcessNotificationOperation(operation, notification_type, origin,
|
| notification_id, action_index, reply);
|
| }
|
| @@ -97,22 +99,16 @@ base::FilePath WriteDataToTmpFile(
|
|
|
| // static
|
| NotificationPlatformBridge* NotificationPlatformBridge::Create() {
|
| - auto npbl = base::MakeUnique<NotificationPlatformBridgeLinux>();
|
| - if (!npbl->BlockUntilReady())
|
| - return nullptr;
|
| - return npbl.release();
|
| + return new NotificationPlatformBridgeLinux();
|
| }
|
|
|
| class NotificationPlatformBridgeLinux::NativeNotificationThread
|
| : public base::Thread {
|
| public:
|
| - NativeNotificationThread()
|
| - : base::Thread("FDO Notifications D-Bus thread"),
|
| - event_(base::WaitableEvent::ResetPolicy::MANUAL,
|
| - base::WaitableEvent::InitialState::NOT_SIGNALED) {
|
| + NativeNotificationThread() : base::Thread("FDO Notifications D-Bus thread") {
|
| base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
|
| if (!StartWithOptions(thread_options))
|
| - event_.Signal();
|
| + OnConnected(false);
|
| }
|
|
|
| ~NativeNotificationThread() override {
|
| @@ -262,11 +258,17 @@ class NotificationPlatformBridgeLinux::NativeNotificationThread
|
| false));
|
| }
|
|
|
| - // Waits until the D-Bus connection has been created. Returns true
|
| - // if |notification_proxy_| is ready to use, and false on error.
|
| - bool BlockUntilReady() {
|
| - event_.Wait();
|
| - return notification_proxy_initialized_.IsSet();
|
| + void IsConnected(const base::Callback<void(bool)> callback) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + base::AutoLock lock(connected_lock_);
|
| + if (connected_.has_value()) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI, FROM_HERE,
|
| + base::Bind(callback, connected_.value()));
|
| + } else {
|
| + DCHECK(!on_connected_callback_.has_value());
|
| + on_connected_callback_ = callback;
|
| + }
|
| }
|
|
|
| private:
|
| @@ -325,9 +327,7 @@ class NotificationPlatformBridgeLinux::NativeNotificationThread
|
| notification_proxy_ =
|
| bus_->GetObjectProxy(kFreedesktopNotificationsName,
|
| dbus::ObjectPath(kFreedesktopNotificationsPath));
|
| - if (notification_proxy_)
|
| - notification_proxy_initialized_.Set();
|
| - event_.Signal();
|
| + OnConnected(notification_proxy_);
|
| if (!notification_proxy_)
|
| return;
|
|
|
| @@ -446,18 +446,27 @@ class NotificationPlatformBridgeLinux::NativeNotificationThread
|
| notifications_.erase(data);
|
| }
|
|
|
| + void OnConnected(bool success) {
|
| + DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
|
| + base::AutoLock lock(connected_lock_);
|
| + connected_ = success;
|
| + if (on_connected_callback_.has_value()) {
|
| + content::BrowserThread::PostTask(
|
| + content::BrowserThread::UI, FROM_HERE,
|
| + base::Bind(on_connected_callback_.value(), success));
|
| + on_connected_callback_ = base::nullopt;
|
| + }
|
| + }
|
| +
|
| + // State necessary for OnConnected() and IsConnected().
|
| + base::Optional<bool> connected_;
|
| + base::Lock connected_lock_;
|
| + base::Optional<base::Callback<void(bool)>> on_connected_callback_;
|
| +
|
| scoped_refptr<dbus::Bus> bus_;
|
|
|
| dbus::ObjectProxy* notification_proxy_ = nullptr;
|
|
|
| - // Event that will be signaled once |notification_proxy_| is done
|
| - // connecting, or has failed to connect.
|
| - base::WaitableEvent event_;
|
| -
|
| - // Set if the |notification_proxy_| has initialized without error.
|
| - // Only valid once |event_| has been signaled.
|
| - base::AtomicFlag notification_proxy_initialized_;
|
| -
|
| // A std::set<std::unique_ptr<T>> doesn't work well because
|
| // eg. std::set::erase(T) would require a std::unique_ptr<T>
|
| // argument, so the data would get double-destructed.
|
| @@ -511,6 +520,7 @@ void NotificationPlatformBridgeLinux::GetDisplayed(
|
| incognito, callback));
|
| }
|
|
|
| -bool NotificationPlatformBridgeLinux::BlockUntilReady() {
|
| - return thread_->BlockUntilReady();
|
| +void NotificationPlatformBridgeLinux::IsConnected(
|
| + const base::Callback<void(bool)>& callback) {
|
| + thread_->IsConnected(callback);
|
| }
|
|
|