Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1549)

Unified Diff: chrome/browser/notifications/notification_platform_bridge_linux.cc

Issue 2849003002: Linux native notifications: Add initial unit test (Closed)
Patch Set: address thestig's comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 cf71db8869d0a8a1c7c5f89085a7fd8338243d6c..3f00eb82d46e4b0e26e3b5016d241cedfca2efb5 100644
--- a/chrome/browser/notifications/notification_platform_bridge_linux.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -127,14 +127,25 @@ class NotificationPlatformBridgeLinuxImpl
public content::NotificationObserver,
public base::RefCountedThreadSafe<NotificationPlatformBridgeLinuxImpl> {
public:
- NotificationPlatformBridgeLinuxImpl()
- : task_runner_(base::CreateSingleThreadTaskRunnerWithTraits(
- base::TaskTraits().MayBlock().WithPriority(
- base::TaskPriority::USER_BLOCKING))) {
+ explicit NotificationPlatformBridgeLinuxImpl(scoped_refptr<dbus::Bus> bus)
+ : bus_(bus) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ task_runner_ = base::CreateSingleThreadTaskRunnerWithTraits(
+ base::TaskTraits().MayBlock().WithPriority(
+ base::TaskPriority::USER_BLOCKING));
registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
- PostTaskToTaskRunnerThread(
- base::BindOnce(&NotificationPlatformBridgeLinuxImpl::Init, this));
+ }
+
+ // InitOnTaskRunner() cannot be posted from within the constructor
+ // because of a race condition. The reference count for |this|
+ // starts out as 0. Posting the Init task would increment the count
+ // to 1. If the task finishes before the constructor returns, the
+ // count will go to 0 and the object would be prematurely
+ // destructed.
+ void Init() {
+ PostTaskToTaskRunnerThread(base::BindOnce(
+ &NotificationPlatformBridgeLinuxImpl::InitOnTaskRunner, this));
}
void Display(NotificationCommon::Type notification_type,
@@ -188,6 +199,12 @@ class NotificationPlatformBridgeLinuxImpl
}
}
+ void CleanUp() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ PostTaskToTaskRunnerThread(base::BindOnce(
+ &NotificationPlatformBridgeLinuxImpl::CleanUpOnTaskRunner, this));
+ }
+
private:
friend class base::RefCountedThreadSafe<NotificationPlatformBridgeLinuxImpl>;
@@ -239,6 +256,7 @@ class NotificationPlatformBridgeLinuxImpl
~NotificationPlatformBridgeLinuxImpl() override {
DCHECK(!bus_);
+ DCHECK(!notification_proxy_);
DCHECK(notifications_.empty());
}
@@ -267,13 +285,16 @@ class NotificationPlatformBridgeLinuxImpl
}
// Sets up the D-Bus connection.
- void Init() {
+ void InitOnTaskRunner() {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
- dbus::Bus::Options bus_options;
- bus_options.bus_type = dbus::Bus::SESSION;
- bus_options.connection_type = dbus::Bus::PRIVATE;
- bus_options.dbus_task_runner = task_runner_;
- bus_ = make_scoped_refptr(new dbus::Bus(bus_options));
+ // |bus_| may be non-null in unit testing where a fake bus is used.
+ if (!bus_) {
+ dbus::Bus::Options bus_options;
+ bus_options.bus_type = dbus::Bus::SESSION;
+ bus_options.connection_type = dbus::Bus::PRIVATE;
+ bus_options.dbus_task_runner = task_runner_;
+ bus_ = make_scoped_refptr(new dbus::Bus(bus_options));
+ }
notification_proxy_ =
bus_->GetObjectProxy(kFreedesktopNotificationsName,
@@ -300,18 +321,10 @@ class NotificationPlatformBridgeLinuxImpl
this));
}
- void CleanUp() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (cleanup_posted_)
- return;
- PostTaskToTaskRunnerThread(base::BindOnce(
- &NotificationPlatformBridgeLinuxImpl::CleanUpOnTaskRunner, this));
- cleanup_posted_ = true;
- }
-
void CleanUpOnTaskRunner() {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
- bus_->ShutdownAndBlock();
+ if (bus_)
+ bus_->ShutdownAndBlock();
bus_ = nullptr;
notification_proxy_ = nullptr;
notifications_.clear();
@@ -586,8 +599,6 @@ class NotificationPlatformBridgeLinuxImpl
base::Optional<bool> connected_;
std::vector<NotificationBridgeReadyCallback> on_connected_callbacks_;
- bool cleanup_posted_ = false;
-
//////////////////////////////////////////////////////////////////////////////
// Members used only on the task runner thread.
@@ -609,7 +620,13 @@ class NotificationPlatformBridgeLinuxImpl
};
NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux()
- : impl_(new NotificationPlatformBridgeLinuxImpl()) {}
+ : NotificationPlatformBridgeLinux(nullptr) {}
+
+NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux(
+ scoped_refptr<dbus::Bus> bus)
+ : impl_(new NotificationPlatformBridgeLinuxImpl(bus)) {
+ impl_->Init();
+}
NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() = default;
@@ -640,3 +657,7 @@ void NotificationPlatformBridgeLinux::SetReadyCallback(
NotificationBridgeReadyCallback callback) {
impl_->SetReadyCallback(std::move(callback));
}
+
+void NotificationPlatformBridgeLinux::CleanUp() {
+ impl_->CleanUp();
+}

Powered by Google App Engine
This is Rietveld 408576698