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 21 matching lines...) Expand all Loading... |
32 | 32 |
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_waiting_for_web_application_info_(false), |
| 43 is_icon_saved_(false), |
42 is_ready_(false), | 44 is_ready_(false), |
| 45 icon_timeout_timer_(false, false), |
43 shortcut_info_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( | 46 shortcut_info_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( |
44 web_contents->GetURL())), | 47 web_contents->GetURL())), |
45 preferred_icon_size_in_px_(kPreferredIconSizeInDp * | 48 preferred_icon_size_in_px_(kPreferredIconSizeInDp * |
46 gfx::Screen::GetScreenFor(web_contents->GetNativeView())-> | 49 gfx::Screen::GetScreenFor(web_contents->GetNativeView())-> |
47 GetPrimaryDisplay().device_scale_factor()) { | 50 GetPrimaryDisplay().device_scale_factor()) { |
48 // Send a message to the renderer to retrieve information about the page. | 51 // Send a message to the renderer to retrieve information about the page. |
49 is_waiting_for_web_application_info_ = true; | 52 is_waiting_for_web_application_info_ = true; |
50 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); | 53 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); |
51 } | 54 } |
52 | 55 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 preferred_icon_size_in_px_, | 115 preferred_icon_size_in_px_, |
113 false, | 116 false, |
114 base::Bind(&ShortcutDataFetcher::OnManifestIconFetched, | 117 base::Bind(&ShortcutDataFetcher::OnManifestIconFetched, |
115 this)); | 118 this)); |
116 } else { | 119 } else { |
117 // Grab the best favicon for the page. | 120 // Grab the best favicon for the page. |
118 FetchFavicon(); | 121 FetchFavicon(); |
119 } | 122 } |
120 | 123 |
121 weak_observer_->OnTitleAvailable(shortcut_info_.title); | 124 weak_observer_->OnTitleAvailable(shortcut_info_.title); |
| 125 |
| 126 // Kick off a timeout for downloading the icon. If an icon isn't set within |
| 127 // the timeout, fall back to using a dynamically-generated launcher icon. |
| 128 icon_timeout_timer_.Start(FROM_HERE, |
| 129 base::TimeDelta::FromMilliseconds(3000), |
| 130 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, |
| 131 this, |
| 132 favicon_base::FaviconRawBitmapResult())); |
122 } | 133 } |
123 | 134 |
124 bool ShortcutDataFetcher::OnMessageReceived(const IPC::Message& message) { | 135 bool ShortcutDataFetcher::OnMessageReceived(const IPC::Message& message) { |
125 if (!is_waiting_for_web_application_info_) return false; | 136 if (!is_waiting_for_web_application_info_) return false; |
126 | 137 |
127 bool handled = true; | 138 bool handled = true; |
128 | 139 |
129 IPC_BEGIN_MESSAGE_MAP(ShortcutDataFetcher, message) | 140 IPC_BEGIN_MESSAGE_MAP(ShortcutDataFetcher, message) |
130 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, | 141 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, |
131 OnDidGetWebApplicationInfo) | 142 OnDidGetWebApplicationInfo) |
(...skipping 25 matching lines...) Expand all Loading... |
157 ServiceAccessType::EXPLICIT_ACCESS); | 168 ServiceAccessType::EXPLICIT_ACCESS); |
158 | 169 |
159 // Using favicon if its size is not smaller than platform required size, | 170 // Using favicon if its size is not smaller than platform required size, |
160 // otherwise using the largest icon among all avaliable icons. | 171 // otherwise using the largest icon among all avaliable icons. |
161 int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1; | 172 int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1; |
162 favicon_service->GetLargestRawFaviconForPageURL( | 173 favicon_service->GetLargestRawFaviconForPageURL( |
163 shortcut_info_.url, | 174 shortcut_info_.url, |
164 icon_types, | 175 icon_types, |
165 threshold_to_get_any_largest_icon, | 176 threshold_to_get_any_largest_icon, |
166 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, this), | 177 base::Bind(&ShortcutDataFetcher::OnFaviconFetched, this), |
167 &cancelable_task_tracker_); | 178 &favicon_task_tracker_); |
168 } | 179 } |
169 | 180 |
170 void ShortcutDataFetcher::OnFaviconFetched( | 181 void ShortcutDataFetcher::OnFaviconFetched( |
171 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 182 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
172 if (!web_contents() || !weak_observer_) return; | 183 if (!web_contents() || !weak_observer_ || is_icon_saved_) { |
| 184 return; |
| 185 } |
173 | 186 |
174 content::BrowserThread::PostTask( | 187 content::BrowserThread::PostTask( |
175 content::BrowserThread::IO, | 188 content::BrowserThread::IO, |
176 FROM_HERE, | 189 FROM_HERE, |
177 base::Bind(&ShortcutDataFetcher::CreateLauncherIcon, | 190 base::Bind(&ShortcutDataFetcher::CreateLauncherIcon, |
178 this, | 191 this, |
179 bitmap_result)); | 192 bitmap_result)); |
180 } | 193 } |
181 | 194 |
182 void ShortcutDataFetcher::CreateLauncherIcon( | 195 void ShortcutDataFetcher::CreateLauncherIcon( |
183 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 196 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
184 if (!web_contents() || !weak_observer_) return; | 197 if (!web_contents() || !weak_observer_) return; |
185 | 198 |
186 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 199 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
187 SkBitmap icon_bitmap; | 200 SkBitmap icon_bitmap; |
188 if (bitmap_result.is_valid()) { | 201 if (bitmap_result.is_valid()) { |
189 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), | 202 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), |
190 bitmap_result.bitmap_data->size(), | 203 bitmap_result.bitmap_data->size(), |
191 &icon_bitmap); | 204 &icon_bitmap); |
192 } | 205 } |
193 | 206 |
194 if (weak_observer_) { | 207 if (weak_observer_) { |
195 shortcut_icon_ = weak_observer_->FinalizeLauncherIcon(icon_bitmap, | 208 icon_bitmap = weak_observer_->FinalizeLauncherIcon(icon_bitmap, |
196 shortcut_info_.url); | 209 shortcut_info_.url); |
197 } | 210 } |
198 | 211 |
199 content::BrowserThread::PostTask( | 212 content::BrowserThread::PostTask( |
200 content::BrowserThread::UI, | 213 content::BrowserThread::UI, |
201 FROM_HERE, | 214 FROM_HERE, |
202 base::Bind(&ShortcutDataFetcher::NotifyObserver, this)); | 215 base::Bind(&ShortcutDataFetcher::NotifyObserver, this, icon_bitmap)); |
203 } | 216 } |
204 | 217 |
205 void ShortcutDataFetcher::OnManifestIconFetched( | 218 void ShortcutDataFetcher::OnManifestIconFetched( |
206 int id, | 219 int id, |
207 int http_status_code, | 220 int http_status_code, |
208 const GURL& url, | 221 const GURL& url, |
209 const std::vector<SkBitmap>& bitmaps, | 222 const std::vector<SkBitmap>& bitmaps, |
210 const std::vector<gfx::Size>& sizes) { | 223 const std::vector<gfx::Size>& sizes) { |
211 if (!web_contents() || !weak_observer_) return; | 224 if (!web_contents() || !weak_observer_) return; |
212 | 225 |
213 // If getting the candidate manifest icon failed, the ShortcutHelper should | 226 // If getting the candidate manifest icon failed, the ShortcutHelper should |
214 // fallback to the favicon. | 227 // fallback to the favicon. |
215 // Otherwise, it sets the state as if there was no manifest icon pending. | 228 // Otherwise, it sets the state as if there was no manifest icon pending. |
216 if (bitmaps.empty()) { | 229 if (bitmaps.empty()) { |
217 FetchFavicon(); | 230 FetchFavicon(); |
218 return; | 231 return; |
219 } | 232 } |
220 | 233 |
221 // There might be multiple bitmaps returned. The one to pick is bigger or | 234 // 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. | 235 // equal to the preferred size. |bitmaps| is ordered from bigger to smaller. |
223 int preferred_bitmap_index = 0; | 236 int preferred_bitmap_index = 0; |
224 for (size_t i = 0; i < bitmaps.size(); ++i) { | 237 for (size_t i = 0; i < bitmaps.size(); ++i) { |
225 if (bitmaps[i].height() < preferred_icon_size_in_px_) | 238 if (bitmaps[i].height() < preferred_icon_size_in_px_) |
226 break; | 239 break; |
227 preferred_bitmap_index = i; | 240 preferred_bitmap_index = i; |
228 } | 241 } |
229 | 242 |
230 shortcut_icon_ = bitmaps[preferred_bitmap_index]; | 243 NotifyObserver(bitmaps[preferred_bitmap_index]); |
231 NotifyObserver(); | |
232 } | 244 } |
233 | 245 |
234 void ShortcutDataFetcher::NotifyObserver() { | 246 void ShortcutDataFetcher::NotifyObserver(const SkBitmap& bitmap) { |
235 if (!web_contents() || !weak_observer_) return; | |
236 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 247 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 248 if (!web_contents() || !weak_observer_ || is_icon_saved_) |
| 249 return; |
237 | 250 |
| 251 is_icon_saved_ = true; |
| 252 shortcut_icon_ = bitmap; |
238 is_ready_ = true; | 253 is_ready_ = true; |
239 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); | 254 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); |
240 } | 255 } |
OLD | NEW |