OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |