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

Side by Side Diff: chrome/browser/android/banners/app_banner_infobar_delegate_android.cc

Issue 2301263004: Add WebAPK installation metrics. (Closed)
Patch Set: Rebase. Created 4 years, 3 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
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698