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

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

Issue 2838833005: Move NewTabPage.LogoShownTime metrics recording into LogoBridge (Closed)
Patch Set: Remove state from LoadTimeMetricsRecorder Created 3 years, 7 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/logo_bridge.h ('k') | components/doodle/doodle_service.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/logo_bridge.h" 5 #include "chrome/browser/android/logo_bridge.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 JNIEnv* env, 70 JNIEnv* env,
71 const search_provider_logos::Logo* logo) { 71 const search_provider_logos::Logo* logo) {
72 if (!logo) 72 if (!logo)
73 return ScopedJavaLocalRef<jobject>(); 73 return ScopedJavaLocalRef<jobject>();
74 74
75 return MakeJavaLogo(env, &logo->image, GURL(logo->metadata.on_click_url), 75 return MakeJavaLogo(env, &logo->image, GURL(logo->metadata.on_click_url),
76 logo->metadata.alt_text, 76 logo->metadata.alt_text,
77 GURL(logo->metadata.animated_url)); 77 GURL(logo->metadata.animated_url));
78 } 78 }
79 79
80 class LoadTimeMetricRecorderImpl : public LogoBridge::LoadTimeMetricRecorder {
81 public:
82 LoadTimeMetricRecorderImpl()
83 : logo_load_start_(base::TimeTicks::Now()), is_recording_(true) {}
84
85 void Cancel() override { is_recording_ = false; }
86
87 void Finish() override {
88 if (!is_recording_) {
89 return;
90 }
91 is_recording_ = false;
92 UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.LogoShownTime",
93 base::TimeTicks::Now() - logo_load_start_);
94 }
95
96 private:
97 base::TimeTicks logo_load_start_;
98 bool is_recording_;
99 bool waiting_for_result_;
100 };
101
102 class LoadTimeMetricRecorderNullImpl
103 : public LogoBridge::LoadTimeMetricRecorder {
104 public:
105 LoadTimeMetricRecorderNullImpl() {}
106 void Cancel() override {}
107 void Finish() override {}
108 };
109
80 class LogoObserverAndroid : public search_provider_logos::LogoObserver { 110 class LogoObserverAndroid : public search_provider_logos::LogoObserver {
81 public: 111 public:
82 LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge, 112 LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge,
83 JNIEnv* env, 113 JNIEnv* env,
84 jobject j_logo_observer) 114 jobject j_logo_observer)
85 : logo_bridge_(logo_bridge) { 115 : logo_bridge_(logo_bridge),
116 load_time_recorder_(new LoadTimeMetricRecorderImpl()) {
86 j_logo_observer_.Reset(env, j_logo_observer); 117 j_logo_observer_.Reset(env, j_logo_observer);
87 } 118 }
88 119
89 ~LogoObserverAndroid() override {} 120 ~LogoObserverAndroid() override {}
90 121
91 // seach_provider_logos::LogoObserver: 122 // seach_provider_logos::LogoObserver:
92 void OnLogoAvailable(const search_provider_logos::Logo* logo, 123 void OnLogoAvailable(const search_provider_logos::Logo* logo,
93 bool from_cache) override { 124 bool from_cache) override {
94 if (!logo_bridge_) 125 if (!logo_bridge_)
95 return; 126 return;
96 127
97 JNIEnv* env = base::android::AttachCurrentThread(); 128 JNIEnv* env = base::android::AttachCurrentThread();
98 ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo); 129 ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo);
130 load_time_recorder_->Finish();
99 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, 131 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo,
100 from_cache); 132 from_cache);
101 } 133 }
102 134
103 void OnObserverRemoved() override { delete this; } 135 void OnObserverRemoved() override { delete this; }
104 136
105 private: 137 private:
106 // The associated LogoBridge. We won't call back to Java if the LogoBridge has 138 // The associated LogoBridge. We won't call back to Java if the LogoBridge has
107 // been destroyed. 139 // been destroyed.
108 base::WeakPtr<LogoBridge> logo_bridge_; 140 base::WeakPtr<LogoBridge> logo_bridge_;
109 141
142 std::unique_ptr<LogoBridge::LoadTimeMetricRecorder> load_time_recorder_;
110 base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_; 143 base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_;
111 144
112 DISALLOW_COPY_AND_ASSIGN(LogoObserverAndroid); 145 DISALLOW_COPY_AND_ASSIGN(LogoObserverAndroid);
113 }; 146 };
114 147
115 } // namespace 148 } // namespace
116 149
117 class LogoBridge::AnimatedLogoFetcher : public net::URLFetcherDelegate { 150 class LogoBridge::AnimatedLogoFetcher : public net::URLFetcherDelegate {
118 public: 151 public:
119 AnimatedLogoFetcher( 152 AnimatedLogoFetcher(
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 animated_logo_fetcher_ = base::MakeUnique<AnimatedLogoFetcher>( 246 animated_logo_fetcher_ = base::MakeUnique<AnimatedLogoFetcher>(
214 profile->GetRequestContext()); 247 profile->GetRequestContext());
215 } 248 }
216 249
217 LogoBridge::~LogoBridge() {} 250 LogoBridge::~LogoBridge() {}
218 251
219 void LogoBridge::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { 252 void LogoBridge::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
220 delete this; 253 delete this;
221 } 254 }
222 255
256 LogoBridge::LoadTimeMetricRecorder* LogoBridge::load_time_recorder() {
257 if (!load_time_recorder_) {
258 load_time_recorder_ = base::MakeUnique<LoadTimeMetricRecorderNullImpl>();
259 }
260 return load_time_recorder_.get();
261 }
262
223 void LogoBridge::GetCurrentLogo(JNIEnv* env, 263 void LogoBridge::GetCurrentLogo(JNIEnv* env,
224 const JavaParamRef<jobject>& obj, 264 const JavaParamRef<jobject>& obj,
225 const JavaParamRef<jobject>& j_logo_observer) { 265 const JavaParamRef<jobject>& j_logo_observer) {
226 if (doodle_service_) { 266 if (doodle_service_) {
227 j_logo_observer_.Reset(j_logo_observer); 267 j_logo_observer_.Reset(j_logo_observer);
268 load_time_recorder_ = base::MakeUnique<LoadTimeMetricRecorderImpl>();
228 269
229 // Immediately hand out any current cached config. 270 // Immediately hand out any current cached config.
230 DoodleConfigReceived(doodle_service_->config(), /*from_cache=*/true); 271 bool cache_hit =
272 DoodleConfigReceived(doodle_service_->config(), /*from_cache=*/true);
231 // Also request a refresh, in case something changed. 273 // Also request a refresh, in case something changed.
232 doodle_service_->Refresh(); 274 bool refresh_triggered =
275 doodle_service_->Refresh() if (!cache_hit && !refresh_triggered) {
276 load_time_recorder()->Cancel();
277 }
233 } else { 278 } else {
234 // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved(). 279 // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved().
235 LogoObserverAndroid* observer = new LogoObserverAndroid( 280 LogoObserverAndroid* observer = new LogoObserverAndroid(
236 weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer); 281 weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer);
237 logo_service_->GetLogo(observer); 282 logo_service_->GetLogo(observer);
238 } 283 }
239 } 284 }
240 285
241 void LogoBridge::GetAnimatedLogo(JNIEnv* env, 286 void LogoBridge::GetAnimatedLogo(JNIEnv* env,
242 const JavaParamRef<jobject>& obj, 287 const JavaParamRef<jobject>& obj,
243 const JavaParamRef<jobject>& j_callback, 288 const JavaParamRef<jobject>& j_callback,
244 const JavaParamRef<jstring>& j_url) { 289 const JavaParamRef<jstring>& j_url) {
245 GURL url = GURL(ConvertJavaStringToUTF8(env, j_url)); 290 GURL url = GURL(ConvertJavaStringToUTF8(env, j_url));
246 animated_logo_fetcher_->Start(env, url, j_callback); 291 animated_logo_fetcher_->Start(env, url, j_callback);
247 } 292 }
248 293
249 void LogoBridge::OnDoodleConfigUpdated( 294 void LogoBridge::OnDoodleConfigUpdated(
250 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config) { 295 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config) {
251 if (j_logo_observer_.is_null()) { 296 if (j_logo_observer_.is_null()) {
252 return; 297 return;
253 } 298 }
254 DoodleConfigReceived(maybe_doodle_config, /*from_cache=*/false); 299 DoodleConfigReceived(maybe_doodle_config, /*from_cache=*/false);
255 } 300 }
256 301
257 void LogoBridge::DoodleConfigReceived( 302 bool LogoBridge::DoodleConfigReceived(
258 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config, 303 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config,
259 bool from_cache) { 304 bool from_cache) {
260 DCHECK(!j_logo_observer_.is_null()); 305 DCHECK(!j_logo_observer_.is_null());
261 306
262 if (!maybe_doodle_config.has_value()) { 307 if (!maybe_doodle_config.has_value()) {
263 JNIEnv* env = base::android::AttachCurrentThread(); 308 JNIEnv* env = base::android::AttachCurrentThread();
264 Java_LogoObserver_onLogoAvailable( 309 Java_LogoObserver_onLogoAvailable(
265 env, j_logo_observer_, ScopedJavaLocalRef<jobject>(), from_cache); 310 env, j_logo_observer_, ScopedJavaLocalRef<jobject>(), from_cache);
266 return; 311 return false;
267 } 312 }
313 load_time_recorder()->WaitForResult();
268 const doodle::DoodleConfig& doodle_config = maybe_doodle_config.value(); 314 const doodle::DoodleConfig& doodle_config = maybe_doodle_config.value();
269 // If there is a CTA image, that means the main image is animated. Show the 315 // If there is a CTA image, that means the main image is animated. Show the
270 // non-animated CTA image first, and load the animated one only when the 316 // non-animated CTA image first, and load the animated one only when the
271 // user requests it. 317 // user requests it.
272 bool has_cta = doodle_config.large_cta_image.has_value(); 318 bool has_cta = doodle_config.large_cta_image.has_value();
273 const GURL& image_url = has_cta ? doodle_config.large_cta_image->url 319 const GURL& image_url = has_cta ? doodle_config.large_cta_image->url
274 : doodle_config.large_image.url; 320 : doodle_config.large_image.url;
275 const GURL& animated_image_url = 321 const GURL& animated_image_url =
276 has_cta ? doodle_config.large_image.url : GURL::EmptyGURL(); 322 has_cta ? doodle_config.large_image.url : GURL::EmptyGURL();
277 // TODO(treib): For interactive doodles, use |fullpage_interactive_url| 323 // TODO(treib): For interactive doodles, use |fullpage_interactive_url|
278 // instead of |target_url|? 324 // instead of |target_url|?
279 const GURL& on_click_url = doodle_config.target_url; 325 const GURL& on_click_url = doodle_config.target_url;
280 const std::string& alt_text = doodle_config.alt_text; 326 const std::string& alt_text = doodle_config.alt_text;
281 image_fetcher_->StartOrQueueNetworkRequest( 327 image_fetcher_->StartOrQueueNetworkRequest(
282 image_url.spec(), image_url, 328 image_url.spec(), image_url,
283 base::Bind(&LogoBridge::DoodleImageFetched, base::Unretained(this), 329 base::Bind(&LogoBridge::DoodleImageFetched, base::Unretained(this),
284 from_cache, on_click_url, alt_text, animated_image_url)); 330 from_cache, on_click_url, alt_text, animated_image_url));
331 return true;
285 } 332 }
286 333
287 void LogoBridge::DoodleImageFetched( 334 void LogoBridge::DoodleImageFetched(
288 bool config_from_cache, 335 bool config_from_cache,
289 const GURL& on_click_url, 336 const GURL& on_click_url,
290 const std::string& alt_text, 337 const std::string& alt_text,
291 const GURL& animated_image_url, 338 const GURL& animated_image_url,
292 const std::string& image_fetch_id, 339 const std::string& image_fetch_id,
293 const gfx::Image& image, 340 const gfx::Image& image,
294 const image_fetcher::RequestMetadata& metadata) { 341 const image_fetcher::RequestMetadata& metadata) {
295 JNIEnv* env = base::android::AttachCurrentThread(); 342 JNIEnv* env = base::android::AttachCurrentThread();
296 343
297 if (image.IsEmpty()) { 344 if (image.IsEmpty()) {
298 DLOG(WARNING) << "Failed to download doodle image"; 345 DLOG(WARNING) << "Failed to download doodle image";
346 load_time_recorder()->Cancel();
299 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, 347 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_,
300 ScopedJavaLocalRef<jobject>(), 348 ScopedJavaLocalRef<jobject>(),
301 config_from_cache); 349 config_from_cache);
302 return; 350 return;
303 } 351 }
304 352
305 UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded", 353 UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded",
306 metadata.from_http_cache); 354 metadata.from_http_cache);
307 355
356 load_time_recorder()->Finish();
308 ScopedJavaLocalRef<jobject> j_logo = MakeJavaLogo( 357 ScopedJavaLocalRef<jobject> j_logo = MakeJavaLogo(
309 env, image.ToSkBitmap(), on_click_url, alt_text, animated_image_url); 358 env, image.ToSkBitmap(), on_click_url, alt_text, animated_image_url);
310 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, 359 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo,
311 config_from_cache); 360 config_from_cache);
312 } 361 }
313 362
314 // static 363 // static
315 bool RegisterLogoBridge(JNIEnv* env) { 364 bool RegisterLogoBridge(JNIEnv* env) {
316 return RegisterNativesImpl(env); 365 return RegisterNativesImpl(env);
317 } 366 }
OLDNEW
« no previous file with comments | « chrome/browser/android/logo_bridge.h ('k') | components/doodle/doodle_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698