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

Side by Side Diff: chrome/browser/notifications/notification_platform_bridge_linux.cc

Issue 2828503005: Add NotificationDisplayServiceProxy (Closed)
Patch Set: Rebase 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 unified diff | Download patch
OLDNEW
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 8
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/strings/nullable_string16.h" 10 #include "base/strings/nullable_string16.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/lock.h"
15 #include "base/task_scheduler/post_task.h" 15 #include "base/task_scheduler/post_task.h"
16 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/notifications/native_notification_display_service.h" 17 #include "chrome/browser/notifications/native_notification_display_service.h"
18 #include "chrome/browser/notifications/notification.h" 18 #include "chrome/browser/notifications/notification.h"
19 #include "chrome/browser/notifications/notification_display_service_factory.h" 19 #include "chrome/browser/notifications/notification_display_service_factory.h"
20 #include "chrome/browser/notifications/notification_display_service_proxy.h"
20 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/shell_integration_linux.h" 22 #include "chrome/browser/shell_integration_linux.h"
22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
23 #include "dbus/bus.h" 24 #include "dbus/bus.h"
24 #include "dbus/message.h" 25 #include "dbus/message.h"
25 #include "dbus/object_proxy.h" 26 #include "dbus/object_proxy.h"
26 #include "ui/gfx/image/image_skia.h" 27 #include "ui/gfx/image/image_skia.h"
27 28
28 namespace { 29 namespace {
29 30
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 const std::string& notification_id, 64 const std::string& notification_id,
64 int action_index, 65 int action_index,
65 const base::NullableString16& reply, 66 const base::NullableString16& reply,
66 Profile* profile) { 67 Profile* profile) {
67 if (!profile) 68 if (!profile)
68 return; 69 return;
69 70
70 NotificationDisplayService* display_service = 71 NotificationDisplayService* display_service =
71 NotificationDisplayServiceFactory::GetForProfile(profile); 72 NotificationDisplayServiceFactory::GetForProfile(profile);
72 73
73 static_cast<NativeNotificationDisplayService*>(display_service) 74 static_cast<NotificationDisplayServiceProxy*>(display_service)
75 ->native_notification_display_service()
74 ->ProcessNotificationOperation(operation, notification_type, origin, 76 ->ProcessNotificationOperation(operation, notification_type, origin,
75 notification_id, action_index, reply); 77 notification_id, action_index, reply);
76 } 78 }
77 79
78 // Writes |data| to a new temporary file and returns its path. 80 // Writes |data| to a new temporary file and returns its path.
79 // Returns base::FilePath() on failure. 81 // Returns base::FilePath() on failure.
80 base::FilePath WriteDataToTmpFile( 82 base::FilePath WriteDataToTmpFile(
81 const scoped_refptr<base::RefCountedMemory>& data) { 83 const scoped_refptr<base::RefCountedMemory>& data) {
82 int data_len = data->size(); 84 int data_len = data->size();
83 if (data_len == 0) 85 if (data_len == 0)
84 return base::FilePath(); 86 return base::FilePath();
85 base::FilePath file_path; 87 base::FilePath file_path;
86 if (!base::CreateTemporaryFile(&file_path)) 88 if (!base::CreateTemporaryFile(&file_path))
87 return base::FilePath(); 89 return base::FilePath();
88 if (base::WriteFile(file_path, data->front_as<char>(), data_len) != 90 if (base::WriteFile(file_path, data->front_as<char>(), data_len) !=
89 data_len) { 91 data_len) {
90 base::DeleteFile(file_path, false); 92 base::DeleteFile(file_path, false);
91 return base::FilePath(); 93 return base::FilePath();
92 } 94 }
93 return file_path; 95 return file_path;
94 } 96 }
95 97
96 } // namespace 98 } // namespace
97 99
98 // static 100 // static
99 NotificationPlatformBridge* NotificationPlatformBridge::Create() { 101 NotificationPlatformBridge* NotificationPlatformBridge::Create() {
100 auto npbl = base::MakeUnique<NotificationPlatformBridgeLinux>(); 102 return new NotificationPlatformBridgeLinux();
101 if (!npbl->BlockUntilReady())
102 return nullptr;
103 return npbl.release();
104 } 103 }
105 104
106 class NotificationPlatformBridgeLinux::NativeNotificationThread 105 class NotificationPlatformBridgeLinux::NativeNotificationThread
107 : public base::Thread { 106 : public base::Thread {
108 public: 107 public:
109 NativeNotificationThread() 108 NativeNotificationThread() : base::Thread("FDO Notifications D-Bus thread") {
110 : base::Thread("FDO Notifications D-Bus thread"),
111 event_(base::WaitableEvent::ResetPolicy::MANUAL,
112 base::WaitableEvent::InitialState::NOT_SIGNALED) {
113 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); 109 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
114 if (!StartWithOptions(thread_options)) 110 if (!StartWithOptions(thread_options))
115 event_.Signal(); 111 OnConnected(false);
116 } 112 }
117 113
118 ~NativeNotificationThread() override { 114 ~NativeNotificationThread() override {
119 Stop(); 115 Stop();
120 // All of the resources should have been cleaned up on the 116 // All of the resources should have been cleaned up on the
121 // notification thread. 117 // notification thread.
122 DCHECK(notifications_.empty()); 118 DCHECK(notifications_.empty());
123 } 119 }
124 120
125 void Display(NotificationCommon::Type notification_type, 121 void Display(NotificationCommon::Type notification_type,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 void GetDisplayed(const std::string& profile_id, 251 void GetDisplayed(const std::string& profile_id,
256 bool incognito, 252 bool incognito,
257 const DisplayedNotificationsCallback& callback) const { 253 const DisplayedNotificationsCallback& callback) const {
258 content::BrowserThread::PostTask( 254 content::BrowserThread::PostTask(
259 content::BrowserThread::UI, FROM_HERE, 255 content::BrowserThread::UI, FROM_HERE,
260 base::Bind(callback, 256 base::Bind(callback,
261 base::Passed(base::MakeUnique<std::set<std::string>>()), 257 base::Passed(base::MakeUnique<std::set<std::string>>()),
262 false)); 258 false));
263 } 259 }
264 260
265 // Waits until the D-Bus connection has been created. Returns true 261 void IsConnected(const base::Callback<void(bool)> callback) {
266 // if |notification_proxy_| is ready to use, and false on error. 262 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
267 bool BlockUntilReady() { 263 base::AutoLock lock(connected_lock_);
268 event_.Wait(); 264 if (connected_.has_value()) {
269 return notification_proxy_initialized_.IsSet(); 265 content::BrowserThread::PostTask(
266 content::BrowserThread::UI, FROM_HERE,
267 base::Bind(callback, connected_.value()));
268 } else {
269 DCHECK(!on_connected_callback_.has_value());
270 on_connected_callback_ = callback;
271 }
270 } 272 }
271 273
272 private: 274 private:
273 struct ResourceFile { 275 struct ResourceFile {
274 explicit ResourceFile(const base::FilePath& file_path) 276 explicit ResourceFile(const base::FilePath& file_path)
275 : file_path(file_path) {} 277 : file_path(file_path) {}
276 ~ResourceFile() { base::DeleteFile(file_path, false); } 278 ~ResourceFile() { base::DeleteFile(file_path, false); }
277 const base::FilePath file_path; 279 const base::FilePath file_path;
278 }; 280 };
279 281
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 320
319 void Init() override { 321 void Init() override {
320 dbus::Bus::Options bus_options; 322 dbus::Bus::Options bus_options;
321 bus_options.bus_type = dbus::Bus::SESSION; 323 bus_options.bus_type = dbus::Bus::SESSION;
322 bus_options.connection_type = dbus::Bus::PRIVATE; 324 bus_options.connection_type = dbus::Bus::PRIVATE;
323 bus_ = make_scoped_refptr(new dbus::Bus(bus_options)); 325 bus_ = make_scoped_refptr(new dbus::Bus(bus_options));
324 326
325 notification_proxy_ = 327 notification_proxy_ =
326 bus_->GetObjectProxy(kFreedesktopNotificationsName, 328 bus_->GetObjectProxy(kFreedesktopNotificationsName,
327 dbus::ObjectPath(kFreedesktopNotificationsPath)); 329 dbus::ObjectPath(kFreedesktopNotificationsPath));
328 if (notification_proxy_) 330 OnConnected(notification_proxy_);
329 notification_proxy_initialized_.Set();
330 event_.Signal();
331 if (!notification_proxy_) 331 if (!notification_proxy_)
332 return; 332 return;
333 333
334 auto on_signal_connected = [](const std::string&, const std::string&, 334 auto on_signal_connected = [](const std::string&, const std::string&,
335 bool success) { DCHECK(success); }; 335 bool success) { DCHECK(success); };
336 notification_proxy_->ConnectToSignal( 336 notification_proxy_->ConnectToSignal(
337 kFreedesktopNotificationsName, "ActionInvoked", 337 kFreedesktopNotificationsName, "ActionInvoked",
338 base::Bind(&NativeNotificationThread::OnActionInvoked, 338 base::Bind(&NativeNotificationThread::OnActionInvoked,
339 base::Unretained(this)), 339 base::Unretained(this)),
340 base::Bind(on_signal_connected)); 340 base::Bind(on_signal_connected));
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 return; 439 return;
440 440
441 NotificationData* data = FindNotificationData(dbus_id); 441 NotificationData* data = FindNotificationData(dbus_id);
442 if (!data) 442 if (!data)
443 return; 443 return;
444 444
445 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1); 445 ForwardNotificationOperation(data, NotificationCommon::CLOSE, -1);
446 notifications_.erase(data); 446 notifications_.erase(data);
447 } 447 }
448 448
449 void OnConnected(bool success) {
450 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
451 base::AutoLock lock(connected_lock_);
452 connected_ = success;
453 if (on_connected_callback_.has_value()) {
454 content::BrowserThread::PostTask(
455 content::BrowserThread::UI, FROM_HERE,
456 base::Bind(on_connected_callback_.value(), success));
457 on_connected_callback_ = base::nullopt;
458 }
459 }
460
461 // State necessary for OnConnected() and IsConnected().
462 base::Optional<bool> connected_;
463 base::Lock connected_lock_;
464 base::Optional<base::Callback<void(bool)>> on_connected_callback_;
465
449 scoped_refptr<dbus::Bus> bus_; 466 scoped_refptr<dbus::Bus> bus_;
450 467
451 dbus::ObjectProxy* notification_proxy_ = nullptr; 468 dbus::ObjectProxy* notification_proxy_ = nullptr;
452 469
453 // Event that will be signaled once |notification_proxy_| is done
454 // connecting, or has failed to connect.
455 base::WaitableEvent event_;
456
457 // Set if the |notification_proxy_| has initialized without error.
458 // Only valid once |event_| has been signaled.
459 base::AtomicFlag notification_proxy_initialized_;
460
461 // A std::set<std::unique_ptr<T>> doesn't work well because 470 // A std::set<std::unique_ptr<T>> doesn't work well because
462 // eg. std::set::erase(T) would require a std::unique_ptr<T> 471 // eg. std::set::erase(T) would require a std::unique_ptr<T>
463 // argument, so the data would get double-destructed. 472 // argument, so the data would get double-destructed.
464 template <typename T> 473 template <typename T>
465 using UnorderedUniqueSet = std::unordered_map<T*, std::unique_ptr<T>>; 474 using UnorderedUniqueSet = std::unordered_map<T*, std::unique_ptr<T>>;
466 475
467 UnorderedUniqueSet<NotificationData> notifications_; 476 UnorderedUniqueSet<NotificationData> notifications_;
468 }; 477 };
469 478
470 NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux() 479 NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 void NotificationPlatformBridgeLinux::GetDisplayed( 513 void NotificationPlatformBridgeLinux::GetDisplayed(
505 const std::string& profile_id, 514 const std::string& profile_id,
506 bool incognito, 515 bool incognito,
507 const DisplayedNotificationsCallback& callback) { 516 const DisplayedNotificationsCallback& callback) {
508 thread_->task_runner()->PostTask( 517 thread_->task_runner()->PostTask(
509 FROM_HERE, base::Bind(&NativeNotificationThread::GetDisplayed, 518 FROM_HERE, base::Bind(&NativeNotificationThread::GetDisplayed,
510 base::Unretained(thread_.get()), profile_id, 519 base::Unretained(thread_.get()), profile_id,
511 incognito, callback)); 520 incognito, callback));
512 } 521 }
513 522
514 bool NotificationPlatformBridgeLinux::BlockUntilReady() { 523 void NotificationPlatformBridgeLinux::IsConnected(
515 return thread_->BlockUntilReady(); 524 const base::Callback<void(bool)>& callback) {
525 thread_->IsConnected(callback);
516 } 526 }
OLDNEW
« no previous file with comments | « chrome/browser/notifications/notification_platform_bridge_linux.h ('k') | chrome/common/features.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698