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 19 matching lines...) Expand all Loading... | |
| 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; |
| 39 | 39 |
| 40 namespace { | |
| 41 | |
| 42 bool IsInfoEmpty(const ShortcutInfo* info) { | |
| 43 return !info || info->url.is_empty(); | |
| 44 } | |
| 45 | |
| 46 } // anonymous namespace | |
| 47 | |
| 40 namespace banners { | 48 namespace banners { |
| 41 | 49 |
| 42 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( | 50 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( |
| 43 base::WeakPtr<AppBannerManager> weak_manager, | 51 base::WeakPtr<AppBannerManager> weak_manager, |
| 44 const base::string16& app_title, | 52 const base::string16& app_title, |
| 45 const GURL& manifest_url, | 53 std::unique_ptr<ShortcutInfo> shortcut_info, |
| 46 const content::Manifest& manifest, | |
| 47 const GURL& icon_url, | |
| 48 std::unique_ptr<SkBitmap> icon, | 54 std::unique_ptr<SkBitmap> icon, |
| 49 int event_request_id, | 55 int event_request_id, |
| 50 bool is_webapk) | 56 bool is_webapk) |
| 51 : weak_manager_(weak_manager), | 57 : weak_manager_(weak_manager), |
| 52 app_title_(app_title), | 58 app_title_(app_title), |
| 53 manifest_url_(manifest_url), | 59 shortcut_info_(std::move(shortcut_info)), |
| 54 manifest_(manifest), | |
| 55 icon_url_(icon_url), | |
| 56 icon_(std::move(icon)), | 60 icon_(std::move(icon)), |
| 57 event_request_id_(event_request_id), | 61 event_request_id_(event_request_id), |
| 58 has_user_interaction_(false), | 62 has_user_interaction_(false), |
| 59 is_webapk_(is_webapk), | 63 is_webapk_(is_webapk), |
| 60 weak_ptr_factory_(this) { | 64 weak_ptr_factory_(this) { |
| 61 DCHECK(!manifest.IsEmpty()); | 65 DCHECK(!IsInfoEmpty(shortcut_info_.get())); |
| 62 CreateJavaDelegate(); | 66 CreateJavaDelegate(); |
| 63 } | 67 } |
| 64 | 68 |
| 65 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( | 69 AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( |
| 66 const base::string16& app_title, | 70 const base::string16& app_title, |
| 67 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, | 71 const base::android::ScopedJavaGlobalRef<jobject>& native_app_data, |
| 68 std::unique_ptr<SkBitmap> icon, | 72 std::unique_ptr<SkBitmap> icon, |
| 69 const std::string& native_app_package, | 73 const std::string& native_app_package, |
| 70 const std::string& referrer, | 74 const std::string& referrer, |
| 71 int event_request_id) | 75 int event_request_id) |
| 72 : app_title_(app_title), | 76 : app_title_(app_title), |
| 73 native_app_data_(native_app_data), | 77 native_app_data_(native_app_data), |
| 74 icon_(std::move(icon)), | 78 icon_(std::move(icon)), |
| 75 native_app_package_(native_app_package), | 79 native_app_package_(native_app_package), |
| 76 referrer_(referrer), | 80 referrer_(referrer), |
| 77 event_request_id_(event_request_id), | 81 event_request_id_(event_request_id), |
| 78 has_user_interaction_(false), | 82 has_user_interaction_(false), |
| 79 weak_ptr_factory_(this) { | 83 weak_ptr_factory_(this) { |
| 80 DCHECK(!native_app_data_.is_null()); | 84 DCHECK(!native_app_data_.is_null()); |
| 81 CreateJavaDelegate(); | 85 CreateJavaDelegate(); |
| 82 } | 86 } |
| 83 | 87 |
| 84 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { | 88 AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { |
| 85 weak_ptr_factory_.InvalidateWeakPtrs(); | 89 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 86 | 90 |
| 87 if (!has_user_interaction_) { | 91 if (!has_user_interaction_) { |
| 88 if (!native_app_data_.is_null()) | 92 if (!native_app_data_.is_null()) |
| 89 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); | 93 TrackUserResponse(USER_RESPONSE_NATIVE_APP_IGNORED); |
| 90 else if (!manifest_.IsEmpty()) | 94 else if (!IsInfoEmpty(shortcut_info_.get())) |
| 91 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); | 95 TrackUserResponse(USER_RESPONSE_WEB_APP_IGNORED); |
| 92 } | 96 } |
| 93 | 97 |
| 94 TrackDismissEvent(DISMISS_EVENT_DISMISSED); | 98 TrackDismissEvent(DISMISS_EVENT_DISMISSED); |
| 95 JNIEnv* env = base::android::AttachCurrentThread(); | 99 JNIEnv* env = base::android::AttachCurrentThread(); |
| 96 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); | 100 Java_AppBannerInfoBarDelegateAndroid_destroy(env, java_delegate_); |
| 97 java_delegate_.Reset(); | 101 java_delegate_.Reset(); |
| 98 } | 102 } |
| 99 | 103 |
| 100 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( | 104 void AppBannerInfoBarDelegateAndroid::UpdateInstallState( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 | 151 |
| 148 if (success) { | 152 if (success) { |
| 149 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED); | 153 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_COMPLETED); |
| 150 UpdateInstallState(env, obj); | 154 UpdateInstallState(env, obj); |
| 151 } else if (infobar()->owner()) { | 155 } else if (infobar()->owner()) { |
| 152 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT); | 156 TrackDismissEvent(DISMISS_EVENT_INSTALL_TIMEOUT); |
| 153 infobar()->owner()->RemoveInfoBar(infobar()); | 157 infobar()->owner()->RemoveInfoBar(infobar()); |
| 154 } | 158 } |
| 155 } | 159 } |
| 156 | 160 |
| 161 void AppBannerInfoBarDelegateAndroid::InstallWebApk( | |
|
Peter Kasting
2016/09/06 19:31:23
Nit: This function just wraps AcceptWebApk(). Mak
Xi Han
2016/09/07 15:53:17
Done.
| |
| 162 content::WebContents* web_contents) { | |
| 163 if (!web_contents) { | |
|
Peter Kasting
2016/09/06 19:31:23
Will callers ever pass you null? If not, do nothi
Xi Han
2016/09/07 15:53:17
Move the extra logic to the callers.
| |
| 164 LOG(ERROR) << "Failed to create infobar to install the WebAPK: " | |
| 165 << "the associated WebContents is null."; | |
| 166 return; | |
| 167 } | |
| 168 AcceptWebApk(web_contents); | |
| 169 } | |
| 170 | |
| 157 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { | 171 void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate() { |
| 158 JNIEnv* env = base::android::AttachCurrentThread(); | 172 JNIEnv* env = base::android::AttachCurrentThread(); |
| 159 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( | 173 java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( |
| 160 env, | 174 env, |
| 161 reinterpret_cast<intptr_t>(this))); | 175 reinterpret_cast<intptr_t>(this))); |
| 162 } | 176 } |
| 163 | 177 |
| 164 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted( | 178 void AppBannerInfoBarDelegateAndroid::SendBannerAccepted( |
| 165 content::WebContents* web_contents, | 179 content::WebContents* web_contents, |
| 166 const std::string& platform) { | 180 const std::string& platform) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 190 | 204 |
| 191 web_contents->GetMainFrame()->Send( | 205 web_contents->GetMainFrame()->Send( |
| 192 new ChromeViewMsg_AppBannerDismissed( | 206 new ChromeViewMsg_AppBannerDismissed( |
| 193 web_contents->GetMainFrame()->GetRoutingID(), | 207 web_contents->GetMainFrame()->GetRoutingID(), |
| 194 event_request_id_)); | 208 event_request_id_)); |
| 195 | 209 |
| 196 if (!native_app_data_.is_null()) { | 210 if (!native_app_data_.is_null()) { |
| 197 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); | 211 TrackUserResponse(USER_RESPONSE_NATIVE_APP_DISMISSED); |
| 198 AppBannerSettingsHelper::RecordBannerDismissEvent( | 212 AppBannerSettingsHelper::RecordBannerDismissEvent( |
| 199 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); | 213 web_contents, native_app_package_, AppBannerSettingsHelper::NATIVE); |
| 200 } else if (!manifest_.IsEmpty()) { | 214 } else if (!IsInfoEmpty(shortcut_info_.get())) { |
| 201 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); | 215 TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED); |
| 202 AppBannerSettingsHelper::RecordBannerDismissEvent( | 216 AppBannerSettingsHelper::RecordBannerDismissEvent( |
| 203 web_contents, manifest_.start_url.spec(), | 217 web_contents, shortcut_info_->url.spec(), |
| 204 AppBannerSettingsHelper::WEB); | 218 AppBannerSettingsHelper::WEB); |
| 205 } | 219 } |
| 206 } | 220 } |
| 207 | 221 |
| 208 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { | 222 base::string16 AppBannerInfoBarDelegateAndroid::GetMessageText() const { |
| 209 return app_title_; | 223 return app_title_; |
| 210 } | 224 } |
| 211 | 225 |
| 212 int AppBannerInfoBarDelegateAndroid::GetButtons() const { | 226 int AppBannerInfoBarDelegateAndroid::GetButtons() const { |
| 213 return BUTTON_OK; | 227 return BUTTON_OK; |
| 214 } | 228 } |
| 215 | 229 |
| 216 bool AppBannerInfoBarDelegateAndroid::Accept() { | 230 bool AppBannerInfoBarDelegateAndroid::Accept() { |
| 217 has_user_interaction_ = true; | 231 has_user_interaction_ = true; |
| 218 | 232 |
| 219 content::WebContents* web_contents = | 233 content::WebContents* web_contents = |
| 220 InfoBarService::WebContentsFromInfoBar(infobar()); | 234 InfoBarService::WebContentsFromInfoBar(infobar()); |
| 221 if (!web_contents) { | 235 if (!web_contents) { |
| 222 TrackDismissEvent(DISMISS_EVENT_ERROR); | 236 TrackDismissEvent(DISMISS_EVENT_ERROR); |
| 223 return true; | 237 return true; |
| 224 } | 238 } |
| 225 | 239 |
| 226 if (!native_app_data_.is_null()) { | 240 if (!native_app_data_.is_null()) { |
| 227 return AcceptNativeApp(web_contents); | 241 return AcceptNativeApp(web_contents); |
| 228 } else if (is_webapk_) { | 242 } else if (is_webapk_) { |
|
Peter Kasting
2016/09/06 19:31:23
Nit: No else after return
Xi Han
2016/09/07 15:53:17
Done.
| |
| 229 return AcceptWebApk(web_contents); | 243 return AcceptWebApk(web_contents); |
| 230 } | 244 } |
| 231 return AcceptWebApp(web_contents); | 245 return AcceptWebApp(web_contents); |
| 232 } | 246 } |
| 233 | 247 |
| 234 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp( | 248 bool AppBannerInfoBarDelegateAndroid::AcceptNativeApp( |
| 235 content::WebContents* web_contents) { | 249 content::WebContents* web_contents) { |
| 236 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); | 250 TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); |
| 237 JNIEnv* env = base::android::AttachCurrentThread(); | 251 JNIEnv* env = base::android::AttachCurrentThread(); |
| 238 | 252 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 253 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); | 267 TrackDismissEvent(DISMISS_EVENT_APP_OPEN); |
| 254 } else { | 268 } else { |
| 255 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); | 269 TrackInstallEvent(INSTALL_EVENT_NATIVE_APP_INSTALL_TRIGGERED); |
| 256 } | 270 } |
| 257 SendBannerAccepted(web_contents, "play"); | 271 SendBannerAccepted(web_contents, "play"); |
| 258 return was_opened; | 272 return was_opened; |
| 259 } | 273 } |
| 260 | 274 |
| 261 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( | 275 bool AppBannerInfoBarDelegateAndroid::AcceptWebApp( |
| 262 content::WebContents* web_contents) { | 276 content::WebContents* web_contents) { |
| 263 if (manifest_.IsEmpty()) | 277 if (IsInfoEmpty(shortcut_info_.get())) |
| 264 return true; | 278 return true; |
| 265 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 279 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
| 266 | 280 |
| 267 AppBannerSettingsHelper::RecordBannerInstallEvent( | 281 AppBannerSettingsHelper::RecordBannerInstallEvent( |
| 268 web_contents, manifest_.start_url.spec(), | 282 web_contents, shortcut_info_->url.spec(), |
| 269 AppBannerSettingsHelper::WEB); | 283 AppBannerSettingsHelper::WEB); |
| 270 | 284 |
| 271 if (weak_manager_) { | 285 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(); | 286 const std::string& uid = base::GenerateGUID(); |
| 279 ShortcutHelper::AddToLauncherWithSkBitmap( | 287 ShortcutHelper::AddToLauncherWithSkBitmap( |
| 280 web_contents->GetBrowserContext(), info, uid, *icon_.get(), | 288 web_contents->GetBrowserContext(), |
| 289 *shortcut_info_.get(), uid, *icon_.get(), | |
| 281 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); | 290 weak_manager_->FetchWebappSplashScreenImageCallback(uid)); |
| 282 } | 291 } |
| 283 | 292 |
| 284 SendBannerAccepted(web_contents, "web"); | 293 SendBannerAccepted(web_contents, "web"); |
| 285 return true; | 294 return true; |
| 286 } | 295 } |
| 287 | 296 |
| 288 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk( | 297 bool AppBannerInfoBarDelegateAndroid::AcceptWebApk( |
| 289 content::WebContents* web_contents) { | 298 content::WebContents* web_contents) { |
| 290 if (manifest_.IsEmpty()) | 299 if (IsInfoEmpty(shortcut_info_.get())) |
| 291 return true; | 300 return true; |
| 292 | 301 |
| 293 JNIEnv* env = base::android::AttachCurrentThread(); | 302 JNIEnv* env = base::android::AttachCurrentThread(); |
| 294 // |webapk_package_name_| is set when the WebAPK has finished installing. | 303 // |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" | 304 // If the |webapk_package_name_| is empty, it means the "Add to Homescreen" |
| 296 // button is pressed, so request WebAPK installation. Otherwise, it means | 305 // button is pressed, so request WebAPK installation. Otherwise, it means |
| 297 // the "Open" button is pressed, then open the installed WebAPK. | 306 // the "Open" button is pressed, then open the installed WebAPK. |
| 298 if (webapk_package_name_.empty()) { | 307 if (webapk_package_name_.empty()) { |
| 299 // Request install the WebAPK. | 308 // Request install the WebAPK. |
| 300 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); | 309 TrackUserResponse(USER_RESPONSE_WEB_APP_ACCEPTED); |
| 301 | 310 |
| 302 AppBannerSettingsHelper::RecordBannerInstallEvent( | 311 AppBannerSettingsHelper::RecordBannerInstallEvent( |
| 303 web_contents, manifest_.start_url.spec(), | 312 web_contents, shortcut_info_->url.spec(), |
| 304 AppBannerSettingsHelper::WEB); | 313 AppBannerSettingsHelper::WEB); |
| 305 | 314 |
| 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( | 315 Java_AppBannerInfoBarDelegateAndroid_setWebApkInstallingState( |
| 313 env, java_delegate_, true); | 316 env, java_delegate_, true); |
| 314 UpdateInstallState(env, nullptr); | 317 UpdateInstallState(env, nullptr); |
| 315 | 318 |
| 316 WebApkInstaller::FinishCallback callback = base::Bind( | 319 WebApkInstaller::FinishCallback callback = base::Bind( |
| 317 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, | 320 &AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished, |
| 318 weak_ptr_factory_.GetWeakPtr()); | 321 weak_ptr_factory_.GetWeakPtr()); |
| 319 DVLOG(1) << "Trigger the installation of the WebAPK."; | 322 DVLOG(1) << "Trigger the installation of the WebAPK."; |
| 320 ShortcutHelper::InstallWebApkWithSkBitmap( | 323 ShortcutHelper::InstallWebApkWithSkBitmap( |
| 321 web_contents->GetBrowserContext(), info, *icon_.get(), callback); | 324 web_contents->GetBrowserContext(), *shortcut_info_.get(), |
| 325 *icon_.get(), callback); | |
| 322 | 326 |
| 323 SendBannerAccepted(web_contents, "web"); | 327 SendBannerAccepted(web_contents, "web"); |
| 324 // Returns false to prevent the infobar from disappearing. | 328 // Returns false to prevent the infobar from disappearing. |
| 325 return false; | 329 return false; |
| 326 } | 330 } |
| 327 | 331 |
| 328 // Open the WebAPK. | 332 // Open the WebAPK. |
| 329 ScopedJavaLocalRef<jstring> java_webapk_package_name = | 333 ScopedJavaLocalRef<jstring> java_webapk_package_name = |
| 330 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); | 334 base::android::ConvertUTF8ToJavaString(env, webapk_package_name_); |
| 331 Java_AppBannerInfoBarDelegateAndroid_openWebApk( | 335 Java_AppBannerInfoBarDelegateAndroid_openWebApk( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 return true; | 379 return true; |
| 376 } | 380 } |
| 377 | 381 |
| 378 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( | 382 Java_AppBannerInfoBarDelegateAndroid_showAppDetails( |
| 379 env, java_delegate_, tab->GetJavaObject(), native_app_data_); | 383 env, java_delegate_, tab->GetJavaObject(), native_app_data_); |
| 380 | 384 |
| 381 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); | 385 TrackDismissEvent(DISMISS_EVENT_BANNER_CLICK); |
| 382 return true; | 386 return true; |
| 383 } | 387 } |
| 384 | 388 |
| 389 AppBannerInfoBarDelegateAndroid* | |
| 390 AppBannerInfoBarDelegateAndroid::AsAppBannerInfoBarDelegateAndroid() { | |
| 391 return this; | |
| 392 } | |
| 393 | |
| 385 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { | 394 bool RegisterAppBannerInfoBarDelegateAndroid(JNIEnv* env) { |
| 386 return RegisterNativesImpl(env); | 395 return RegisterNativesImpl(env); |
| 387 } | 396 } |
| 388 | 397 |
| 389 } // namespace banners | 398 } // namespace banners |
| OLD | NEW |