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

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

Issue 2290603005: Trigger app banner when add to homescreen is pressed and WebAPKs are enabled. (Closed)
Patch Set: dominickn@ and dfalcantara@'s comments. 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 19 matching lines...) Expand all
30 #include "ui/gfx/android/java_bitmap.h" 30 #include "ui/gfx/android/java_bitmap.h"
31 #include "url/gurl.h" 31 #include "url/gurl.h"
32 32
33 using base::android::ConvertJavaStringToUTF8; 33 using base::android::ConvertJavaStringToUTF8;
34 using base::android::ConvertJavaStringToUTF16; 34 using base::android::ConvertJavaStringToUTF16;
35 using base::android::ConvertUTF8ToJavaString; 35 using base::android::ConvertUTF8ToJavaString;
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 {
41
42 bool isInfoEmpty(const ShortcutInfo* info) {
dominickn 2016/09/02 01:00:58 Nit: capital "I" in "Is" (C++ naming convention)
Xi Han 2016/09/02 13:58:23 Done.
43 return !info || info->url.is_empty();
44 }
45
46 std::unique_ptr<ShortcutInfo> CreateShortcutInfo(
47 const GURL& manifest_url,
48 const content::Manifest& manifest,
49 const GURL& icon_url) {
50 std::unique_ptr<ShortcutInfo> info_ptr(new ShortcutInfo(GURL::EmptyGURL()));
51 if (manifest.IsEmpty())
dominickn 2016/09/02 01:00:58 Nit (save a return statement): if (!manifest.IsEm
Xi Han 2016/09/02 13:58:23 Done.
52 return info_ptr;
53 info_ptr->UpdateFromManifest(manifest);
54 info_ptr->manifest_url = manifest_url;
55 info_ptr->icon_url = icon_url;
56 info_ptr->UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
57 return info_ptr;
58 }
59
60 } // anonymous namespace
61
40 namespace banners { 62 namespace banners {
41 63
42 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 64 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
43 base::WeakPtr<AppBannerManager> weak_manager, 65 base::WeakPtr<AppBannerManager> weak_manager,
44 const base::string16& app_title, 66 const base::string16& app_title,
45 const GURL& manifest_url, 67 const GURL& manifest_url,
46 const content::Manifest& manifest, 68 std::unique_ptr<ShortcutInfo> shortcut_info,
47 const GURL& icon_url, 69 const GURL& icon_url,
48 std::unique_ptr<SkBitmap> icon, 70 std::unique_ptr<SkBitmap> icon,
49 int event_request_id, 71 int event_request_id,
50 bool is_webapk) 72 bool is_webapk)
51 : weak_manager_(weak_manager), 73 : weak_manager_(weak_manager),
52 app_title_(app_title), 74 app_title_(app_title),
53 manifest_url_(manifest_url), 75 manifest_url_(manifest_url),
54 manifest_(manifest), 76 shortcut_info_(std::move(shortcut_info)),
55 icon_url_(icon_url), 77 icon_url_(icon_url),
56 icon_(std::move(icon)), 78 icon_(std::move(icon)),
57 event_request_id_(event_request_id), 79 event_request_id_(event_request_id),
58 has_user_interaction_(false), 80 has_user_interaction_(false),
59 is_webapk_(is_webapk), 81 is_webapk_(is_webapk),
60 weak_ptr_factory_(this) { 82 weak_ptr_factory_(this) {
61 DCHECK(!manifest.IsEmpty()); 83 DCHECK(!isInfoEmpty(shortcut_info_.get()));
62 CreateJavaDelegate(); 84 CreateJavaDelegate();
63 } 85 }
64 86
65 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 87 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
88 base::WeakPtr<AppBannerManager> weak_manager,
89 const base::string16& app_title,
90 const GURL& manifest_url,
91 const content::Manifest& manifest,
92 const GURL& icon_url,
93 std::unique_ptr<SkBitmap> icon,
94 int event_request_id,
95 bool is_webapk)
96 : AppBannerInfoBarDelegateAndroid(
97 weak_manager, app_title, manifest_url,
98 CreateShortcutInfo(manifest_url, manifest, icon_url),
99 icon_url, std::move(icon), event_request_id, is_webapk) {
100 }
101
102 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
66 const base::string16& app_title, 103 const base::string16& app_title,
67 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, 104 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
68 std::unique_ptr<SkBitmap> icon, 105 std::unique_ptr<SkBitmap> icon,
69 const std::string& native_app_package, 106 const std::string& native_app_package,
70 const std::string& referrer, 107 const std::string& referrer,
71 int event_request_id) 108 int event_request_id)
72 : app_title_(app_title), 109 : app_title_(app_title),
73 native_app_data_(native_app_data), 110 native_app_data_(native_app_data),
74 icon_(std::move(icon)), 111 icon_(std::move(icon)),
75 native_app_package_(native_app_package), 112 native_app_package_(native_app_package),
76 referrer_(referrer), 113 referrer_(referrer),
77 event_request_id_(event_request_id), 114 event_request_id_(event_request_id),
78 has_user_interaction_(false), 115 has_user_interaction_(false),
79 weak_ptr_factory_(this) { 116 weak_ptr_factory_(this) {
80 DCHECK(!native_app_data_.is_null()); 117 DCHECK(!native_app_data_.is_null());
81 CreateJavaDelegate(); 118 CreateJavaDelegate();
82 } 119 }
83 120
84 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { 121 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
85 weak_ptr_factory_.InvalidateWeakPtrs(); 122 weak_ptr_factory_.InvalidateWeakPtrs();
86 123
87 if (!has_user_interaction_) { 124 if (!has_user_interaction_) {
88 if (!native_app_data_.is_null()) 125 if (!native_app_data_.is_null())
89 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); 126 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
90 else if (!manifest_.IsEmpty()) 127 else if (!isInfoEmpty(shortcut_info_.get()))
91 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); 128 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
92 } 129 }
93 130
94 TrackDismissEvent(DISMISS_EVENT_DISMISSED); 131 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
95 JNIEnv* env = base::android::AttachCurrentThread(); 132 JNIEnv* env = base::android::AttachCurrentThread();
96 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); 133 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_);
97 java_delegate_.Reset(); 134 java_delegate_.Reset();
98 } 135 }
99 136
100 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( 137 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 184
148 if (success) { 185 if (success) {
149 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED); 186 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED);
150 UpdateInstallState(env, obj); 187 UpdateInstallState(env, obj);
151 } else if (infobar()->owner()) { 188 } else if (infobar()->owner()) {
152 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT); 189 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT);
153 infobar()->owner()->RemoveInfoBar(infobar()); 190 infobar()->owner()->RemoveInfoBar(infobar());
154 } 191 }
155 } 192 }
156 193
194 void AppBannerInfoBarDelegateAndroid::InstallWebApk(
195 content::WebContents* web_contents) {
196 if (!web_contents) {
197 LOG(ERROR) << "Failed to create infobar to install the WebAPK: "
198 << "the associated WebContents is null.";
199 return;
200 }
201 AcceptWebApk(web_contents);
202 }
203
157 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { 204 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() {
158 JNIEnv* env = base::android::AttachCurrentThread(); 205 JNIEnv* env = base::android::AttachCurrentThread();
159 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( 206 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create(
160 env, 207 env,
161 reinterpret_cast<intptr_t>(this))); 208 reinterpret_cast<intptr_t>(this)));
162 } 209 }
163 210
164 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted( 211 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted(
165 content::WebContents* web_contents, 212 content::WebContents* web_contents,
166 const std::string& platform) { 213 const std::string& platform) {
(...skipping 23 matching lines...) Expand all
190 237
191 web_contents->GetMainFrame()->Send( 238 web_contents->GetMainFrame()->Send(
192 new ChromeViewMsg_AppBannerDismissed( 239 new ChromeViewMsg_AppBannerDismissed(
193 web_contents->GetMainFrame()->GetRoutingID(), 240 web_contents->GetMainFrame()->GetRoutingID(),
194 event_request_id_)); 241 event_request_id_));
195 242
196 if (!native_app_data_.is_null()) { 243 if (!native_app_data_.is_null()) {
197 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); 244 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED);
198 AppBannerSettingsHelper::RecordBannerDismissEvent( 245 AppBannerSettingsHelper::RecordBannerDismissEvent(
199 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); 246 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE);
200 } else if (!manifest_.IsEmpty()) { 247 } else if (!isInfoEmpty(shortcut_info_.get())) {
201 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); 248 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
202 AppBannerSettingsHelper::RecordBannerDismissEvent( 249 AppBannerSettingsHelper::RecordBannerDismissEvent(
203 web_contents, manifest_.start_url.spec(), 250 web_contents, shortcut_info_->url.spec(),
204 AppBannerSettingsHelper::WEB); 251 AppBannerSettingsHelper::WEB);
205 } 252 }
206 } 253 }
207 254
208 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { 255 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const {
209 return app_title_; 256 return app_title_;
210 } 257 }
211 258
212 int AppBannerInfoBarDelegateAndroid::GetButtons() const { 259 int AppBannerInfoBarDelegateAndroid::GetButtons() const {
213 return BUTTON_OK; 260 return BUTTON_OK;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); 300 TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
254 } else { 301 } else {
255 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); 302 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED);
256 } 303 }
257 SendBannerAccepted(web_contents, "play"); 304 SendBannerAccepted(web_contents, "play");
258 return was_opened; 305 return was_opened;
259 } 306 }
260 307
261 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( 308 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp(
262 content::WebContents* web_contents) { 309 content::WebContents* web_contents) {
263 if (manifest_.IsEmpty()) 310 if (isInfoEmpty(shortcut_info_.get()))
264 return true; 311 return true;
265 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 312 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
266 313
267 AppBannerSettingsHelper::RecordBannerInstallEvent( 314 AppBannerSettingsHelper::RecordBannerInstallEvent(
268 web_contents, manifest_.start_url.spec(), 315 web_contents, shortcut_info_->url.spec(),
269 AppBannerSettingsHelper::WEB); 316 AppBannerSettingsHelper::WEB);
270 317
271 if (weak_manager_) { 318 if (weak_manager_) {
272 ShortcutInfo info(GURL::EmptyGURL());
273 info.UpdateFromManifest(manifest_);
274 info.manifest_url = manifest_url_;
275 info.icon_url = icon_url_;
276 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
277
278 const std::string& uid = base::GenerateGUID(); 319 const std::string& uid = base::GenerateGUID();
279 ShortcutHelper::AddToLauncherWithSkBitmap( 320 ShortcutHelper::AddToLauncherWithSkBitmap(
280 web_contents->GetBrowserContext(), info, uid, *icon_.get(), 321 web_contents->GetBrowserContext(),
322 *shortcut_info_.get(), uid, *icon_.get(),
281 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); 323 weak_manager_->FetchWebappSplashScreenImageCallback(uid));
282 } 324 }
283 325
284 SendBannerAccepted(web_contents, "web"); 326 SendBannerAccepted(web_contents, "web");
285 return true; 327 return true;
286 } 328 }
287 329
288 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk( 330 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk(
289 content::WebContents* web_contents) { 331 content::WebContents* web_contents) {
290 if (manifest_.IsEmpty()) 332 if (isInfoEmpty(shortcut_info_.get()))
291 return true; 333 return true;
292 334
293 JNIEnv* env = base::android::AttachCurrentThread(); 335 JNIEnv* env = base::android::AttachCurrentThread();
294 // |webapk_package_name_| is set when the WebAPK has finished installing. 336 // |webapk_package_name_| is set when the WebAPK has finished installing.
295 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" 337 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen"
296 // button is pressed, so request WebAPK installation. Otherwise, it means 338 // button is pressed, so request WebAPK installation. Otherwise, it means
297 // the "Open" button is pressed, then open the installed WebAPK. 339 // the "Open" button is pressed, then open the installed WebAPK.
298 if (webapk_package_name_.empty()) { 340 if (webapk_package_name_.empty()) {
299 // Request install the WebAPK. 341 // Request install the WebAPK.
300 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 342 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
301 343
302 AppBannerSettingsHelper::RecordBannerInstallEvent( 344 AppBannerSettingsHelper::RecordBannerInstallEvent(
303 web_contents, manifest_.start_url.spec(), 345 web_contents, shortcut_info_->url.spec(),
304 AppBannerSettingsHelper::WEB); 346 AppBannerSettingsHelper::WEB);
305 347
306 ShortcutInfo info(GURL::EmptyGURL());
307 info.UpdateFromManifest(manifest_);
308 info.manifest_url = manifest_url_;
309 info.icon_url = icon_url_;
310 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
311
312 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( 348 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
313 env, java_delegate_, true); 349 env, java_delegate_, true);
314 UpdateInstallState(env, nullptr); 350 UpdateInstallState(env, nullptr);
315 351
316 WebApkInstaller::FinishCallback callback = base::Bind( 352 WebApkInstaller::FinishCallback callback = base::Bind(
317 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, 353 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished,
318 weak_ptr_factory_.GetWeakPtr()); 354 weak_ptr_factory_.GetWeakPtr());
319 DVLOG(1) << "Trigger the installation of the WebAPK."; 355 DVLOG(1) << "Trigger the installation of the WebAPK.";
320 ShortcutHelper::InstallWebApkWithSkBitmap( 356 ShortcutHelper::InstallWebApkWithSkBitmap(
321 web_contents->GetBrowserContext(), info, *icon_.get(), callback); 357 web_contents->GetBrowserContext(), *shortcut_info_.get(),
358 *icon_.get(), callback);
322 359
323 SendBannerAccepted(web_contents, "web"); 360 SendBannerAccepted(web_contents, "web");
324 // Returns false to prevent the infobar from disappearing. 361 // Returns false to prevent the infobar from disappearing.
325 return false; 362 return false;
326 } 363 }
327 364
328 // Open the WebAPK. 365 // Open the WebAPK.
329 ScopedJavaLocalRef<jstring> java_webapk_package_name = 366 ScopedJavaLocalRef<jstring> java_webapk_package_name =
330 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); 367 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_);
331 Java_AppBannerInfoBarDelegateAndroid_openWebApk( 368 Java_AppBannerInfoBarDelegateAndroid_openWebApk(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 return true; 412 return true;
376 } 413 }
377 414
378 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( 415 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(
379 env, java_delegate_, tab->GetJavaObject(), native_app_data_); 416 env, java_delegate_, tab->GetJavaObject(), native_app_data_);
380 417
381 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); 418 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
382 return true; 419 return true;
383 } 420 }
384 421
422 AppBannerInfoBarDelegateAndroid*
423 AppBannerInfoBarDelegateAndroid::AsAppBannerInfoBarDelegateAndroid() {
424 return this;
425 }
426
385 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { 427 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
386 return RegisterNativesImpl(env); 428 return RegisterNativesImpl(env);
387 } 429 }
388 430
389 } // namespace banners 431 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698