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

Side by Side Diff: chrome/browser/sync/glue/session_change_processor.cc

Issue 5705004: [SYNC] Sessions datatype refactor. Most things related to sessions under-the-... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix typecasting that windows didn't like Created 10 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 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/sync/glue/session_change_processor.h" 5 #include "chrome/browser/sync/glue/session_change_processor.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/scoped_vector.h" 12 #include "base/scoped_vector.h"
13 #include "chrome/browser/browser_thread.h"
14 #include "chrome/browser/sync/engine/syncapi.h" 13 #include "chrome/browser/sync/engine/syncapi.h"
15 #include "chrome/browser/sync/glue/session_model_associator.h" 14 #include "chrome/browser/sync/glue/session_model_associator.h"
15 #include "chrome/browser/tab_contents/navigation_controller.h"
16 #include "chrome/browser/tab_contents/tab_contents.h"
16 #include "chrome/common/notification_details.h" 17 #include "chrome/common/notification_details.h"
17 #include "chrome/common/notification_service.h" 18 #include "chrome/common/notification_service.h"
18 #include "chrome/common/notification_source.h" 19 #include "chrome/common/notification_source.h"
19 20
20 namespace browser_sync { 21 namespace browser_sync {
21 22
22 SessionChangeProcessor::SessionChangeProcessor( 23 SessionChangeProcessor::SessionChangeProcessor(
23 UnrecoverableErrorHandler* error_handler, 24 UnrecoverableErrorHandler* error_handler,
24 SessionModelAssociator* session_model_associator) 25 SessionModelAssociator* session_model_associator)
25 : ChangeProcessor(error_handler), 26 : ChangeProcessor(error_handler),
26 session_model_associator_(session_model_associator), 27 session_model_associator_(session_model_associator),
27 profile_(NULL) { 28 profile_(NULL) {
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
29 DCHECK(error_handler); 30 DCHECK(error_handler);
30 DCHECK(session_model_associator_); 31 DCHECK(session_model_associator_);
31 } 32 }
32 33
33 SessionChangeProcessor::~SessionChangeProcessor() { 34 SessionChangeProcessor::~SessionChangeProcessor() {
34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
35 } 36 }
36 37
37 void SessionChangeProcessor::Observe(NotificationType type, 38 void SessionChangeProcessor::Observe(NotificationType type,
38 const NotificationSource& source, 39 const NotificationSource& source,
39 const NotificationDetails& details) { 40 const NotificationDetails& details) {
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
41 DCHECK(running()); 42 DCHECK(running());
42 DCHECK(profile_); 43 DCHECK(profile_);
44
45 // Track which windows and/or tabs are modified.
46 std::vector<TabContents*> modified_tabs;
47 bool windows_changed = false;
43 switch (type.value) { 48 switch (type.value) {
44 case NotificationType::SESSION_SERVICE_SAVED: { 49 case NotificationType::BROWSER_OPENED: {
45 std::string tag = session_model_associator_->GetCurrentMachineTag(); 50 Browser* browser = Source<Browser>(source).ptr();
46 DCHECK_EQ(Source<Profile>(source).ptr(), profile_); 51 if (browser->profile() != profile_) {
47 session_model_associator_->UpdateSyncModelDataFromClient(); 52 return;
53 }
54
55 windows_changed = true;
56 break;
57 }
58
59 case NotificationType::TAB_PARENTED: {
60 NavigationController* controller =
61 Source<NavigationController>(source).ptr();
62 windows_changed = true;
63 modified_tabs.push_back(controller->tab_contents());
64 break;
65 }
66
67 case NotificationType::TAB_CLOSED: {
68 windows_changed = true;
69 // TODO(zea): mark tab as closed? For now we just make sure the window
70 // no longer tracks this tab.
71 break;
72 }
73
74 case NotificationType::NAV_LIST_PRUNED: {
75 NavigationController* controller =
76 Source<NavigationController>(source).ptr();
77 modified_tabs.push_back(controller->tab_contents());
78 break;
79 }
80
81 case NotificationType::NAV_ENTRY_CHANGED: {
82 NavigationController* controller =
83 Source<NavigationController>(source).ptr();
84 modified_tabs.push_back(controller->tab_contents());
85 break;
86 }
87
88 case NotificationType::NAV_ENTRY_COMMITTED: {
89 NavigationController* controller =
90 Source<NavigationController>(source).ptr();
91 modified_tabs.push_back(controller->tab_contents());
92 break;
93 }
94
95 case NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED: {
96 TabContents* tab_contents = Source<TabContents>(source).ptr();
97 DCHECK(tab_contents);
98 if (tab_contents->extension_app()) {
99 modified_tabs.push_back(tab_contents);
100 }
48 break; 101 break;
49 } 102 }
50 default: 103 default:
51 LOG(DFATAL) << "Received unexpected notification of type " 104 LOG(ERROR) << "Received unexpected notification of type "
52 << type.value; 105 << type.value;
53 break; 106 break;
54 } 107 }
108
109 // Associate windows first to ensure tabs have homes.
110 if (windows_changed)
111 session_model_associator_->ReassociateWindows(false);
112 if (!modified_tabs.empty())
113 session_model_associator_->ReassociateTabs(modified_tabs);
55 } 114 }
56 115
57 void SessionChangeProcessor::ApplyChangesFromSyncModel( 116 void SessionChangeProcessor::ApplyChangesFromSyncModel(
58 const sync_api::BaseTransaction* trans, 117 const sync_api::BaseTransaction* trans,
59 const sync_api::SyncManager::ChangeRecord* changes, 118 const sync_api::SyncManager::ChangeRecord* changes,
60 int change_count) { 119 int change_count) {
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62 if (!running()) { 121 if (!running()) {
63 return; 122 return;
64 } 123 }
65 124
66 StopObserving(); 125 StopObserving();
67 126
68 // This currently ignores the tracked changes and rebuilds the sessions from 127 sync_api::ReadNode root(trans);
69 // all the session sync nodes. 128 if (!root.InitByTagLookup(kSessionsTag)) {
70 // TODO(zea): Make use of |changes| to adjust only modified sessions. 129 error_handler()->OnUnrecoverableError(FROM_HERE,
71 session_model_associator_->UpdateFromSyncModel(trans); 130 "Sessions root node lookup failed.");
131 return;
132 }
133
134 for (int i = 0; i < change_count; ++i) {
135 const sync_api::SyncManager::ChangeRecord& change = changes[i];
136 sync_api::SyncManager::ChangeRecord::Action action(change.action);
137 if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == action) {
138 // Deletions should only be for a foreign client itself, and hence affect
139 // the header node, never a tab node.
140 sync_api::ReadNode node(trans);
141 if (!node.InitByIdLookup(change.id)) {
142 error_handler()->OnUnrecoverableError(FROM_HERE,
143 "Session node lookup failed.");
144 return;
145 }
146 DCHECK_EQ(node.GetModelType(), syncable::SESSIONS);
147 const sync_pb::SessionSpecifics& specifics = node.GetSessionSpecifics();
148 session_model_associator_->DisassociateForeignSession(
149 specifics.session_tag());
150 continue;
151 }
152
153 // Handle an update or add.
154 sync_api::ReadNode sync_node(trans);
155 if (!sync_node.InitByIdLookup(change.id)) {
156 error_handler()->OnUnrecoverableError(FROM_HERE,
157 "Session node lookup failed.");
158 return;
159 }
160
161 // Check that the changed node is a child of the session folder.
162 DCHECK(root.GetId() == sync_node.GetParentId());
163 DCHECK(syncable::SESSIONS == sync_node.GetModelType());
164
165 const sync_pb::SessionSpecifics& specifics(
166 sync_node.GetSessionSpecifics());
167 const int64 mtime = sync_node.GetModificationTime();
168 // Model associator handles foreign session update and add the same.
169 session_model_associator_->AssociateForeignSpecifics(specifics, mtime);
170 }
72 171
73 // Notify foreign session handlers that there are new sessions. 172 // Notify foreign session handlers that there are new sessions.
74 NotificationService::current()->Notify( 173 NotificationService::current()->Notify(
75 NotificationType::FOREIGN_SESSION_UPDATED, 174 NotificationType::FOREIGN_SESSION_UPDATED,
76 NotificationService::AllSources(), 175 NotificationService::AllSources(),
77 NotificationService::NoDetails()); 176 NotificationService::NoDetails());
78 177
79 StartObserving(); 178 StartObserving();
80 } 179 }
81 180
82 void SessionChangeProcessor::StartImpl(Profile* profile) { 181 void SessionChangeProcessor::StartImpl(Profile* profile) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84 DCHECK(profile); 183 DCHECK(profile);
85 DCHECK(profile_ == NULL); 184 DCHECK(profile_ == NULL);
86 profile_ = profile; 185 profile_ = profile;
87 StartObserving(); 186 StartObserving();
88 } 187 }
89 188
90 void SessionChangeProcessor::StopImpl() { 189 void SessionChangeProcessor::StopImpl() {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 StopObserving(); 191 StopObserving();
93 profile_ = NULL; 192 profile_ = NULL;
94 } 193 }
95 194
96 void SessionChangeProcessor::StartObserving() { 195 void SessionChangeProcessor::StartObserving() {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 DCHECK(profile_); 197 DCHECK(profile_);
99 notification_registrar_.Add( 198 notification_registrar_.Add(this, NotificationType::TAB_PARENTED,
100 this, NotificationType::SESSION_SERVICE_SAVED, 199 NotificationService::AllSources());
101 Source<Profile>(profile_)); 200 notification_registrar_.Add(this, NotificationType::TAB_CLOSED,
201 NotificationService::AllSources());
202 notification_registrar_.Add(this, NotificationType::NAV_LIST_PRUNED,
203 NotificationService::AllSources());
204 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_CHANGED,
205 NotificationService::AllSources());
206 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
207 NotificationService::AllSources());
208 notification_registrar_.Add(this, NotificationType::BROWSER_OPENED,
209 NotificationService::AllSources());
tim (not reviewing) 2010/12/15 21:14:00 seems like we should specify the source (Profile,
Nicolas Zea 2010/12/16 18:09:18 The source is either the Browser, NavigationContro
210 notification_registrar_.Add(this,
211 NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
212 NotificationService::AllSources());
102 } 213 }
103 214
104 void SessionChangeProcessor::StopObserving() { 215 void SessionChangeProcessor::StopObserving() {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106 DCHECK(profile_); 217 DCHECK(profile_);
107 notification_registrar_.RemoveAll(); 218 notification_registrar_.RemoveAll();
108 } 219 }
109 220
110 } // namespace browser_sync 221 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698