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

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: Try to fix test failures 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 17 matching lines...) Expand all
28 #include "content/public/common/manifest.h" 28 #include "content/public/common/manifest.h"
29 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h" 29 #include "jni/AppBannerInfoBarDelegateAndroid_jni.h"
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;
Peter Kasting 2016/09/08 04:56:57 Nit: Be cautious with using directives; prefer to
Xi Han 2016/09/08 15:49:09 I will keep this in mind.
39 39
40 namespace {
41
42 bool IsInfoEmpty(const ShortcutInfo* info) {
Peter Kasting 2016/09/08 04:56:57 Nit: Take a const unique_ptr& and you won't have t
Xi Han 2016/09/08 15:49:10 It can't be a unique_ptr since when this function
Peter Kasting 2016/09/08 20:57:05 I said "const unique_ptr&", not "unique_ptr".
43 return !info || info->url.is_empty();
Peter Kasting 2016/09/08 04:56:57 Note that if you split this class in the future, I
Xi Han 2016/09/08 15:49:09 Acknowledged.
44 }
45
46 } // anonymous namespace
Peter Kasting 2016/09/08 04:56:56 Nit: No need for this comment
Xi Han 2016/09/08 15:49:10 Done.
47
40 namespace banners { 48 namespace banners {
41 49
42 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 50 // static
51 bool AppBannerInfoBarDelegateAndroid::Create(
52 content::WebContents* web_contents,
43 base::WeakPtr<AppBannerManager> weak_manager, 53 base::WeakPtr<AppBannerManager> weak_manager,
44 const base::string16& app_title, 54 const base::string16& app_title,
45 const GURL& manifest_url, 55 std::unique_ptr<ShortcutInfo> shortcut_info,
46 const content::Manifest& manifest,
47 const GURL& icon_url,
48 std::unique_ptr<SkBitmap> icon, 56 std::unique_ptr<SkBitmap> icon,
49 int event_request_id, 57 int event_request_id,
50 bool is_webapk) 58 bool is_webapk,
51 : weak_manager_(weak_manager), 59 bool start_install_webapk) {
52 app_title_(app_title), 60 const GURL& url = shortcut_info->url;
Peter Kasting 2016/09/08 04:56:57 Nit: Inline this into the caller below (even if yo
Xi Han 2016/09/08 15:49:09 It has to be done before std::move(shortcut_info)
Peter Kasting 2016/09/08 20:57:05 Oh bah.
53 manifest_url_(manifest_url), 61 auto infobar_delegate =
54 manifest_(manifest), 62 base::WrapUnique(new banners::AppBannerInfoBarDelegateAndroid(
55 icon_url_(icon_url), 63 weak_manager, app_title, std::move(shortcut_info), std::move(icon),
56 icon_(std::move(icon)), 64 event_request_id, is_webapk));
57 event_request_id_(event_request_id), 65 auto raw_delegate = infobar_delegate.get();
58 has_user_interaction_(false), 66
Peter Kasting 2016/09/08 04:56:57 Nit: Can't really figure out the logic on when thi
Xi Han 2016/09/08 15:49:09 Sure, updated.
59 is_webapk_(is_webapk), 67 auto infobar = base::MakeUnique<AppBannerInfoBarAndroid>(
60 weak_ptr_factory_(this) { 68 std::move(infobar_delegate), url, is_webapk);
61 DCHECK(!manifest.IsEmpty()); 69
62 CreateJavaDelegate(); 70 if (!InfoBarService::FromWebContents(web_contents)
71 ->AddInfoBar(std::move(infobar)))
72 return false;
73
74 if (is_webapk && start_install_webapk)
75 raw_delegate->AcceptWebApk(web_contents);
76 return true;
63 } 77 }
64 78
65 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( 79 // static
80 bool AppBannerInfoBarDelegateAndroid::Create(
81 content::WebContents* web_contents,
66 const base::string16& app_title, 82 const base::string16& app_title,
67 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, 83 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
68 std::unique_ptr<SkBitmap> icon, 84 std::unique_ptr<SkBitmap> icon,
69 const std::string& native_app_package, 85 const std::string& native_app_package,
70 const std::string& referrer, 86 const std::string& referrer,
71 int event_request_id) 87 int event_request_id) {
72 : app_title_(app_title), 88 auto infobar_delegate = base::WrapUnique(new AppBannerInfoBarDelegateAndroid(
73 native_app_data_(native_app_data), 89 app_title, native_app_data, std::move(icon), native_app_package, referrer,
74 icon_(std::move(icon)), 90 event_request_id));
75 native_app_package_(native_app_package), 91 auto infobar = base::MakeUnique<AppBannerInfoBarAndroid>(
76 referrer_(referrer), 92 std::move(infobar_delegate), native_app_data);
Peter Kasting 2016/09/08 04:56:57 Nit: Might want to inline this below (or even both
Xi Han 2016/09/08 15:49:09 Inline the infobar one only, since the delegate on
77 event_request_id_(event_request_id), 93
Peter Kasting 2016/09/08 04:56:57 Nit: Maybe remove this newline?
Xi Han 2016/09/08 15:49:10 Done.
78 has_user_interaction_(false), 94 return InfoBarService::FromWebContents(web_contents)
79 weak_ptr_factory_(this) { 95 ->AddInfoBar(std::move(infobar));
80 DCHECK(!native_app_data_.is_null());
81 CreateJavaDelegate();
82 } 96 }
83 97
84 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { 98 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() {
85 weak_ptr_factory_.InvalidateWeakPtrs(); 99 weak_ptr_factory_.InvalidateWeakPtrs();
86 100
87 if (!has_user_interaction_) { 101 if (!has_user_interaction_) {
88 if (!native_app_data_.is_null()) 102 if (!native_app_data_.is_null())
89 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); 103 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED);
90 else if (!manifest_.IsEmpty()) 104 else if (!IsInfoEmpty(shortcut_info_.get()))
91 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); 105 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED);
92 } 106 }
93 107
94 TrackDismissEvent(DISMISS_EVENT_DISMISSED); 108 TrackDismissEvent(DISMISS_EVENT_DISMISSED);
95 JNIEnv* env = base::android::AttachCurrentThread(); 109 JNIEnv* env = base::android::AttachCurrentThread();
96 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); 110 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_);
97 java_delegate_.Reset(); 111 java_delegate_.Reset();
98 } 112 }
99 113
100 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( 114 void AppBannerInfoBarDelegateAndroid::UpdateInstallState(
101 JNIEnv* env, 115 JNIEnv* env,
102 const JavaParamRef<jobject>& obj) { 116 const JavaParamRef<jobject>& obj) {
103 if (native_app_data_.is_null() && !is_webapk_) 117 if (native_app_data_.is_null() && !is_webapk_)
104 return; 118 return;
105 119
106 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState( 120 int newState = Java_AppBannerInfoBarDelegateAndroid_determineInstallState(
Peter Kasting 2016/09/08 04:56:56 Nit: |new_state| (this isn't Java) Or just inline
Xi Han 2016/09/08 15:49:09 Done.
107 env, java_delegate_, native_app_data_); 121 env, java_delegate_, native_app_data_);
108 static_cast<AppBannerInfoBarAndroid*>(infobar()) 122 static_cast<AppBannerInfoBarAndroid*>(infobar())
109 ->OnInstallStateChanged(newState); 123 ->OnInstallStateChanged(newState);
110 } 124 }
111 125
112 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned( 126 void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned(
113 JNIEnv* env, 127 JNIEnv* env,
114 const JavaParamRef<jobject>& obj, 128 const JavaParamRef<jobject>& obj,
115 jboolean jis_installing) { 129 jboolean jis_installing) {
116 if (!infobar()) 130 if (!infobar())
Peter Kasting 2016/09/08 04:56:57 How can this ever be null? A delegate should neve
Xi Han 2016/09/08 15:49:10 Add DCHECK instead.
117 return; 131 return;
118 132
119 content::WebContents* web_contents = 133 content::WebContents* web_contents =
120 InfoBarService::WebContentsFromInfoBar(infobar()); 134 InfoBarService::WebContentsFromInfoBar(infobar());
121 if (!web_contents) 135 if (!web_contents)
Peter Kasting 2016/09/08 04:56:57 Can this really be called when the infobar is unow
Xi Han 2016/09/08 15:49:10 Removed.
122 return; 136 return;
123 137
124 if (jis_installing) { 138 if (jis_installing) {
125 AppBannerSettingsHelper::RecordBannerEvent( 139 AppBannerSettingsHelper::RecordBannerEvent(
126 web_contents, 140 web_contents,
127 web_contents->GetURL(), 141 web_contents->GetURL(),
128 native_app_package_, 142 native_app_package_,
129 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, 143 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN,
130 AppBannerManager::GetCurrentTime()); 144 AppBannerManager::GetCurrentTime());
131 145
(...skipping 15 matching lines...) Expand all
147 161
148 if (success) { 162 if (success) {
149 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED); 163 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED);
150 UpdateInstallState(env, obj); 164 UpdateInstallState(env, obj);
151 } else if (infobar()->owner()) { 165 } else if (infobar()->owner()) {
152 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT); 166 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT);
153 infobar()->owner()->RemoveInfoBar(infobar()); 167 infobar()->owner()->RemoveInfoBar(infobar());
154 } 168 }
155 } 169 }
156 170
171 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk(
172 content::WebContents* web_contents) {
173 if (IsInfoEmpty(shortcut_info_.get()))
174 return true;
175
176 JNIEnv* env = base::android::AttachCurrentThread();
177 // |webapk_package_name_| is set when the WebAPK has finished installing.
178 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen"
179 // button is pressed, so request WebAPK installation. Otherwise, it means
180 // the "Open" button is pressed, then open the installed WebAPK.
Peter Kasting 2016/09/08 04:56:57 Nit: then -> so
Xi Han 2016/09/08 15:49:10 Done.
181 if (webapk_package_name_.empty()) {
182 // Request install the WebAPK.
183 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
184
185 AppBannerSettingsHelper::RecordBannerInstallEvent(
186 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
187
188 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
189 env, java_delegate_, true);
190 UpdateInstallState(env, nullptr);
191
192 WebApkInstaller::FinishCallback callback =
193 base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished,
194 weak_ptr_factory_.GetWeakPtr());
195 DVLOG(1) << "Trigger the installation of the WebAPK.";
Peter Kasting 2016/09/08 04:56:56 Nit: Avoid checking in logging if possible.
Xi Han 2016/09/08 15:49:09 Done.
196 ShortcutHelper::InstallWebApkWithSkBitmap(web_contents->GetBrowserContext(),
197 *shortcut_info_.get(),
Peter Kasting 2016/09/08 04:56:57 Nit: .get() not necessary when dereferencing a sma
Xi Han 2016/09/08 15:49:09 Done.
198 *icon_.get(), callback);
199
200 SendBannerAccepted(web_contents, "web");
201 // Returns false to prevent the infobar from disappearing.
Peter Kasting 2016/09/08 04:56:57 Nit: We can see it returns false; maybe instead sa
Xi Han 2016/09/08 15:49:09 Done.
202 return false;
203 }
204
205 // Open the WebAPK.
Peter Kasting 2016/09/08 04:56:57 Nit: Consider making this shorter arm the one in t
Xi Han 2016/09/08 15:49:09 Done.
206 ScopedJavaLocalRef<jstring> java_webapk_package_name =
207 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_);
208 Java_AppBannerInfoBarDelegateAndroid_openWebApk(env, java_delegate_,
209 java_webapk_package_name);
210
211 SendBannerAccepted(web_contents, "web");
212 return true;
213 }
214
215 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
216 base::WeakPtr<AppBannerManager> weak_manager,
217 const base::string16& app_title,
218 std::unique_ptr<ShortcutInfo> shortcut_info,
219 std::unique_ptr<SkBitmap> icon,
220 int event_request_id,
221 bool is_webapk)
222 : weak_manager_(weak_manager),
223 app_title_(app_title),
224 shortcut_info_(std::move(shortcut_info)),
225 icon_(std::move(icon)),
226 event_request_id_(event_request_id),
227 has_user_interaction_(false),
228 is_webapk_(is_webapk),
229 weak_ptr_factory_(this) {
230 DCHECK(!IsInfoEmpty(shortcut_info_.get()));
231 CreateJavaDelegate();
232 }
233
234 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid(
235 const base::string16& app_title,
236 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data,
237 std::unique_ptr<SkBitmap> icon,
238 const std::string& native_app_package,
239 const std::string& referrer,
240 int event_request_id)
241 : app_title_(app_title),
242 native_app_data_(native_app_data),
243 icon_(std::move(icon)),
244 native_app_package_(native_app_package),
245 referrer_(referrer),
246 event_request_id_(event_request_id),
247 has_user_interaction_(false),
248 weak_ptr_factory_(this) {
249 DCHECK(!native_app_data_.is_null());
250 CreateJavaDelegate();
251 }
252
157 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { 253 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() {
158 JNIEnv* env = base::android::AttachCurrentThread(); 254 JNIEnv* env = base::android::AttachCurrentThread();
Peter Kasting 2016/09/08 04:56:57 Nit: Just inline this below
Xi Han 2016/09/08 15:49:10 Done.
159 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( 255 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create(
160 env, 256 env,
161 reinterpret_cast<intptr_t>(this))); 257 reinterpret_cast<intptr_t>(this)));
162 } 258 }
163 259
164 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted( 260 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted(
165 content::WebContents* web_contents, 261 content::WebContents* web_contents,
166 const std::string& platform) { 262 const std::string& platform) {
167 web_contents->GetMainFrame()->Send( 263 web_contents->GetMainFrame()->Send(
168 new ChromeViewMsg_AppBannerAccepted( 264 new ChromeViewMsg_AppBannerAccepted(
169 web_contents->GetMainFrame()->GetRoutingID(), 265 web_contents->GetMainFrame()->GetRoutingID(),
170 event_request_id_, 266 event_request_id_,
171 platform)); 267 platform));
172 } 268 }
173 269
174 infobars::InfoBarDelegate::InfoBarIdentifier 270 infobars::InfoBarDelegate::InfoBarIdentifier
175 AppBannerInfoBarDelegateAndroid::GetIdentifier() const { 271 AppBannerInfoBarDelegateAndroid::GetIdentifier() const {
176 return APP_BANNER_INFOBAR_DELEGATE_ANDROID; 272 return APP_BANNER_INFOBAR_DELEGATE_ANDROID;
177 } 273 }
178 274
179 gfx::Image AppBannerInfoBarDelegateAndroid::GetIcon() const { 275 gfx::Image AppBannerInfoBarDelegateAndroid::GetIcon() const {
180 return gfx::Image::CreateFrom1xBitmap(*icon_.get()); 276 return gfx::Image::CreateFrom1xBitmap(*icon_.get());
181 } 277 }
182 278
183 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() { 279 void AppBannerInfoBarDelegateAndroid::InfoBarDismissed() {
184 has_user_interaction_ = true; 280 has_user_interaction_ = true;
185 281
186 content::WebContents* web_contents = 282 content::WebContents* web_contents =
187 InfoBarService::WebContentsFromInfoBar(infobar()); 283 InfoBarService::WebContentsFromInfoBar(infobar());
188 if (!web_contents) 284 if (!web_contents)
Peter Kasting 2016/09/08 04:56:56 How can this ever be null? We should never be get
Xi Han 2016/09/08 15:49:09 Done.
189 return; 285 return;
190 286
191 web_contents->GetMainFrame()->Send( 287 web_contents->GetMainFrame()->Send(
192 new ChromeViewMsg_AppBannerDismissed( 288 new ChromeViewMsg_AppBannerDismissed(
193 web_contents->GetMainFrame()->GetRoutingID(), 289 web_contents->GetMainFrame()->GetRoutingID(),
194 event_request_id_)); 290 event_request_id_));
195 291
196 if (!native_app_data_.is_null()) { 292 if (!native_app_data_.is_null()) {
197 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); 293 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED);
198 AppBannerSettingsHelper::RecordBannerDismissEvent( 294 AppBannerSettingsHelper::RecordBannerDismissEvent(
199 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); 295 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE);
200 } else if (!manifest_.IsEmpty()) { 296 } else if (!IsInfoEmpty(shortcut_info_.get())) {
Peter Kasting 2016/09/08 04:56:57 Can both these conditions fail, or is one always t
Xi Han 2016/09/08 15:49:09 I believe one is always true, see the DCHECH in th
201 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); 297 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
202 AppBannerSettingsHelper::RecordBannerDismissEvent( 298 AppBannerSettingsHelper::RecordBannerDismissEvent(
203 web_contents, manifest_.start_url.spec(), 299 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
204 AppBannerSettingsHelper::WEB);
205 } 300 }
206 } 301 }
207 302
208 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { 303 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const {
209 return app_title_; 304 return app_title_;
210 } 305 }
211 306
212 int AppBannerInfoBarDelegateAndroid::GetButtons() const { 307 int AppBannerInfoBarDelegateAndroid::GetButtons() const {
213 return BUTTON_OK; 308 return BUTTON_OK;
214 } 309 }
215 310
216 bool AppBannerInfoBarDelegateAndroid::Accept() { 311 bool AppBannerInfoBarDelegateAndroid::Accept() {
217 has_user_interaction_ = true; 312 has_user_interaction_ = true;
218 313
219 content::WebContents* web_contents = 314 content::WebContents* web_contents =
220 InfoBarService::WebContentsFromInfoBar(infobar()); 315 InfoBarService::WebContentsFromInfoBar(infobar());
221 if (!web_contents) { 316 if (!web_contents) {
222 TrackDismissEvent(DISMISS_EVENT_ERROR); 317 TrackDismissEvent(DISMISS_EVENT_ERROR);
223 return true; 318 return true;
224 } 319 }
225 320
226 if (!native_app_data_.is_null()) { 321 if (!native_app_data_.is_null())
227 return AcceptNativeApp(web_contents); 322 return AcceptNativeApp(web_contents);
228 } else if (is_webapk_) { 323 else if (is_webapk_)
Peter Kasting 2016/09/08 04:56:56 Nit: No else after return (2 places)
Xi Han 2016/09/08 15:49:09 Done.
229 return AcceptWebApk(web_contents); 324 return AcceptWebApk(web_contents);
230 } 325 else
231 return AcceptWebApp(web_contents); 326 return AcceptWebApp(web_contents);
232 } 327 }
233 328
234 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp( 329 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp(
235 content::WebContents* web_contents) { 330 content::WebContents* web_contents) {
236 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); 331 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED);
237 JNIEnv* env = base::android::AttachCurrentThread(); 332 JNIEnv* env = base::android::AttachCurrentThread();
238 333
239 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); 334 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
240 if (tab == nullptr) { 335 if (tab == nullptr) {
Peter Kasting 2016/09/08 04:56:57 Can this be null? When? Nit: "if (!tab)" is prob
Xi Han 2016/09/08 15:49:09 It looks like the tab shouldn't be null, but I am
241 TrackDismissEvent(DISMISS_EVENT_ERROR); 336 TrackDismissEvent(DISMISS_EVENT_ERROR);
242 return true; 337 return true;
243 } 338 }
244 ScopedJavaLocalRef<jstring> jreferrer( 339 ScopedJavaLocalRef<jstring> jreferrer(
245 ConvertUTF8ToJavaString(env, referrer_)); 340 ConvertUTF8ToJavaString(env, referrer_));
246 341
247 bool was_opened = 342 bool was_opened =
248 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp( 343 Java_AppBannerInfoBarDelegateAndroid_installOrOpenNativeApp(
249 env, java_delegate_, tab->GetJavaObject(), 344 env, java_delegate_, tab->GetJavaObject(),
250 native_app_data_, jreferrer); 345 native_app_data_, jreferrer);
251 346
252 if (was_opened) { 347 if (was_opened) {
Peter Kasting 2016/09/08 04:56:57 Nit: No {}
Xi Han 2016/09/08 15:49:09 Done.
253 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); 348 TrackDismissEvent(DISMISS_EVENT_APP_OPEN);
254 } else { 349 } else {
255 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); 350 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED);
256 } 351 }
257 SendBannerAccepted(web_contents, "play"); 352 SendBannerAccepted(web_contents, "play");
258 return was_opened; 353 return was_opened;
259 } 354 }
260 355
261 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( 356 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp(
262 content::WebContents* web_contents) { 357 content::WebContents* web_contents) {
263 if (manifest_.IsEmpty()) 358 if (IsInfoEmpty(shortcut_info_.get()))
264 return true; 359 return true;
265 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); 360 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
266 361
267 AppBannerSettingsHelper::RecordBannerInstallEvent( 362 AppBannerSettingsHelper::RecordBannerInstallEvent(
268 web_contents, manifest_.start_url.spec(), 363 web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
269 AppBannerSettingsHelper::WEB);
270 364
271 if (weak_manager_) { 365 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(); 366 const std::string& uid = base::GenerateGUID();
279 ShortcutHelper::AddToLauncherWithSkBitmap( 367 ShortcutHelper::AddToLauncherWithSkBitmap(
280 web_contents->GetBrowserContext(), info, uid, *icon_.get(), 368 web_contents->GetBrowserContext(), *shortcut_info_.get(), uid,
281 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); 369 *icon_.get(), weak_manager_->FetchWebappSplashScreenImageCallback(uid));
282 } 370 }
283 371
284 SendBannerAccepted(web_contents, "web"); 372 SendBannerAccepted(web_contents, "web");
285 return true; 373 return true;
286 } 374 }
287 375
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.
300 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED);
301
302 AppBannerSettingsHelper::RecordBannerInstallEvent(
303 web_contents, manifest_.start_url.spec(),
304 AppBannerSettingsHelper::WEB);
305
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(
313 env, java_delegate_, true);
314 UpdateInstallState(env, nullptr);
315
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);
322
323 SendBannerAccepted(web_contents, "web");
324 // Returns false to prevent the infobar from disappearing.
325 return false;
326 }
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");
335 return true;
336 }
337
338 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished( 376 void AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished(
339 bool success, 377 bool success,
340 const std::string& webapk_package_name) { 378 const std::string& webapk_package_name) {
341 JNIEnv* env = base::android::AttachCurrentThread(); 379 JNIEnv* env = base::android::AttachCurrentThread();
342 if (!success) { 380 if (!success) {
343 // The installation failed. 381 // The installation failed.
344 if (infobar()) 382 if (infobar())
345 infobar()->RemoveSelf(); 383 infobar()->RemoveSelf();
Peter Kasting 2016/09/08 04:56:57 Nit: Might be safer to do this after the next func
Xi Han 2016/09/08 15:49:09 In the UI, we would like to see a toast shown afte
Peter Kasting 2016/09/08 20:57:05 Are these orders perceptibly different to the user
346 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env); 384 Java_AppBannerInfoBarDelegateAndroid_showWebApkInstallFailureToast(env);
347 DVLOG(1) << "The WebAPK installation failed."; 385 DVLOG(1) << "The WebAPK installation failed.";
Peter Kasting 2016/09/08 04:56:56 Nit: Similarly, avoid this logging unless it's act
Xi Han 2016/09/08 15:49:09 Personally I still prefer to have this log which h
348 return; 386 return;
349 } 387 }
350 388
351 webapk_package_name_ = webapk_package_name; 389 webapk_package_name_ = webapk_package_name;
352 ScopedJavaLocalRef<jstring> java_webapk_package_name = 390 ScopedJavaLocalRef<jstring> java_webapk_package_name =
353 base::android::ConvertUTF8ToJavaString(env, webapk_package_name); 391 base::android::ConvertUTF8ToJavaString(env, webapk_package_name);
354 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( 392 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState(
355 env, java_delegate_, false); 393 env, java_delegate_, false);
356 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName( 394 Java_AppBannerInfoBarDelegateAndroid_setWebApkPackageName(
357 env, java_delegate_, java_webapk_package_name); 395 env, java_delegate_, java_webapk_package_name);
358 UpdateInstallState(env, nullptr); 396 UpdateInstallState(env, nullptr);
359 } 397 }
360 398
361 bool AppBannerInfoBarDelegateAndroid::LinkClicked( 399 bool AppBannerInfoBarDelegateAndroid::LinkClicked(
362 WindowOpenDisposition disposition) { 400 WindowOpenDisposition disposition) {
363 if (native_app_data_.is_null()) 401 if (native_app_data_.is_null())
364 return false; 402 return false;
365 403
366 // Try to show the details for the native app. 404 // Try to show the details for the native app.
367 JNIEnv* env = base::android::AttachCurrentThread(); 405 JNIEnv* env = base::android::AttachCurrentThread();
368 406
369 content::WebContents* web_contents = 407 content::WebContents* web_contents =
370 InfoBarService::WebContentsFromInfoBar(infobar()); 408 InfoBarService::WebContentsFromInfoBar(infobar());
371 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents) 409 TabAndroid* tab = web_contents ? TabAndroid::FromWebContents(web_contents)
372 : nullptr; 410 : nullptr;
373 if (tab == nullptr) { 411 if (tab == nullptr) {
Peter Kasting 2016/09/08 04:56:57 Again, can this be null? When?
Xi Han 2016/09/08 15:49:10 Add a DCHECK instead.
374 TrackDismissEvent(DISMISS_EVENT_ERROR); 412 TrackDismissEvent(DISMISS_EVENT_ERROR);
375 return true; 413 return true;
376 } 414 }
377 415
378 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( 416 Java_AppBannerInfoBarDelegateAndroid_showAppDetails(
379 env, java_delegate_, tab->GetJavaObject(), native_app_data_); 417 env, java_delegate_, tab->GetJavaObject(), native_app_data_);
380 418
381 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); 419 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK);
382 return true; 420 return true;
383 } 421 }
384 422
385 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { 423 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) {
386 return RegisterNativesImpl(env); 424 return RegisterNativesImpl(env);
387 } 425 }
388 426
389 } // namespace banners 427 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698