Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |