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

Side by Side Diff: chrome/browser/android/most_visited_sites.cc

Issue 1265983007: Popular sites on the NTP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 4 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
« no previous file with comments | « chrome/browser/android/most_visited_sites.h ('k') | chrome/browser/android/popular_sites.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/android/most_visited_sites.h" 5 #include "chrome/browser/android/most_visited_sites.h"
6 6
7 #include <string>
8 #include <vector>
9
10 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
11 #include "base/android/jni_array.h" 8 #include "base/android/jni_array.h"
12 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
13 #include "base/android/scoped_java_ref.h" 10 #include "base/android/scoped_java_ref.h"
14 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/command_line.h"
15 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
16 #include "base/metrics/sparse_histogram.h" 14 #include "base/metrics/sparse_histogram.h"
17 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h" 18 #include "base/time/time.h"
19 #include "chrome/browser/android/popular_sites.h"
21 #include "chrome/browser/history/top_sites_factory.h" 20 #include "chrome/browser/history/top_sites_factory.h"
22 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/profiles/profile_android.h" 22 #include "chrome/browser/profiles/profile_android.h"
24 #include "chrome/browser/search/suggestions/suggestions_service_factory.h" 23 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
25 #include "chrome/browser/search/suggestions/suggestions_source.h" 24 #include "chrome/browser/search/suggestions/suggestions_source.h"
26 #include "chrome/browser/sync/profile_sync_service.h" 25 #include "chrome/browser/sync/profile_sync_service.h"
27 #include "chrome/browser/sync/profile_sync_service_factory.h" 26 #include "chrome/browser/sync/profile_sync_service_factory.h"
28 #include "chrome/browser/thumbnails/thumbnail_list_source.h" 27 #include "chrome/browser/thumbnails/thumbnail_list_source.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "components/history/core/browser/top_sites.h" 29 #include "components/history/core/browser/top_sites.h"
30 #include "components/suggestions/suggestions_service.h" 30 #include "components/suggestions/suggestions_service.h"
31 #include "components/suggestions/suggestions_utils.h" 31 #include "components/suggestions/suggestions_utils.h"
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/url_data_source.h" 33 #include "content/public/browser/url_data_source.h"
34 #include "jni/MostVisitedSites_jni.h" 34 #include "jni/MostVisitedSites_jni.h"
35 #include "third_party/skia/include/core/SkBitmap.h" 35 #include "third_party/skia/include/core/SkBitmap.h"
36 #include "ui/gfx/android/java_bitmap.h" 36 #include "ui/gfx/android/java_bitmap.h"
37 #include "ui/gfx/codec/jpeg_codec.h" 37 #include "ui/gfx/codec/jpeg_codec.h"
38 #include "url/gurl.h"
38 39
39 using base::android::AttachCurrentThread; 40 using base::android::AttachCurrentThread;
40 using base::android::ConvertUTF8ToJavaString;
41 using base::android::ConvertJavaStringToUTF8; 41 using base::android::ConvertJavaStringToUTF8;
42 using base::android::ScopedJavaGlobalRef; 42 using base::android::ScopedJavaGlobalRef;
43 using base::android::ScopedJavaLocalRef; 43 using base::android::ScopedJavaLocalRef;
44 using base::android::ToJavaArrayOfStrings; 44 using base::android::ToJavaArrayOfStrings;
45 using base::android::CheckException;
46 using base::WeakPtr;
47 using content::BrowserThread; 45 using content::BrowserThread;
48 using history::TopSites; 46 using history::TopSites;
49 using suggestions::ChromeSuggestion; 47 using suggestions::ChromeSuggestion;
50 using suggestions::SuggestionsProfile; 48 using suggestions::SuggestionsProfile;
51 using suggestions::SuggestionsService; 49 using suggestions::SuggestionsService;
52 using suggestions::SuggestionsServiceFactory; 50 using suggestions::SuggestionsServiceFactory;
53 using suggestions::SyncState; 51 using suggestions::SyncState;
54 52
55 namespace { 53 namespace {
56 54
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 ProfileSyncService* sync = 107 ProfileSyncService* sync =
110 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); 108 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
111 if (!sync) 109 if (!sync)
112 return SyncState::SYNC_OR_HISTORY_SYNC_DISABLED; 110 return SyncState::SYNC_OR_HISTORY_SYNC_DISABLED;
113 return suggestions::GetSyncState( 111 return suggestions::GetSyncState(
114 sync->CanSyncStart(), 112 sync->CanSyncStart(),
115 sync->IsSyncActive() && sync->ConfigurationDone(), 113 sync->IsSyncActive() && sync->ConfigurationDone(),
116 sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES)); 114 sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES));
117 } 115 }
118 116
117 bool ShouldShowPopularSites() {
118 // Note: It's important to query the field trial state first, to ensure that
119 // UMA reports the correct group.
120 const std::string group_name =
121 base::FieldTrialList::FindFullName("NTPPopularSites");
122 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
123 if (cmd_line->HasSwitch(switches::kDisableNTPPopularSites))
124 return false;
125 if (cmd_line->HasSwitch(switches::kEnableNTPPopularSites))
126 return true;
127 return group_name == "Enabled";
128 }
129
119 } // namespace 130 } // namespace
120 131
121 MostVisitedSites::MostVisitedSites(Profile* profile) 132 MostVisitedSites::MostVisitedSites(Profile* profile)
122 : profile_(profile), num_sites_(0), initial_load_done_(false), 133 : profile_(profile), num_sites_(0), initial_load_done_(false),
123 num_local_thumbs_(0), num_server_thumbs_(0), num_empty_thumbs_(0), 134 num_local_thumbs_(0), num_server_thumbs_(0), num_empty_thumbs_(0),
124 scoped_observer_(this), weak_ptr_factory_(this) { 135 scoped_observer_(this), weak_ptr_factory_(this) {
125 // Register the debugging page for the Suggestions Service and the thumbnails 136 // Register the debugging page for the Suggestions Service and the thumbnails
126 // debugging page. 137 // debugging page.
127 content::URLDataSource::Add(profile_, 138 content::URLDataSource::Add(profile_,
128 new suggestions::SuggestionsSource(profile_)); 139 new suggestions::SuggestionsSource(profile_));
129 content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_)); 140 content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
130 141
131 // Register this class as an observer to the sync service. It is important to 142 // Register this class as an observer to the sync service. It is important to
132 // be notified of changes in the sync state such as initialization, sync 143 // be notified of changes in the sync state such as initialization, sync
133 // being enabled or disabled, etc. 144 // being enabled or disabled, etc.
134 ProfileSyncService* profile_sync_service = 145 ProfileSyncService* profile_sync_service =
135 ProfileSyncServiceFactory::GetForProfile(profile_); 146 ProfileSyncServiceFactory::GetForProfile(profile_);
136 if (profile_sync_service) 147 if (profile_sync_service)
137 profile_sync_service->AddObserver(this); 148 profile_sync_service->AddObserver(this);
149
150 if (ShouldShowPopularSites()) {
151 popular_sites_.reset(new PopularSites(
152 profile_->GetRequestContext(),
153 base::Bind(&MostVisitedSites::OnPopularSitesAvailable,
154 base::Unretained(this))));
155 }
138 } 156 }
139 157
140 MostVisitedSites::~MostVisitedSites() { 158 MostVisitedSites::~MostVisitedSites() {
141 ProfileSyncService* profile_sync_service = 159 ProfileSyncService* profile_sync_service =
142 ProfileSyncServiceFactory::GetForProfile(profile_); 160 ProfileSyncServiceFactory::GetForProfile(profile_);
143 if (profile_sync_service && profile_sync_service->HasObserver(this)) 161 if (profile_sync_service && profile_sync_service->HasObserver(this))
144 profile_sync_service->RemoveObserver(this); 162 profile_sync_service->RemoveObserver(this);
145 } 163 }
146 164
147 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) { 165 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 urls.push_back(visited.url.spec()); 362 urls.push_back(visited.url.spec());
345 } 363 }
346 364
347 // Only log impression metrics on the initial load of the NTP. 365 // Only log impression metrics on the initial load of the NTP.
348 if (!initial_load_done_) { 366 if (!initial_load_done_) {
349 for (int i = 0; i < num_tiles; ++i) { 367 for (int i = 0; i < num_tiles; ++i) {
350 UMA_HISTOGRAM_SPARSE_SLOWLY(kImpressionClientHistogramName, i); 368 UMA_HISTOGRAM_SPARSE_SLOWLY(kImpressionClientHistogramName, i);
351 } 369 }
352 } 370 }
353 mv_source_ = TOP_SITES; 371 mv_source_ = TOP_SITES;
372 AddPopularSites(&titles, &urls);
354 NotifyMostVisitedURLsObserver(titles, urls); 373 NotifyMostVisitedURLsObserver(titles, urls);
355 } 374 }
356 375
357 void MostVisitedSites::OnSuggestionsProfileAvailable( 376 void MostVisitedSites::OnSuggestionsProfileAvailable(
358 const SuggestionsProfile& suggestions_profile) { 377 const SuggestionsProfile& suggestions_profile) {
359 int num_tiles = suggestions_profile.suggestions_size(); 378 int num_tiles = suggestions_profile.suggestions_size();
360 // With no server suggestions, fall back to local Most Visited. 379 // With no server suggestions, fall back to local Most Visited.
361 if (num_tiles == 0) { 380 if (num_tiles == 0) {
362 InitiateTopSitesQuery(); 381 InitiateTopSitesQuery();
363 return; 382 return;
(...skipping 14 matching lines...) Expand all
378 kImpressionServerHistogramFormat, suggestion.providers(0)); 397 kImpressionServerHistogramFormat, suggestion.providers(0));
379 LogHistogramEvent(histogram, i, num_sites_); 398 LogHistogramEvent(histogram, i, num_sites_);
380 } else { 399 } else {
381 UMA_HISTOGRAM_SPARSE_SLOWLY(kImpressionServerHistogramName, i); 400 UMA_HISTOGRAM_SPARSE_SLOWLY(kImpressionServerHistogramName, i);
382 } 401 }
383 } 402 }
384 } 403 }
385 mv_source_ = SUGGESTIONS_SERVICE; 404 mv_source_ = SUGGESTIONS_SERVICE;
386 // Keep a copy of the suggestions for eventual logging. 405 // Keep a copy of the suggestions for eventual logging.
387 server_suggestions_ = suggestions_profile; 406 server_suggestions_ = suggestions_profile;
407 AddPopularSites(&titles, &urls);
388 NotifyMostVisitedURLsObserver(titles, urls); 408 NotifyMostVisitedURLsObserver(titles, urls);
389 } 409 }
390 410
411 void MostVisitedSites::AddPopularSites(std::vector<base::string16>* titles,
412 std::vector<std::string>* urls) {
413 if (!popular_sites_)
414 return;
415
416 DCHECK_EQ(titles->size(), urls->size());
417 if (static_cast<int>(titles->size()) >= num_sites_)
418 return;
419
420 for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
421 // Skip popular sites that are already in the suggestions.
422 auto it = std::find_if(urls->begin(), urls->end(),
423 [&popular_site](const std::string& url) {
424 return GURL(url).host() == popular_site.url.host();
425 });
426 if (it != urls->end())
427 continue;
428
429 titles->push_back(popular_site.title);
430 urls->push_back(popular_site.url.spec());
431 if (static_cast<int>(titles->size()) >= num_sites_)
432 break;
433 }
434 }
435
391 void MostVisitedSites::NotifyMostVisitedURLsObserver( 436 void MostVisitedSites::NotifyMostVisitedURLsObserver(
392 const std::vector<base::string16>& titles, 437 const std::vector<base::string16>& titles,
393 const std::vector<std::string>& urls) { 438 const std::vector<std::string>& urls) {
394 DCHECK_EQ(titles.size(), urls.size()); 439 DCHECK_EQ(titles.size(), urls.size());
395 if (!initial_load_done_) 440 if (!initial_load_done_)
396 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumTilesHistogramName, titles.size()); 441 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumTilesHistogramName, titles.size());
397 initial_load_done_ = true; 442 initial_load_done_ = true;
398 JNIEnv* env = AttachCurrentThread(); 443 JNIEnv* env = AttachCurrentThread();
399 Java_MostVisitedURLsObserver_onMostVisitedURLsAvailable( 444 Java_MostVisitedURLsObserver_onMostVisitedURLsAvailable(
400 env, observer_.obj(), ToJavaArrayOfStrings(env, titles).obj(), 445 env, observer_.obj(), ToJavaArrayOfStrings(env, titles).obj(),
401 ToJavaArrayOfStrings(env, urls).obj()); 446 ToJavaArrayOfStrings(env, urls).obj());
402 } 447 }
403 448
449 void MostVisitedSites::OnPopularSitesAvailable(bool success) {
450 if (!success) {
451 LOG(WARNING) << "Download of popular sites failed";
452 return;
453 }
454
455 if (!observer_.is_null())
456 QueryMostVisitedURLs();
457 }
458
404 void MostVisitedSites::RecordUMAMetrics() { 459 void MostVisitedSites::RecordUMAMetrics() {
405 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumLocalThumbnailTilesHistogramName, 460 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumLocalThumbnailTilesHistogramName,
406 num_local_thumbs_); 461 num_local_thumbs_);
407 num_local_thumbs_ = 0; 462 num_local_thumbs_ = 0;
408 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumEmptyTilesHistogramName, num_empty_thumbs_); 463 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumEmptyTilesHistogramName, num_empty_thumbs_);
409 num_empty_thumbs_ = 0; 464 num_empty_thumbs_ = 0;
410 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumServerTilesHistogramName, num_server_thumbs_); 465 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumServerTilesHistogramName, num_server_thumbs_);
411 num_server_thumbs_ = 0; 466 num_server_thumbs_ = 0;
412 } 467 }
413 468
414 void MostVisitedSites::TopSitesLoaded(history::TopSites* top_sites) { 469 void MostVisitedSites::TopSitesLoaded(history::TopSites* top_sites) {
415 } 470 }
416 471
417 void MostVisitedSites::TopSitesChanged(history::TopSites* top_sites, 472 void MostVisitedSites::TopSitesChanged(history::TopSites* top_sites,
418 ChangeReason change_reason) { 473 ChangeReason change_reason) {
419 if (mv_source_ == TOP_SITES) { 474 if (mv_source_ == TOP_SITES) {
420 // The displayed suggestions are invalidated. 475 // The displayed suggestions are invalidated.
421 QueryMostVisitedURLs(); 476 QueryMostVisitedURLs();
422 } 477 }
423 } 478 }
424 479
425 static jlong Init(JNIEnv* env, jobject obj, jobject jprofile) { 480 static jlong Init(JNIEnv* env, jobject obj, jobject jprofile) {
426 MostVisitedSites* most_visited_sites = 481 MostVisitedSites* most_visited_sites =
427 new MostVisitedSites(ProfileAndroid::FromProfileAndroid(jprofile)); 482 new MostVisitedSites(ProfileAndroid::FromProfileAndroid(jprofile));
428 return reinterpret_cast<intptr_t>(most_visited_sites); 483 return reinterpret_cast<intptr_t>(most_visited_sites);
429 } 484 }
OLDNEW
« no previous file with comments | « chrome/browser/android/most_visited_sites.h ('k') | chrome/browser/android/popular_sites.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698