| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_infobar_delegate_android.h" | 5 #include "chrome/browser/android/banners/app_banner_infobar_delegate_android.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/guid.h" | 9 #include "base/guid.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/string16.h" | |
| 13 #include "base/strings/utf_string_conversions.h" | |
| 14 #include "chrome/browser/android/shortcut_helper.h" | 12 #include "chrome/browser/android/shortcut_helper.h" |
| 15 #include "chrome/browser/android/shortcut_info.h" | 13 #include "chrome/browser/android/shortcut_info.h" |
| 16 #include "chrome/browser/android/tab_android.h" | 14 #include "chrome/browser/android/tab_android.h" |
| 17 #include "chrome/browser/android/webapk/webapk_installer.h" | 15 #include "chrome/browser/android/webapk/webapk_installer.h" |
| 18 #include "chrome/browser/banners/app_banner_manager.h" | 16 #include "chrome/browser/banners/app_banner_manager.h" |
| 19 #include "chrome/browser/banners/app_banner_metrics.h" | 17 #include "chrome/browser/banners/app_banner_metrics.h" |
| 20 #include "chrome/browser/banners/app_banner_settings_helper.h" | 18 #include "chrome/browser/banners/app_banner_settings_helper.h" |
| 21 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
| 22 #include "chrome/browser/infobars/infobar_service.h" | 20 #include "chrome/browser/infobars/infobar_service.h" |
| 23 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" | 21 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" |
| 24 #include "chrome/common/render_messages.h" | |
| 25 #include "components/rappor/rappor_utils.h" | 22 #include "components/rappor/rappor_utils.h" |
| 26 #include "content/public/browser/render_frame_host.h" | |
| 27 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
| 28 #include "content/public/common/manifest.h" | 24 #include "content/public/common/manifest.h" |
| 29 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h" | 25 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h" |
| 30 #include "ui/gfx/android/java_bitmap.h" | 26 #include "ui/gfx/android/java_bitmap.h" |
| 31 #include "url/gurl.h" | 27 #include "url/gurl.h" |
| 32 | 28 |
| 33 using base::android::ConvertJavaStringToUTF8; | 29 using base::android::ConvertJavaStringToUTF8; |
| 34 using base::android::ConvertJavaStringToUTF16; | 30 using base::android::ConvertJavaStringToUTF16; |
| 35 using base::android::ConvertUTF8ToJavaString; | 31 using base::android::ConvertUTF8ToJavaString; |
| 36 using base::android::ConvertUTF16ToJavaString; | 32 using base::android::ConvertUTF16ToJavaString; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" | 176 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" |
| 181 // button is pressed, so request WebAPK installation. Otherwise, it means | 177 // button is pressed, so request WebAPK installation. Otherwise, it means |
| 182 // the "Open" button is pressed, so open the installed WebAPK. | 178 // the "Open" button is pressed, so open the installed WebAPK. |
| 183 if (!webapk_package_name_.empty()) { | 179 if (!webapk_package_name_.empty()) { |
| 184 // Open the WebAPK. | 180 // Open the WebAPK. |
| 185 ScopedJavaLocalRef<jstring> java_webapk_package_name = | 181 ScopedJavaLocalRef<jstring> java_webapk_package_name = |
| 186 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); | 182 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); |
| 187 Java_AppBannerInfoBarDelegateAndroid_openWebApk(env, java_delegate_, | 183 Java_AppBannerInfoBarDelegateAndroid_openWebApk(env, java_delegate_, |
| 188 java_webapk_package_name); | 184 java_webapk_package_name); |
| 189 webapk::TrackUserAction(webapk::USER_ACTION_INSTALLED_OPEN); | 185 webapk::TrackUserAction(webapk::USER_ACTION_INSTALLED_OPEN); |
| 190 SendBannerAccepted(web_contents, "web"); | 186 SendBannerAccepted(); |
| 191 return true; | 187 return true; |
| 192 } | 188 } |
| 193 | 189 |
| 194 // Check whether the WebAPK has been installed. | 190 // Check whether the WebAPK has been installed. |
| 195 std::string installed_webapk_package_name = | 191 std::string installed_webapk_package_name = |
| 196 ShortcutHelper::QueryWebApkPackage(web_contents->GetLastCommittedURL()); | 192 ShortcutHelper::QueryWebApkPackage(web_contents->GetLastCommittedURL()); |
| 197 if (installed_webapk_package_name.empty()) { | 193 if (installed_webapk_package_name.empty()) { |
| 198 // Request install the WebAPK. | 194 // Request install the WebAPK. |
| 199 install_state_ = INSTALLING; | 195 install_state_ = INSTALLING; |
| 200 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 196 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
| 201 webapk::TrackInstallSource(webapk_install_source_); | 197 webapk::TrackInstallSource(webapk_install_source_); |
| 202 AppBannerSettingsHelper::RecordBannerInstallEvent( | 198 AppBannerSettingsHelper::RecordBannerInstallEvent( |
| 203 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); | 199 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); |
| 204 | 200 |
| 205 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( | 201 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( |
| 206 env, java_delegate_, true); | 202 env, java_delegate_, true); |
| 207 UpdateInstallState(env, nullptr); | 203 UpdateInstallState(env, nullptr); |
| 208 WebApkInstaller::FinishCallback callback = | 204 WebApkInstaller::FinishCallback callback = |
| 209 base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, | 205 base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, |
| 210 weak_ptr_factory_.GetWeakPtr()); | 206 weak_ptr_factory_.GetWeakPtr()); |
| 211 ShortcutHelper::InstallWebApkWithSkBitmap(web_contents->GetBrowserContext(), | 207 ShortcutHelper::InstallWebApkWithSkBitmap(web_contents->GetBrowserContext(), |
| 212 *shortcut_info_, | 208 *shortcut_info_, |
| 213 *icon_.get(), callback); | 209 *icon_.get(), callback); |
| 214 SendBannerAccepted(web_contents, "web"); | 210 SendBannerAccepted(); |
| 215 | 211 |
| 216 // Prevent the infobar from disappearing, because the infobar will show | 212 // Prevent the infobar from disappearing, because the infobar will show |
| 217 // "Adding" during the installation process. | 213 // "Adding" during the installation process. |
| 218 return false; | 214 return false; |
| 219 } | 215 } |
| 220 | 216 |
| 221 // Bypass the installation since WebAPK is already installed. | 217 // Bypass the installation since WebAPK is already installed. |
| 222 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 218 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
| 223 OnWebApkInstallFinished(true, installed_webapk_package_name); | 219 OnWebApkInstallFinished(true, installed_webapk_package_name); |
| 224 return false; | 220 return false; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 DCHECK(!native_app_data_.is_null()); | 260 DCHECK(!native_app_data_.is_null()); |
| 265 CreateJavaDelegate(); | 261 CreateJavaDelegate(); |
| 266 } | 262 } |
| 267 | 263 |
| 268 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { | 264 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { |
| 269 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( | 265 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( |
| 270 base::android::AttachCurrentThread(), | 266 base::android::AttachCurrentThread(), |
| 271 reinterpret_cast<intptr_t>(this))); | 267 reinterpret_cast<intptr_t>(this))); |
| 272 } | 268 } |
| 273 | 269 |
| 274 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted( | 270 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted() { |
| 275 content::WebContents* web_contents, | 271 if (weak_manager_) |
| 276 const std::string& platform) { | 272 weak_manager_->SendBannerAccepted(event_request_id_); |
| 277 web_contents->GetMainFrame()->Send( | |
| 278 new ChromeViewMsg_AppBannerAccepted( | |
| 279 web_contents->GetMainFrame()->GetRoutingID(), | |
| 280 event_request_id_, | |
| 281 platform)); | |
| 282 } | 273 } |
| 283 | 274 |
| 284 infobars::InfoBarDelegate::InfoBarIdentifier | 275 infobars::InfoBarDelegate::InfoBarIdentifier |
| 285 AppBannerInfoBarDelegateAndroid::GetIdentifier() const { | 276 AppBannerInfoBarDelegateAndroid::GetIdentifier() const { |
| 286 return APP_BANNER_INFOBAR_DELEGATE_ANDROID; | 277 return APP_BANNER_INFOBAR_DELEGATE_ANDROID; |
| 287 } | 278 } |
| 288 | 279 |
| 289 gfx::Image AppBannerInfoBarDelegateAndroid::GetIcon() const { | 280 gfx::Image AppBannerInfoBarDelegateAndroid::GetIcon() const { |
| 290 return gfx::Image::CreateFrom1xBitmap(*icon_.get()); | 281 return gfx::Image::CreateFrom1xBitmap(*icon_.get()); |
| 291 } | 282 } |
| 292 | 283 |
| 293 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() { | 284 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() { |
| 294 has_user_interaction_ = true; | 285 has_user_interaction_ = true; |
| 295 | 286 |
| 296 content::WebContents* web_contents = | 287 content::WebContents* web_contents = |
| 297 InfoBarService::WebContentsFromInfoBar(infobar()); | 288 InfoBarService::WebContentsFromInfoBar(infobar()); |
| 298 | 289 |
| 299 web_contents->GetMainFrame()->Send( | 290 if (weak_manager_) |
| 300 new ChromeViewMsg_AppBannerDismissed( | 291 weak_manager_->SendBannerDismissed(event_request_id_); |
| 301 web_contents->GetMainFrame()->GetRoutingID(), | |
| 302 event_request_id_)); | |
| 303 | 292 |
| 304 if (native_app_data_.is_null()) { | 293 if (native_app_data_.is_null()) { |
| 305 if (is_webapk_) | 294 if (is_webapk_) |
| 306 TrackWebApkInstallationDismissEvents(install_state_); | 295 TrackWebApkInstallationDismissEvents(install_state_); |
| 307 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); | 296 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); |
| 308 AppBannerSettingsHelper::RecordBannerDismissEvent( | 297 AppBannerSettingsHelper::RecordBannerDismissEvent( |
| 309 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); | 298 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); |
| 310 } else { | 299 } else { |
| 311 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); | 300 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); |
| 312 AppBannerSettingsHelper::RecordBannerDismissEvent( | 301 AppBannerSettingsHelper::RecordBannerDismissEvent( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 bool was_opened = | 343 bool was_opened = |
| 355 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp( | 344 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp( |
| 356 env, java_delegate_, tab->GetJavaObject(), | 345 env, java_delegate_, tab->GetJavaObject(), |
| 357 native_app_data_, jreferrer); | 346 native_app_data_, jreferrer); |
| 358 | 347 |
| 359 if (was_opened) | 348 if (was_opened) |
| 360 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); | 349 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); |
| 361 else | 350 else |
| 362 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); | 351 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); |
| 363 | 352 |
| 364 SendBannerAccepted(web_contents, "play"); | 353 SendBannerAccepted(); |
| 365 return was_opened; | 354 return was_opened; |
| 366 } | 355 } |
| 367 | 356 |
| 368 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( | 357 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( |
| 369 content::WebContents* web_contents) { | 358 content::WebContents* web_contents) { |
| 370 if (IsInfoEmpty(shortcut_info_)) | 359 if (IsInfoEmpty(shortcut_info_)) |
| 371 return true; | 360 return true; |
| 372 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 361 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
| 373 | 362 |
| 374 AppBannerSettingsHelper::RecordBannerInstallEvent( | 363 AppBannerSettingsHelper::RecordBannerInstallEvent( |
| 375 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); | 364 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); |
| 376 | 365 |
| 377 if (weak_manager_) { | 366 if (weak_manager_) { |
| 378 const std::string& uid = base::GenerateGUID(); | 367 const std::string& uid = base::GenerateGUID(); |
| 379 ShortcutHelper::AddToLauncherWithSkBitmap( | 368 ShortcutHelper::AddToLauncherWithSkBitmap( |
| 380 web_contents->GetBrowserContext(), *shortcut_info_, uid, | 369 web_contents->GetBrowserContext(), *shortcut_info_, uid, |
| 381 *icon_.get(), weak_manager_->FetchWebappSplashScreenImageCallback(uid)); | 370 *icon_.get(), weak_manager_->FetchWebappSplashScreenImageCallback(uid)); |
| 382 } | 371 } |
| 383 | 372 |
| 384 SendBannerAccepted(web_contents, "web"); | 373 SendBannerAccepted(); |
| 385 return true; | 374 return true; |
| 386 } | 375 } |
| 387 | 376 |
| 388 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished( | 377 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished( |
| 389 bool success, | 378 bool success, |
| 390 const std::string& webapk_package_name) { | 379 const std::string& webapk_package_name) { |
| 391 JNIEnv* env = base::android::AttachCurrentThread(); | 380 JNIEnv* env = base::android::AttachCurrentThread(); |
| 392 if (!success) { | 381 if (!success) { |
| 393 DVLOG(1) << "The WebAPK installation failed."; | 382 DVLOG(1) << "The WebAPK installation failed."; |
| 394 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env); | 383 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 DCHECK(tab); | 426 DCHECK(tab); |
| 438 | 427 |
| 439 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( | 428 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( |
| 440 env, java_delegate_, tab->GetJavaObject(), native_app_data_); | 429 env, java_delegate_, tab->GetJavaObject(), native_app_data_); |
| 441 | 430 |
| 442 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); | 431 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); |
| 443 return true; | 432 return true; |
| 444 } | 433 } |
| 445 | 434 |
| 446 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { | 435 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { |
| 447 return RegisterNativesImpl(env); | 436 return RegisterNativesImpl(env); |
| 448 } | 437 } |
| 449 | 438 |
| 450 } // namespace banners | 439 } // namespace banners |
| OLD | NEW |