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

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

Issue 2259553002: Make AppBannerInfoBar install WebAPK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/android/shortcut_helper.h" 14 #include "chrome/browser/android/shortcut_helper.h"
15 #include "chrome/browser/android/shortcut_info.h" 15 #include "chrome/browser/android/shortcut_info.h"
16 #include "chrome/browser/android/tab_android.h" 16 #include "chrome/browser/android/tab_android.h"
17 #include "chrome/browser/android/webapk/webapk_installer.h"
17 #include "chrome/browser/banners/app_banner_manager.h" 18 #include "chrome/browser/banners/app_banner_manager.h"
18 #include "chrome/browser/banners/app_banner_metrics.h" 19 #include "chrome/browser/banners/app_banner_metrics.h"
19 #include "chrome/browser/banners/app_banner_settings_helper.h" 20 #include "chrome/browser/banners/app_banner_settings_helper.h"
20 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/infobars/infobar_service.h" 22 #include "chrome/browser/infobars/infobar_service.h"
22 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" 23 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
23 #include "chrome/common/render_messages.h" 24 #include "chrome/common/render_messages.h"
24 #include "components/rappor/rappor_utils.h" 25 #include "components/rappor/rappor_utils.h"
25 #include "content/public/browser/render_frame_host.h" 26 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
(...skipping 11 matching lines...) Expand all
38 39
39 namespace banners { 40 namespace banners {
40 41
41 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 42 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
42 base::WeakPtr<AppBannerManager> weak_manager, 43 base::WeakPtr<AppBannerManager> weak_manager,
43 const base::string16& app_title, 44 const base::string16& app_title,
44 const GURL& manifest_url, 45 const GURL& manifest_url,
45 const content::Manifest& manifest, 46 const content::Manifest& manifest,
46 const GURL& icon_url, 47 const GURL& icon_url,
47 std::unique_ptr<SkBitmap> icon, 48 std::unique_ptr<SkBitmap> icon,
48 int event_request_id) 49 int event_request_id,
50 bool is_webapk)
49 : weak_manager_(weak_manager), 51 : weak_manager_(weak_manager),
50 app_title_(app_title), 52 app_title_(app_title),
51 manifest_url_(manifest_url), 53 manifest_url_(manifest_url),
52 manifest_(manifest), 54 manifest_(manifest),
53 icon_url_(icon_url), 55 icon_url_(icon_url),
54 icon_(std::move(icon)), 56 icon_(std::move(icon)),
55 event_request_id_(event_request_id), 57 event_request_id_(event_request_id),
56 has_user_interaction_(false) { 58 has_user_interaction_(false),
59 is_webapk_(is_webapk),
60 weak_ptr_factory_(this) {
57 DCHECK(!manifest.IsEmpty()); 61 DCHECK(!manifest.IsEmpty());
58 CreateJavaDelegate(); 62 CreateJavaDelegate();
59 } 63 }
60 64
61 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 65 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
62 const base::string16& app_title, 66 const base::string16& app_title,
63 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, 67 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
64 std::unique_ptr<SkBitmap> icon, 68 std::unique_ptr<SkBitmap> icon,
65 const std::string& native_app_package, 69 const std::string& native_app_package,
66 const std::string& referrer, 70 const std::string& referrer,
67 int event_request_id) 71 int event_request_id)
68 : app_title_(app_title), 72 : app_title_(app_title),
69 native_app_data_(native_app_data), 73 native_app_data_(native_app_data),
70 icon_(std::move(icon)), 74 icon_(std::move(icon)),
71 native_app_package_(native_app_package), 75 native_app_package_(native_app_package),
72 referrer_(referrer), 76 referrer_(referrer),
73 event_request_id_(event_request_id), 77 event_request_id_(event_request_id),
74 has_user_interaction_(false) { 78 has_user_interaction_(false),
79 weak_ptr_factory_(this) {
75 DCHECK(!native_app_data_.is_null()); 80 DCHECK(!native_app_data_.is_null());
76 CreateJavaDelegate(); 81 CreateJavaDelegate();
77 } 82 }
78 83
79 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { 84 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
85 weak_ptr_factory_.InvalidateWeakPtrs();
86
80 if (!has_user_interaction_) { 87 if (!has_user_interaction_) {
81 if (!native_app_data_.is_null()) 88 if (!native_app_data_.is_null())
82 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); 89 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
83 else if (!manifest_.IsEmpty()) 90 else if (!manifest_.IsEmpty())
84 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); 91 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
85 } 92 }
86 93
87 TrackDismissEvent(DISMISS_EVENT_DISMISSED); 94 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
88 JNIEnv* env = base::android::AttachCurrentThread(); 95 JNIEnv* env = base::android::AttachCurrentThread();
89 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); 96 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_);
90 java_delegate_.Reset(); 97 java_delegate_.Reset();
91 } 98 }
92 99
93 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( 100 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(
94 JNIEnv* env, 101 JNIEnv* env,
95 const JavaParamRef<jobject>& obj) { 102 const JavaParamRef<jobject>& obj) {
96 if (native_app_data_.is_null()) 103 if (native_app_data_.is_null() && !is_webapk_)
97 return; 104 return;
98 105
99 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState( 106 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState(
100 env, java_delegate_, native_app_data_); 107 env, java_delegate_, native_app_data_);
101 static_cast<AppBannerInfoBarAndroid*>(infobar()) 108 static_cast<AppBannerInfoBarAndroid*>(infobar())
102 ->OnInstallStateChanged(newState); 109 ->OnInstallStateChanged(newState);
103 } 110 }
104 111
105 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned( 112 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned(
106 JNIEnv* env, 113 JNIEnv* env,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 has_user_interaction_ = true; 217 has_user_interaction_ = true;
211 218
212 content::WebContents* web_contents = 219 content::WebContents* web_contents =
213 InfoBarService::WebContentsFromInfoBar(infobar()); 220 InfoBarService::WebContentsFromInfoBar(infobar());
214 if (!web_contents) { 221 if (!web_contents) {
215 TrackDismissEvent(DISMISS_EVENT_ERROR); 222 TrackDismissEvent(DISMISS_EVENT_ERROR);
216 return true; 223 return true;
217 } 224 }
218 225
219 if (!native_app_data_.is_null()) { 226 if (!native_app_data_.is_null()) {
220 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); 227 return AcceptNativeApp(web_contents);
221 JNIEnv* env = base::android::AttachCurrentThread(); 228 } else if (is_webapk_) {
229 return AcceptWebApk(web_contents);
230 }
231 return AcceptWebApp(web_contents);
232 }
222 233
223 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); 234 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp(
224 if (tab == nullptr) { 235 content::WebContents* web_contents) {
225 TrackDismissEvent(DISMISS_EVENT_ERROR); 236 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED);
226 return true; 237 JNIEnv* env = base::android::AttachCurrentThread();
227 }
228 ScopedJavaLocalRef<jstring> jreferrer(
229 ConvertUTF8ToJavaString(env, referrer_));
230 238
231 bool was_opened = 239 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
232 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp( 240 if (tab == nullptr) {
233 env, java_delegate_, tab->GetJavaObject(), native_app_data_, 241 TrackDismissEvent(DISMISS_EVENT_ERROR);
234 jreferrer); 242 return true;
243 }
244 ScopedJavaLocalRef<jstring> jreferrer(
245 ConvertUTF8ToJavaString(env, referrer_));
235 246
236 if (was_opened) { 247 bool was_opened =
237 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); 248 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp(
238 } else { 249 env, java_delegate_, tab->GetJavaObject(),
239 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); 250 native_app_data_, jreferrer);
240 } 251
241 SendBannerAccepted(web_contents, "play"); 252 if (was_opened) {
242 return was_opened; 253 TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
243 } else if (!manifest_.IsEmpty()) { 254 } else {
255 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED);
256 }
257 SendBannerAccepted(web_contents, "play");
258 return was_opened;
259 }
260
261 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp(
262 content::WebContents* web_contents) {
263 if (manifest_.IsEmpty())
264 return true;
265 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
266
267 AppBannerSettingsHelper::RecordBannerInstallEvent(
268 web_contents, manifest_.start_url.spec(),
269 AppBannerSettingsHelper::WEB);
270
271 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();
279 ShortcutHelper::AddToLauncherWithSkBitmap(
280 web_contents->GetBrowserContext(), info, uid, *icon_.get(),
281 weak_manager_->FetchWebappSplashScreenImageCallback(uid));
282 }
283
284 SendBannerAccepted(web_contents, "web");
285 return true;
286 }
287
288 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk(
289 content::WebContents* web_contents) {
290 if (manifest_.IsEmpty())
291 return true;
292
293 JNIEnv* env = base::android::AttachCurrentThread();
294 // |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"
296 // button is pressed, so request WebAPK installation. Otherwise, it means
297 // the "Open" button is pressed, then open the installed WebAPK.
298 if (webapk_package_name_.empty()) {
299 // Request install the WebAPK.
244 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 300 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
245 301
246 AppBannerSettingsHelper::RecordBannerInstallEvent( 302 AppBannerSettingsHelper::RecordBannerInstallEvent(
247 web_contents, manifest_.start_url.spec(), 303 web_contents, manifest_.start_url.spec(),
248 AppBannerSettingsHelper::WEB); 304 AppBannerSettingsHelper::WEB);
249 305
250 if (weak_manager_) { 306 ShortcutInfo info(GURL::EmptyGURL());
251 ShortcutInfo info(GURL::EmptyGURL()); 307 info.UpdateFromManifest(manifest_);
252 info.UpdateFromManifest(manifest_); 308 info.manifest_url = manifest_url_;
253 info.manifest_url = manifest_url_; 309 info.icon_url = icon_url_;
254 info.icon_url = icon_url_; 310 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
255 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
256 311
257 const std::string& uid = base::GenerateGUID(); 312 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
258 ShortcutHelper::AddToLauncherWithSkBitmap( 313 env, java_delegate_, true);
259 web_contents->GetBrowserContext(), info, uid, *icon_.get(), 314 UpdateInstallState(env, nullptr);
260 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); 315
261 } 316 WebApkInstaller::FinishCallback callback = base::Bind(
317 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished,
318 weak_ptr_factory_.GetWeakPtr());
319 DVLOG(1) << "Trigger the installation of the WebAPK.";
320 ShortcutHelper::InstallWebApkWithSkBitmap(
321 web_contents->GetBrowserContext(), info, *icon_.get(), callback);
262 322
263 SendBannerAccepted(web_contents, "web"); 323 SendBannerAccepted(web_contents, "web");
264 return true; 324 // Returns false to prevent the infobar from disappearing.
325 return false;
265 } 326 }
266 327
328 // Open the WebAPK.
329 ScopedJavaLocalRef<jstring> java_webapk_package_name =
330 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_);
331 Java_AppBannerInfoBarDelegateAndroid_openWebApk(
332 env, java_delegate_, java_webapk_package_name);
333
334 SendBannerAccepted(web_contents, "web");
267 return true; 335 return true;
268 } 336 }
269 337
338 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished(
339 bool success,
340 const std::string& webapk_package_name) {
341 JNIEnv* env = base::android::AttachCurrentThread();
342 if (!success) {
343 // The installation failed.
344 if (infobar())
345 infobar()->RemoveSelf();
346 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env);
347 DVLOG(1) << "The WebAPK installation failed.";
348 return;
349 }
350
351 webapk_package_name_ = webapk_package_name;
352 ScopedJavaLocalRef<jstring> java_webapk_package_name =
353 base::android::ConvertUTF8ToJavaString(env, webapk_package_name);
354 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
355 env, java_delegate_, false);
356 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName(
357 env, java_delegate_, java_webapk_package_name);
358 UpdateInstallState(env, nullptr);
359 }
360
270 bool AppBannerInfoBarDelegateAndroid::LinkClicked( 361 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
271 WindowOpenDisposition disposition) { 362 WindowOpenDisposition disposition) {
272 if (native_app_data_.is_null()) 363 if (native_app_data_.is_null())
273 return false; 364 return false;
274 365
275 // Try to show the details for the native app. 366 // Try to show the details for the native app.
276 JNIEnv* env = base::android::AttachCurrentThread(); 367 JNIEnv* env = base::android::AttachCurrentThread();
277 368
278 content::WebContents* web_contents = 369 content::WebContents* web_contents =
279 InfoBarService::WebContentsFromInfoBar(infobar()); 370 InfoBarService::WebContentsFromInfoBar(infobar());
280 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents) 371 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents)
281 : nullptr; 372 : nullptr;
282 if (tab == nullptr) { 373 if (tab == nullptr) {
283 TrackDismissEvent(DISMISS_EVENT_ERROR); 374 TrackDismissEvent(DISMISS_EVENT_ERROR);
284 return true; 375 return true;
285 } 376 }
286 377
287 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( 378 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(
288 env, java_delegate_, tab->GetJavaObject(), native_app_data_); 379 env, java_delegate_, tab->GetJavaObject(), native_app_data_);
289 380
290 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); 381 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
291 return true; 382 return true;
292 } 383 }
293 384
294 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { 385 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
295 return RegisterNativesImpl(env); 386 return RegisterNativesImpl(env);
296 } 387 }
297 388
298 } // namespace banners 389 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698