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

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: Add a TODO. 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"
26 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/manifest.h" 29 #include "content/public/common/manifest.h"
28 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h" 30 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h"
29 #include "ui/gfx/android/java_bitmap.h" 31 #include "ui/gfx/android/java_bitmap.h"
30 #include "url/gurl.h" 32 #include "url/gurl.h"
31 33
32 using base::android::ConvertJavaStringToUTF8; 34 using base::android::ConvertJavaStringToUTF8;
33 using base::android::ConvertJavaStringToUTF16; 35 using base::android::ConvertJavaStringToUTF16;
34 using base::android::ConvertUTF8ToJavaString; 36 using base::android::ConvertUTF8ToJavaString;
35 using base::android::ConvertUTF16ToJavaString; 37 using base::android::ConvertUTF16ToJavaString;
36 using base::android::JavaParamRef; 38 using base::android::JavaParamRef;
37 using base::android::ScopedJavaLocalRef; 39 using base::android::ScopedJavaLocalRef;
38 40
39 namespace banners { 41 namespace banners {
40 42
41 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 43 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
42 base::WeakPtr<AppBannerManager> weak_manager, 44 base::WeakPtr<AppBannerManager> weak_manager,
43 const base::string16& app_title, 45 const base::string16& app_title,
44 const GURL& manifest_url, 46 const GURL& manifest_url,
45 const content::Manifest& manifest, 47 const content::Manifest& manifest,
46 const GURL& icon_url, 48 const GURL& icon_url,
47 std::unique_ptr<SkBitmap> icon, 49 std::unique_ptr<SkBitmap> icon,
48 int event_request_id) 50 int event_request_id,
51 bool is_webapk)
49 : weak_manager_(weak_manager), 52 : weak_manager_(weak_manager),
50 app_title_(app_title), 53 app_title_(app_title),
51 manifest_url_(manifest_url), 54 manifest_url_(manifest_url),
52 manifest_(manifest), 55 manifest_(manifest),
53 icon_url_(icon_url), 56 icon_url_(icon_url),
54 icon_(std::move(icon)), 57 icon_(std::move(icon)),
55 event_request_id_(event_request_id), 58 event_request_id_(event_request_id),
56 has_user_interaction_(false) { 59 has_user_interaction_(false),
60 is_webapk_(is_webapk),
61 weak_ptr_factory_(this) {
57 DCHECK(!manifest.IsEmpty()); 62 DCHECK(!manifest.IsEmpty());
58 CreateJavaDelegate(); 63 CreateJavaDelegate();
59 } 64 }
60 65
61 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 66 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
62 const base::string16& app_title, 67 const base::string16& app_title,
63 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, 68 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
64 std::unique_ptr<SkBitmap> icon, 69 std::unique_ptr<SkBitmap> icon,
65 const std::string& native_app_package, 70 const std::string& native_app_package,
66 const std::string& referrer, 71 const std::string& referrer,
67 int event_request_id) 72 int event_request_id)
68 : app_title_(app_title), 73 : app_title_(app_title),
69 native_app_data_(native_app_data), 74 native_app_data_(native_app_data),
70 icon_(std::move(icon)), 75 icon_(std::move(icon)),
71 native_app_package_(native_app_package), 76 native_app_package_(native_app_package),
72 referrer_(referrer), 77 referrer_(referrer),
73 event_request_id_(event_request_id), 78 event_request_id_(event_request_id),
74 has_user_interaction_(false) { 79 has_user_interaction_(false),
80 weak_ptr_factory_(this) {
75 DCHECK(!native_app_data_.is_null()); 81 DCHECK(!native_app_data_.is_null());
76 CreateJavaDelegate(); 82 CreateJavaDelegate();
77 } 83 }
78 84
79 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { 85 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
80 if (!has_user_interaction_) { 86 if (!has_user_interaction_) {
81 if (!native_app_data_.is_null()) 87 if (!native_app_data_.is_null())
82 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); 88 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
83 else if (!manifest_.IsEmpty()) 89 else if (!manifest_.IsEmpty())
84 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); 90 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
85 } 91 }
86 92
87 TrackDismissEvent(DISMISS_EVENT_DISMISSED); 93 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
88 JNIEnv* env = base::android::AttachCurrentThread(); 94 JNIEnv* env = base::android::AttachCurrentThread();
89 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); 95 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_);
90 java_delegate_.Reset(); 96 java_delegate_.Reset();
97 weak_ptr_factory_.InvalidateWeakPtrs();
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 if (webapk_package_name_.empty()) {
295 // Request install the WebAPK.
244 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 296 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
245 297
246 AppBannerSettingsHelper::RecordBannerInstallEvent( 298 AppBannerSettingsHelper::RecordBannerInstallEvent(
247 web_contents, manifest_.start_url.spec(), 299 web_contents, manifest_.start_url.spec(),
248 AppBannerSettingsHelper::WEB); 300 AppBannerSettingsHelper::WEB);
249 301
250 if (weak_manager_) { 302 ShortcutInfo info(GURL::EmptyGURL());
251 ShortcutInfo info(GURL::EmptyGURL()); 303 info.UpdateFromManifest(manifest_);
252 info.UpdateFromManifest(manifest_); 304 info.manifest_url = manifest_url_;
253 info.manifest_url = manifest_url_; 305 info.icon_url = icon_url_;
254 info.icon_url = icon_url_; 306 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
255 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
256 307
257 const std::string& uid = base::GenerateGUID(); 308 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
258 ShortcutHelper::AddToLauncherWithSkBitmap( 309 env, java_delegate_, true);
259 web_contents->GetBrowserContext(), info, uid, *icon_.get(), 310 UpdateInstallState(env, nullptr);
260 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); 311
261 } 312 WebApkInstaller::FinishCallback callback = base::Bind(
313 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished,
314 weak_ptr_factory_.GetWeakPtr());
315 DVLOG(1) << "Trigger the installation of the WebAPK.";
316 ShortcutHelper::InstallWebApkWithSkBitmap(
317 web_contents->GetBrowserContext(), info, *icon_.get(), callback);
262 318
263 SendBannerAccepted(web_contents, "web"); 319 SendBannerAccepted(web_contents, "web");
264 return true; 320 return false;
265 } 321 }
266 322
323 // Open the WebAPK.
324 ScopedJavaLocalRef<jstring> java_webapk_package_name =
325 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_);
326 Java_AppBannerInfoBarDelegateAndroid_openWebApk(
327 env, java_delegate_, java_webapk_package_name);
328
329 SendBannerAccepted(web_contents, "web");
267 return true; 330 return true;
268 } 331 }
269 332
333 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished(
334 bool success,
335 const std::string& webapk_package_name) {
336 JNIEnv* env = base::android::AttachCurrentThread();
337 if (!success) {
338 // The installation failed.
339 if (infobar())
340 infobar()->RemoveSelf();
341 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env);
342 DVLOG(1) << "The installation of WebAPK failed.";
343 return;
344 }
345
346 webapk_package_name_ = webapk_package_name;
347 ScopedJavaLocalRef<jstring> java_webapk_package_name =
348 base::android::ConvertUTF8ToJavaString(env, webapk_package_name);
349 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
350 env, java_delegate_, false);
351 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName(
352 env, java_delegate_, java_webapk_package_name);
353 UpdateInstallState(env, nullptr);
354 }
355
270 bool AppBannerInfoBarDelegateAndroid::LinkClicked( 356 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
271 WindowOpenDisposition disposition) { 357 WindowOpenDisposition disposition) {
272 if (native_app_data_.is_null()) 358 if (native_app_data_.is_null())
273 return false; 359 return false;
274 360
275 // Try to show the details for the native app. 361 // Try to show the details for the native app.
276 JNIEnv* env = base::android::AttachCurrentThread(); 362 JNIEnv* env = base::android::AttachCurrentThread();
277 363
278 content::WebContents* web_contents = 364 content::WebContents* web_contents =
279 InfoBarService::WebContentsFromInfoBar(infobar()); 365 InfoBarService::WebContentsFromInfoBar(infobar());
280 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents) 366 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents)
281 : nullptr; 367 : nullptr;
282 if (tab == nullptr) { 368 if (tab == nullptr) {
283 TrackDismissEvent(DISMISS_EVENT_ERROR); 369 TrackDismissEvent(DISMISS_EVENT_ERROR);
284 return true; 370 return true;
285 } 371 }
286 372
287 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( 373 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(
288 env, java_delegate_, tab->GetJavaObject(), native_app_data_); 374 env, java_delegate_, tab->GetJavaObject(), native_app_data_);
289 375
290 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); 376 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
291 return true; 377 return true;
292 } 378 }
293 379
294 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { 380 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
295 return RegisterNativesImpl(env); 381 return RegisterNativesImpl(env);
296 } 382 }
297 383
298 } // namespace banners 384 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698