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" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 using base::android::ConvertUTF16ToJavaString; | 36 using base::android::ConvertUTF16ToJavaString; |
37 using base::android::JavaParamRef; | 37 using base::android::JavaParamRef; |
38 using base::android::ScopedJavaLocalRef; | 38 using base::android::ScopedJavaLocalRef; |
39 | 39 |
40 namespace { | 40 namespace { |
41 | 41 |
42 bool IsInfoEmpty(const ShortcutInfo* info) { | 42 bool IsInfoEmpty(const ShortcutInfo* info) { |
43 return !info || info->url.is_empty(); | 43 return !info || info->url.is_empty(); |
44 } | 44 } |
45 | 45 |
46 void TrackWebApkInstallationDismissEvents(webapk::InstallState install_state) { | |
47 if (install_state == webapk::WAIT_FOR_START) | |
48 webapk::TrackInstallEvent(webapk::INSTALL_EVENT_ADD_TO_HOME_SCREEN_DISMISS); | |
49 else if (install_state == webapk::INSTALLING) | |
50 webapk::TrackInstallEvent(webapk::INSTALL_EVENT_ADDING_DISMISS); | |
51 else if (install_state == webapk::INSTALLED) | |
52 webapk::TrackUserAction(webapk::USER_ACTION_INSTALLED_OPEN_DISMISS); | |
46 } | 53 } |
47 | 54 |
55 } // namespace | |
56 | |
48 namespace banners { | 57 namespace banners { |
49 | 58 |
50 // static | 59 // static |
51 bool AppBannerInfoBarDelegateAndroid::Create( | 60 bool AppBannerInfoBarDelegateAndroid::Create( |
52 content::WebContents* web_contents, | 61 content::WebContents* web_contents, |
53 base::WeakPtr<AppBannerManager> weak_manager, | 62 base::WeakPtr<AppBannerManager> weak_manager, |
54 const base::string16& app_title, | 63 const base::string16& app_title, |
55 std::unique_ptr<ShortcutInfo> shortcut_info, | 64 std::unique_ptr<ShortcutInfo> shortcut_info, |
56 std::unique_ptr<SkBitmap> icon, | 65 std::unique_ptr<SkBitmap> icon, |
57 int event_request_id, | 66 int event_request_id, |
58 bool is_webapk, | 67 bool is_webapk, |
59 bool start_install_webapk) { | 68 bool start_install_webapk) { |
60 const GURL& url = shortcut_info->url; | 69 const GURL& url = shortcut_info->url; |
61 auto infobar_delegate = | 70 auto infobar_delegate = |
62 base::WrapUnique(new banners::AppBannerInfoBarDelegateAndroid( | 71 base::WrapUnique(new banners::AppBannerInfoBarDelegateAndroid( |
63 weak_manager, app_title, std::move(shortcut_info), std::move(icon), | 72 weak_manager, app_title, std::move(shortcut_info), std::move(icon), |
64 event_request_id, is_webapk)); | 73 event_request_id, is_webapk)); |
65 auto raw_delegate = infobar_delegate.get(); | 74 auto raw_delegate = infobar_delegate.get(); |
66 auto infobar = base::MakeUnique<AppBannerInfoBarAndroid>( | 75 auto infobar = base::MakeUnique<AppBannerInfoBarAndroid>( |
67 std::move(infobar_delegate), url, is_webapk); | 76 std::move(infobar_delegate), url, is_webapk); |
68 if (!InfoBarService::FromWebContents(web_contents) | 77 if (!InfoBarService::FromWebContents(web_contents) |
69 ->AddInfoBar(std::move(infobar))) | 78 ->AddInfoBar(std::move(infobar))) |
70 return false; | 79 return false; |
71 | 80 |
72 if (is_webapk && start_install_webapk) | 81 if (is_webapk) { |
73 raw_delegate->AcceptWebApk(web_contents); | 82 if (start_install_webapk) { |
83 raw_delegate->AcceptWebApk(web_contents); | |
84 webapk::TrackStartType(webapk::STARTED_FROM_ADD_TO_HOME_SCREEN_MENU); | |
85 } else { | |
86 webapk::TrackStartType(webapk::TRIGGERED_FROM_BANNER); | |
87 } | |
88 } | |
74 | 89 |
75 return true; | 90 return true; |
76 } | 91 } |
77 | 92 |
78 // static | 93 // static |
79 bool AppBannerInfoBarDelegateAndroid::Create( | 94 bool AppBannerInfoBarDelegateAndroid::Create( |
80 content::WebContents* web_contents, | 95 content::WebContents* web_contents, |
81 const base::string16& app_title, | 96 const base::string16& app_title, |
82 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, | 97 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, |
83 std::unique_ptr<SkBitmap> icon, | 98 std::unique_ptr<SkBitmap> icon, |
84 const std::string& native_app_package, | 99 const std::string& native_app_package, |
85 const std::string& referrer, | 100 const std::string& referrer, |
86 int event_request_id) { | 101 int event_request_id) { |
87 auto infobar_delegate = base::WrapUnique(new AppBannerInfoBarDelegateAndroid( | 102 auto infobar_delegate = base::WrapUnique(new AppBannerInfoBarDelegateAndroid( |
88 app_title, native_app_data, std::move(icon), native_app_package, referrer, | 103 app_title, native_app_data, std::move(icon), native_app_package, referrer, |
89 event_request_id)); | 104 event_request_id)); |
90 return InfoBarService::FromWebContents(web_contents) | 105 return InfoBarService::FromWebContents(web_contents) |
91 ->AddInfoBar(base::MakeUnique<AppBannerInfoBarAndroid>( | 106 ->AddInfoBar(base::MakeUnique<AppBannerInfoBarAndroid>( |
92 std::move(infobar_delegate), native_app_data)); | 107 std::move(infobar_delegate), native_app_data)); |
93 } | 108 } |
94 | 109 |
95 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { | 110 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { |
96 weak_ptr_factory_.InvalidateWeakPtrs(); | 111 weak_ptr_factory_.InvalidateWeakPtrs(); |
97 | 112 |
98 if (!has_user_interaction_) { | 113 if (!has_user_interaction_) { |
99 if (!native_app_data_.is_null()) | 114 if (!native_app_data_.is_null()) { |
100 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); | 115 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); |
101 else if (!IsInfoEmpty(shortcut_info_.get())) | 116 } else if (!IsInfoEmpty(shortcut_info_.get())) { |
102 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); | 117 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); |
118 if (is_webapk_) | |
119 webapk::TrackInstallEvent(webapk::INSTALL_EVENT_BANNER_IGNORED); | |
120 } | |
103 } | 121 } |
104 | 122 |
105 TrackDismissEvent(DISMISS_EVENT_DISMISSED); | 123 TrackDismissEvent(DISMISS_EVENT_DISMISSED); |
106 JNIEnv* env = base::android::AttachCurrentThread(); | 124 JNIEnv* env = base::android::AttachCurrentThread(); |
107 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); | 125 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); |
108 java_delegate_.Reset(); | 126 java_delegate_.Reset(); |
109 } | 127 } |
110 | 128 |
111 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( | 129 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( |
112 JNIEnv* env, | 130 JNIEnv* env, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 // |webapk_package_name_| is set when the WebAPK has finished installing. | 187 // |webapk_package_name_| is set when the WebAPK has finished installing. |
170 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" | 188 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" |
171 // button is pressed, so request WebAPK installation. Otherwise, it means | 189 // button is pressed, so request WebAPK installation. Otherwise, it means |
172 // the "Open" button is pressed, so open the installed WebAPK. | 190 // the "Open" button is pressed, so open the installed WebAPK. |
173 if (!webapk_package_name_.empty()) { | 191 if (!webapk_package_name_.empty()) { |
174 // Open the WebAPK. | 192 // Open the WebAPK. |
175 ScopedJavaLocalRef<jstring> java_webapk_package_name = | 193 ScopedJavaLocalRef<jstring> java_webapk_package_name = |
176 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); | 194 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); |
177 Java_AppBannerInfoBarDelegateAndroid_openWebApk(env, java_delegate_, | 195 Java_AppBannerInfoBarDelegateAndroid_openWebApk(env, java_delegate_, |
178 java_webapk_package_name); | 196 java_webapk_package_name); |
179 | 197 webapk::TrackUserAction(webapk::USER_ACTION_INSTALLED_OPEN); |
180 SendBannerAccepted(web_contents, "web"); | 198 SendBannerAccepted(web_contents, "web"); |
181 return true; | 199 return true; |
182 } | 200 } |
183 | 201 |
184 // Request install the WebAPK. | 202 // Request install the WebAPK. |
203 install_state_ = webapk::INSTALLING; | |
185 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 204 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
186 AppBannerSettingsHelper::RecordBannerInstallEvent( | 205 AppBannerSettingsHelper::RecordBannerInstallEvent( |
187 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); | 206 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); |
188 | 207 |
189 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( | 208 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( |
190 env, java_delegate_, true); | 209 env, java_delegate_, true); |
191 UpdateInstallState(env, nullptr); | 210 UpdateInstallState(env, nullptr); |
192 WebApkInstaller::FinishCallback callback = | 211 WebApkInstaller::FinishCallback callback = |
193 base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, | 212 base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, |
194 weak_ptr_factory_.GetWeakPtr()); | 213 weak_ptr_factory_.GetWeakPtr()); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 web_contents->GetMainFrame()->Send( | 293 web_contents->GetMainFrame()->Send( |
275 new ChromeViewMsg_AppBannerDismissed( | 294 new ChromeViewMsg_AppBannerDismissed( |
276 web_contents->GetMainFrame()->GetRoutingID(), | 295 web_contents->GetMainFrame()->GetRoutingID(), |
277 event_request_id_)); | 296 event_request_id_)); |
278 | 297 |
279 if (!native_app_data_.is_null()) { | 298 if (!native_app_data_.is_null()) { |
280 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); | 299 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); |
281 AppBannerSettingsHelper::RecordBannerDismissEvent( | 300 AppBannerSettingsHelper::RecordBannerDismissEvent( |
282 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); | 301 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); |
283 } else { | 302 } else { |
303 if (is_webapk_) | |
304 TrackWebApkInstallationDismissEvents(install_state_); | |
284 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); | 305 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); |
285 AppBannerSettingsHelper::RecordBannerDismissEvent( | 306 AppBannerSettingsHelper::RecordBannerDismissEvent( |
286 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); | 307 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB); |
287 } | 308 } |
288 } | 309 } |
289 | 310 |
290 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { | 311 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { |
291 return app_title_; | 312 return app_title_; |
292 } | 313 } |
293 | 314 |
294 int AppBannerInfoBarDelegateAndroid::GetButtons() const { | 315 int AppBannerInfoBarDelegateAndroid::GetButtons() const { |
295 return BUTTON_OK; | 316 return BUTTON_OK; |
296 } | 317 } |
297 | 318 |
298 bool AppBannerInfoBarDelegateAndroid::Accept() { | 319 bool AppBannerInfoBarDelegateAndroid::Accept() { |
299 has_user_interaction_ = true; | 320 has_user_interaction_ = true; |
300 | 321 |
301 content::WebContents* web_contents = | 322 content::WebContents* web_contents = |
302 InfoBarService::WebContentsFromInfoBar(infobar()); | 323 InfoBarService::WebContentsFromInfoBar(infobar()); |
303 if (!web_contents) { | 324 if (!web_contents) { |
304 TrackDismissEvent(DISMISS_EVENT_ERROR); | 325 TrackDismissEvent(DISMISS_EVENT_ERROR); |
305 return true; | 326 return true; |
306 } | 327 } |
307 | 328 |
308 if (!native_app_data_.is_null()) | 329 if (!native_app_data_.is_null()) |
309 return AcceptNativeApp(web_contents); | 330 return AcceptNativeApp(web_contents); |
310 | 331 |
311 if (is_webapk_) | 332 if (is_webapk_) { |
333 webapk::TrackStartType(webapk::STARTED_FROM_BANNER); | |
dominickn
2016/09/09 08:14:11
Won't this metric be hit at least twice when the u
Xi Han
2016/09/09 15:37:32
No, it is only hit here, not by AppBannerInfoBarDe
| |
312 return AcceptWebApk(web_contents); | 334 return AcceptWebApk(web_contents); |
335 } | |
313 | 336 |
314 return AcceptWebApp(web_contents); | 337 return AcceptWebApp(web_contents); |
315 } | 338 } |
316 | 339 |
317 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp( | 340 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp( |
318 content::WebContents* web_contents) { | 341 content::WebContents* web_contents) { |
319 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); | 342 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); |
320 JNIEnv* env = base::android::AttachCurrentThread(); | 343 JNIEnv* env = base::android::AttachCurrentThread(); |
321 | 344 |
322 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); | 345 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished( | 384 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished( |
362 bool success, | 385 bool success, |
363 const std::string& webapk_package_name) { | 386 const std::string& webapk_package_name) { |
364 JNIEnv* env = base::android::AttachCurrentThread(); | 387 JNIEnv* env = base::android::AttachCurrentThread(); |
365 if (!success) { | 388 if (!success) { |
366 // The installation failed. | 389 // The installation failed. |
367 if (infobar()) | 390 if (infobar()) |
368 infobar()->RemoveSelf(); | 391 infobar()->RemoveSelf(); |
369 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env); | 392 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env); |
370 DVLOG(1) << "The WebAPK installation failed."; | 393 DVLOG(1) << "The WebAPK installation failed."; |
394 webapk::TrackInstallEvent(webapk::INSTALL_EVENT_FAILED); | |
371 return; | 395 return; |
372 } | 396 } |
373 | 397 |
374 webapk_package_name_ = webapk_package_name; | 398 webapk_package_name_ = webapk_package_name; |
375 ScopedJavaLocalRef<jstring> java_webapk_package_name = | 399 ScopedJavaLocalRef<jstring> java_webapk_package_name = |
376 base::android::ConvertUTF8ToJavaString(env, webapk_package_name); | 400 base::android::ConvertUTF8ToJavaString(env, webapk_package_name); |
377 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( | 401 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( |
378 env, java_delegate_, false); | 402 env, java_delegate_, false); |
379 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName( | 403 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName( |
380 env, java_delegate_, java_webapk_package_name); | 404 env, java_delegate_, java_webapk_package_name); |
381 UpdateInstallState(env, nullptr); | 405 UpdateInstallState(env, nullptr); |
406 install_state_ = webapk::INSTALLED; | |
407 webapk::TrackInstallEvent(webapk::INSTALL_EVENT_COMPLETED); | |
382 } | 408 } |
383 | 409 |
384 bool AppBannerInfoBarDelegateAndroid::LinkClicked( | 410 bool AppBannerInfoBarDelegateAndroid::LinkClicked( |
385 WindowOpenDisposition disposition) { | 411 WindowOpenDisposition disposition) { |
386 if (native_app_data_.is_null()) | 412 if (native_app_data_.is_null()) |
387 return false; | 413 return false; |
388 | 414 |
389 // Try to show the details for the native app. | 415 // Try to show the details for the native app. |
390 JNIEnv* env = base::android::AttachCurrentThread(); | 416 JNIEnv* env = base::android::AttachCurrentThread(); |
391 | 417 |
392 content::WebContents* web_contents = | 418 content::WebContents* web_contents = |
393 InfoBarService::WebContentsFromInfoBar(infobar()); | 419 InfoBarService::WebContentsFromInfoBar(infobar()); |
394 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); | 420 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); |
395 DCHECK(tab); | 421 DCHECK(tab); |
396 | 422 |
397 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( | 423 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( |
398 env, java_delegate_, tab->GetJavaObject(), native_app_data_); | 424 env, java_delegate_, tab->GetJavaObject(), native_app_data_); |
399 | 425 |
400 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); | 426 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); |
401 return true; | 427 return true; |
402 } | 428 } |
403 | 429 |
404 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { | 430 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { |
405 return RegisterNativesImpl(env); | 431 return RegisterNativesImpl(env); |
406 } | 432 } |
407 | 433 |
408 } // namespace banners | 434 } // namespace banners |
OLD | NEW |