OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/typed_url_change_processor.h" | 5 #include "chrome/browser/sync/glue/typed_url_change_processor.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 DCHECK(error_handler); | 51 DCHECK(error_handler); |
52 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); | 52 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); |
53 // When running in unit tests, there is already a NotificationService object. | 53 // When running in unit tests, there is already a NotificationService object. |
54 // Since only one can exist at a time per thread, check first. | 54 // Since only one can exist at a time per thread, check first. |
55 if (!content::NotificationService::current()) | 55 if (!content::NotificationService::current()) |
56 notification_service_.reset(content::NotificationService::Create()); | 56 notification_service_.reset(content::NotificationService::Create()); |
57 } | 57 } |
58 | 58 |
59 TypedUrlChangeProcessor::~TypedUrlChangeProcessor() { | 59 TypedUrlChangeProcessor::~TypedUrlChangeProcessor() { |
60 DCHECK(backend_loop_ == base::MessageLoop::current()); | 60 DCHECK(backend_loop_ == base::MessageLoop::current()); |
| 61 DCHECK(history_backend_); |
| 62 history_backend_->RemoveObserver(this); |
61 } | 63 } |
62 | 64 |
63 void TypedUrlChangeProcessor::Observe( | 65 void TypedUrlChangeProcessor::Observe( |
64 int type, | 66 int type, |
65 const content::NotificationSource& source, | 67 const content::NotificationSource& source, |
66 const content::NotificationDetails& details) { | 68 const content::NotificationDetails& details) { |
67 DCHECK(backend_loop_ == base::MessageLoop::current()); | 69 DCHECK(backend_loop_ == base::MessageLoop::current()); |
68 | 70 |
69 base::AutoLock al(disconnect_lock_); | 71 base::AutoLock al(disconnect_lock_); |
70 if (disconnected_) | 72 if (disconnected_) |
71 return; | 73 return; |
72 | 74 |
73 DVLOG(1) << "Observed typed_url change."; | 75 DVLOG(1) << "Observed typed_url change."; |
74 if (type == chrome::NOTIFICATION_HISTORY_URLS_MODIFIED) { | 76 if (type == chrome::NOTIFICATION_HISTORY_URLS_MODIFIED) { |
75 HandleURLsModified( | 77 HandleURLsModified( |
76 content::Details<history::URLsModifiedDetails>(details).ptr()); | 78 content::Details<history::URLsModifiedDetails>(details).ptr()); |
77 } else if (type == chrome::NOTIFICATION_HISTORY_URLS_DELETED) { | 79 } else if (type == chrome::NOTIFICATION_HISTORY_URLS_DELETED) { |
78 HandleURLsDeleted( | 80 HandleURLsDeleted( |
79 content::Details<history::URLsDeletedDetails>(details).ptr()); | 81 content::Details<history::URLsDeletedDetails>(details).ptr()); |
80 } else { | |
81 DCHECK_EQ(chrome::NOTIFICATION_HISTORY_URL_VISITED, type); | |
82 HandleURLsVisited( | |
83 content::Details<history::URLVisitedDetails>(details).ptr()); | |
84 } | 82 } |
85 UMA_HISTOGRAM_PERCENTAGE("Sync.TypedUrlChangeProcessorErrors", | 83 UMA_HISTOGRAM_PERCENTAGE("Sync.TypedUrlChangeProcessorErrors", |
86 model_associator_->GetErrorPercentage()); | 84 model_associator_->GetErrorPercentage()); |
| 85 } |
| 86 |
| 87 void TypedUrlChangeProcessor::OnURLVisited( |
| 88 history::HistoryBackend* history_backend, |
| 89 ui::PageTransition transition, |
| 90 const history::URLRow& row, |
| 91 const history::RedirectList& redirects, |
| 92 base::Time visit_time) { |
| 93 DCHECK(backend_loop_ == base::MessageLoop::current()); |
| 94 |
| 95 base::AutoLock al(disconnect_lock_); |
| 96 if (disconnected_) |
| 97 return; |
| 98 |
| 99 DVLOG(1) << "Observed typed_url change."; |
| 100 if (ShouldSyncVisit(row.typed_count(), transition)) { |
| 101 syncer::WriteTransaction trans(FROM_HERE, share_handle()); |
| 102 CreateOrUpdateSyncNode(row, &trans); |
| 103 } |
| 104 UMA_HISTOGRAM_PERCENTAGE("Sync.TypedUrlChangeProcessorErrors", |
| 105 model_associator_->GetErrorPercentage()); |
87 } | 106 } |
88 | 107 |
89 void TypedUrlChangeProcessor::HandleURLsModified( | 108 void TypedUrlChangeProcessor::HandleURLsModified( |
90 history::URLsModifiedDetails* details) { | 109 history::URLsModifiedDetails* details) { |
91 | 110 |
92 syncer::WriteTransaction trans(FROM_HERE, share_handle()); | 111 syncer::WriteTransaction trans(FROM_HERE, share_handle()); |
93 for (history::URLRows::iterator url = details->changed_urls.begin(); | 112 for (history::URLRows::iterator url = details->changed_urls.begin(); |
94 url != details->changed_urls.end(); ++url) { | 113 url != details->changed_urls.end(); ++url) { |
95 if (url->typed_count() > 0) { | 114 if (url->typed_count() > 0) { |
96 // If there were any errors updating the sync node, just ignore them and | 115 // If there were any errors updating the sync node, just ignore them and |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 // in the sync DB. | 207 // in the sync DB. |
189 if (sync_node.InitByClientTagLookup(syncer::TYPED_URLS, | 208 if (sync_node.InitByClientTagLookup(syncer::TYPED_URLS, |
190 row->url().spec()) == | 209 row->url().spec()) == |
191 syncer::BaseNode::INIT_OK) { | 210 syncer::BaseNode::INIT_OK) { |
192 sync_node.Tombstone(); | 211 sync_node.Tombstone(); |
193 } | 212 } |
194 } | 213 } |
195 } | 214 } |
196 } | 215 } |
197 | 216 |
198 void TypedUrlChangeProcessor::HandleURLsVisited( | 217 bool TypedUrlChangeProcessor::ShouldSyncVisit(int typed_count, |
199 history::URLVisitedDetails* details) { | 218 ui::PageTransition transition) { |
200 if (!ShouldSyncVisit(details)) | |
201 return; | |
202 | |
203 syncer::WriteTransaction trans(FROM_HERE, share_handle()); | |
204 CreateOrUpdateSyncNode(details->row, &trans); | |
205 } | |
206 | |
207 bool TypedUrlChangeProcessor::ShouldSyncVisit( | |
208 history::URLVisitedDetails* details) { | |
209 int typed_count = details->row.typed_count(); | |
210 ui::PageTransition transition = | |
211 ui::PageTransitionStripQualifier(details->transition); | |
212 | |
213 // Just use an ad-hoc criteria to determine whether to ignore this | 219 // Just use an ad-hoc criteria to determine whether to ignore this |
214 // notification. For most users, the distribution of visits is roughly a bell | 220 // notification. For most users, the distribution of visits is roughly a bell |
215 // curve with a long tail - there are lots of URLs with < 5 visits so we want | 221 // curve with a long tail - there are lots of URLs with < 5 visits so we want |
216 // to make sure we sync up every visit to ensure the proper ordering of | 222 // to make sure we sync up every visit to ensure the proper ordering of |
217 // suggestions. But there are relatively few URLs with > 10 visits, and those | 223 // suggestions. But there are relatively few URLs with > 10 visits, and those |
218 // tend to be more broadly distributed such that there's no need to sync up | 224 // tend to be more broadly distributed such that there's no need to sync up |
219 // every visit to preserve their relative ordering. | 225 // every visit to preserve their relative ordering. |
220 return (transition == ui::PAGE_TRANSITION_TYPED && | 226 return (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) && |
221 typed_count > 0 && | 227 typed_count > 0 && |
222 (typed_count < kTypedUrlVisitThrottleThreshold || | 228 (typed_count < kTypedUrlVisitThrottleThreshold || |
223 (typed_count % kTypedUrlVisitThrottleMultiple) == 0)); | 229 (typed_count % kTypedUrlVisitThrottleMultiple) == 0)); |
224 } | 230 } |
225 | 231 |
226 void TypedUrlChangeProcessor::ApplyChangesFromSyncModel( | 232 void TypedUrlChangeProcessor::ApplyChangesFromSyncModel( |
227 const syncer::BaseTransaction* trans, | 233 const syncer::BaseTransaction* trans, |
228 int64 model_version, | 234 int64 model_version, |
229 const syncer::ImmutableChangeRecordList& changes) { | 235 const syncer::ImmutableChangeRecordList& changes) { |
230 DCHECK(backend_loop_ == base::MessageLoop::current()); | 236 DCHECK(backend_loop_ == base::MessageLoop::current()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
329 DCHECK(history_backend_); | 335 DCHECK(history_backend_); |
330 DCHECK(backend_loop_); | 336 DCHECK(backend_loop_); |
331 backend_loop_->PostTask(FROM_HERE, | 337 backend_loop_->PostTask(FROM_HERE, |
332 base::Bind(&TypedUrlChangeProcessor::StartObserving, | 338 base::Bind(&TypedUrlChangeProcessor::StartObserving, |
333 base::Unretained(this))); | 339 base::Unretained(this))); |
334 } | 340 } |
335 | 341 |
336 void TypedUrlChangeProcessor::StartObserving() { | 342 void TypedUrlChangeProcessor::StartObserving() { |
337 DCHECK(backend_loop_ == base::MessageLoop::current()); | 343 DCHECK(backend_loop_ == base::MessageLoop::current()); |
| 344 DCHECK(history_backend_); |
338 DCHECK(profile_); | 345 DCHECK(profile_); |
339 notification_registrar_.Add( | 346 notification_registrar_.Add( |
340 this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, | 347 this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, |
341 content::Source<Profile>(profile_)); | 348 content::Source<Profile>(profile_)); |
342 notification_registrar_.Add( | 349 notification_registrar_.Add( |
343 this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 350 this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
344 content::Source<Profile>(profile_)); | 351 content::Source<Profile>(profile_)); |
345 notification_registrar_.Add( | 352 history_backend_->AddObserver(this); |
346 this, chrome::NOTIFICATION_HISTORY_URL_VISITED, | |
347 content::Source<Profile>(profile_)); | |
348 } | 353 } |
349 | 354 |
350 void TypedUrlChangeProcessor::StopObserving() { | 355 void TypedUrlChangeProcessor::StopObserving() { |
351 DCHECK(backend_loop_ == base::MessageLoop::current()); | 356 DCHECK(backend_loop_ == base::MessageLoop::current()); |
| 357 DCHECK(history_backend_); |
352 DCHECK(profile_); | 358 DCHECK(profile_); |
353 notification_registrar_.Remove( | 359 notification_registrar_.Remove( |
354 this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, | 360 this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, |
355 content::Source<Profile>(profile_)); | 361 content::Source<Profile>(profile_)); |
356 notification_registrar_.Remove( | 362 notification_registrar_.Remove( |
357 this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 363 this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
358 content::Source<Profile>(profile_)); | 364 content::Source<Profile>(profile_)); |
359 notification_registrar_.Remove( | 365 history_backend_->RemoveObserver(this); |
360 this, chrome::NOTIFICATION_HISTORY_URL_VISITED, | |
361 content::Source<Profile>(profile_)); | |
362 } | 366 } |
363 | 367 |
364 } // namespace browser_sync | 368 } // namespace browser_sync |
OLD | NEW |