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); |
} |