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/shortcut_data_fetcher.h" | 5 #include "chrome/browser/android/shortcut_data_fetcher.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "base/task/cancelable_task_tracker.h" | 10 #include "base/task/cancelable_task_tracker.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
33 // Android's preferred icon size in DP is 48, as defined in | 33 // Android's preferred icon size in DP is 48, as defined in |
34 // http://developer.android.com/design/style/iconography.html | 34 // http://developer.android.com/design/style/iconography.html |
35 const int ShortcutDataFetcher::kPreferredIconSizeInDp = 48; | 35 const int ShortcutDataFetcher::kPreferredIconSizeInDp = 48; |
36 | 36 |
37 ShortcutDataFetcher::ShortcutDataFetcher( | 37 ShortcutDataFetcher::ShortcutDataFetcher( |
38 content::WebContents* web_contents, | 38 content::WebContents* web_contents, |
39 Observer* observer) | 39 Observer* observer) |
40 : WebContentsObserver(web_contents), | 40 : WebContentsObserver(web_contents), |
41 weak_observer_(observer), | 41 weak_observer_(observer), |
42 is_ready_(false), | 42 is_ready_(false), |
43 icon_timeout_timer_(false, false), | |
43 shortcut_info_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( | 44 shortcut_info_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( |
44 web_contents->GetURL())), | 45 web_contents->GetURL())), |
45 preferred_icon_size_in_px_(kPreferredIconSizeInDp * | 46 preferred_icon_size_in_px_(kPreferredIconSizeInDp * |
46 gfx::Screen::GetScreenFor(web_contents->GetNativeView())-> | 47 gfx::Screen::GetScreenFor(web_contents->GetNativeView())-> |
47 GetPrimaryDisplay().device_scale_factor()) { | 48 GetPrimaryDisplay().device_scale_factor()) { |
48 // Send a message to the renderer to retrieve information about the page. | 49 // Send a message to the renderer to retrieve information about the page. |
49 is_waiting_for_web_application_info_ = true; | 50 is_waiting_for_web_application_info_ = true; |
50 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); | 51 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); |
51 } | 52 } |
52 | 53 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 preferred_icon_size_in_px_, | 113 preferred_icon_size_in_px_, |
113 false, | 114 false, |
114 base::Bind(&ShortcutDataFetcher::OnManifestIconFetched, | 115 base::Bind(&ShortcutDataFetcher::OnManifestIconFetched, |
115 this)); | 116 this)); |
116 } else { | 117 } else { |
117 // Grab the best favicon for the page. | 118 // Grab the best favicon for the page. |
118 FetchFavicon(); | 119 FetchFavicon(); |
119 } | 120 } |
120 | 121 |
121 weak_observer_->OnTitleAvailable(shortcut_info_.title); | 122 weak_observer_->OnTitleAvailable(shortcut_info_.title); |
123 | |
124 // Kick off a timeout for downloading the icon. If an icon isn't set within | |
125 // the timeout, fall back to using a dynamically-generated launcher icon. | |
126 icon_timeout_timer_.Start(FROM_HERE, | |
benwells
2015/05/07 04:26:12
Is there any reason why not to put this in FetchFa
gone
2015/05/07 18:35:29
AIUI we're also trying to catch slow manifest icon
| |
127 base::TimeDelta::FromMilliseconds(3000), | |
128 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, | |
129 this, | |
130 favicon_base::FaviconRawBitmapResult())); | |
122 } | 131 } |
123 | 132 |
124 bool ShortcutDataFetcher::OnMessageReceived(const IPC::Message& message) { | 133 bool ShortcutDataFetcher::OnMessageReceived(const IPC::Message& message) { |
125 if (!is_waiting_for_web_application_info_) return false; | 134 if (!is_waiting_for_web_application_info_) return false; |
126 | 135 |
127 bool handled = true; | 136 bool handled = true; |
128 | 137 |
129 IPC_BEGIN_MESSAGE_MAP(ShortcutDataFetcher, message) | 138 IPC_BEGIN_MESSAGE_MAP(ShortcutDataFetcher, message) |
130 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, | 139 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, |
131 OnDidGetWebApplicationInfo) | 140 OnDidGetWebApplicationInfo) |
(...skipping 25 matching lines...) Expand all Loading... | |
157 ServiceAccessType::EXPLICIT_ACCESS); | 166 ServiceAccessType::EXPLICIT_ACCESS); |
158 | 167 |
159 // Using favicon if its size is not smaller than platform required size, | 168 // Using favicon if its size is not smaller than platform required size, |
160 // otherwise using the largest icon among all avaliable icons. | 169 // otherwise using the largest icon among all avaliable icons. |
161 int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1; | 170 int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1; |
162 favicon_service->GetLargestRawFaviconForPageURL( | 171 favicon_service->GetLargestRawFaviconForPageURL( |
163 shortcut_info_.url, | 172 shortcut_info_.url, |
164 icon_types, | 173 icon_types, |
165 threshold_to_get_any_largest_icon, | 174 threshold_to_get_any_largest_icon, |
166 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, this), | 175 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, this), |
167 &cancelable_task_tracker_); | 176 &favicon_task_tracker_); |
168 } | 177 } |
169 | 178 |
170 void ShortcutDataFetcher::OnFaviconFetched( | 179 void ShortcutDataFetcher::OnFaviconFetched( |
benwells
2015/05/07 04:26:12
What happens if a second callback happens? E.g. th
gone
2015/05/07 18:35:29
Should be caught by the !shortcut_icon_.drawsNothi
benwells
2015/05/08 00:34:16
Ah, OK. That and the other comment makes sense, bu
gone
2015/05/08 00:44:43
Used 'is_icon_saved_'; seems more explicit that we
| |
171 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 180 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
172 if (!web_contents() || !weak_observer_) return; | 181 if (!web_contents() || !weak_observer_ || !shortcut_icon_.drawsNothing()) { |
182 return; | |
183 } | |
173 | 184 |
174 content::BrowserThread::PostTask( | 185 content::BrowserThread::PostTask( |
175 content::BrowserThread::IO, | 186 content::BrowserThread::IO, |
176 FROM_HERE, | 187 FROM_HERE, |
177 base::Bind(&ShortcutDataFetcher::CreateLauncherIcon, | 188 base::Bind(&ShortcutDataFetcher::CreateLauncherIcon, |
178 this, | 189 this, |
179 bitmap_result)); | 190 bitmap_result)); |
180 } | 191 } |
181 | 192 |
182 void ShortcutDataFetcher::CreateLauncherIcon( | 193 void ShortcutDataFetcher::CreateLauncherIcon( |
183 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 194 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
184 if (!web_contents() || !weak_observer_) return; | 195 if (!web_contents() || !weak_observer_) return; |
185 | 196 |
186 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 197 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
187 SkBitmap icon_bitmap; | 198 SkBitmap icon_bitmap; |
188 if (bitmap_result.is_valid()) { | 199 if (bitmap_result.is_valid()) { |
189 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), | 200 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), |
190 bitmap_result.bitmap_data->size(), | 201 bitmap_result.bitmap_data->size(), |
191 &icon_bitmap); | 202 &icon_bitmap); |
192 } | 203 } |
193 | 204 |
194 if (weak_observer_) { | 205 if (weak_observer_) { |
195 shortcut_icon_ = weak_observer_->FinalizeLauncherIcon(icon_bitmap, | 206 icon_bitmap = weak_observer_->FinalizeLauncherIcon(icon_bitmap, |
196 shortcut_info_.url); | 207 shortcut_info_.url); |
197 } | 208 } |
198 | 209 |
199 content::BrowserThread::PostTask( | 210 content::BrowserThread::PostTask( |
200 content::BrowserThread::UI, | 211 content::BrowserThread::UI, |
201 FROM_HERE, | 212 FROM_HERE, |
202 base::Bind(&ShortcutDataFetcher::NotifyObserver, this)); | 213 base::Bind(&ShortcutDataFetcher::NotifyObserver, this, icon_bitmap)); |
203 } | 214 } |
204 | 215 |
205 void ShortcutDataFetcher::OnManifestIconFetched( | 216 void ShortcutDataFetcher::OnManifestIconFetched( |
206 int id, | 217 int id, |
207 int http_status_code, | 218 int http_status_code, |
208 const GURL& url, | 219 const GURL& url, |
209 const std::vector<SkBitmap>& bitmaps, | 220 const std::vector<SkBitmap>& bitmaps, |
210 const std::vector<gfx::Size>& sizes) { | 221 const std::vector<gfx::Size>& sizes) { |
211 if (!web_contents() || !weak_observer_) return; | 222 if (!web_contents() || !weak_observer_) return; |
benwells
2015/05/08 00:34:16
Is there a reason why this path doesn't do the Fin
gone
2015/05/08 00:37:59
Short answer: Pretty sure it didn't do it before.
| |
212 | 223 |
213 // If getting the candidate manifest icon failed, the ShortcutHelper should | 224 // If getting the candidate manifest icon failed, the ShortcutHelper should |
214 // fallback to the favicon. | 225 // fallback to the favicon. |
215 // Otherwise, it sets the state as if there was no manifest icon pending. | 226 // Otherwise, it sets the state as if there was no manifest icon pending. |
216 if (bitmaps.empty()) { | 227 if (bitmaps.empty()) { |
217 FetchFavicon(); | 228 FetchFavicon(); |
218 return; | 229 return; |
219 } | 230 } |
220 | 231 |
221 // There might be multiple bitmaps returned. The one to pick is bigger or | 232 // There might be multiple bitmaps returned. The one to pick is bigger or |
222 // equal to the preferred size. |bitmaps| is ordered from bigger to smaller. | 233 // equal to the preferred size. |bitmaps| is ordered from bigger to smaller. |
223 int preferred_bitmap_index = 0; | 234 int preferred_bitmap_index = 0; |
224 for (size_t i = 0; i < bitmaps.size(); ++i) { | 235 for (size_t i = 0; i < bitmaps.size(); ++i) { |
225 if (bitmaps[i].height() < preferred_icon_size_in_px_) | 236 if (bitmaps[i].height() < preferred_icon_size_in_px_) |
226 break; | 237 break; |
227 preferred_bitmap_index = i; | 238 preferred_bitmap_index = i; |
228 } | 239 } |
229 | 240 |
230 shortcut_icon_ = bitmaps[preferred_bitmap_index]; | 241 NotifyObserver(bitmaps[preferred_bitmap_index]); |
231 NotifyObserver(); | |
232 } | 242 } |
233 | 243 |
234 void ShortcutDataFetcher::NotifyObserver() { | 244 void ShortcutDataFetcher::NotifyObserver(const SkBitmap& bitmap) { |
235 if (!web_contents() || !weak_observer_) return; | |
236 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 245 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
246 if (!web_contents() || !weak_observer_ || !shortcut_icon_.drawsNothing()) | |
247 return; | |
237 | 248 |
249 shortcut_icon_ = bitmap; | |
238 is_ready_ = true; | 250 is_ready_ = true; |
239 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); | 251 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); |
240 } | 252 } |
OLD | NEW |