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

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: Remove webpak-metrics and nits. 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 "chrome/grit/generated_resources.h" 25 #include "chrome/grit/generated_resources.h"
25 #include "components/rappor/rappor_utils.h" 26 #include "components/rappor/rappor_utils.h"
27 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_frame_host.h" 28 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/manifest.h" 30 #include "content/public/common/manifest.h"
29 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h" 31 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h"
30 #include "ui/gfx/android/java_bitmap.h" 32 #include "ui/gfx/android/java_bitmap.h"
31 #include "url/gurl.h" 33 #include "url/gurl.h"
32 34
33 using base::android::ConvertJavaStringToUTF8; 35 using base::android::ConvertJavaStringToUTF8;
34 using base::android::ConvertJavaStringToUTF16; 36 using base::android::ConvertJavaStringToUTF16;
35 using base::android::ConvertUTF8ToJavaString; 37 using base::android::ConvertUTF8ToJavaString;
36 using base::android::ConvertUTF16ToJavaString; 38 using base::android::ConvertUTF16ToJavaString;
37 using base::android::JavaParamRef; 39 using base::android::JavaParamRef;
38 using base::android::ScopedJavaLocalRef; 40 using base::android::ScopedJavaLocalRef;
39 41
40 namespace banners { 42 namespace banners {
41 43
42 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 44 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
43 base::WeakPtr<AppBannerManager> weak_manager, 45 base::WeakPtr<AppBannerManager> weak_manager,
44 const base::string16& app_title, 46 const base::string16& app_title,
45 const GURL& manifest_url, 47 const GURL& manifest_url,
46 const content::Manifest& manifest, 48 const content::Manifest& manifest,
47 const GURL& icon_url, 49 const GURL& icon_url,
48 std::unique_ptr<SkBitmap> icon, 50 std::unique_ptr<SkBitmap> icon,
49 int event_request_id) 51 int event_request_id,
52 bool is_webapk)
50 : weak_manager_(weak_manager), 53 : weak_manager_(weak_manager),
51 app_title_(app_title), 54 app_title_(app_title),
52 manifest_url_(manifest_url), 55 manifest_url_(manifest_url),
53 manifest_(manifest), 56 manifest_(manifest),
54 icon_url_(icon_url), 57 icon_url_(icon_url),
55 icon_(std::move(icon)), 58 icon_(std::move(icon)),
56 event_request_id_(event_request_id), 59 event_request_id_(event_request_id),
57 has_user_interaction_(false) { 60 has_user_interaction_(false),
61 is_webapk_(is_webapk),
62 weak_ptr_factory_(this) {
58 DCHECK(!manifest.IsEmpty()); 63 DCHECK(!manifest.IsEmpty());
59 CreateJavaDelegate(); 64 CreateJavaDelegate();
60 } 65 }
61 66
62 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 67 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
63 const base::string16& app_title, 68 const base::string16& app_title,
64 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, 69 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
65 std::unique_ptr<SkBitmap> icon, 70 std::unique_ptr<SkBitmap> icon,
66 const std::string& native_app_package, 71 const std::string& native_app_package,
67 const std::string& referrer, 72 const std::string& referrer,
68 int event_request_id) 73 int event_request_id)
69 : app_title_(app_title), 74 : app_title_(app_title),
70 native_app_data_(native_app_data), 75 native_app_data_(native_app_data),
71 icon_(std::move(icon)), 76 icon_(std::move(icon)),
72 native_app_package_(native_app_package), 77 native_app_package_(native_app_package),
73 referrer_(referrer), 78 referrer_(referrer),
74 event_request_id_(event_request_id), 79 event_request_id_(event_request_id),
75 has_user_interaction_(false) { 80 has_user_interaction_(false),
81 weak_ptr_factory_(this) {
76 DCHECK(!native_app_data_.is_null()); 82 DCHECK(!native_app_data_.is_null());
77 CreateJavaDelegate(); 83 CreateJavaDelegate();
78 } 84 }
79 85
80 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { 86 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
dominickn 2016/08/26 19:19:34 Add weak_ptr_factory_.InvalidateWeakPtrs(); here t
Xi Han 2016/08/29 14:44:53 Done.
81 if (!has_user_interaction_) { 87 if (!has_user_interaction_) {
82 if (!native_app_data_.is_null()) 88 if (!native_app_data_.is_null())
83 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); 89 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
84 else if (!manifest_.IsEmpty()) 90 else if (!manifest_.IsEmpty())
85 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); 91 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
86 } 92 }
87 93
88 TrackDismissEvent(DISMISS_EVENT_DISMISSED); 94 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
89 JNIEnv* env = base::android::AttachCurrentThread(); 95 JNIEnv* env = base::android::AttachCurrentThread();
90 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); 96 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_);
91 java_delegate_.Reset(); 97 java_delegate_.Reset();
92 } 98 }
93 99
94 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( 100 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(
95 JNIEnv* env, 101 JNIEnv* env,
96 const JavaParamRef<jobject>& obj) { 102 const JavaParamRef<jobject>& obj) {
97 if (native_app_data_.is_null()) 103 if (native_app_data_.is_null() && !is_webapk_)
98 return; 104 return;
99 105
100 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState( 106 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState(
101 env, java_delegate_, native_app_data_); 107 env, java_delegate_, native_app_data_);
102 static_cast<AppBannerInfoBarAndroid*>(infobar()) 108 static_cast<AppBannerInfoBarAndroid*>(infobar())
103 ->OnInstallStateChanged(newState); 109 ->OnInstallStateChanged(newState);
104 } 110 }
105 111
106 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned( 112 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned(
107 JNIEnv* env, 113 JNIEnv* env,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 has_user_interaction_ = true; 217 has_user_interaction_ = true;
212 218
213 content::WebContents* web_contents = 219 content::WebContents* web_contents =
214 InfoBarService::WebContentsFromInfoBar(infobar()); 220 InfoBarService::WebContentsFromInfoBar(infobar());
215 if (!web_contents) { 221 if (!web_contents) {
216 TrackDismissEvent(DISMISS_EVENT_ERROR); 222 TrackDismissEvent(DISMISS_EVENT_ERROR);
217 return true; 223 return true;
218 } 224 }
219 225
220 if (!native_app_data_.is_null()) { 226 if (!native_app_data_.is_null()) {
221 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); 227 return AcceptNativeApp(web_contents);
222 JNIEnv* env = base::android::AttachCurrentThread(); 228 } else if (is_webapk_) {
229 return AcceptWebApk(web_contents);
230 }
231 return AcceptWebApp(web_contents);
232 }
223 233
224 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); 234 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp(
225 if (tab == nullptr) { 235 content::WebContents* web_contents) {
226 TrackDismissEvent(DISMISS_EVENT_ERROR); 236 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED);
227 return true; 237 JNIEnv* env = base::android::AttachCurrentThread();
228 }
229 ScopedJavaLocalRef<jstring> jreferrer(
230 ConvertUTF8ToJavaString(env, referrer_));
231 238
232 bool was_opened = 239 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
233 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp( 240 if (tab == nullptr) {
234 env, java_delegate_, tab->GetJavaObject(), native_app_data_, 241 TrackDismissEvent(DISMISS_EVENT_ERROR);
235 jreferrer); 242 return true;
243 }
244 ScopedJavaLocalRef<jstring> jreferrer(
245 ConvertUTF8ToJavaString(env, referrer_));
236 246
237 if (was_opened) { 247 bool was_opened =
238 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); 248 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp(
239 } else { 249 env, java_delegate_, tab->GetJavaObject(),
240 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); 250 native_app_data_, jreferrer);
241 } 251
242 SendBannerAccepted(web_contents, "play"); 252 if (was_opened) {
243 return was_opened; 253 TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
244 } 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.
245 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 296 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
246 297
247 AppBannerSettingsHelper::RecordBannerInstallEvent( 298 AppBannerSettingsHelper::RecordBannerInstallEvent(
248 web_contents, manifest_.start_url.spec(), 299 web_contents, manifest_.start_url.spec(),
249 AppBannerSettingsHelper::WEB); 300 AppBannerSettingsHelper::WEB);
250 301
251 if (weak_manager_) { 302 ShortcutInfo info(GURL::EmptyGURL());
252 ShortcutInfo info(GURL::EmptyGURL()); 303 info.UpdateFromManifest(manifest_);
253 info.UpdateFromManifest(manifest_); 304 info.manifest_url = manifest_url_;
254 info.manifest_url = manifest_url_; 305 info.icon_url = icon_url_;
255 info.icon_url = icon_url_; 306 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
256 info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
257 307
258 const std::string& uid = base::GenerateGUID(); 308 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
259 ShortcutHelper::AddToLauncherWithSkBitmap( 309 env, java_delegate_, true);
260 web_contents->GetBrowserContext(), info, uid, *icon_.get(), 310 UpdateInstallState(env, nullptr);
261 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); 311
262 } 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);
263 318
264 SendBannerAccepted(web_contents, "web"); 319 SendBannerAccepted(web_contents, "web");
265 return true; 320 return false;
266 } 321 }
267 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");
268 return true; 330 return true;
269 } 331 }
270 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 content::BrowserThread::PostTask(
340 content::BrowserThread::UI, FROM_HERE,
341 base::Bind(&AppBannerInfoBarDelegateAndroid::RemoveInfoBarOnUIThread,
342 weak_ptr_factory_.GetWeakPtr()));
dominickn 2016/08/26 19:19:34 This method is invoked through a base::Bind call o
Xi Han 2016/08/29 14:44:52 Good catch. The code doesn't need to be posted to
343 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env);
344 DVLOG(1) << "The installation of WebAPK failed.";
345 return;
346 }
347
348 webapk_package_name_ = webapk_package_name;
349 ScopedJavaLocalRef<jstring> java_webapk_package_name =
350 base::android::ConvertUTF8ToJavaString(env, webapk_package_name);
351 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
352 env, java_delegate_, false);
353 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName(
354 env, java_delegate_, java_webapk_package_name);
355 UpdateInstallState(env, nullptr);
356 }
357
358 void AppBannerInfoBarDelegateAndroid::RemoveInfoBarOnUIThread() {
359 infobar()->RemoveSelf();
360 }
361
271 bool AppBannerInfoBarDelegateAndroid::LinkClicked( 362 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
272 WindowOpenDisposition disposition) { 363 WindowOpenDisposition disposition) {
273 if (native_app_data_.is_null()) 364 if (native_app_data_.is_null())
274 return false; 365 return false;
275 366
276 // Try to show the details for the native app. 367 // Try to show the details for the native app.
277 JNIEnv* env = base::android::AttachCurrentThread(); 368 JNIEnv* env = base::android::AttachCurrentThread();
278 369
279 content::WebContents* web_contents = 370 content::WebContents* web_contents =
280 InfoBarService::WebContentsFromInfoBar(infobar()); 371 InfoBarService::WebContentsFromInfoBar(infobar());
281 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents) 372 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents)
282 : nullptr; 373 : nullptr;
283 if (tab == nullptr) { 374 if (tab == nullptr) {
284 TrackDismissEvent(DISMISS_EVENT_ERROR); 375 TrackDismissEvent(DISMISS_EVENT_ERROR);
285 return true; 376 return true;
286 } 377 }
287 378
288 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( 379 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(
289 env, java_delegate_, tab->GetJavaObject(), native_app_data_); 380 env, java_delegate_, tab->GetJavaObject(), native_app_data_);
290 381
291 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); 382 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
292 return true; 383 return true;
293 } 384 }
294 385
295 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { 386 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
296 return RegisterNativesImpl(env); 387 return RegisterNativesImpl(env);
297 } 388 }
298 389
299 } // namespace banners 390 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698