| OLD | NEW |
| 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 Loading... |
| 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 Abort() 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 void WaitForResult() override { waiting_for_result_ = true; } |
| 97 |
| 98 void AbortIfNotWaiting() override { |
| 99 if (!waiting_for_result_) { |
| 100 Abort(); |
| 101 } |
| 102 } |
| 103 |
| 104 private: |
| 105 base::TimeTicks logo_load_start_; |
| 106 bool is_recording_; |
| 107 bool waiting_for_result_; |
| 108 }; |
| 109 |
| 110 class LoadTimeMetricRecorderNullImpl |
| 111 : public LogoBridge::LoadTimeMetricRecorder { |
| 112 public: |
| 113 LoadTimeMetricRecorderNullImpl() {} |
| 114 void Abort() override {} |
| 115 void Finish() override {} |
| 116 void WaitForResult() override {} |
| 117 void AbortIfNotWaiting() override {} |
| 118 }; |
| 119 |
| 80 class LogoObserverAndroid : public search_provider_logos::LogoObserver { | 120 class LogoObserverAndroid : public search_provider_logos::LogoObserver { |
| 81 public: | 121 public: |
| 82 LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge, | 122 LogoObserverAndroid(base::WeakPtr<LogoBridge> logo_bridge, |
| 83 JNIEnv* env, | 123 JNIEnv* env, |
| 84 jobject j_logo_observer) | 124 jobject j_logo_observer) |
| 85 : logo_bridge_(logo_bridge) { | 125 : logo_bridge_(logo_bridge), |
| 126 load_time_recorder_(new LoadTimeMetricRecorderImpl()) { |
| 86 j_logo_observer_.Reset(env, j_logo_observer); | 127 j_logo_observer_.Reset(env, j_logo_observer); |
| 87 } | 128 } |
| 88 | 129 |
| 89 ~LogoObserverAndroid() override {} | 130 ~LogoObserverAndroid() override {} |
| 90 | 131 |
| 91 // seach_provider_logos::LogoObserver: | 132 // seach_provider_logos::LogoObserver: |
| 92 void OnLogoAvailable(const search_provider_logos::Logo* logo, | 133 void OnLogoAvailable(const search_provider_logos::Logo* logo, |
| 93 bool from_cache) override { | 134 bool from_cache) override { |
| 94 if (!logo_bridge_) | 135 if (!logo_bridge_) |
| 95 return; | 136 return; |
| 96 | 137 |
| 97 JNIEnv* env = base::android::AttachCurrentThread(); | 138 JNIEnv* env = base::android::AttachCurrentThread(); |
| 98 ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo); | 139 ScopedJavaLocalRef<jobject> j_logo = ConvertLogoToJavaObject(env, logo); |
| 140 load_time_recorder_->Finish(); |
| 99 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, | 141 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, |
| 100 from_cache); | 142 from_cache); |
| 101 } | 143 } |
| 102 | 144 |
| 103 void OnObserverRemoved() override { delete this; } | 145 void OnObserverRemoved() override { delete this; } |
| 104 | 146 |
| 105 private: | 147 private: |
| 106 // The associated LogoBridge. We won't call back to Java if the LogoBridge has | 148 // The associated LogoBridge. We won't call back to Java if the LogoBridge has |
| 107 // been destroyed. | 149 // been destroyed. |
| 108 base::WeakPtr<LogoBridge> logo_bridge_; | 150 base::WeakPtr<LogoBridge> logo_bridge_; |
| 109 | 151 |
| 152 std::unique_ptr<LogoBridge::LoadTimeMetricRecorder> load_time_recorder_; |
| 110 base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_; | 153 base::android::ScopedJavaGlobalRef<jobject> j_logo_observer_; |
| 111 | 154 |
| 112 DISALLOW_COPY_AND_ASSIGN(LogoObserverAndroid); | 155 DISALLOW_COPY_AND_ASSIGN(LogoObserverAndroid); |
| 113 }; | 156 }; |
| 114 | 157 |
| 115 } // namespace | 158 } // namespace |
| 116 | 159 |
| 117 class LogoBridge::AnimatedLogoFetcher : public net::URLFetcherDelegate { | 160 class LogoBridge::AnimatedLogoFetcher : public net::URLFetcherDelegate { |
| 118 public: | 161 public: |
| 119 AnimatedLogoFetcher( | 162 AnimatedLogoFetcher( |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 animated_logo_fetcher_ = base::MakeUnique<AnimatedLogoFetcher>( | 256 animated_logo_fetcher_ = base::MakeUnique<AnimatedLogoFetcher>( |
| 214 profile->GetRequestContext()); | 257 profile->GetRequestContext()); |
| 215 } | 258 } |
| 216 | 259 |
| 217 LogoBridge::~LogoBridge() {} | 260 LogoBridge::~LogoBridge() {} |
| 218 | 261 |
| 219 void LogoBridge::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 262 void LogoBridge::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 220 delete this; | 263 delete this; |
| 221 } | 264 } |
| 222 | 265 |
| 266 LoadTimeRecorder* LogoBridge::load_time_recorder() { |
| 267 if (!load_time_recorder_) { |
| 268 load_time_recorder_ = base::MakeUnique<LoadTimeMetricRecorderNullImpl>(); |
| 269 } |
| 270 return load_time_recorder_.get(); |
| 271 } |
| 272 |
| 223 void LogoBridge::GetCurrentLogo(JNIEnv* env, | 273 void LogoBridge::GetCurrentLogo(JNIEnv* env, |
| 224 const JavaParamRef<jobject>& obj, | 274 const JavaParamRef<jobject>& obj, |
| 225 const JavaParamRef<jobject>& j_logo_observer) { | 275 const JavaParamRef<jobject>& j_logo_observer) { |
| 226 if (doodle_service_) { | 276 if (doodle_service_) { |
| 227 j_logo_observer_.Reset(j_logo_observer); | 277 j_logo_observer_.Reset(j_logo_observer); |
| 278 load_time_recorder_ = base::MakeUnique<LoadTimeMetricRecorderImpl>(); |
| 228 | 279 |
| 229 // Immediately hand out any current cached config. | 280 // Immediately hand out any current cached config. |
| 230 DoodleConfigReceived(doodle_service_->config(), /*from_cache=*/true); | 281 DoodleConfigReceived(doodle_service_->config(), /*from_cache=*/true); |
| 231 // Also request a refresh, in case something changed. | 282 // Also request a refresh, in case something changed. |
| 232 doodle_service_->Refresh(); | 283 if (!doodle_service_->Refresh()) { |
| 284 load_time_recorder()->AbortIfNotWaiting(); |
| 285 } |
| 233 } else { | 286 } else { |
| 234 // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved(). | 287 // |observer| is deleted in LogoObserverAndroid::OnObserverRemoved(). |
| 235 LogoObserverAndroid* observer = new LogoObserverAndroid( | 288 LogoObserverAndroid* observer = new LogoObserverAndroid( |
| 236 weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer); | 289 weak_ptr_factory_.GetWeakPtr(), env, j_logo_observer); |
| 237 logo_service_->GetLogo(observer); | 290 logo_service_->GetLogo(observer); |
| 238 } | 291 } |
| 239 } | 292 } |
| 240 | 293 |
| 241 void LogoBridge::GetAnimatedLogo(JNIEnv* env, | 294 void LogoBridge::GetAnimatedLogo(JNIEnv* env, |
| 242 const JavaParamRef<jobject>& obj, | 295 const JavaParamRef<jobject>& obj, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 258 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config, | 311 const base::Optional<doodle::DoodleConfig>& maybe_doodle_config, |
| 259 bool from_cache) { | 312 bool from_cache) { |
| 260 DCHECK(!j_logo_observer_.is_null()); | 313 DCHECK(!j_logo_observer_.is_null()); |
| 261 | 314 |
| 262 if (!maybe_doodle_config.has_value()) { | 315 if (!maybe_doodle_config.has_value()) { |
| 263 JNIEnv* env = base::android::AttachCurrentThread(); | 316 JNIEnv* env = base::android::AttachCurrentThread(); |
| 264 Java_LogoObserver_onLogoAvailable( | 317 Java_LogoObserver_onLogoAvailable( |
| 265 env, j_logo_observer_, ScopedJavaLocalRef<jobject>(), from_cache); | 318 env, j_logo_observer_, ScopedJavaLocalRef<jobject>(), from_cache); |
| 266 return; | 319 return; |
| 267 } | 320 } |
| 321 load_time_recorder()->WaitForResult(); |
| 268 const doodle::DoodleConfig& doodle_config = maybe_doodle_config.value(); | 322 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 | 323 // 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 | 324 // non-animated CTA image first, and load the animated one only when the |
| 271 // user requests it. | 325 // user requests it. |
| 272 bool has_cta = doodle_config.large_cta_image.has_value(); | 326 bool has_cta = doodle_config.large_cta_image.has_value(); |
| 273 const GURL& image_url = has_cta ? doodle_config.large_cta_image->url | 327 const GURL& image_url = has_cta ? doodle_config.large_cta_image->url |
| 274 : doodle_config.large_image.url; | 328 : doodle_config.large_image.url; |
| 275 const GURL& animated_image_url = | 329 const GURL& animated_image_url = |
| 276 has_cta ? doodle_config.large_image.url : GURL::EmptyGURL(); | 330 has_cta ? doodle_config.large_image.url : GURL::EmptyGURL(); |
| 277 // TODO(treib): For interactive doodles, use |fullpage_interactive_url| | 331 // TODO(treib): For interactive doodles, use |fullpage_interactive_url| |
| (...skipping 11 matching lines...) Expand all Loading... |
| 289 const GURL& on_click_url, | 343 const GURL& on_click_url, |
| 290 const std::string& alt_text, | 344 const std::string& alt_text, |
| 291 const GURL& animated_image_url, | 345 const GURL& animated_image_url, |
| 292 const std::string& image_fetch_id, | 346 const std::string& image_fetch_id, |
| 293 const gfx::Image& image, | 347 const gfx::Image& image, |
| 294 const image_fetcher::RequestMetadata& metadata) { | 348 const image_fetcher::RequestMetadata& metadata) { |
| 295 JNIEnv* env = base::android::AttachCurrentThread(); | 349 JNIEnv* env = base::android::AttachCurrentThread(); |
| 296 | 350 |
| 297 if (image.IsEmpty()) { | 351 if (image.IsEmpty()) { |
| 298 DLOG(WARNING) << "Failed to download doodle image"; | 352 DLOG(WARNING) << "Failed to download doodle image"; |
| 353 load_time_recorder()->Abort(); |
| 299 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, | 354 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, |
| 300 ScopedJavaLocalRef<jobject>(), | 355 ScopedJavaLocalRef<jobject>(), |
| 301 config_from_cache); | 356 config_from_cache); |
| 302 return; | 357 return; |
| 303 } | 358 } |
| 304 | 359 |
| 305 UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded", | 360 UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded", |
| 306 metadata.from_http_cache); | 361 metadata.from_http_cache); |
| 307 | 362 |
| 363 load_time_recorder()->Finish(); |
| 308 ScopedJavaLocalRef<jobject> j_logo = MakeJavaLogo( | 364 ScopedJavaLocalRef<jobject> j_logo = MakeJavaLogo( |
| 309 env, image.ToSkBitmap(), on_click_url, alt_text, animated_image_url); | 365 env, image.ToSkBitmap(), on_click_url, alt_text, animated_image_url); |
| 310 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, | 366 Java_LogoObserver_onLogoAvailable(env, j_logo_observer_, j_logo, |
| 311 config_from_cache); | 367 config_from_cache); |
| 312 } | 368 } |
| 313 | 369 |
| 314 // static | 370 // static |
| 315 bool RegisterLogoBridge(JNIEnv* env) { | 371 bool RegisterLogoBridge(JNIEnv* env) { |
| 316 return RegisterNativesImpl(env); | 372 return RegisterNativesImpl(env); |
| 317 } | 373 } |
| OLD | NEW |