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

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: Rebase Created 9 years, 11 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 | 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 if (controller->profile() != profile_) {
63 return;
64 }
65 windows_changed = true;
66 modified_tabs.push_back(controller->tab_contents());
67 break;
68 }
69
70 case NotificationType::TAB_CLOSED: {
71 NavigationController* controller =
72 Source<NavigationController>(source).ptr();
73 if (controller->profile() != profile_) {
74 return;
75 }
76 windows_changed = true;
77 modified_tabs.push_back(controller->tab_contents());
78 break;
79 }
80
81 case NotificationType::NAV_LIST_PRUNED: {
82 NavigationController* controller =
83 Source<NavigationController>(source).ptr();
84 if (controller->profile() != profile_) {
85 return;
86 }
87 modified_tabs.push_back(controller->tab_contents());
88 break;
89 }
90
91 case NotificationType::NAV_ENTRY_CHANGED: {
92 NavigationController* controller =
93 Source<NavigationController>(source).ptr();
94 if (controller->profile() != profile_) {
95 return;
96 }
97 modified_tabs.push_back(controller->tab_contents());
98 break;
99 }
100
101 case NotificationType::NAV_ENTRY_COMMITTED: {
102 NavigationController* controller =
103 Source<NavigationController>(source).ptr();
104 if (controller->profile() != profile_) {
105 return;
106 }
107 modified_tabs.push_back(controller->tab_contents());
108 break;
109 }
110
111 case NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED: {
112 TabContents* tab_contents = Source<TabContents>(source).ptr();
113 DCHECK(tab_contents);
114 if (tab_contents->profile() != profile_) {
115 return;
116 }
117 if (tab_contents->extension_app()) {
118 modified_tabs.push_back(tab_contents);
119 }
48 break; 120 break;
49 } 121 }
50 default: 122 default:
51 LOG(DFATAL) << "Received unexpected notification of type " 123 LOG(ERROR) << "Received unexpected notification of type "
52 << type.value; 124 << type.value;
53 break; 125 break;
54 } 126 }
127
128 // Associate windows first to ensure tabs have homes.
129 if (windows_changed)
130 session_model_associator_->ReassociateWindows(false);
131 if (!modified_tabs.empty())
132 session_model_associator_->ReassociateTabs(modified_tabs);
55 } 133 }
56 134
57 void SessionChangeProcessor::ApplyChangesFromSyncModel( 135 void SessionChangeProcessor::ApplyChangesFromSyncModel(
58 const sync_api::BaseTransaction* trans, 136 const sync_api::BaseTransaction* trans,
59 const sync_api::SyncManager::ChangeRecord* changes, 137 const sync_api::SyncManager::ChangeRecord* changes,
60 int change_count) { 138 int change_count) {
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62 if (!running()) { 140 if (!running()) {
63 return; 141 return;
64 } 142 }
65 143
66 StopObserving(); 144 StopObserving();
67 145
68 // This currently ignores the tracked changes and rebuilds the sessions from 146 sync_api::ReadNode root(trans);
69 // all the session sync nodes. 147 if (!root.InitByTagLookup(kSessionsTag)) {
70 // TODO(zea): Make use of |changes| to adjust only modified sessions. 148 error_handler()->OnUnrecoverableError(FROM_HERE,
71 session_model_associator_->UpdateFromSyncModel(trans); 149 "Sessions root node lookup failed.");
150 return;
151 }
152
153 for (int i = 0; i < change_count; ++i) {
154 const sync_api::SyncManager::ChangeRecord& change = changes[i];
155 sync_api::SyncManager::ChangeRecord::Action action(change.action);
156 if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == action) {
157 // Deletions should only be for a foreign client itself, and hence affect
158 // the header node, never a tab node.
159 sync_api::ReadNode node(trans);
160 if (!node.InitByIdLookup(change.id)) {
161 error_handler()->OnUnrecoverableError(FROM_HERE,
162 "Session node lookup failed.");
163 return;
164 }
165 DCHECK_EQ(node.GetModelType(), syncable::SESSIONS);
166 const sync_pb::SessionSpecifics& specifics = node.GetSessionSpecifics();
167 session_model_associator_->DisassociateForeignSession(
168 specifics.session_tag());
169 continue;
170 }
171
172 // Handle an update or add.
173 sync_api::ReadNode sync_node(trans);
174 if (!sync_node.InitByIdLookup(change.id)) {
175 error_handler()->OnUnrecoverableError(FROM_HERE,
176 "Session node lookup failed.");
177 return;
178 }
179
180 // Check that the changed node is a child of the session folder.
181 DCHECK(root.GetId() == sync_node.GetParentId());
182 DCHECK(syncable::SESSIONS == sync_node.GetModelType());
183
184 const sync_pb::SessionSpecifics& specifics(
185 sync_node.GetSessionSpecifics());
186 const int64 mtime = sync_node.GetModificationTime();
187 // Model associator handles foreign session update and add the same.
188 session_model_associator_->AssociateForeignSpecifics(specifics, mtime);
189 }
72 190
73 // Notify foreign session handlers that there are new sessions. 191 // Notify foreign session handlers that there are new sessions.
74 NotificationService::current()->Notify( 192 NotificationService::current()->Notify(
75 NotificationType::FOREIGN_SESSION_UPDATED, 193 NotificationType::FOREIGN_SESSION_UPDATED,
76 NotificationService::AllSources(), 194 NotificationService::AllSources(),
77 NotificationService::NoDetails()); 195 NotificationService::NoDetails());
78 196
79 StartObserving(); 197 StartObserving();
80 } 198 }
81 199
82 void SessionChangeProcessor::StartImpl(Profile* profile) { 200 void SessionChangeProcessor::StartImpl(Profile* profile) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
84 DCHECK(profile); 202 DCHECK(profile);
85 DCHECK(profile_ == NULL); 203 DCHECK(profile_ == NULL);
86 profile_ = profile; 204 profile_ = profile;
87 StartObserving(); 205 StartObserving();
88 } 206 }
89 207
90 void SessionChangeProcessor::StopImpl() { 208 void SessionChangeProcessor::StopImpl() {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 StopObserving(); 210 StopObserving();
93 profile_ = NULL; 211 profile_ = NULL;
94 } 212 }
95 213
96 void SessionChangeProcessor::StartObserving() { 214 void SessionChangeProcessor::StartObserving() {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 DCHECK(profile_); 216 DCHECK(profile_);
99 notification_registrar_.Add( 217 notification_registrar_.Add(this, NotificationType::TAB_PARENTED,
100 this, NotificationType::SESSION_SERVICE_SAVED, 218 NotificationService::AllSources());
101 Source<Profile>(profile_)); 219 notification_registrar_.Add(this, NotificationType::TAB_CLOSED,
220 NotificationService::AllSources());
221 notification_registrar_.Add(this, NotificationType::NAV_LIST_PRUNED,
222 NotificationService::AllSources());
223 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_CHANGED,
224 NotificationService::AllSources());
225 notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
226 NotificationService::AllSources());
227 notification_registrar_.Add(this, NotificationType::BROWSER_OPENED,
228 NotificationService::AllSources());
229 notification_registrar_.Add(this,
230 NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED,
231 NotificationService::AllSources());
102 } 232 }
103 233
104 void SessionChangeProcessor::StopObserving() { 234 void SessionChangeProcessor::StopObserving() {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106 DCHECK(profile_); 236 DCHECK(profile_);
107 notification_registrar_.RemoveAll(); 237 notification_registrar_.RemoveAll();
108 } 238 }
109 239
110 } // namespace browser_sync 240 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/foreign_session_tracker.cc ('k') | chrome/browser/sync/glue/session_model_associator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698