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

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

Issue 2849003002: Linux native notifications: Add initial unit test (Closed)
Patch Set: peter'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..f0f34a0742f86ea63d03baad46e7acf98ac218ad 100644
--- a/chrome/browser/notifications/notification_platform_bridge_linux.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -127,12 +127,22 @@ 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());
+ }
+
+ // Init() cannot be called 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.
Peter Beverloo 2017/05/03 00:31:26 Thank you for the detailed comment!
+ void InitAfterConstructor() {
Lei Zhang 2017/05/03 01:10:45 This can be Init(), and Init() can be InitOnTaskRu
Tom (Use chromium acct) 2017/05/03 01:22:17 Done.
PostTaskToTaskRunnerThread(
base::BindOnce(&NotificationPlatformBridgeLinuxImpl::Init, this));
}
@@ -188,6 +198,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 +255,7 @@ class NotificationPlatformBridgeLinuxImpl
~NotificationPlatformBridgeLinuxImpl() override {
DCHECK(!bus_);
+ DCHECK(!notification_proxy_);
DCHECK(notifications_.empty());
}
@@ -269,11 +286,13 @@ class NotificationPlatformBridgeLinuxImpl
// Sets up the D-Bus connection.
void Init() {
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));
+ if (!bus_) {
Lei Zhang 2017/05/03 01:10:46 May be good to mention this happens under normal c
Tom (Use chromium acct) 2017/05/03 01:22:17 Done.
+ 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 +319,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 +597,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 +618,13 @@ class NotificationPlatformBridgeLinuxImpl
};
NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux()
- : impl_(new NotificationPlatformBridgeLinuxImpl()) {}
+ : NotificationPlatformBridgeLinux(nullptr) {}
+
+NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux(
+ scoped_refptr<dbus::Bus> bus)
+ : impl_(new NotificationPlatformBridgeLinuxImpl(bus)) {
+ impl_->InitAfterConstructor();
+}
NotificationPlatformBridgeLinux::~NotificationPlatformBridgeLinux() = default;
@@ -640,3 +655,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