session_change_processor.cc revision bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/sync/glue/session_change_processor.h" 6 7#include <sstream> 8#include <string> 9 10#include "base/logging.h" 11#include "chrome/browser/chrome_thread.h" 12#include "chrome/browser/sync/engine/syncapi.h" 13#include "chrome/browser/sync/glue/session_model_associator.h" 14#include "chrome/common/notification_details.h" 15#include "chrome/common/notification_source.h" 16 17namespace browser_sync { 18 19SessionChangeProcessor::SessionChangeProcessor( 20 UnrecoverableErrorHandler* error_handler, 21 SessionModelAssociator* session_model_associator) 22 : ChangeProcessor(error_handler), 23 session_model_associator_(session_model_associator), 24 profile_(NULL) { 25 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 26 DCHECK(error_handler); 27 DCHECK(session_model_associator_); 28} 29 30SessionChangeProcessor::~SessionChangeProcessor() { 31 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 32} 33 34void SessionChangeProcessor::Observe(NotificationType type, 35 const NotificationSource& source, 36 const NotificationDetails& details) { 37 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 38 DCHECK(running()); 39 DCHECK(profile_); 40 switch (type.value) { 41 case NotificationType::SESSION_SERVICE_SAVED: { 42 std::string tag = session_model_associator_->GetCurrentMachineTag(); 43 DCHECK_EQ(Source<Profile>(source).ptr(), profile_); 44 LOG(INFO) << "Got change notification of type " << type.value 45 << " for session " << tag; 46 session_model_associator_->UpdateSyncModelDataFromClient(); 47 break; 48 } 49 default: 50 LOG(DFATAL) << "Received unexpected notification of type " 51 << type.value; 52 break; 53 } 54} 55 56void SessionChangeProcessor::ApplyChangesFromSyncModel( 57 const sync_api::BaseTransaction* trans, 58 const sync_api::SyncManager::ChangeRecord* changes, 59 int change_count) { 60 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 61 if (!running()) { 62 return; 63 } 64 for (int i = 0; i < change_count; ++i) { 65 const sync_api::SyncManager::ChangeRecord& change = changes[i]; 66 switch (change.action) { 67 case sync_api::SyncManager::ChangeRecord::ACTION_ADD: 68 UpdateModel(trans, change, true); 69 break; 70 case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: 71 UpdateModel(trans, change, true); 72 break; 73 case sync_api::SyncManager::ChangeRecord::ACTION_DELETE: 74 UpdateModel(trans, change, false); 75 break; 76 } 77 } 78} 79 80void SessionChangeProcessor::UpdateModel(const sync_api::BaseTransaction* trans, 81 const sync_api::SyncManager::ChangeRecord& change, bool associate) { 82 sync_api::ReadNode node(trans); 83 if (!node.InitByIdLookup(change.id)) { 84 std::stringstream error; 85 error << "Session node lookup failed for change " << change.id 86 << " of action type " << change.action; 87 error_handler()->OnUnrecoverableError(FROM_HERE, error.str()); 88 return; 89 } 90 DCHECK_EQ(node.GetModelType(), syncable::SESSIONS); 91 StopObserving(); 92 if (associate) { 93 session_model_associator_->Associate( 94 (const sync_pb::SessionSpecifics *) NULL, node.GetId()); 95 } else { 96 session_model_associator_->Disassociate(node.GetId()); 97 } 98 StartObserving(); 99} 100 101void SessionChangeProcessor::StartImpl(Profile* profile) { 102 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 103 DCHECK(profile); 104 DCHECK(profile_ == NULL); 105 profile_ = profile; 106 StartObserving(); 107} 108 109void SessionChangeProcessor::StopImpl() { 110 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 111 StopObserving(); 112 profile_ = NULL; 113} 114 115void SessionChangeProcessor::StartObserving() { 116 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 117 DCHECK(profile_); 118 LOG(INFO) << "Observing SESSION_SERVICE_SAVED"; 119 notification_registrar_.Add( 120 this, NotificationType::SESSION_SERVICE_SAVED, 121 Source<Profile>(profile_)); 122} 123 124void SessionChangeProcessor::StopObserving() { 125 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 126 DCHECK(profile_); 127 LOG(INFO) << "removing observation of all notifications"; 128 notification_registrar_.RemoveAll(); 129} 130 131} // namespace browser_sync 132 133