OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_manager.h" | 5 #include "chrome/browser/android/banners/app_banner_manager.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/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/threading/worker_pool.h" | |
13 #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" | 12 #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" |
14 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" | 13 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" |
15 #include "chrome/browser/android/banners/app_banner_utilities.h" | 14 #include "chrome/browser/android/banners/app_banner_utilities.h" |
16 #include "chrome/browser/android/manifest_icon_selector.h" | 15 #include "chrome/browser/android/manifest_icon_selector.h" |
17 #include "chrome/browser/android/shortcut_helper.h" | 16 #include "chrome/browser/android/shortcut_helper.h" |
18 #include "chrome/browser/android/shortcut_info.h" | 17 #include "chrome/browser/android/shortcut_info.h" |
19 #include "chrome/browser/banners/app_banner_settings_helper.h" | 18 #include "chrome/browser/banners/app_banner_settings_helper.h" |
20 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" | 19 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" |
21 #include "chrome/browser/infobars/infobar_service.h" | 20 #include "chrome/browser/infobars/infobar_service.h" |
22 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
(...skipping 30 matching lines...) Expand all Loading... |
53 : weak_java_banner_view_manager_(env, obj), weak_factory_(this) { | 52 : weak_java_banner_view_manager_(env, obj), weak_factory_(this) { |
54 } | 53 } |
55 | 54 |
56 AppBannerManager::~AppBannerManager() { | 55 AppBannerManager::~AppBannerManager() { |
57 } | 56 } |
58 | 57 |
59 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { | 58 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { |
60 delete this; | 59 delete this; |
61 } | 60 } |
62 | 61 |
63 void AppBannerManager::BlockBanner(JNIEnv* env, | |
64 jobject obj, | |
65 jstring jurl, | |
66 jstring jpackage) { | |
67 if (!web_contents()) | |
68 return; | |
69 | |
70 GURL url(ConvertJavaStringToUTF8(env, jurl)); | |
71 std::string package_name = ConvertJavaStringToUTF8(env, jpackage); | |
72 AppBannerSettingsHelper::RecordBannerEvent( | |
73 web_contents(), url, package_name, | |
74 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
75 } | |
76 | |
77 void AppBannerManager::Block() const { | |
78 if (!web_contents()) | |
79 return; | |
80 | |
81 if (!native_app_data_.is_null()) { | |
82 AppBannerSettingsHelper::RecordBannerEvent( | |
83 web_contents(), web_contents()->GetURL(), | |
84 native_app_package_, | |
85 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
86 } else if (!web_app_data_.IsEmpty()) { | |
87 AppBannerSettingsHelper::RecordBannerEvent( | |
88 web_contents(), web_contents()->GetURL(), | |
89 web_app_data_.start_url.spec(), | |
90 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_BLOCK, base::Time::Now()); | |
91 } | |
92 } | |
93 | |
94 void AppBannerManager::OnInfoBarDestroyed() { | |
95 weak_infobar_ptr_ = nullptr; | |
96 } | |
97 | |
98 bool AppBannerManager::OnButtonClicked() const { | |
99 if (!web_contents()) | |
100 return true; | |
101 | |
102 if (!native_app_data_.is_null()) { | |
103 JNIEnv* env = base::android::AttachCurrentThread(); | |
104 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
105 if (jobj.is_null()) | |
106 return true; | |
107 | |
108 return Java_AppBannerManager_installOrOpenNativeApp(env, | |
109 jobj.obj(), | |
110 native_app_data_.obj()); | |
111 } else if (!web_app_data_.IsEmpty()) { | |
112 AppBannerSettingsHelper::RecordBannerEvent( | |
113 web_contents(), web_contents()->GetURL(), | |
114 web_app_data_.start_url.spec(), | |
115 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, | |
116 base::Time::Now()); | |
117 | |
118 InstallManifestApp(web_app_data_, *app_icon_.get()); | |
119 return true; | |
120 } | |
121 | |
122 return true; | |
123 } | |
124 | |
125 bool AppBannerManager::OnLinkClicked() const { | |
126 if (!web_contents()) | |
127 return true; | |
128 | |
129 if (!native_app_data_.is_null()) { | |
130 // Try to show the details for the native app. | |
131 JNIEnv* env = base::android::AttachCurrentThread(); | |
132 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
133 if (jobj.is_null()) | |
134 return true; | |
135 | |
136 Java_AppBannerManager_showAppDetails(env, | |
137 jobj.obj(), | |
138 native_app_data_.obj()); | |
139 return true; | |
140 } else { | |
141 // Nothing should happen if the user is installing a web app. | |
142 return false; | |
143 } | |
144 } | |
145 | |
146 base::string16 AppBannerManager::GetTitle() const { | |
147 return app_title_; | |
148 } | |
149 | |
150 gfx::Image AppBannerManager::GetIcon() const { | |
151 return gfx::Image::CreateFrom1xBitmap(*app_icon_.get()); | |
152 } | |
153 | |
154 void AppBannerManager::ReplaceWebContents(JNIEnv* env, | 62 void AppBannerManager::ReplaceWebContents(JNIEnv* env, |
155 jobject obj, | 63 jobject obj, |
156 jobject jweb_contents) { | 64 jobject jweb_contents) { |
157 content::WebContents* web_contents = | 65 content::WebContents* web_contents = |
158 content::WebContents::FromJavaWebContents(jweb_contents); | 66 content::WebContents::FromJavaWebContents(jweb_contents); |
159 Observe(web_contents); | 67 Observe(web_contents); |
160 } | 68 } |
161 | 69 |
162 void AppBannerManager::DidNavigateMainFrame( | 70 void AppBannerManager::DidNavigateMainFrame( |
163 const content::LoadCommittedDetails& details, | 71 const content::LoadCommittedDetails& details, |
164 const content::FrameNavigateParams& params) { | 72 const content::FrameNavigateParams& params) { |
165 // Clear current state. | 73 // Clear current state. |
166 fetcher_.reset(); | 74 fetcher_.reset(); |
167 app_title_ = base::string16(); | 75 app_title_ = base::string16(); |
168 app_icon_.reset(); | |
169 web_app_data_ = content::Manifest(); | 76 web_app_data_ = content::Manifest(); |
170 native_app_data_.Reset(); | 77 native_app_data_.Reset(); |
171 native_app_package_ = std::string(); | 78 native_app_package_ = std::string(); |
172 } | 79 } |
173 | 80 |
174 void AppBannerManager::DidFinishLoad( | 81 void AppBannerManager::DidFinishLoad( |
175 content::RenderFrameHost* render_frame_host, | 82 content::RenderFrameHost* render_frame_host, |
176 const GURL& validated_url) { | 83 const GURL& validated_url) { |
177 if (render_frame_host->GetParent()) | 84 if (render_frame_host->GetParent()) |
178 return; | 85 return; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if (!bitmap || url != app_icon_url_) { | 176 if (!bitmap || url != app_icon_url_) { |
270 DVLOG(1) << "Failed to retrieve image: " << url; | 177 DVLOG(1) << "Failed to retrieve image: " << url; |
271 return; | 178 return; |
272 } | 179 } |
273 | 180 |
274 JNIEnv* env = base::android::AttachCurrentThread(); | 181 JNIEnv* env = base::android::AttachCurrentThread(); |
275 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 182 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
276 if (jobj.is_null()) | 183 if (jobj.is_null()) |
277 return; | 184 return; |
278 | 185 |
279 app_icon_.reset(new SkBitmap(*bitmap)); | |
280 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); | 186 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); |
281 | 187 |
282 weak_infobar_ptr_ = nullptr; | 188 AppBannerInfoBar* weak_infobar_ptr = nullptr; |
283 if (!native_app_data_.is_null()) { | 189 if (!native_app_data_.is_null()) { |
284 RecordCouldShowBanner(native_app_package_); | 190 RecordCouldShowBanner(native_app_package_); |
285 if (!CheckIfShouldShow(native_app_package_)) | 191 if (!CheckIfShouldShow(native_app_package_)) |
286 return; | 192 return; |
287 | 193 |
288 weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForNativeApp( | 194 weak_infobar_ptr = AppBannerInfoBarDelegate::CreateForNativeApp( |
289 service, | 195 service, |
290 this, | 196 app_title_, |
291 native_app_data_); | 197 new SkBitmap(*bitmap), |
| 198 native_app_data_, |
| 199 native_app_package_); |
292 } else if (!web_app_data_.IsEmpty()){ | 200 } else if (!web_app_data_.IsEmpty()){ |
293 RecordCouldShowBanner(web_app_data_.start_url.spec()); | 201 RecordCouldShowBanner(web_app_data_.start_url.spec()); |
294 if (!CheckIfShouldShow(web_app_data_.start_url.spec())) | 202 if (!CheckIfShouldShow(web_app_data_.start_url.spec())) |
295 return; | 203 return; |
296 | 204 |
297 weak_infobar_ptr_ = AppBannerInfoBarDelegate::CreateForWebApp( | 205 weak_infobar_ptr = AppBannerInfoBarDelegate::CreateForWebApp( |
298 service, | 206 service, |
299 this, | 207 app_title_, |
300 web_app_data_.start_url); | 208 new SkBitmap(*bitmap), |
| 209 web_app_data_); |
301 } | 210 } |
302 | 211 |
303 if (weak_infobar_ptr_ != nullptr) | 212 if (weak_infobar_ptr != nullptr) |
304 banners::TrackDisplayEvent(DISPLAY_CREATED); | 213 banners::TrackDisplayEvent(DISPLAY_CREATED); |
305 } | 214 } |
306 | 215 |
307 void AppBannerManager::OnDidRetrieveMetaTagContent( | 216 void AppBannerManager::OnDidRetrieveMetaTagContent( |
308 bool success, | 217 bool success, |
309 const std::string& tag_name, | 218 const std::string& tag_name, |
310 const std::string& tag_content, | 219 const std::string& tag_content, |
311 const GURL& expected_url) { | 220 const GURL& expected_url) { |
312 DCHECK(web_contents()); | 221 DCHECK(web_contents()); |
313 if (!success || tag_name != kBannerTag || validated_url_ != expected_url || | 222 if (!success || tag_name != kBannerTag || validated_url_ != expected_url || |
(...skipping 28 matching lines...) Expand all Loading... |
342 if (validated_url_ != web_contents()->GetURL()) | 251 if (validated_url_ != web_contents()->GetURL()) |
343 return false; | 252 return false; |
344 | 253 |
345 std::string image_url = ConvertJavaStringToUTF8(env, jicon_url); | 254 std::string image_url = ConvertJavaStringToUTF8(env, jicon_url); |
346 app_title_ = ConvertJavaStringToUTF16(env, japp_title); | 255 app_title_ = ConvertJavaStringToUTF16(env, japp_title); |
347 native_app_package_ = ConvertJavaStringToUTF8(env, japp_package); | 256 native_app_package_ = ConvertJavaStringToUTF8(env, japp_package); |
348 native_app_data_.Reset(env, japp_data); | 257 native_app_data_.Reset(env, japp_data); |
349 return FetchIcon(GURL(image_url)); | 258 return FetchIcon(GURL(image_url)); |
350 } | 259 } |
351 | 260 |
352 void AppBannerManager::OnInstallIntentReturned(JNIEnv* env, | |
353 jobject obj, | |
354 jboolean jis_installing) { | |
355 if (!weak_infobar_ptr_) | |
356 return; | |
357 | |
358 if (jis_installing) { | |
359 AppBannerSettingsHelper::RecordBannerEvent( | |
360 web_contents(), | |
361 web_contents()->GetURL(), | |
362 native_app_package_, | |
363 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_ADD_TO_HOMESCREEN, | |
364 base::Time::Now()); | |
365 } | |
366 | |
367 UpdateInstallState(env, obj); | |
368 } | |
369 | |
370 void AppBannerManager::OnInstallFinished(JNIEnv* env, | |
371 jobject obj, | |
372 jboolean success) { | |
373 if (!weak_infobar_ptr_) | |
374 return; | |
375 | |
376 if (success) { | |
377 UpdateInstallState(env, obj); | |
378 } else { | |
379 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); | |
380 service->RemoveInfoBar(weak_infobar_ptr_); | |
381 } | |
382 } | |
383 | |
384 void AppBannerManager::UpdateInstallState(JNIEnv* env, jobject obj) { | |
385 if (!weak_infobar_ptr_ || native_app_data_.is_null()) | |
386 return; | |
387 | |
388 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | |
389 if (jobj.is_null()) | |
390 return; | |
391 | |
392 int newState = Java_AppBannerManager_determineInstallState( | |
393 env, | |
394 jobj.obj(), | |
395 native_app_data_.obj()); | |
396 weak_infobar_ptr_->OnInstallStateChanged(newState); | |
397 } | |
398 | |
399 bool AppBannerManager::FetchIcon(const GURL& image_url) { | 261 bool AppBannerManager::FetchIcon(const GURL& image_url) { |
400 if (!web_contents()) | 262 if (!web_contents()) |
401 return false; | 263 return false; |
402 | 264 |
403 // Begin asynchronously fetching the app icon. | 265 // Begin asynchronously fetching the app icon. |
404 Profile* profile = | 266 Profile* profile = |
405 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | 267 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
406 fetcher_.reset(new chrome::BitmapFetcher(image_url, this)); | 268 fetcher_.reset(new chrome::BitmapFetcher(image_url, this)); |
407 fetcher_.get()->Start( | 269 fetcher_.get()->Start( |
408 profile->GetRequestContext(), | 270 profile->GetRequestContext(), |
409 std::string(), | 271 std::string(), |
410 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | 272 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
411 net::LOAD_NORMAL); | 273 net::LOAD_NORMAL); |
412 app_icon_url_ = image_url; | 274 app_icon_url_ = image_url; |
413 return true; | 275 return true; |
414 } | 276 } |
415 | 277 |
416 int AppBannerManager::GetPreferredIconSize() { | 278 int AppBannerManager::GetPreferredIconSize() { |
417 JNIEnv* env = base::android::AttachCurrentThread(); | 279 JNIEnv* env = base::android::AttachCurrentThread(); |
418 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 280 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
419 if (jobj.is_null()) | 281 if (jobj.is_null()) |
420 return 0; | 282 return 0; |
421 | 283 |
422 return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); | 284 return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); |
423 } | 285 } |
424 | 286 |
425 // static | |
426 void AppBannerManager::InstallManifestApp(const content::Manifest& manifest, | |
427 const SkBitmap& icon) { | |
428 ShortcutInfo info; | |
429 info.UpdateFromManifest(manifest); | |
430 | |
431 base::WorkerPool::PostTask( | |
432 FROM_HERE, | |
433 base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap, | |
434 info, | |
435 icon), | |
436 true); | |
437 } | |
438 | |
439 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { | 287 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { |
440 banners::TrackDismissEvent(metric); | 288 banners::TrackDismissEvent(metric); |
441 } | 289 } |
442 | 290 |
443 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { | 291 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { |
444 banners::TrackInstallEvent(metric); | 292 banners::TrackInstallEvent(metric); |
445 } | 293 } |
446 | 294 |
447 jlong Init(JNIEnv* env, jobject obj) { | 295 jlong Init(JNIEnv* env, jobject obj) { |
448 AppBannerManager* manager = new AppBannerManager(env, obj); | 296 AppBannerManager* manager = new AppBannerManager(env, obj); |
449 return reinterpret_cast<intptr_t>(manager); | 297 return reinterpret_cast<intptr_t>(manager); |
450 } | 298 } |
451 | 299 |
452 jboolean IsEnabled(JNIEnv* env, jclass clazz) { | 300 jboolean IsEnabled(JNIEnv* env, jclass clazz) { |
453 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 301 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
454 switches::kEnableAppInstallAlerts); | 302 switches::kEnableAppInstallAlerts); |
455 } | 303 } |
456 | 304 |
457 // Register native methods | 305 // Register native methods |
458 bool RegisterAppBannerManager(JNIEnv* env) { | 306 bool RegisterAppBannerManager(JNIEnv* env) { |
459 return RegisterNativesImpl(env); | 307 return RegisterNativesImpl(env); |
460 } | 308 } |
461 | 309 |
462 } // namespace banners | 310 } // namespace banners |
OLD | NEW |