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

Unified Diff: jingle/notifier/listener/non_blocking_push_client.cc

Issue 10413014: [Sync] Turn notifier::PushClient into an interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head Created 8 years, 7 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: jingle/notifier/listener/non_blocking_push_client.cc
diff --git a/jingle/notifier/listener/non_blocking_push_client.cc b/jingle/notifier/listener/non_blocking_push_client.cc
new file mode 100644
index 0000000000000000000000000000000000000000..23a84029523362037bb064c27685984391a23296
--- /dev/null
+++ b/jingle/notifier/listener/non_blocking_push_client.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "jingle/notifier/listener/non_blocking_push_client.h"
+
+#include "base/bind.h"
+#include "base/message_loop_proxy.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "jingle/notifier/listener/push_client_observer.h"
+
+namespace notifier {
+
+// All methods are called on the delegate thread unless specified
+// otherwise.
+class NonBlockingPushClient::Core
+ : public base::RefCountedThreadSafe<NonBlockingPushClient::Core>,
+ public PushClientObserver {
+ public:
+ // Called on the parent thread.
+ explicit Core(
+ const scoped_refptr<base::SingleThreadTaskRunner>&
+ delegate_task_runner,
+ const base::WeakPtr<NonBlockingPushClient>& parent_push_client);
+
+ // Must be called after being created.
+ //
+ // This is separated out from the constructor since posting tasks
+ // from the constructor is dangerous.
+ void CreateOnDelegateThread(
+ const CreateBlockingPushClientCallback&
+ create_blocking_push_client_callback);
+
+ // Must be called before being destroyed.
+ void DestroyOnDelegateThread();
+
+ void UpdateSubscriptions(const SubscriptionList& subscriptions);
+ void UpdateCredentials(const std::string& email, const std::string& token);
+ void SendNotification(const Notification& data);
+
+ virtual void OnNotificationStateChange(
+ bool notifications_enabled) OVERRIDE;
+ virtual void OnIncomingNotification(
+ const Notification& notification) OVERRIDE;
+
+ private:
+ friend class base::RefCountedThreadSafe<NonBlockingPushClient::Core>;
+
+ // Called on either the parent thread or the delegate thread.
+ virtual ~Core();
+
+ const scoped_refptr<base::SingleThreadTaskRunner> parent_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_;
+
+ const base::WeakPtr<NonBlockingPushClient> parent_push_client_;
+ scoped_ptr<PushClient> delegate_push_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+NonBlockingPushClient::Core::Core(
+ const scoped_refptr<base::SingleThreadTaskRunner>& delegate_task_runner,
+ const base::WeakPtr<NonBlockingPushClient>& parent_push_client)
+ : parent_task_runner_(base::MessageLoopProxy::current()),
+ delegate_task_runner_(delegate_task_runner),
+ parent_push_client_(parent_push_client) {}
+
+NonBlockingPushClient::Core::~Core() {
+ DCHECK(parent_task_runner_->BelongsToCurrentThread() ||
+ delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(!delegate_push_client_.get());
+}
+
+void NonBlockingPushClient::Core::CreateOnDelegateThread(
+ const CreateBlockingPushClientCallback&
+ create_blocking_push_client_callback) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(!delegate_push_client_.get());
+ delegate_push_client_ = create_blocking_push_client_callback.Run();
+ delegate_push_client_->AddObserver(this);
+}
+
+void NonBlockingPushClient::Core::DestroyOnDelegateThread() {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(delegate_push_client_.get());
+ delegate_push_client_->RemoveObserver(this);
+ delegate_push_client_.reset();
+}
+
+void NonBlockingPushClient::Core::UpdateSubscriptions(
+ const SubscriptionList& subscriptions) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(delegate_push_client_.get());
+ delegate_push_client_->UpdateSubscriptions(subscriptions);
+}
+
+void NonBlockingPushClient::Core::UpdateCredentials(
+ const std::string& email, const std::string& token) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(delegate_push_client_.get());
+ delegate_push_client_->UpdateCredentials(email, token);
+}
+
+void NonBlockingPushClient::Core::SendNotification(
+ const Notification& notification) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ DCHECK(delegate_push_client_.get());
+ delegate_push_client_->SendNotification(notification);
+}
+
+void NonBlockingPushClient::Core::OnNotificationStateChange(
+ bool notifications_enabled) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ parent_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::OnNotificationStateChange,
+ parent_push_client_, notifications_enabled));
+}
+
+void NonBlockingPushClient::Core::OnIncomingNotification(
+ const Notification& notification) {
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread());
+ parent_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::OnIncomingNotification,
+ parent_push_client_, notification));
+}
+
+NonBlockingPushClient::NonBlockingPushClient(
+ const scoped_refptr<base::SingleThreadTaskRunner>& delegate_task_runner,
+ const CreateBlockingPushClientCallback&
+ create_blocking_push_client_callback)
+ : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ delegate_task_runner_(delegate_task_runner),
+ core_(new Core(delegate_task_runner_,
+ weak_ptr_factory_.GetWeakPtr())) {
+ delegate_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::Core::CreateOnDelegateThread,
+ core_.get(), create_blocking_push_client_callback));
+}
+
+NonBlockingPushClient::~NonBlockingPushClient() {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ delegate_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::Core::DestroyOnDelegateThread,
+ core_.get()));
+}
+
+void NonBlockingPushClient::AddObserver(PushClientObserver* observer) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ observers_.AddObserver(observer);
+}
+
+void NonBlockingPushClient::RemoveObserver(PushClientObserver* observer) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ observers_.RemoveObserver(observer);
+}
+
+void NonBlockingPushClient::UpdateSubscriptions(
+ const SubscriptionList& subscriptions) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ delegate_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::Core::UpdateSubscriptions,
+ core_.get(), subscriptions));
+}
+
+void NonBlockingPushClient::UpdateCredentials(
+ const std::string& email, const std::string& token) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ delegate_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::Core::UpdateCredentials,
+ core_.get(), email, token));
+}
+
+void NonBlockingPushClient::SendNotification(
+ const Notification& notification) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ delegate_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&NonBlockingPushClient::Core::SendNotification, core_.get(),
+ notification));
+}
+
+void NonBlockingPushClient::OnNotificationStateChange(
+ bool notifications_enabled) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ FOR_EACH_OBSERVER(PushClientObserver, observers_,
+ OnNotificationStateChange(notifications_enabled));
+}
+
+void NonBlockingPushClient::OnIncomingNotification(
+ const Notification& notification) {
+ DCHECK(non_thread_safe_.CalledOnValidThread());
+ FOR_EACH_OBSERVER(PushClientObserver, observers_,
+ OnIncomingNotification(notification));
+}
+
+} // namespace notifier
« no previous file with comments | « jingle/notifier/listener/non_blocking_push_client.h ('k') | jingle/notifier/listener/non_blocking_push_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698