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

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

Issue 1373983003: Add UMA stats for which icon types are shown and clicked on the NTP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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
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 "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h" 8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h" 9 #include "base/android/jni_string.h"
10 #include "base/android/scoped_java_ref.h" 10 #include "base/android/scoped_java_ref.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 using suggestions::ChromeSuggestion; 51 using suggestions::ChromeSuggestion;
52 using suggestions::SuggestionsProfile; 52 using suggestions::SuggestionsProfile;
53 using suggestions::SuggestionsService; 53 using suggestions::SuggestionsService;
54 using suggestions::SuggestionsServiceFactory; 54 using suggestions::SuggestionsServiceFactory;
55 using suggestions::SyncState; 55 using suggestions::SyncState;
56 56
57 namespace { 57 namespace {
58 58
59 // Total number of tiles displayed. 59 // Total number of tiles displayed.
60 const char kNumTilesHistogramName[] = "NewTabPage.NumberOfTiles"; 60 const char kNumTilesHistogramName[] = "NewTabPage.NumberOfTiles";
61 // Tracking thumbnails.
62 const char kNumLocalThumbnailTilesHistogramName[] =
63 "NewTabPage.NumberOfThumbnailTiles";
64 const char kNumEmptyTilesHistogramName[] = "NewTabPage.NumberOfGrayTiles";
65 const char kNumServerTilesHistogramName[] = "NewTabPage.NumberOfExternalTiles";
66 61
67 // Format for tile clicks histogram. 62 // Format for tile clicks histograms.
68 const char kOpenedItemHistogramFormat[] = "NewTabPage.MostVisited.%s"; 63 const char kOpenedItemPositionHistogramFormat[] = "NewTabPage.MostVisited.%s";
69 // Format for tile impressions histogram. 64 const char kOpenedItemTypeHistogramFormat[] = "NewTabPage.TileTypeClicked.%s";
70 const char kImpressionHistogramFormat[] = "NewTabPage.SuggestionsImpression.%s"; 65 // Format for tile impressions histograms.
66 const char kImpressionPositionHistogramFormat[] =
67 "NewTabPage.SuggestionsImpression.%s";
68 const char kImpressionTypeHistogramFormat[] = "NewTabPage.TileType.%s";
71 // Identifiers for the various tile sources. 69 // Identifiers for the various tile sources.
72 const char kHistogramClientName[] = "client"; 70 const char kHistogramClientName[] = "client";
73 const char kHistogramServerName[] = "server"; 71 const char kHistogramServerName[] = "server";
74 const char kHistogramServerFormat[] = "server%d"; 72 const char kHistogramServerFormat[] = "server%d";
75 const char kHistogramPopularName[] = "popular"; 73 const char kHistogramPopularName[] = "popular";
76 74
77 const char kPopularSitesFieldTrialName[] = "NTPPopularSites"; 75 const char kPopularSitesFieldTrialName[] = "NTPPopularSites";
78 76
77 // The visual type of a most visited tile.
78 //
79 // These values must stay in sync with the MostVisitedTileType enum
80 // in histograms.xml.
81 //
82 // A Java counterpart will be generated for this enum.
83 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ntp
84 enum MostVisitedTileType {
85 // The icon or thumbnail hasn't loaded yet.
86 NONE,
87 // The item displays a site's actual favicon or touch icon.
88 ICON_REAL,
89 // The item displays a color derived from the site's favicon or touch icon.
90 ICON_COLOR,
91 // The item displays a default gray box in place of an icon.
92 ICON_DEFAULT,
93 // The item displays a locally-captured thumbnail of the site content.
94 THUMBNAIL_LOCAL,
95 // The item displays a server-provided thumbnail of the site content.
96 THUMBNAIL_SERVER,
97 // The item displays a default graphic in place of a thumbnail.
98 THUMBNAIL_DEFAULT,
99 NUM_TILE_TYPES,
100 };
101
79 scoped_ptr<SkBitmap> MaybeFetchLocalThumbnail( 102 scoped_ptr<SkBitmap> MaybeFetchLocalThumbnail(
80 const GURL& url, 103 const GURL& url,
81 const scoped_refptr<TopSites>& top_sites) { 104 const scoped_refptr<TopSites>& top_sites) {
82 DCHECK_CURRENTLY_ON(BrowserThread::DB); 105 DCHECK_CURRENTLY_ON(BrowserThread::DB);
83 scoped_refptr<base::RefCountedMemory> image; 106 scoped_refptr<base::RefCountedMemory> image;
84 scoped_ptr<SkBitmap> bitmap; 107 scoped_ptr<SkBitmap> bitmap;
85 if (top_sites && top_sites->GetPageThumbnail(url, false, &image)) 108 if (top_sites && top_sites->GetPageThumbnail(url, false, &image))
86 bitmap.reset(gfx::JPEGCodec::Decode(image->front(), image->size())); 109 bitmap.reset(gfx::JPEGCodec::Decode(image->front(), image->size()));
87 return bitmap.Pass(); 110 return bitmap.Pass();
88 } 111 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 ? base::StringPrintf(kHistogramServerFormat, provider_index) 222 ? base::StringPrintf(kHistogramServerFormat, provider_index)
200 : kHistogramServerName; 223 : kHistogramServerName;
201 } 224 }
202 NOTREACHED(); 225 NOTREACHED();
203 return std::string(); 226 return std::string();
204 } 227 }
205 228
206 MostVisitedSites::MostVisitedSites(Profile* profile) 229 MostVisitedSites::MostVisitedSites(Profile* profile)
207 : profile_(profile), num_sites_(0), received_most_visited_sites_(false), 230 : profile_(profile), num_sites_(0), received_most_visited_sites_(false),
208 received_popular_sites_(false), recorded_uma_(false), 231 received_popular_sites_(false), recorded_uma_(false),
209 num_local_thumbs_(0), num_server_thumbs_(0), num_empty_thumbs_(0),
210 scoped_observer_(this), weak_ptr_factory_(this) { 232 scoped_observer_(this), weak_ptr_factory_(this) {
211 // Register the debugging page for the Suggestions Service and the thumbnails 233 // Register the debugging page for the Suggestions Service and the thumbnails
212 // debugging page. 234 // debugging page.
213 content::URLDataSource::Add(profile_, 235 content::URLDataSource::Add(profile_,
214 new suggestions::SuggestionsSource(profile_)); 236 new suggestions::SuggestionsSource(profile_));
215 content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_)); 237 content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
216 238
217 // Register this class as an observer to the sync service. It is important to 239 // Register this class as an observer to the sync service. It is important to
218 // be notified of changes in the sync state such as initialization, sync 240 // be notified of changes in the sync state such as initialization, sync
219 // being enabled or disabled, etc. 241 // being enabled or disabled, etc.
220 ProfileSyncService* profile_sync_service = 242 ProfileSyncService* profile_sync_service =
221 ProfileSyncServiceFactory::GetForProfile(profile_); 243 ProfileSyncServiceFactory::GetForProfile(profile_);
222 if (profile_sync_service) 244 if (profile_sync_service)
223 profile_sync_service->AddObserver(this); 245 profile_sync_service->AddObserver(this);
224 } 246 }
225 247
226 MostVisitedSites::~MostVisitedSites() { 248 MostVisitedSites::~MostVisitedSites() {
227 ProfileSyncService* profile_sync_service = 249 ProfileSyncService* profile_sync_service =
228 ProfileSyncServiceFactory::GetForProfile(profile_); 250 ProfileSyncServiceFactory::GetForProfile(profile_);
229 if (profile_sync_service && profile_sync_service->HasObserver(this)) 251 if (profile_sync_service && profile_sync_service->HasObserver(this))
230 profile_sync_service->RemoveObserver(this); 252 profile_sync_service->RemoveObserver(this);
231 } 253 }
232 254
233 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) { 255 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) {
234 delete this; 256 delete this;
235 } 257 }
236 258
237 void MostVisitedSites::OnLoadingComplete(JNIEnv* env, jobject obj) {
238 RecordThumbnailUMAMetrics();
239 }
240
241 void MostVisitedSites::SetMostVisitedURLsObserver(JNIEnv* env, 259 void MostVisitedSites::SetMostVisitedURLsObserver(JNIEnv* env,
242 jobject obj, 260 jobject obj,
243 jobject j_observer, 261 jobject j_observer,
244 jint num_sites) { 262 jint num_sites) {
245 observer_.Reset(env, j_observer); 263 observer_.Reset(env, j_observer);
246 num_sites_ = num_sites; 264 num_sites_ = num_sites;
247 265
248 if (ShouldShowPopularSites() && 266 if (ShouldShowPopularSites() &&
249 NeedPopularSites(profile_->GetPrefs(), num_sites_)) { 267 NeedPopularSites(profile_->GetPrefs(), num_sites_)) {
250 popular_sites_.reset(new PopularSites( 268 popular_sites_.reset(new PopularSites(
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 } 354 }
337 355
338 void MostVisitedSites::OnObtainedThumbnail( 356 void MostVisitedSites::OnObtainedThumbnail(
339 bool is_local_thumbnail, 357 bool is_local_thumbnail,
340 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_callback, 358 scoped_ptr<ScopedJavaGlobalRef<jobject>> j_callback,
341 const GURL& url, 359 const GURL& url,
342 const SkBitmap* bitmap) { 360 const SkBitmap* bitmap) {
343 DCHECK_CURRENTLY_ON(BrowserThread::UI); 361 DCHECK_CURRENTLY_ON(BrowserThread::UI);
344 JNIEnv* env = AttachCurrentThread(); 362 JNIEnv* env = AttachCurrentThread();
345 ScopedJavaLocalRef<jobject> j_bitmap; 363 ScopedJavaLocalRef<jobject> j_bitmap;
346 if (bitmap) { 364 if (bitmap)
347 j_bitmap = gfx::ConvertToJavaBitmap(bitmap); 365 j_bitmap = gfx::ConvertToJavaBitmap(bitmap);
348 if (is_local_thumbnail) {
349 ++num_local_thumbs_;
350 } else {
351 ++num_server_thumbs_;
352 }
353 } else {
354 ++num_empty_thumbs_;
355 }
356 Java_ThumbnailCallback_onMostVisitedURLsThumbnailAvailable( 366 Java_ThumbnailCallback_onMostVisitedURLsThumbnailAvailable(
357 env, j_callback->obj(), j_bitmap.obj()); 367 env, j_callback->obj(), j_bitmap.obj(), is_local_thumbnail);
358 } 368 }
359 369
360 void MostVisitedSites::BlacklistUrl(JNIEnv* env, 370 void MostVisitedSites::BlacklistUrl(JNIEnv* env,
361 jobject obj, 371 jobject obj,
362 jstring j_url) { 372 jstring j_url) {
363 GURL url(ConvertJavaStringToUTF8(env, j_url)); 373 GURL url(ConvertJavaStringToUTF8(env, j_url));
364 374
365 // Always blacklist in the local TopSites. 375 // Always blacklist in the local TopSites.
366 scoped_refptr<TopSites> top_sites = TopSitesFactory::GetForProfile(profile_); 376 scoped_refptr<TopSites> top_sites = TopSitesFactory::GetForProfile(profile_);
367 if (top_sites) 377 if (top_sites)
368 top_sites->AddBlacklistedURL(url); 378 top_sites->AddBlacklistedURL(url);
369 379
370 // Only blacklist in the server-side suggestions service if it's active. 380 // Only blacklist in the server-side suggestions service if it's active.
371 if (mv_source_ == SUGGESTIONS_SERVICE) { 381 if (mv_source_ == SUGGESTIONS_SERVICE) {
372 SuggestionsService* suggestions_service = 382 SuggestionsService* suggestions_service =
373 SuggestionsServiceFactory::GetForProfile(profile_); 383 SuggestionsServiceFactory::GetForProfile(profile_);
374 DCHECK(suggestions_service); 384 DCHECK(suggestions_service);
375 suggestions_service->BlacklistURL( 385 suggestions_service->BlacklistURL(
376 url, base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable, 386 url, base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable,
377 weak_ptr_factory_.GetWeakPtr()), 387 weak_ptr_factory_.GetWeakPtr()),
378 base::Closure()); 388 base::Closure());
379 } 389 }
380 } 390 }
381 391
392 void MostVisitedSites::RecordTileTypeMetrics(JNIEnv* env,
393 jobject obj,
394 jintArray jtile_types,
395 jboolean is_icon_mode) {
396 std::vector<int> tile_types;
397 base::android::JavaIntArrayToIntVector(env, jtile_types, &tile_types);
398 DCHECK_EQ(current_suggestions_.size(), tile_types.size());
399
400 int counts_per_type[NUM_TILE_TYPES] = {0};
401 for (size_t i = 0; i < tile_types.size(); i++) {
402 int tile_type = tile_types[i];
403 counts_per_type[tile_type]++;
404 std::string histogram = base::StringPrintf(
405 kImpressionTypeHistogramFormat,
406 current_suggestions_[i]->GetSourceHistogramName().c_str());
407 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES);
408 }
409
410 if (is_icon_mode) {
411 UMA_HISTOGRAM_COUNTS_100("NewTabPage.IconsReal",
412 counts_per_type[ICON_REAL]);
413 UMA_HISTOGRAM_COUNTS_100("NewTabPage.IconsColor",
414 counts_per_type[ICON_COLOR]);
415 UMA_HISTOGRAM_COUNTS_100("NewTabPage.IconsGray",
416 counts_per_type[ICON_DEFAULT]);
417 } else {
418 UMA_HISTOGRAM_COUNTS_100("NewTabPage.NumberOfThumbnailTiles",
419 counts_per_type[THUMBNAIL_LOCAL]);
420 UMA_HISTOGRAM_COUNTS_100("NewTabPage.NumberOfExternalTiles",
421 counts_per_type[THUMBNAIL_SERVER]);
422 UMA_HISTOGRAM_COUNTS_100("NewTabPage.NumberOfGrayTiles",
423 counts_per_type[THUMBNAIL_DEFAULT]);
424 }
425 }
426
382 void MostVisitedSites::RecordOpenedMostVisitedItem(JNIEnv* env, 427 void MostVisitedSites::RecordOpenedMostVisitedItem(JNIEnv* env,
383 jobject obj, 428 jobject obj,
384 jint index) { 429 jint index,
430 jint tile_type) {
385 DCHECK_GE(index, 0); 431 DCHECK_GE(index, 0);
386 DCHECK_LT(index, static_cast<int>(current_suggestions_.size())); 432 DCHECK_LT(index, static_cast<int>(current_suggestions_.size()));
387 std::string histogram = base::StringPrintf( 433 std::string histogram = base::StringPrintf(
388 kOpenedItemHistogramFormat, 434 kOpenedItemPositionHistogramFormat,
389 current_suggestions_[index]->GetSourceHistogramName().c_str()); 435 current_suggestions_[index]->GetSourceHistogramName().c_str());
390 LogHistogramEvent(histogram, index, num_sites_); 436 LogHistogramEvent(histogram, index, num_sites_);
437
438 histogram = base::StringPrintf(
439 kOpenedItemTypeHistogramFormat,
440 current_suggestions_[index]->GetSourceHistogramName().c_str());
441 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES);
391 } 442 }
392 443
393 void MostVisitedSites::OnStateChanged() { 444 void MostVisitedSites::OnStateChanged() {
394 // There have been changes to the sync state. This class cares about a few 445 // There have been changes to the sync state. This class cares about a few
395 // (just initialized, enabled/disabled or history sync state changed). Re-run 446 // (just initialized, enabled/disabled or history sync state changed). Re-run
396 // the query code which will use the proper state. 447 // the query code which will use the proper state.
397 QueryMostVisitedURLs(); 448 QueryMostVisitedURLs();
398 } 449 }
399 450
400 // static 451 // static
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 favicon_urls.push_back(popular_site.favicon_url.spec()); 754 favicon_urls.push_back(popular_site.favicon_url.spec());
704 } 755 }
705 JNIEnv* env = AttachCurrentThread(); 756 JNIEnv* env = AttachCurrentThread();
706 Java_MostVisitedURLsObserver_onPopularURLsAvailable( 757 Java_MostVisitedURLsObserver_onPopularURLsAvailable(
707 env, observer_.obj(), ToJavaArrayOfStrings(env, urls).obj(), 758 env, observer_.obj(), ToJavaArrayOfStrings(env, urls).obj(),
708 ToJavaArrayOfStrings(env, favicon_urls).obj()); 759 ToJavaArrayOfStrings(env, favicon_urls).obj());
709 760
710 QueryMostVisitedURLs(); 761 QueryMostVisitedURLs();
711 } 762 }
712 763
713 void MostVisitedSites::RecordThumbnailUMAMetrics() {
714 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumLocalThumbnailTilesHistogramName,
715 num_local_thumbs_);
716 num_local_thumbs_ = 0;
717 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumEmptyTilesHistogramName, num_empty_thumbs_);
718 num_empty_thumbs_ = 0;
719 UMA_HISTOGRAM_SPARSE_SLOWLY(kNumServerTilesHistogramName, num_server_thumbs_);
720 num_server_thumbs_ = 0;
721 }
722
723 void MostVisitedSites::RecordImpressionUMAMetrics() { 764 void MostVisitedSites::RecordImpressionUMAMetrics() {
724 for (size_t i = 0; i < current_suggestions_.size(); i++) { 765 for (size_t i = 0; i < current_suggestions_.size(); i++) {
725 std::string histogram = base::StringPrintf( 766 std::string histogram = base::StringPrintf(
726 kImpressionHistogramFormat, 767 kImpressionPositionHistogramFormat,
727 current_suggestions_[i]->GetSourceHistogramName().c_str()); 768 current_suggestions_[i]->GetSourceHistogramName().c_str());
728 LogHistogramEvent(histogram, static_cast<int>(i), num_sites_); 769 LogHistogramEvent(histogram, static_cast<int>(i), num_sites_);
729 } 770 }
730 } 771 }
731 772
732 void MostVisitedSites::TopSitesLoaded(history::TopSites* top_sites) { 773 void MostVisitedSites::TopSitesLoaded(history::TopSites* top_sites) {
733 } 774 }
734 775
735 void MostVisitedSites::TopSitesChanged(history::TopSites* top_sites, 776 void MostVisitedSites::TopSitesChanged(history::TopSites* top_sites,
736 ChangeReason change_reason) { 777 ChangeReason change_reason) {
737 if (mv_source_ == TOP_SITES) { 778 if (mv_source_ == TOP_SITES) {
738 // The displayed suggestions are invalidated. 779 // The displayed suggestions are invalidated.
739 QueryMostVisitedURLs(); 780 InitiateTopSitesQuery();
newt (away) 2015/09/28 22:34:21 There's no need to requery the server suggestions
740 } 781 }
741 } 782 }
742 783
743 static jlong Init(JNIEnv* env, 784 static jlong Init(JNIEnv* env,
744 const JavaParamRef<jobject>& obj, 785 const JavaParamRef<jobject>& obj,
745 const JavaParamRef<jobject>& jprofile) { 786 const JavaParamRef<jobject>& jprofile) {
746 MostVisitedSites* most_visited_sites = 787 MostVisitedSites* most_visited_sites =
747 new MostVisitedSites(ProfileAndroid::FromProfileAndroid(jprofile)); 788 new MostVisitedSites(ProfileAndroid::FromProfileAndroid(jprofile));
748 return reinterpret_cast<intptr_t>(most_visited_sites); 789 return reinterpret_cast<intptr_t>(most_visited_sites);
749 } 790 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698