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 "chrome/browser/android/banners/app_banner_infobar_delegate.h" |
12 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" | 13 #include "chrome/browser/android/banners/app_banner_metrics_ids.h" |
13 #include "chrome/browser/android/banners/app_banner_settings_helper.h" | 14 #include "chrome/browser/android/banners/app_banner_settings_helper.h" |
14 #include "chrome/browser/android/banners/app_banner_utilities.h" | 15 #include "chrome/browser/android/banners/app_banner_utilities.h" |
15 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" | 16 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" |
| 17 #include "chrome/browser/infobars/infobar_service.h" |
16 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/common/chrome_constants.h" | 19 #include "chrome/common/chrome_constants.h" |
18 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
19 #include "chrome/common/render_messages.h" | 21 #include "chrome/common/render_messages.h" |
20 #include "content/public/browser/android/content_view_core.h" | 22 #include "content/public/browser/android/content_view_core.h" |
21 #include "content/public/browser/navigation_details.h" | 23 #include "content/public/browser/navigation_details.h" |
22 #include "content/public/browser/render_frame_host.h" | 24 #include "content/public/browser/render_frame_host.h" |
23 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
24 #include "content/public/common/frame_navigate_params.h" | 26 #include "content/public/common/frame_navigate_params.h" |
25 #include "content/public/common/manifest.h" | 27 #include "content/public/common/manifest.h" |
26 #include "jni/AppBannerManager_jni.h" | 28 #include "jni/AppBannerManager_jni.h" |
27 #include "net/base/load_flags.h" | 29 #include "net/base/load_flags.h" |
28 #include "ui/gfx/android/java_bitmap.h" | 30 #include "ui/gfx/android/java_bitmap.h" |
29 | 31 |
30 using base::android::ConvertJavaStringToUTF8; | 32 using base::android::ConvertJavaStringToUTF8; |
31 using base::android::ConvertUTF8ToJavaString; | 33 using base::android::ConvertUTF8ToJavaString; |
| 34 using base::android::ConvertUTF16ToJavaString; |
32 | 35 |
33 namespace { | 36 namespace { |
34 const char kBannerTag[] = "google-play-id"; | 37 const char kBannerTag[] = "google-play-id"; |
35 } | 38 } |
36 | 39 |
37 namespace banners { | 40 namespace banners { |
38 | 41 |
39 AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj) | 42 AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj) |
40 : weak_java_banner_view_manager_(env, obj) {} | 43 : weak_java_banner_view_manager_(env, obj) {} |
41 | 44 |
42 AppBannerManager::~AppBannerManager() { | 45 AppBannerManager::~AppBannerManager() { |
43 } | 46 } |
44 | 47 |
45 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { | 48 void AppBannerManager::Destroy(JNIEnv* env, jobject obj) { |
46 delete this; | 49 delete this; |
47 } | 50 } |
48 | 51 |
49 void AppBannerManager::BlockBanner(JNIEnv* env, | 52 void AppBannerManager::BlockBanner(JNIEnv* env, |
50 jobject obj, | 53 jobject obj, |
51 jstring jurl, | 54 jstring jurl, |
52 jstring jpackage) { | 55 jstring jpackage) { |
53 if (!web_contents()) | 56 if (!web_contents()) |
54 return; | 57 return; |
55 | 58 |
56 GURL url(ConvertJavaStringToUTF8(env, jurl)); | 59 GURL url(ConvertJavaStringToUTF8(env, jurl)); |
57 std::string package_name = ConvertJavaStringToUTF8(env, jpackage); | 60 std::string package_name = ConvertJavaStringToUTF8(env, jpackage); |
58 AppBannerSettingsHelper::Block(web_contents(), url, package_name); | 61 AppBannerSettingsHelper::Block(web_contents(), url, package_name); |
59 } | 62 } |
60 | 63 |
| 64 void AppBannerManager::Block() const { |
| 65 if (!web_contents() || manifest_.IsEmpty()) |
| 66 return; |
| 67 |
| 68 AppBannerSettingsHelper::Block(web_contents(), |
| 69 web_contents()->GetURL(), |
| 70 manifest_.start_url.spec()); |
| 71 } |
| 72 |
| 73 void AppBannerManager::Install() const { |
| 74 if (!web_contents()) |
| 75 return; |
| 76 |
| 77 if (!manifest_.IsEmpty()) { |
| 78 // TODO(dfalcantara): Trigger shortcut creation. |
| 79 } |
| 80 } |
| 81 |
| 82 gfx::Image AppBannerManager::GetIcon() const { |
| 83 return gfx::Image::CreateFrom1xBitmap(*app_icon_.get()); |
| 84 } |
| 85 |
61 void AppBannerManager::ReplaceWebContents(JNIEnv* env, | 86 void AppBannerManager::ReplaceWebContents(JNIEnv* env, |
62 jobject obj, | 87 jobject obj, |
63 jobject jweb_contents) { | 88 jobject jweb_contents) { |
64 content::WebContents* web_contents = | 89 content::WebContents* web_contents = |
65 content::WebContents::FromJavaWebContents(jweb_contents); | 90 content::WebContents::FromJavaWebContents(jweb_contents); |
66 Observe(web_contents); | 91 Observe(web_contents); |
67 } | 92 } |
68 | 93 |
69 void AppBannerManager::DidNavigateMainFrame( | 94 void AppBannerManager::DidNavigateMainFrame( |
70 const content::LoadCommittedDetails& details, | 95 const content::LoadCommittedDetails& details, |
71 const content::FrameNavigateParams& params) { | 96 const content::FrameNavigateParams& params) { |
| 97 // Clear current state. |
| 98 fetcher_.reset(); |
| 99 manifest_ = content::Manifest(); |
| 100 app_icon_.reset(); |
| 101 |
72 // Get rid of the current banner. | 102 // Get rid of the current banner. |
73 JNIEnv* env = base::android::AttachCurrentThread(); | 103 JNIEnv* env = base::android::AttachCurrentThread(); |
74 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 104 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
75 if (jobj.is_null()) | 105 if (jobj.is_null()) |
76 return; | 106 return; |
77 Java_AppBannerManager_dismissCurrentBanner(env, jobj.obj(), DISMISS_NAVIGATE); | 107 Java_AppBannerManager_dismissCurrentBanner(env, jobj.obj(), DISMISS_NAVIGATE); |
78 } | 108 } |
79 | 109 |
80 void AppBannerManager::DidFinishLoad( | 110 void AppBannerManager::DidFinishLoad( |
81 content::RenderFrameHost* render_frame_host, | 111 content::RenderFrameHost* render_frame_host, |
(...skipping 16 matching lines...) Expand all Loading... |
98 if (manifest.IsEmpty()) { | 128 if (manifest.IsEmpty()) { |
99 // No manifest, see if there is a play store meta tag. | 129 // No manifest, see if there is a play store meta tag. |
100 Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(), | 130 Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(), |
101 validated_url_, | 131 validated_url_, |
102 kBannerTag)); | 132 kBannerTag)); |
103 return; | 133 return; |
104 } | 134 } |
105 | 135 |
106 // TODO(benwells): Check triggering parameters here and if there is a meta | 136 // TODO(benwells): Check triggering parameters here and if there is a meta |
107 // tag. | 137 // tag. |
108 // TODO(dfalcantara): Show banner for web site with manifest. | 138 |
| 139 // Create an infobar to promote the manifest's app. |
| 140 manifest_ = manifest; |
| 141 |
| 142 /* TODO(dfalcantara): Use after landing https://crrev.com/880203004. |
| 143 GURL icon_url = |
| 144 ManifestIconSelector::FindBestMatchingIcon(manifest.icons, |
| 145 GetPreferredIconSize(), |
| 146 web_contents()); |
| 147 if (icon_url.is_empty()) |
| 148 return; |
| 149 */ |
| 150 if (manifest.icons.empty()) |
| 151 return; |
| 152 GURL icon_url = manifest.icons.back().src; |
| 153 |
| 154 FetchIcon(icon_url); |
109 } | 155 } |
110 | 156 |
111 bool AppBannerManager::OnMessageReceived(const IPC::Message& message) { | 157 bool AppBannerManager::OnMessageReceived(const IPC::Message& message) { |
112 bool handled = true; | 158 bool handled = true; |
113 IPC_BEGIN_MESSAGE_MAP(AppBannerManager, message) | 159 IPC_BEGIN_MESSAGE_MAP(AppBannerManager, message) |
114 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent, | 160 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent, |
115 OnDidRetrieveMetaTagContent) | 161 OnDidRetrieveMetaTagContent) |
116 IPC_MESSAGE_UNHANDLED(handled = false) | 162 IPC_MESSAGE_UNHANDLED(handled = false) |
117 IPC_END_MESSAGE_MAP() | 163 IPC_END_MESSAGE_MAP() |
118 return handled; | 164 return handled; |
119 } | 165 } |
120 | 166 |
121 void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) { | 167 void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) { |
122 if (bitmap) { | 168 if (bitmap) { |
123 JNIEnv* env = base::android::AttachCurrentThread(); | 169 JNIEnv* env = base::android::AttachCurrentThread(); |
124 | 170 |
125 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); | 171 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
126 if (jobj.is_null()) | 172 if (jobj.is_null()) |
127 return; | 173 return; |
128 | 174 |
129 ScopedJavaLocalRef<jstring> jimage_url( | 175 bool displayed; |
130 ConvertUTF8ToJavaString(env, url.spec())); | 176 if (manifest_.IsEmpty()) { |
131 ScopedJavaLocalRef<jobject> jimage = gfx::ConvertToJavaBitmap(bitmap); | 177 ScopedJavaLocalRef<jobject> jimage = gfx::ConvertToJavaBitmap(bitmap); |
132 bool displayed = Java_AppBannerManager_createBanner(env, | 178 ScopedJavaLocalRef<jstring> jimage_url( |
133 jobj.obj(), | 179 ConvertUTF8ToJavaString(env, url.spec())); |
134 jimage_url.obj(), | 180 |
135 jimage.obj()); | 181 displayed = Java_AppBannerManager_createBanner(env, |
| 182 jobj.obj(), |
| 183 jimage_url.obj(), |
| 184 jimage.obj()); |
| 185 } else { |
| 186 app_icon_.reset(new SkBitmap(*bitmap)); |
| 187 InfoBarService* service = InfoBarService::FromWebContents(web_contents()); |
| 188 displayed = AppBannerInfoBarDelegate::CreateForWebApp( |
| 189 service, |
| 190 this, |
| 191 manifest_.name.string(), |
| 192 manifest_.start_url) != NULL; |
| 193 } |
| 194 |
136 if (displayed) | 195 if (displayed) |
137 banners::TrackDisplayEvent(DISPLAY_CREATED); | 196 banners::TrackDisplayEvent(DISPLAY_CREATED); |
138 } else { | 197 } else { |
139 DVLOG(1) << "Failed to retrieve image: " << url; | 198 DVLOG(1) << "Failed to retrieve image: " << url; |
140 } | 199 } |
141 | 200 |
142 fetcher_.reset(); | 201 fetcher_.reset(); |
143 } | 202 } |
144 | 203 |
145 void AppBannerManager::OnDidRetrieveMetaTagContent( | 204 void AppBannerManager::OnDidRetrieveMetaTagContent( |
(...skipping 28 matching lines...) Expand all Loading... |
174 Java_AppBannerManager_prepareBanner(env, | 233 Java_AppBannerManager_prepareBanner(env, |
175 jobj.obj(), | 234 jobj.obj(), |
176 jurl.obj(), | 235 jurl.obj(), |
177 jpackage.obj()); | 236 jpackage.obj()); |
178 } | 237 } |
179 | 238 |
180 bool AppBannerManager::FetchIcon(JNIEnv* env, | 239 bool AppBannerManager::FetchIcon(JNIEnv* env, |
181 jobject obj, | 240 jobject obj, |
182 jstring jimage_url) { | 241 jstring jimage_url) { |
183 std::string image_url = ConvertJavaStringToUTF8(env, jimage_url); | 242 std::string image_url = ConvertJavaStringToUTF8(env, jimage_url); |
| 243 return FetchIcon(GURL(image_url)); |
| 244 } |
| 245 |
| 246 bool AppBannerManager::FetchIcon(const GURL& image_url) { |
184 if (!web_contents()) | 247 if (!web_contents()) |
185 return false; | 248 return false; |
186 | 249 |
187 // Begin asynchronously fetching the app icon. | 250 // Begin asynchronously fetching the app icon. |
188 Profile* profile = | 251 Profile* profile = |
189 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | 252 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
190 fetcher_.reset(new chrome::BitmapFetcher(GURL(image_url), this)); | 253 fetcher_.reset(new chrome::BitmapFetcher(image_url, this)); |
191 fetcher_.get()->Start( | 254 fetcher_.get()->Start( |
192 profile->GetRequestContext(), | 255 profile->GetRequestContext(), |
193 std::string(), | 256 std::string(), |
194 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | 257 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
195 net::LOAD_NORMAL); | 258 net::LOAD_NORMAL); |
196 return true; | 259 return true; |
197 } | 260 } |
198 | 261 |
| 262 int AppBannerManager::GetPreferredIconSize() { |
| 263 JNIEnv* env = base::android::AttachCurrentThread(); |
| 264 ScopedJavaLocalRef<jobject> jobj = weak_java_banner_view_manager_.get(env); |
| 265 if (jobj.is_null()) |
| 266 return 0; |
| 267 |
| 268 return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); |
| 269 } |
| 270 |
199 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { | 271 void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { |
200 banners::TrackDismissEvent(metric); | 272 banners::TrackDismissEvent(metric); |
201 } | 273 } |
202 | 274 |
203 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { | 275 void RecordInstallEvent(JNIEnv* env, jclass clazz, jint metric) { |
204 banners::TrackInstallEvent(metric); | 276 banners::TrackInstallEvent(metric); |
205 } | 277 } |
206 | 278 |
207 jlong Init(JNIEnv* env, jobject obj) { | 279 jlong Init(JNIEnv* env, jobject obj) { |
208 AppBannerManager* manager = new AppBannerManager(env, obj); | 280 AppBannerManager* manager = new AppBannerManager(env, obj); |
209 return reinterpret_cast<intptr_t>(manager); | 281 return reinterpret_cast<intptr_t>(manager); |
210 } | 282 } |
211 | 283 |
212 jboolean IsEnabled(JNIEnv* env, jclass clazz) { | 284 jboolean IsEnabled(JNIEnv* env, jclass clazz) { |
213 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 285 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
214 switches::kEnableAppInstallAlerts); | 286 switches::kEnableAppInstallAlerts); |
215 } | 287 } |
216 | 288 |
217 // Register native methods | 289 // Register native methods |
218 bool RegisterAppBannerManager(JNIEnv* env) { | 290 bool RegisterAppBannerManager(JNIEnv* env) { |
219 return RegisterNativesImpl(env); | 291 return RegisterNativesImpl(env); |
220 } | 292 } |
221 | 293 |
222 } // namespace banners | 294 } // namespace banners |
OLD | NEW |