| Index: chrome/browser/sync/notifier/sync_notifier_impl.cc
|
| diff --git a/chrome/browser/sync/notifier/sync_notifier_impl.cc b/chrome/browser/sync/notifier/sync_notifier_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..41433770113aa3311940dbaa8a870490c8aab4ed
|
| --- /dev/null
|
| +++ b/chrome/browser/sync/notifier/sync_notifier_impl.cc
|
| @@ -0,0 +1,196 @@
|
| +// Copyright (c) 2011 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 "chrome/browser/sync/notifier/sync_notifier_impl.h"
|
| +
|
| +#include "chrome/browser/sync/notifier/server_notifier_thread.h"
|
| +#include "chrome/browser/sync/notifier/sync_notifier_observer.h"
|
| +#include "chrome/browser/sync/protocol/service_constants.h"
|
| +#include "chrome/browser/sync/sessions/session_state.h"
|
| +#include "chrome/browser/sync/syncable/model_type.h"
|
| +#include "chrome/browser/sync/sync_constants.h"
|
| +#include "jingle/notifier/listener/mediator_thread_impl.h"
|
| +#include "jingle/notifier/listener/notification_constants.h"
|
| +
|
| +// TODO(akalin): Split this class into two implementations - one for p2p and
|
| +// one for server issued notifications.
|
| +using notifier::TalkMediator;
|
| +using notifier::TalkMediatorImpl;
|
| +namespace sync_notifier {
|
| +
|
| +SyncNotifierImpl::SyncNotifierImpl(
|
| + const notifier::NotifierOptions& notifier_options)
|
| + : notifier_options_(notifier_options),
|
| + server_notifier_thread_(NULL) { }
|
| +
|
| +SyncNotifierImpl::~SyncNotifierImpl() {
|
| + scoped_ptr<TalkMediator> talk_mediator(talk_mediator_.release());
|
| +
|
| + // Shutdown the xmpp buzz connection.
|
| + if (talk_mediator.get()) {
|
| + VLOG(1) << "P2P: Mediator logout started.";
|
| + talk_mediator->Logout();
|
| + VLOG(1) << "P2P: Mediator logout completed.";
|
| + talk_mediator.reset();
|
| +
|
| + // |server_notifier_thread_| is owned by |talk_mediator|. We NULL
|
| + // it out here so as to not have a dangling pointer.
|
| + server_notifier_thread_= NULL;
|
| + VLOG(1) << "P2P: Mediator destroyed.";
|
| + }
|
| +}
|
| +
|
| +void SyncNotifierImpl::AddObserver(SyncNotifierObserver* observer) {
|
| + observer_list_.AddObserver(observer);
|
| +}
|
| +
|
| +void SyncNotifierImpl::RemoveObserver(SyncNotifierObserver* observer) {
|
| + observer_list_.RemoveObserver(observer);
|
| +}
|
| +
|
| +void SyncNotifierImpl::OnNotificationStateChange(bool notifications_enabled) {
|
| + FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_,
|
| + OnNotificationStateChange(notifications_enabled));
|
| +
|
| + // If using p2p notifications, generate a notification for all enabled types.
|
| + // Used only for tests.
|
| + if ((notifier_options_.notification_method !=
|
| + notifier::NOTIFICATION_SERVER) && notifications_enabled) {
|
| + browser_sync::sessions::TypePayloadMap model_types_with_payloads =
|
| + browser_sync::sessions::MakeTypePayloadMapFromBitSet(
|
| + syncable::ModelTypeBitSetFromSet(enabled_types_), std::string());
|
| + FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_,
|
| + OnIncomingNotification(model_types_with_payloads));
|
| + }
|
| +}
|
| +
|
| +void SyncNotifierImpl::OnIncomingNotification(
|
| + const IncomingNotificationData& notification_data) {
|
| + browser_sync::sessions::TypePayloadMap model_types_with_payloads;
|
| +
|
| + // Check if the service url is a sync URL. An empty service URL is
|
| + // treated as a legacy sync notification. If we're listening to
|
| + // server-issued notifications, no need to check the service_url.
|
| + if (notifier_options_.notification_method ==
|
| + notifier::NOTIFICATION_SERVER) {
|
| + VLOG(1) << "Sync received server notification from " <<
|
| + notification_data.service_url << ": " <<
|
| + notification_data.service_specific_data;
|
| + syncable::ModelTypeBitSet model_types;
|
| + const std::string& model_type_list = notification_data.service_url;
|
| + const std::string& notification_payload =
|
| + notification_data.service_specific_data;
|
| +
|
| + if (!syncable::ModelTypeBitSetFromString(model_type_list, &model_types)) {
|
| + LOG(DFATAL) << "Could not extract model types from server data.";
|
| + model_types.set();
|
| + }
|
| +
|
| + model_types_with_payloads =
|
| + browser_sync::sessions::MakeTypePayloadMapFromBitSet(model_types,
|
| + notification_payload);
|
| + } else if (notification_data.service_url.empty() ||
|
| + (notification_data.service_url ==
|
| + browser_sync::kSyncLegacyServiceUrl) ||
|
| + (notification_data.service_url ==
|
| + browser_sync::kSyncServiceUrl)) {
|
| + VLOG(1) << "Sync received P2P notification.";
|
| +
|
| + // Catch for sync integration tests (uses p2p). Just set all enabled
|
| + // datatypes.
|
| + model_types_with_payloads =
|
| + browser_sync::sessions::MakeTypePayloadMapFromBitSet(
|
| + syncable::ModelTypeBitSetFromSet(enabled_types_), std::string());
|
| + } else {
|
| + LOG(WARNING) << "Notification fron unexpected source: "
|
| + << notification_data.service_url;
|
| + }
|
| +
|
| + FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_,
|
| + OnIncomingNotification(model_types_with_payloads));
|
| +}
|
| +
|
| +void SyncNotifierImpl::WriteState(const std::string& state) {
|
| + FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_,
|
| + StoreState(state));
|
| +}
|
| +
|
| +void SyncNotifierImpl::UpdateCredentials(
|
| + const std::string& email, const std::string& token) {
|
| + // Reset talk_mediator_ before creating ServerNotifierThread/MediatorThread,
|
| + // to avoid any problems with having two of those threads at the same time.
|
| + talk_mediator_.reset();
|
| +
|
| + if (notifier_options_.notification_method ==
|
| + notifier::NOTIFICATION_SERVER) {
|
| +
|
| + // |talk_mediator_| takes ownership of |sync_notifier_thread_|
|
| + // but it is guaranteed that |sync_notifier_thread_| is destroyed only
|
| + // when |talk_mediator_| is (see the comments in talk_mediator.h).
|
| + server_notifier_thread_ = new sync_notifier::ServerNotifierThread(
|
| + notifier_options_, state_, this);
|
| + talk_mediator_.reset(
|
| + new TalkMediatorImpl(server_notifier_thread_,
|
| + notifier_options_.invalidate_xmpp_login,
|
| + notifier_options_.allow_insecure_connection));
|
| +
|
| + // Since we may be initialized more than once, make sure that any
|
| + // newly created server notifier thread has the latest enabled types.
|
| + server_notifier_thread_->UpdateEnabledTypes(enabled_types_);
|
| + } else {
|
| + notifier::MediatorThread* mediator_thread =
|
| + new notifier::MediatorThreadImpl(notifier_options_);
|
| + talk_mediator_.reset(
|
| + new TalkMediatorImpl(mediator_thread,
|
| + notifier_options_.invalidate_xmpp_login,
|
| + notifier_options_.allow_insecure_connection));
|
| + talk_mediator_->AddSubscribedServiceUrl(browser_sync::kSyncServiceUrl);
|
| + server_notifier_thread_ = NULL;
|
| + }
|
| + talk_mediator_->SetDelegate(this);
|
| + talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME);
|
| + talk_mediator_->Login();
|
| +}
|
| +
|
| +void SyncNotifierImpl::SetState(const std::string& state) {
|
| + state_ = state;
|
| +}
|
| +
|
| +void SyncNotifierImpl::UpdateEnabledTypes(const syncable::ModelTypeSet& types) {
|
| + enabled_types_ = types;
|
| + if (server_notifier_thread_ != NULL) {
|
| + server_notifier_thread_->UpdateEnabledTypes(types);
|
| + }
|
| +}
|
| +
|
| +void SyncNotifierImpl::SendNotification() {
|
| + // Do nothing if we are using server based notifications.
|
| + if (notifier_options_.notification_method ==
|
| + notifier::NOTIFICATION_SERVER) {
|
| + return;
|
| + }
|
| +
|
| + if (!talk_mediator_.get()) {
|
| + NOTREACHED() << "Cannot send notification: talk_mediator_ is NULL";
|
| + return;
|
| + }
|
| +
|
| + VLOG(1) << "Sending XMPP notification...";
|
| + OutgoingNotificationData notification_data;
|
| + notification_data.service_id = browser_sync::kSyncServiceId;
|
| + notification_data.service_url = browser_sync::kSyncServiceUrl;
|
| + notification_data.send_content = true;
|
| + notification_data.priority = browser_sync::kSyncPriority;
|
| + notification_data.write_to_cache_only = true;
|
| + notification_data.service_specific_data =
|
| + browser_sync::kSyncServiceSpecificData;
|
| + notification_data.require_subscription = true;
|
| + bool success = talk_mediator_->SendNotification(notification_data);
|
| + if (success) {
|
| + VLOG(1) << "Sent XMPP notification";
|
| + } else {
|
| + VLOG(1) << "Could not send XMPP notification";
|
| + }
|
| +}
|
| +} // namespace sync_notifier
|
|
|