| OLD | NEW |
| 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_model_associator.h" | 5 #include "chrome/browser/sync/glue/session_model_associator.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 SessionModelAssociator::SessionModelAssociator( | 30 SessionModelAssociator::SessionModelAssociator( |
| 31 ProfileSyncService* sync_service) : sync_service_(sync_service) { | 31 ProfileSyncService* sync_service) : sync_service_(sync_service) { |
| 32 DCHECK(CalledOnValidThread()); | 32 DCHECK(CalledOnValidThread()); |
| 33 DCHECK(sync_service_); | 33 DCHECK(sync_service_); |
| 34 } | 34 } |
| 35 | 35 |
| 36 SessionModelAssociator::~SessionModelAssociator() { | 36 SessionModelAssociator::~SessionModelAssociator() { |
| 37 DCHECK(CalledOnValidThread()); | 37 DCHECK(CalledOnValidThread()); |
| 38 } | 38 } |
| 39 | 39 |
| 40 // Sends a notification to ForeignSessionHandler to update the UI, because | |
| 41 // the session corresponding to the id given has changed state. | |
| 42 void SessionModelAssociator::Associate( | |
| 43 const sync_pb::SessionSpecifics* specifics, int64 sync_id) { | |
| 44 DCHECK(CalledOnValidThread()); | |
| 45 NotificationService::current()->Notify( | |
| 46 NotificationType::FOREIGN_SESSION_UPDATED, | |
| 47 NotificationService::AllSources(), | |
| 48 Details<int64>(&sync_id)); | |
| 49 } | |
| 50 | |
| 51 bool SessionModelAssociator::AssociateModels() { | 40 bool SessionModelAssociator::AssociateModels() { |
| 52 DCHECK(CalledOnValidThread()); | 41 DCHECK(CalledOnValidThread()); |
| 42 |
| 43 // Make sure we have a machine tag. |
| 44 if (current_machine_tag_.empty()) |
| 45 InitializeCurrentMachineTag(); // Creates a syncable::BaseTransaction. |
| 46 |
| 47 { |
| 48 // Do an initial update from sync model (in case we just re-enabled and |
| 49 // already had data). |
| 50 sync_api::ReadTransaction trans( |
| 51 sync_service_->backend()->GetUserShareHandle()); |
| 52 UpdateFromSyncModel(&trans); |
| 53 } |
| 54 |
| 55 // Check if anything has changed on the client side. |
| 53 UpdateSyncModelDataFromClient(); | 56 UpdateSyncModelDataFromClient(); |
| 54 return true; | 57 return true; |
| 55 } | 58 } |
| 56 | 59 |
| 57 bool SessionModelAssociator::ChromeModelHasUserCreatedNodes( | 60 bool SessionModelAssociator::ChromeModelHasUserCreatedNodes( |
| 58 bool* has_nodes) { | 61 bool* has_nodes) { |
| 59 DCHECK(CalledOnValidThread()); | 62 DCHECK(CalledOnValidThread()); |
| 60 CHECK(has_nodes); | 63 CHECK(has_nodes); |
| 61 // This is wrong, but this function is unused, anyway. | 64 // This is wrong, but this function is unused, anyway. |
| 62 *has_nodes = true; | 65 *has_nodes = true; |
| 63 return true; | 66 return true; |
| 64 } | 67 } |
| 65 | 68 |
| 66 // Sends a notification to ForeignSessionHandler to update the UI, because | 69 bool SessionModelAssociator::DisassociateModels() { |
| 67 // the session corresponding to the id given has been deleted. | 70 specifics_.clear(); |
| 68 void SessionModelAssociator::Disassociate(int64 sync_id) { | 71 |
| 72 // There is no local model stored with which to disassociate, just notify |
| 73 // foreign session handlers. |
| 69 NotificationService::current()->Notify( | 74 NotificationService::current()->Notify( |
| 70 NotificationType::FOREIGN_SESSION_DELETED, | 75 NotificationType::FOREIGN_SESSION_DISABLED, |
| 71 NotificationService::AllSources(), | 76 NotificationService::AllSources(), |
| 72 Details<int64>(&sync_id)); | 77 NotificationService::NoDetails()); |
| 78 return true; |
| 73 } | 79 } |
| 74 | 80 |
| 75 const sync_pb::SessionSpecifics* SessionModelAssociator:: | 81 const sync_pb::SessionSpecifics* SessionModelAssociator:: |
| 76 GetChromeNodeFromSyncId(int64 sync_id) { | 82 GetChromeNodeFromSyncId(int64 sync_id) { |
| 77 sync_api::ReadTransaction trans( | 83 sync_api::ReadTransaction trans( |
| 78 sync_service_->backend()->GetUserShareHandle()); | 84 sync_service_->backend()->GetUserShareHandle()); |
| 79 sync_api::ReadNode node(&trans); | 85 sync_api::ReadNode node(&trans); |
| 80 if (!node.InitByIdLookup(sync_id)) | 86 if (!node.InitByIdLookup(sync_id)) |
| 81 return NULL; | 87 return NULL; |
| 82 return new sync_pb::SessionSpecifics(node.GetSessionSpecifics()); | 88 return new sync_pb::SessionSpecifics(node.GetSessionSpecifics()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 113 LOG(ERROR) << kNoSessionsFolderError; | 119 LOG(ERROR) << kNoSessionsFolderError; |
| 114 return false; | 120 return false; |
| 115 } | 121 } |
| 116 // The sync model has user created nodes iff the sessions folder has | 122 // The sync model has user created nodes iff the sessions folder has |
| 117 // any children. | 123 // any children. |
| 118 *has_nodes = root.GetFirstChildId() != sync_api::kInvalidId; | 124 *has_nodes = root.GetFirstChildId() != sync_api::kInvalidId; |
| 119 return true; | 125 return true; |
| 120 } | 126 } |
| 121 | 127 |
| 122 std::string SessionModelAssociator::GetCurrentMachineTag() { | 128 std::string SessionModelAssociator::GetCurrentMachineTag() { |
| 123 if (current_machine_tag_.empty()) | |
| 124 InitializeCurrentMachineTag(); | |
| 125 DCHECK(!current_machine_tag_.empty()); | 129 DCHECK(!current_machine_tag_.empty()); |
| 126 return current_machine_tag_; | 130 return current_machine_tag_; |
| 127 } | 131 } |
| 128 | 132 |
| 129 void SessionModelAssociator::AppendForeignSessionFromSpecifics( | |
| 130 const sync_pb::SessionSpecifics* specifics, | |
| 131 std::vector<ForeignSession*>* session) { | |
| 132 ForeignSession* foreign_session = new ForeignSession(); | |
| 133 foreign_session->foreign_tession_tag = specifics->session_tag(); | |
| 134 session->insert(session->end(), foreign_session); | |
| 135 for (int i = 0; i < specifics->session_window_size(); i++) { | |
| 136 const sync_pb::SessionWindow* window = &specifics->session_window(i); | |
| 137 SessionWindow* session_window = new SessionWindow(); | |
| 138 PopulateSessionWindowFromSpecifics(session_window, window); | |
| 139 foreign_session->windows.insert( | |
| 140 foreign_session->windows.end(), session_window); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 // Fills the given vector with foreign session windows to restore. | |
| 145 void SessionModelAssociator::AppendForeignSessionWithID(int64 id, | |
| 146 std::vector<ForeignSession*>* session, sync_api::BaseTransaction* trans) { | |
| 147 if (id == sync_api::kInvalidId) | |
| 148 return; | |
| 149 sync_api::ReadNode node(trans); | |
| 150 if (!node.InitByIdLookup(id)) | |
| 151 return; | |
| 152 const sync_pb::SessionSpecifics* ref = &node.GetSessionSpecifics(); | |
| 153 AppendForeignSessionFromSpecifics(ref, session); | |
| 154 } | |
| 155 | |
| 156 void SessionModelAssociator::UpdateSyncModelDataFromClient() { | 133 void SessionModelAssociator::UpdateSyncModelDataFromClient() { |
| 157 DCHECK(CalledOnValidThread()); | 134 DCHECK(CalledOnValidThread()); |
| 158 SessionService::SessionCallback* callback = | 135 SessionService::SessionCallback* callback = |
| 159 NewCallback(this, &SessionModelAssociator::OnGotSession); | 136 NewCallback(this, &SessionModelAssociator::OnGotSession); |
| 160 // TODO(jerrica): Stop current race condition, possibly make new method in | 137 // TODO(jerrica): Stop current race condition, possibly make new method in |
| 161 // session service, which only grabs the windows from memory. | 138 // session service, which only grabs the windows from memory. |
| 162 GetSessionService()->GetCurrentSession(&consumer_, callback); | 139 GetSessionService()->GetCurrentSession(&consumer_, callback); |
| 163 } | 140 } |
| 164 | 141 |
| 165 bool SessionModelAssociator::GetSessionDataFromSyncModel( | 142 // TODO(zea): Don't recreate sessions_ vector from scratch each time. This |
| 166 std::vector<ForeignSession*>* sessions) { | 143 // will involve knowing which sessions have been changed (a different data |
| 167 std::vector<const sync_pb::SessionSpecifics*> specifics; | 144 // structure will probably be better too). |
| 145 bool SessionModelAssociator::UpdateFromSyncModel( |
| 146 const sync_api::BaseTransaction* trans) { |
| 168 DCHECK(CalledOnValidThread()); | 147 DCHECK(CalledOnValidThread()); |
| 169 sync_api::ReadTransaction trans( | 148 |
| 170 sync_service_->backend()->GetUserShareHandle()); | 149 // Rebuild specifics_ vector |
| 171 sync_api::ReadNode root(&trans); | 150 specifics_.clear(); |
| 151 if (!QuerySyncModel(trans, specifics_)) { |
| 152 LOG(ERROR) << "SessionModelAssociator failed to updated from sync model"; |
| 153 return false; |
| 154 } |
| 155 |
| 156 return true; |
| 157 } |
| 158 |
| 159 bool SessionModelAssociator::QuerySyncModel( |
| 160 const sync_api::BaseTransaction* trans, |
| 161 std::vector<const sync_pb::SessionSpecifics*>& specifics) { |
| 162 DCHECK(CalledOnValidThread()); |
| 163 sync_api::ReadNode root(trans); |
| 172 if (!root.InitByTagLookup(kSessionsTag)) { | 164 if (!root.InitByTagLookup(kSessionsTag)) { |
| 173 LOG(ERROR) << kNoSessionsFolderError; | 165 LOG(ERROR) << kNoSessionsFolderError; |
| 174 return false; | 166 return false; |
| 175 } | 167 } |
| 176 sync_api::ReadNode current_machine(&trans); | 168 sync_api::ReadNode current_machine(trans); |
| 177 int64 current_id = (current_machine.InitByClientTagLookup(syncable::SESSIONS, | 169 int64 current_id = (current_machine.InitByClientTagLookup(syncable::SESSIONS, |
| 178 GetCurrentMachineTag())) ? current_machine.GetId() : sync_api::kInvalidId; | 170 GetCurrentMachineTag())) ? current_machine.GetId() : sync_api::kInvalidId; |
| 171 |
| 179 // Iterate through the nodes and populate the session model. | 172 // Iterate through the nodes and populate the session model. |
| 180 int64 id = root.GetFirstChildId(); | 173 int64 id = root.GetFirstChildId(); |
| 181 while (id != sync_api::kInvalidId) { | 174 while (id != sync_api::kInvalidId) { |
| 182 sync_api::ReadNode sync_node(&trans); | 175 sync_api::ReadNode sync_node(trans); |
| 183 if (!sync_node.InitByIdLookup(id)) { | 176 if (!sync_node.InitByIdLookup(id)) { |
| 184 LOG(ERROR) << "Failed to fetch sync node for id " << id; | 177 LOG(ERROR) << "Failed to fetch sync node for id " << id; |
| 185 return false; | 178 return false; |
| 186 } | 179 } |
| 187 if (id != current_id) { | 180 if (id != current_id) { |
| 188 specifics.insert(specifics.end(), &sync_node.GetSessionSpecifics()); | 181 specifics.insert(specifics.end(), &sync_node.GetSessionSpecifics()); |
| 189 } | 182 } |
| 190 id = sync_node.GetSuccessorId(); | 183 id = sync_node.GetSuccessorId(); |
| 191 } | 184 } |
| 185 return true; |
| 186 } |
| 187 |
| 188 bool SessionModelAssociator::GetSessionData( |
| 189 std::vector<ForeignSession*>* sessions) { |
| 190 DCHECK(CalledOnValidThread()); |
| 191 |
| 192 // Build vector of sessions from specifics data |
| 192 for (std::vector<const sync_pb::SessionSpecifics*>::const_iterator i = | 193 for (std::vector<const sync_pb::SessionSpecifics*>::const_iterator i = |
| 193 specifics.begin(); i != specifics.end(); ++i) { | 194 specifics_.begin(); i != specifics_.end(); ++i) { |
| 194 AppendForeignSessionFromSpecifics(*i, sessions); | 195 AppendForeignSessionFromSpecifics(*i, sessions); |
| 195 } | 196 } |
| 197 |
| 196 return true; | 198 return true; |
| 197 } | 199 } |
| 198 | 200 |
| 201 void SessionModelAssociator::AppendForeignSessionFromSpecifics( |
| 202 const sync_pb::SessionSpecifics* specifics, |
| 203 std::vector<ForeignSession*>* session) { |
| 204 ForeignSession* foreign_session = new ForeignSession(); |
| 205 foreign_session->foreign_tession_tag = specifics->session_tag(); |
| 206 session->insert(session->end(), foreign_session); |
| 207 for (int i = 0; i < specifics->session_window_size(); i++) { |
| 208 const sync_pb::SessionWindow* window = &specifics->session_window(i); |
| 209 SessionWindow* session_window = new SessionWindow(); |
| 210 PopulateSessionWindowFromSpecifics(session_window, window); |
| 211 foreign_session->windows.insert( |
| 212 foreign_session->windows.end(), session_window); |
| 213 } |
| 214 } |
| 215 |
| 216 // Fills the given vector with foreign session windows to restore. |
| 217 void SessionModelAssociator::AppendForeignSessionWithID(int64 id, |
| 218 std::vector<ForeignSession*>* session, sync_api::BaseTransaction* trans) { |
| 219 if (id == sync_api::kInvalidId) |
| 220 return; |
| 221 sync_api::ReadNode node(trans); |
| 222 if (!node.InitByIdLookup(id)) |
| 223 return; |
| 224 const sync_pb::SessionSpecifics* ref = &node.GetSessionSpecifics(); |
| 225 AppendForeignSessionFromSpecifics(ref, session); |
| 226 } |
| 227 |
| 199 SessionService* SessionModelAssociator::GetSessionService() { | 228 SessionService* SessionModelAssociator::GetSessionService() { |
| 200 DCHECK(sync_service_); | 229 DCHECK(sync_service_); |
| 201 Profile* profile = sync_service_->profile(); | 230 Profile* profile = sync_service_->profile(); |
| 202 DCHECK(profile); | 231 DCHECK(profile); |
| 203 SessionService* sessions_service = profile->GetSessionService(); | 232 SessionService* sessions_service = profile->GetSessionService(); |
| 204 DCHECK(sessions_service); | 233 DCHECK(sessions_service); |
| 205 return sessions_service; | 234 return sessions_service; |
| 206 } | 235 } |
| 207 | 236 |
| 208 void SessionModelAssociator::InitializeCurrentMachineTag() { | 237 void SessionModelAssociator::InitializeCurrentMachineTag() { |
| 209 sync_api::WriteTransaction trans(sync_service_->backend()-> | 238 sync_api::WriteTransaction trans(sync_service_->backend()-> |
| 210 GetUserShareHandle()); | 239 GetUserShareHandle()); |
| 211 syncable::Directory* dir = | 240 syncable::Directory* dir = |
| 212 trans.GetWrappedWriteTrans()->directory(); | 241 trans.GetWrappedWriteTrans()->directory(); |
| 242 |
| 243 // TODO(zea): We need a better way of creating a machine tag. The directory |
| 244 // kernel's cache_guid changes every time syncing is turned on and off. This |
| 245 // will result in session's associated with stale machine tags persisting on |
| 246 // the server since that tag will not be reused. Eventually this should |
| 247 // become some string identifiable to the user. (Home, Work, Laptop, etc.) |
| 248 // See issue 59672 |
| 213 current_machine_tag_ = "session_sync"; | 249 current_machine_tag_ = "session_sync"; |
| 214 current_machine_tag_.append(dir->cache_guid()); | 250 current_machine_tag_.append(dir->cache_guid()); |
| 251 LOG(INFO) << "Creating machine tag: " << current_machine_tag_; |
| 215 } | 252 } |
| 216 | 253 |
| 217 // See PopulateSessionSpecificsTab for use. May add functionality that includes | 254 // See PopulateSessionSpecificsTab for use. May add functionality that includes |
| 218 // the state later. | 255 // the state later. |
| 219 void SessionModelAssociator::PopulateSessionSpecificsNavigation( | 256 void SessionModelAssociator::PopulateSessionSpecificsNavigation( |
| 220 const TabNavigation* navigation, sync_pb::TabNavigation* tab_navigation) { | 257 const TabNavigation* navigation, sync_pb::TabNavigation* tab_navigation) { |
| 221 tab_navigation->set_index(navigation->index()); | 258 tab_navigation->set_index(navigation->index()); |
| 222 tab_navigation->set_virtual_url(navigation->virtual_url().spec()); | 259 tab_navigation->set_virtual_url(navigation->virtual_url().spec()); |
| 223 tab_navigation->set_referrer(navigation->referrer().spec()); | 260 tab_navigation->set_referrer(navigation->referrer().spec()); |
| 224 tab_navigation->set_title(UTF16ToUTF8(navigation->title())); | 261 tab_navigation->set_title(UTF16ToUTF8(navigation->title())); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 return false; | 555 return false; |
| 519 } | 556 } |
| 520 create_node.SetSessionSpecifics(*session_data); | 557 create_node.SetSessionSpecifics(*session_data); |
| 521 return true; | 558 return true; |
| 522 } | 559 } |
| 523 write_node.SetSessionSpecifics(*session_data); | 560 write_node.SetSessionSpecifics(*session_data); |
| 524 return true; | 561 return true; |
| 525 } | 562 } |
| 526 | 563 |
| 527 } // namespace browser_sync | 564 } // namespace browser_sync |
| 528 | |
| OLD | NEW |