1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/typed_url_model_associator.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_backend.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync { 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTypedUrlTag[] = "google_chrome_typed_urls"; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTypedUrlModelAssociator::TypedUrlModelAssociator( 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProfileSyncService* sync_service, 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::HistoryBackend* history_backend) 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : sync_service_(sync_service), 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_backend_(history_backend), 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url_node_id_(sync_api::kInvalidId), 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch expected_loop_(MessageLoop::current()) { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(sync_service_); 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(history_backend_); 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTypedUrlModelAssociator::~TypedUrlModelAssociator() {} 32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::AssociateModels() { 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Associating TypedUrl Models"; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<history::URLRow> typed_urls; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!history_backend_->GetAllTypedURLs(&typed_urls)) { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not get the typed_url entries."; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get all the visits. 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<history::URLID, history::VisitVector> visit_vectors; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<history::URLRow>::iterator ix = typed_urls.begin(); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ix != typed_urls.end(); ++ix) { 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!history_backend_->GetVisitsForURL(ix->id(), 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &(visit_vectors[ix->id()]))) { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not get the url's visits."; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!visit_vectors[ix->id()].empty()); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TypedUrlTitleVector titles; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TypedUrlVector new_urls; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TypedUrlVisitVector new_visits; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TypedUrlUpdateVector updated_urls; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch { 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_api::WriteTransaction trans(sync_service_->GetUserShare()); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode typed_url_root(&trans); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!typed_url_root.InitByTagLookup(kTypedUrlTag)) { 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Server did not create the top-level typed_url node. We " 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "might be running against an out-of-date server."; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<std::string> current_urls; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<history::URLRow>::iterator ix = typed_urls.begin(); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ix != typed_urls.end(); ++ix) { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string tag = ix->url().spec(); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitVector& visits = visit_vectors[ix->id()]; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(visits.size() == static_cast<size_t>(ix->visit_count())); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (visits.size() != static_cast<size_t>(ix->visit_count())) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Visit count does not match."; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode node(&trans); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::TypedUrlSpecifics& typed_url( 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.GetTypedUrlSpecifics()); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(tag, typed_url.url()); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::URLRow new_url(ix->url()); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<base::Time> added_visits; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int difference = MergeUrls(typed_url, *ix, &visits, &new_url, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &added_visits); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (difference & DIFF_NODE_CHANGED) { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode write_node(&trans); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!write_node.InitByClientTagLookup(syncable::TYPED_URLS, tag)) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Failed to edit typed_url sync node."; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteToSyncNode(new_url, visits, &write_node); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (difference & DIFF_TITLE_CHANGED) { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titles.push_back(std::pair<GURL, string16>(new_url.url(), 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.title())); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (difference & DIFF_ROW_CHANGED) { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch updated_urls.push_back( 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::pair<history::URLID, history::URLRow>(ix->id(), new_url)); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (difference & DIFF_VISITS_ADDED) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits.push_back( 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::pair<GURL, std::vector<base::Time> >(ix->url(), 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch added_visits)); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Associate(&tag, node.GetId()); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode node(&trans); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!node.InitUniqueByCreation(syncable::TYPED_URLS, 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url_root, tag)) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Failed to create typed_url sync node."; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.SetTitle(UTF8ToWide(tag)); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteToSyncNode(*ix, visits, &node); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Associate(&tag, node.GetId()); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch current_urls.insert(tag); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 sync_child_id = typed_url_root.GetFirstChildId(); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (sync_child_id != sync_api::kInvalidId) { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode sync_child_node(&trans); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_child_node.InitByIdLookup(sync_child_id)) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Failed to fetch child node."; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::TypedUrlSpecifics& typed_url( 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_child_node.GetTypedUrlSpecifics()); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (current_urls.find(typed_url.url()) == current_urls.end()) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits.push_back( 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::pair<GURL, std::vector<base::Time> >( 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL(typed_url.url()), 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<base::Time>())); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<base::Time>& visits = new_visits.back().second; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::URLRow new_url(GURL(typed_url.url())); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.set_title(UTF8ToUTF16(typed_url.title())); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When we add a new url, the last visit is always added, thus we set 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the initial visit count to one. This value will be automatically 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // incremented as visits are added. 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.set_visit_count(1); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.set_typed_count(typed_url.typed_count()); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.set_hidden(typed_url.hidden()); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The latest visit gets added automatically, so skip it. 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int c = 0; c < typed_url.visit_size() - 1; ++c) { 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(typed_url.visit(c) < typed_url.visit(c + 1)); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visits.push_back(base::Time::FromInternalValue(typed_url.visit(c))); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url.set_last_visit(base::Time::FromInternalValue( 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.visit(typed_url.visit_size() - 1))); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Associate(&typed_url.url(), sync_child_node.GetId()); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_urls.push_back(new_url); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_child_id = sync_child_node.GetSuccessorId(); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Since we're on the history thread, we don't have to worry about updating 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the history database after closing the write transaction, since 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // this is the only thread that writes to the database. We also don't have 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to worry about the sync model getting out of sync, because changes are 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // propagated to the ChangeProcessor on this thread. 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WriteToHistoryBackend(&titles, &new_urls, &updated_urls, 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &new_visits, NULL); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::DeleteAllNodes( 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteTransaction* trans) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TypedUrlToSyncIdMap::iterator node_id = id_map_.begin(); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node_id != id_map_.end(); ++node_id) { 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode sync_node(trans); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitByIdLookup(node_id->second)) { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Typed url node lookup failed."; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_node.Remove(); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_.clear(); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_inverse_.clear(); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::DisassociateModels() { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_.clear(); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_inverse_.clear(); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(has_nodes); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *has_nodes = false; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 typed_url_sync_id; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GetSyncIdForTaggedNode(kTypedUrlTag, &typed_url_sync_id)) { 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Server did not create the top-level typed_url node. We " 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "might be running against an out-of-date server."; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_api::ReadTransaction trans(sync_service_->GetUserShare()); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode typed_url_node(&trans); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!typed_url_node.InitByIdLookup(typed_url_sync_id)) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Server did not create the top-level typed_url node. We " 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "might be running against an out-of-date server."; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The sync model has user created nodes if the typed_url folder has any 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // children. 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *has_nodes = sync_api::kInvalidId != typed_url_node.GetFirstChildId(); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid TypedUrlModelAssociator::AbortAssociation() { 23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(zork): Implement this. 23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst std::string* TypedUrlModelAssociator::GetChromeNodeFromSyncId( 23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int64 sync_id) { 23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return NULL; 24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool TypedUrlModelAssociator::InitSyncNodeFromChromeId( 24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string& node_id, 24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen sync_api::BaseNode* sync_node) { 24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint64 TypedUrlModelAssociator::GetSyncIdFromChromeId( 24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string& typed_url) { 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TypedUrlToSyncIdMap::const_iterator iter = id_map_.find(typed_url); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return iter == id_map_.end() ? sync_api::kInvalidId : iter->second; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TypedUrlModelAssociator::Associate( 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string* typed_url, int64 sync_id) { 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_NE(sync_api::kInvalidId, sync_id); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(id_map_.find(*typed_url) == id_map_.end()); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end()); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_[*typed_url] = sync_id; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_inverse_[sync_id] = *typed_url; 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TypedUrlModelAssociator::Disassociate(int64 sync_id) { 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(expected_loop_ == MessageLoop::current()); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncIdToTypedUrlMap::iterator iter = id_map_inverse_.find(sync_id); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (iter == id_map_inverse_.end()) 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(id_map_.erase(iter->second)); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id_map_inverse_.erase(iter); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64* sync_id) { 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_api::ReadTransaction trans(sync_service_->GetUserShare()); 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::ReadNode sync_node(&trans); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!sync_node.InitByTagLookup(tag.c_str())) 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *sync_id = sync_node.GetId(); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TypedUrlModelAssociator::WriteToHistoryBackend( 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TypedUrlTitleVector* titles, 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TypedUrlVector* new_urls, 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TypedUrlUpdateVector* updated_urls, 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TypedUrlVisitVector* new_visits, 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::VisitVector* deleted_visits) { 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (titles) { 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TypedUrlTitleVector::const_iterator title = titles->begin(); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch title != titles->end(); ++title) { 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_backend_->SetPageTitle(title->first, title->second); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_urls) { 2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick history_backend_->AddPagesWithDetails(*new_urls, history::SOURCE_SYNCED); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (updated_urls) { 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TypedUrlUpdateVector::const_iterator url = updated_urls->begin(); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url != updated_urls->end(); ++url) { 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!history_backend_->UpdateURL(url->first, url->second)) { 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not update page: " << url->second.url().spec(); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_visits) { 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (TypedUrlVisitVector::const_iterator visits = new_visits->begin(); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visits != new_visits->end(); ++visits) { 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!history_backend_->AddVisits(visits->first, visits->second, 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick history::SOURCE_SYNCED)) { 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not add visits."; 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (deleted_visits) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!history_backend_->RemoveVisits(*deleted_visits)) { 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Could not remove visits."; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint TypedUrlModelAssociator::MergeUrls( 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::TypedUrlSpecifics& typed_url, 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLRow& url, 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitVector* visits, 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::URLRow* new_url, 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<base::Time>* new_visits) { 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(new_url); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!typed_url.url().compare(url.url().spec())); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!typed_url.url().compare(new_url->url().spec())); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(visits->size()); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_visit_count(visits->size()); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Convert these values only once. 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 typed_title(UTF8ToUTF16(typed_url.title())); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time typed_visit = 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromInternalValue( 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.visit(typed_url.visit_size() - 1)); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a bitfield represting what we'll need to update with the output 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value. 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int different = DIFF_NONE; 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if the non-incremented values changed. 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((typed_title.compare(url.title()) != 0) || 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (typed_url.hidden() != url.hidden())) { 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use the values from the most recent visit. 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (typed_visit >= url.last_visit()) { 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_title(typed_title); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_hidden(typed_url.hidden()); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_ROW_CHANGED; 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we're changing the local title, note this. 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_url->title().compare(url.title()) != 0) { 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_TITLE_CHANGED; 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_title(url.title()); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_hidden(url.hidden()); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_NODE_CHANGED; 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No difference. 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_title(url.title()); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_hidden(url.hidden()); 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For typed count, we just select the maximum value. 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (typed_url.typed_count() > url.typed_count()) { 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_typed_count(typed_url.typed_count()); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_ROW_CHANGED; 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (typed_url.typed_count() < url.typed_count()) { 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_typed_count(url.typed_count()); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_NODE_CHANGED; 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No difference. 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_typed_count(typed_url.typed_count()); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t left_visit_count = typed_url.visit_size(); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t right_visit_count = visits->size(); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t left = 0; 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t right = 0; 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (left < left_visit_count && right < right_visit_count) { 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time left_time = base::Time::FromInternalValue(typed_url.visit(left)); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (left_time < (*visits)[right].visit_time) { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_VISITS_ADDED; 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits->push_back(left_time); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This visit is added to visits below. 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++left; 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (left_time > (*visits)[right].visit_time) { 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_NODE_CHANGED; 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++right; 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++left; 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++right; 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; left < left_visit_count; ++left) { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch different |= DIFF_VISITS_ADDED; 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time left_time = base::Time::FromInternalValue(typed_url.visit(left)); 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits->push_back(left_time); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This visit is added to visits below. 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (different & DIFF_VISITS_ADDED) { 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitVector::iterator visit_ix = visits->begin(); 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<base::Time>::iterator new_visit = new_visits->begin(); 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visit != new_visits->end(); ++new_visit) { 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (visit_ix != visits->end() && *new_visit > visit_ix->visit_time) { 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++visit_ix; 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visit_ix = visits->insert(visit_ix, 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitRow(url.id(), *new_visit, 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, 0)); 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++visit_ix; 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_url->set_last_visit(visits->back().visit_time); 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(static_cast<size_t>(new_url->visit_count()) == 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (visits->size() - new_visits->size())); 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return different; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TypedUrlModelAssociator::WriteToSyncNode( 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::URLRow& url, 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::VisitVector& visits, 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_api::WriteNode* node) { 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!url.last_visit().is_null()); 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!visits.empty()); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(url.last_visit() == visits.back().visit_time); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::TypedUrlSpecifics typed_url; 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.set_url(url.url().spec()); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.set_title(UTF16ToUTF8(url.title())); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.set_typed_count(url.typed_count()); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.set_hidden(url.hidden()); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (history::VisitVector::const_iterator visit = visits.begin(); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch visit != visits.end(); ++visit) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typed_url.add_visit(visit->visit_time.ToInternalValue()); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node->SetTypedUrlSpecifics(typed_url); 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TypedUrlModelAssociator::DiffVisits( 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const history::VisitVector& old_visits, 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::TypedUrlSpecifics& new_url, 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<base::Time>* new_visits, 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::VisitVector* removed_visits) { 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t left_visit_count = old_visits.size(); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t right_visit_count = new_url.visit_size(); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t left = 0; 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t right = 0; 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (left < left_visit_count && right < right_visit_count) { 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time right_time = base::Time::FromInternalValue(new_url.visit(right)); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (old_visits[left].visit_time < right_time) { 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch removed_visits->push_back(old_visits[left]); 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++left; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (old_visits[left].visit_time > right_time) { 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits->push_back(right_time); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++right; 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++left; 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++right; 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; left < left_visit_count; ++left) { 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch removed_visits->push_back(old_visits[left]); 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; right < right_visit_count; ++right) { 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_visits->push_back(base::Time::FromInternalValue(new_url.visit(right))); 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool TypedUrlModelAssociator::CryptoReadyIfNecessary() { 491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We only access the cryptographer while holding a transaction. 492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sync_api::ReadTransaction trans(sync_service_->GetUserShare()); 493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen syncable::ModelTypeSet encrypted_types; 494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sync_service_->GetEncryptedDataTypes(&encrypted_types); 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return encrypted_types.count(syncable::TYPED_URLS) == 0 || 496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sync_service_->IsCryptographerReady(&trans); 497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace browser_sync 500