| 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/banners/app_banner_manager.h" | 5 #include "chrome/browser/android/banners/app_banner_manager.h" |
| 6 | 6 |
| 7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
| 8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/threading/worker_pool.h" | |
| 13 #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" | 12 #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" |
| 14 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" | 13 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" |
| 15 #include "chrome/browser/android/banners/app_banner_utilities.h" | 14 #include "chrome/browser/android/banners/app_banner_utilities.h" |
| 16 #include "chrome/browser/android/manifest_icon_selector.h" | 15 #include "chrome/browser/android/manifest_icon_selector.h" |
| 17 #include "chrome/browser/android/shortcut_helper.h" | 16 #include "chrome/browser/android/shortcut_helper.h" |
| 18 #include "chrome/browser/android/shortcut_info.h" | 17 #include "chrome/browser/android/shortcut_info.h" |
| 19 #include "chrome/browser/banners/app_banner_settings_helper.h" | 18 #include "chrome/browser/banners/app_banner_settings_helper.h" |
| 20 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" | 19 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" |
| 21 #include "chrome/browser/infobars/infobar_service.h" | 20 #include "chrome/browser/infobars/infobar_service.h" |
| 22 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 53 : weak_java_banner_view_manager_(env, obj), weak_factory_(this) { | 52 : weak_java_banner_view_manager_(env, obj), weak_factory_(this) { |
| 54 } | 53 } |
| 55 | 54 |
| 56 AppBannerManager::~AppBannerManager() { | 55 AppBannerManager::~AppBannerManager() { |
| 57 } | 56 } |
| 58 | 57 |
| 59 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { | 58 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { |
| 60 delete this; | 59 delete this; |
| 61 } | 60 } |
| 62 | 61 |
| 63 void AppBannerManager::BlockBanner(JNIEnv* env, | |
| 64 jobject obj, | |
| 65 jstring jurl, | |
| 66 jstring jpackage) { | |
| 67 if (!web_contents()) | |
| 68 return; | |
| 69 | |
| 70 GURL url(ConvertJavaStringToUTF8(env, jurl)); | |
| 71 std::string package_name = ConvertJavaStringToUTF8(env, jpackage); | |
| 72 AppBannerSettingsHelper::RecordBannerEvent( | |
| 73 web_contents(), url, package_name, | |
| 74 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
| 75 } | |
| 76 | |
| 77 void AppBannerManager::Block() const { | |
| 78 if (!web_contents()) | |
| 79 return; | |
| 80 | |
| 81 if (!native_app_data_.is_null()) { | |
| 82 AppBannerSettingsHelper::RecordBannerEvent( | |
| 83 web_contents(), web_contents()->GetURL(), | |
| 84 native_app_package_, | |
| 85 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
| 86 } else if (!web_app_data_.IsEmpty()) { | |
| 87 AppBannerSettingsHelper::RecordBannerEvent( | |
| 88 web_contents(), web_contents()->GetURL(), | |
| 89 web_app_data_.start_url.spec(), | |
| 90 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 void AppBannerManager::OnInfoBarDestroyed() { | |
| 95 weak_infobar_ptr_ = nullptr; | |
| 96 } | |
| 97 | |
| 98 bool AppBannerManager::OnButtonClicked() const { | |
| 99 if (!web_contents()) | |
| 100 return true; | |
| 101 | |
| 102 if (!native_app_data_.is_null()) { | |
| 103 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 104 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
| 105 if (jobj.is_null()) | |
| 106 return true; | |
| 107 | |
| 108 return Java_AppBannerManager_installOrOpenNativeApp(env, | |
| 109 jobj.obj(), | |
| 110 native_app_data_.obj()); | |
| 111 } else if (!web_app_data_.IsEmpty()) { | |
| 112 AppBannerSettingsHelper::RecordBannerEvent( | |
| 113 web_contents(), web_contents()->GetURL(), | |
| 114 web_app_data_.start_url.spec(), | |
| 115 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, | |
| 116 base::Time::Now()); | |
| 117 | |
| 118 InstallManifestApp(web_app_data_, *app_icon_.get()); | |
| 119 return true; | |
| 120 } | |
| 121 | |
| 122 return true; | |
| 123 } | |
| 124 | |
| 125 bool AppBannerManager::OnLinkClicked() const { | |
| 126 if (!web_contents()) | |
| 127 return true; | |
| 128 | |
| 129 if (!native_app_data_.is_null()) { | |
| 130 // Try to show the details for the native app. | |
| 131 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 132 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
| 133 if (jobj.is_null()) | |
| 134 return true; | |
| 135 | |
| 136 Java_AppBannerManager_showAppDetails(env, | |
| 137 jobj.obj(), | |
| 138 native_app_data_.obj()); | |
| 139 return true; | |
| 140 } else { | |
| 141 // Nothing should happen if the user is installing a web app. | |
| 142 return false; | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 base::string16 AppBannerManager::GetTitle() const { | |
| 147 return app_title_; | |
| 148 } | |
| 149 | |
| 150 gfx::Image AppBannerManager::GetIcon() const { | |
| 151 return gfx::Image::CreateFrom1xBitmap(*app_icon_.get()); | |
| 152 } | |
| 153 | |
| 154 void AppBannerManager::ReplaceWebContents(JNIEnv* env, | 62 void AppBannerManager::ReplaceWebContents(JNIEnv* env, |
| 155 jobject obj, | 63 jobject obj, |
| 156 jobject jweb_contents) { | 64 jobject jweb_contents) { |
| 157 content::WebContents* web_contents = | 65 content::WebContents* web_contents = |
| 158 content::WebContents::FromJavaWebContents(jweb_contents); | 66 content::WebContents::FromJavaWebContents(jweb_contents); |
| 159 Observe(web_contents); | 67 Observe(web_contents); |
| 160 } | 68 } |
| 161 | 69 |
| 162 void AppBannerManager::DidNavigateMainFrame( | 70 void AppBannerManager::DidNavigateMainFrame( |
| 163 const content::LoadCommittedDetails& details, | 71 const content::LoadCommittedDetails& details, |
| 164 const content::FrameNavigateParams& params) { | 72 const content::FrameNavigateParams& params) { |
| 165 // Clear current state. | 73 // Clear current state. |
| 166 fetcher_.reset(); | 74 fetcher_.reset(); |
| 167 app_title_ = base::string16(); | 75 app_title_ = base::string16(); |
| 168 app_icon_.reset(); | |
| 169 web_app_data_ = content::Manifest(); | 76 web_app_data_ = content::Manifest(); |
| 170 native_app_data_.Reset(); | 77 native_app_data_.Reset(); |
| 171 native_app_package_ = std::string(); | 78 native_app_package_ = std::string(); |
| 172 } | 79 } |
| 173 | 80 |
| 174 void AppBannerManager::DidFinishLoad( | 81 void AppBannerManager::DidFinishLoad( |
| 175 content::RenderFrameHost* render_frame_host, | 82 content::RenderFrameHost* render_frame_host, |
| 176 const GURL& validated_url) { | 83 const GURL& validated_url) { |
| 177 if (render_frame_host->GetParent()) | 84 if (render_frame_host->GetParent()) |
| 178 return; | 85 return; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 if (!bitmap || url != app_icon_url_) { | 176 if (!bitmap || url != app_icon_url_) { |
| 270 DVLOG(1) << "Failed to retrieve image: " << url; | 177 DVLOG(1) << "Failed to retrieve image: " << url; |
| 271 return; | 178 return; |
| 272 } | 179 } |
| 273 | 180 |
| 274 JNIEnv* env = base::android::AttachCurrentThread(); | 181 JNIEnv* env = base::android::AttachCurrentThread(); |
| 275 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 182 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
| 276 if (jobj.is_null()) | 183 if (jobj.is_null()) |
| 277 return; | 184 return; |
| 278 | 185 |
| 279 app_icon_.reset(new SkBitmap(*bitmap)); | |
| 280 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); | 186 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); |
| 281 | 187 |
| 282 weak_infobar_ptr_ = nullptr; | 188 AppBannerInfoBar* weak_infobar_ptr = nullptr; |
| 283 if (!native_app_data_.is_null()) { | 189 if (!native_app_data_.is_null()) { |
| 284 RecordCouldShowBanner(native_app_package_); | 190 RecordCouldShowBanner(native_app_package_); |
| 285 if (!CheckIfShouldShow(native_app_package_)) | 191 if (!CheckIfShouldShow(native_app_package_)) |
| 286 return; | 192 return; |
| 287 | 193 |
| 288 weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForNativeApp( | 194 weak_infobar_ptr = AppBannerInfoBarDelegate::CreateForNativeApp( |
| 289 service, | 195 service, |
| 290 this, | 196 app_title_, |
| 291 native_app_data_); | 197 new SkBitmap(*bitmap), |
| 198 native_app_data_, |
| 199 native_app_package_); |
| 292 } else if (!web_app_data_.IsEmpty()){ | 200 } else if (!web_app_data_.IsEmpty()){ |
| 293 RecordCouldShowBanner(web_app_data_.start_url.spec()); | 201 RecordCouldShowBanner(web_app_data_.start_url.spec()); |
| 294 if (!CheckIfShouldShow(web_app_data_.start_url.spec())) | 202 if (!CheckIfShouldShow(web_app_data_.start_url.spec())) |
| 295 return; | 203 return; |
| 296 | 204 |
| 297 weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForWebApp( | 205 weak_infobar_ptr = AppBannerInfoBarDelegate::CreateForWebApp( |
| 298 service, | 206 service, |
| 299 this, | 207 app_title_, |
| 300 web_app_data_.start_url); | 208 new SkBitmap(*bitmap), |
| 209 web_app_data_); |
| 301 } | 210 } |
| 302 | 211 |
| 303 if (weak_infobar_ptr_ != nullptr) | 212 if (weak_infobar_ptr != nullptr) |
| 304 banners::TrackDisplayEvent(DISPLAY_CREATED); | 213 banners::TrackDisplayEvent(DISPLAY_CREATED); |
| 305 } | 214 } |
| 306 | 215 |
| 307 void AppBannerManager::OnDidRetrieveMetaTagContent( | 216 void AppBannerManager::OnDidRetrieveMetaTagContent( |
| 308 bool success, | 217 bool success, |
| 309 const std::string& tag_name, | 218 const std::string& tag_name, |
| 310 const std::string& tag_content, | 219 const std::string& tag_content, |
| 311 const GURL& expected_url) { | 220 const GURL& expected_url) { |
| 312 DCHECK(web_contents()); | 221 DCHECK(web_contents()); |
| 313 if (!success || tag_name != kBannerTag || validated_url_ != expected_url || | 222 if (!success || tag_name != kBannerTag || validated_url_ != expected_url || |
| (...skipping 28 matching lines...) Expand all Loading... |
| 342 if (validated_url_ != web_contents()->GetURL()) | 251 if (validated_url_ != web_contents()->GetURL()) |
| 343 return false; | 252 return false; |
| 344 | 253 |
| 345 std::string image_url = ConvertJavaStringToUTF8(env, jicon_url); | 254 std::string image_url = ConvertJavaStringToUTF8(env, jicon_url); |
| 346 app_title_ = ConvertJavaStringToUTF16(env, japp_title); | 255 app_title_ = ConvertJavaStringToUTF16(env, japp_title); |
| 347 native_app_package_ = ConvertJavaStringToUTF8(env, japp_package); | 256 native_app_package_ = ConvertJavaStringToUTF8(env, japp_package); |
| 348 native_app_data_.Reset(env, japp_data); | 257 native_app_data_.Reset(env, japp_data); |
| 349 return FetchIcon(GURL(image_url)); | 258 return FetchIcon(GURL(image_url)); |
| 350 } | 259 } |
| 351 | 260 |
| 352 void AppBannerManager::OnInstallIntentReturned(JNIEnv* env, | |
| 353 jobject obj, | |
| 354 jboolean jis_installing) { | |
| 355 if (!weak_infobar_ptr_) | |
| 356 return; | |
| 357 | |
| 358 if (jis_installing) { | |
| 359 AppBannerSettingsHelper::RecordBannerEvent( | |
| 360 web_contents(), | |
| 361 web_contents()->GetURL(), | |
| 362 native_app_package_, | |
| 363 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, | |
| 364 base::Time::Now()); | |
| 365 } | |
| 366 | |
| 367 UpdateInstallState(env, obj); | |
| 368 } | |
| 369 | |
| 370 void AppBannerManager::OnInstallFinished(JNIEnv* env, | |
| 371 jobject obj, | |
| 372 jboolean success) { | |
| 373 if (!weak_infobar_ptr_) | |
| 374 return; | |
| 375 | |
| 376 if (success) { | |
| 377 UpdateInstallState(env, obj); | |
| 378 } else { | |
| 379 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); | |
| 380 service->RemoveInfoBar(weak_infobar_ptr_); | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 void AppBannerManager::UpdateInstallState(JNIEnv* env, jobject obj) { | |
| 385 if (!weak_infobar_ptr_ || native_app_data_.is_null()) | |
| 386 return; | |
| 387 | |
| 388 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
| 389 if (jobj.is_null()) | |
| 390 return; | |
| 391 | |
| 392 int newState = Java_AppBannerManager_determineInstallState( | |
| 393 env, | |
| 394 jobj.obj(), | |
| 395 native_app_data_.obj()); | |
| 396 weak_infobar_ptr_->OnInstallStateChanged(newState); | |
| 397 } | |
| 398 | |
| 399 bool AppBannerManager::FetchIcon(const GURL& image_url) { | 261 bool AppBannerManager::FetchIcon(const GURL& image_url) { |
| 400 if (!web_contents()) | 262 if (!web_contents()) |
| 401 return false; | 263 return false; |
| 402 | 264 |
| 403 // Begin asynchronously fetching the app icon. | 265 // Begin asynchronously fetching the app icon. |
| 404 Profile* profile = | 266 Profile* profile = |
| 405 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | 267 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| 406 fetcher_.reset(new chrome::BitmapFetcher(image_url, this)); | 268 fetcher_.reset(new chrome::BitmapFetcher(image_url, this)); |
| 407 fetcher_.get()->Start( | 269 fetcher_.get()->Start( |
| 408 profile->GetRequestContext(), | 270 profile->GetRequestContext(), |
| 409 std::string(), | 271 std::string(), |
| 410 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | 272 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
| 411 net::LOAD_NORMAL); | 273 net::LOAD_NORMAL); |
| 412 app_icon_url_ = image_url; | 274 app_icon_url_ = image_url; |
| 413 return true; | 275 return true; |
| 414 } | 276 } |
| 415 | 277 |
| 416 int AppBannerManager::GetPreferredIconSize() { | 278 int AppBannerManager::GetPreferredIconSize() { |
| 417 JNIEnv* env = base::android::AttachCurrentThread(); | 279 JNIEnv* env = base::android::AttachCurrentThread(); |
| 418 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 280 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
| 419 if (jobj.is_null()) | 281 if (jobj.is_null()) |
| 420 return 0; | 282 return 0; |
| 421 | 283 |
| 422 return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); | 284 return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); |
| 423 } | 285 } |
| 424 | 286 |
| 425 // static | |
| 426 void AppBannerManager::InstallManifestApp(const content::Manifest& manifest, | |
| 427 const SkBitmap& icon) { | |
| 428 ShortcutInfo info; | |
| 429 info.UpdateFromManifest(manifest); | |
| 430 | |
| 431 base::WorkerPool::PostTask( | |
| 432 FROM_HERE, | |
| 433 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap, | |
| 434 info, | |
| 435 icon), | |
| 436 true); | |
| 437 } | |
| 438 | |
| 439 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { | 287 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { |
| 440 banners::TrackDismissEvent(metric); | 288 banners::TrackDismissEvent(metric); |
| 441 } | 289 } |
| 442 | 290 |
| 443 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { | 291 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { |
| 444 banners::TrackInstallEvent(metric); | 292 banners::TrackInstallEvent(metric); |
| 445 } | 293 } |
| 446 | 294 |
| 447 jlong Init(JNIEnv* env, jobject obj) { | 295 jlong Init(JNIEnv* env, jobject obj) { |
| 448 AppBannerManager* manager = new AppBannerManager(env, obj); | 296 AppBannerManager* manager = new AppBannerManager(env, obj); |
| 449 return reinterpret_cast<intptr_t>(manager); | 297 return reinterpret_cast<intptr_t>(manager); |
| 450 } | 298 } |
| 451 | 299 |
| 452 jboolean IsEnabled(JNIEnv* env, jclass clazz) { | 300 jboolean IsEnabled(JNIEnv* env, jclass clazz) { |
| 453 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 301 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 454 switches::kEnableAppInstallAlerts); | 302 switches::kEnableAppInstallAlerts); |
| 455 } | 303 } |
| 456 | 304 |
| 457 // Register native methods | 305 // Register native methods |
| 458 bool RegisterAppBannerManager(JNIEnv* env) { | 306 bool RegisterAppBannerManager(JNIEnv* env) { |
| 459 return RegisterNativesImpl(env); | 307 return RegisterNativesImpl(env); |
| 460 } | 308 } |
| 461 | 309 |
| 462 } // namespace banners | 310 } // namespace banners |
| OLD | NEW |