| 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/webapps/add_to_homescreen_data_fetcher.h" | 5 #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 } | 66 } |
| 67 | 67 |
| 68 } // namespace | 68 } // namespace |
| 69 | 69 |
| 70 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( | 70 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( |
| 71 content::WebContents* web_contents, | 71 content::WebContents* web_contents, |
| 72 int ideal_icon_size_in_dp, | 72 int ideal_icon_size_in_dp, |
| 73 int minimum_icon_size_in_dp, | 73 int minimum_icon_size_in_dp, |
| 74 int ideal_splash_image_size_in_dp, | 74 int ideal_splash_image_size_in_dp, |
| 75 int minimum_splash_image_size_in_dp, | 75 int minimum_splash_image_size_in_dp, |
| 76 bool check_installable, | 76 bool check_webapk_compatibility, |
| 77 Observer* observer) | 77 Observer* observer) |
| 78 : WebContentsObserver(web_contents), | 78 : WebContentsObserver(web_contents), |
| 79 weak_observer_(observer), | 79 weak_observer_(observer), |
| 80 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), | 80 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), |
| 81 web_contents->GetLastCommittedURL())), | 81 web_contents->GetLastCommittedURL())), |
| 82 data_timeout_timer_(false, false), | 82 data_timeout_timer_(false, false), |
| 83 ideal_icon_size_in_dp_(ideal_icon_size_in_dp), | 83 ideal_icon_size_in_dp_(ideal_icon_size_in_dp), |
| 84 minimum_icon_size_in_dp_(minimum_icon_size_in_dp), | 84 minimum_icon_size_in_dp_(minimum_icon_size_in_dp), |
| 85 ideal_splash_image_size_in_dp_(ideal_splash_image_size_in_dp), | 85 ideal_splash_image_size_in_dp_(ideal_splash_image_size_in_dp), |
| 86 minimum_splash_image_size_in_dp_(minimum_splash_image_size_in_dp), | 86 minimum_splash_image_size_in_dp_(minimum_splash_image_size_in_dp), |
| 87 check_installable_(check_installable), | 87 check_webapk_compatibility_(check_webapk_compatibility), |
| 88 is_waiting_for_installable_check_(check_installable), | |
| 89 is_waiting_for_web_application_info_(true), | 88 is_waiting_for_web_application_info_(true), |
| 89 is_installable_check_complete_(false), |
| 90 is_icon_saved_(false), | 90 is_icon_saved_(false), |
| 91 is_ready_(false) { | 91 is_ready_(false) { |
| 92 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); | 92 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); |
| 93 DCHECK(minimum_splash_image_size_in_dp <= ideal_splash_image_size_in_dp); | 93 DCHECK(minimum_splash_image_size_in_dp <= ideal_splash_image_size_in_dp); |
| 94 | 94 |
| 95 // Send a message to the renderer to retrieve information about the page. | 95 // Send a message to the renderer to retrieve information about the page. |
| 96 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); | 96 Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); |
| 97 } | 97 } |
| 98 | 98 |
| 99 base::Closure AddToHomescreenDataFetcher::FetchSplashScreenImageCallback( | 99 base::Closure AddToHomescreenDataFetcher::FetchSplashScreenImageCallback( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 146 |
| 147 InstallableManager::CreateForWebContents(web_contents()); | 147 InstallableManager::CreateForWebContents(web_contents()); |
| 148 InstallableManager* manager = | 148 InstallableManager* manager = |
| 149 InstallableManager::FromWebContents(web_contents()); | 149 InstallableManager::FromWebContents(web_contents()); |
| 150 DCHECK(manager); | 150 DCHECK(manager); |
| 151 | 151 |
| 152 // Kick off a timeout for downloading data. If we haven't finished within the | 152 // Kick off a timeout for downloading data. If we haven't finished within the |
| 153 // timeout, fall back to using a dynamically-generated launcher icon. | 153 // timeout, fall back to using a dynamically-generated launcher icon. |
| 154 data_timeout_timer_.Start( | 154 data_timeout_timer_.Start( |
| 155 FROM_HERE, base::TimeDelta::FromMilliseconds(4000), | 155 FROM_HERE, base::TimeDelta::FromMilliseconds(4000), |
| 156 base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this, | 156 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this)); |
| 157 favicon_base::FaviconRawBitmapResult())); | |
| 158 | 157 |
| 159 manager->GetData( | 158 manager->GetData( |
| 160 ParamsToPerformInstallableCheck(ideal_icon_size_in_dp_, | 159 ParamsToPerformInstallableCheck(ideal_icon_size_in_dp_, |
| 161 minimum_icon_size_in_dp_, | 160 minimum_icon_size_in_dp_, |
| 162 check_installable_), | 161 check_webapk_compatibility_), |
| 163 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, | 162 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, |
| 164 this)); | 163 this)); |
| 165 } | 164 } |
| 166 | 165 |
| 167 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() { | 166 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() { |
| 168 DCHECK(!weak_observer_); | 167 DCHECK(!weak_observer_); |
| 169 } | 168 } |
| 170 | 169 |
| 171 bool AddToHomescreenDataFetcher::OnMessageReceived( | 170 bool AddToHomescreenDataFetcher::OnMessageReceived( |
| 172 const IPC::Message& message) { | 171 const IPC::Message& message) { |
| 173 if (!is_waiting_for_web_application_info_) | 172 if (!is_waiting_for_web_application_info_) |
| 174 return false; | 173 return false; |
| 175 | 174 |
| 176 bool handled = true; | 175 bool handled = true; |
| 177 | 176 |
| 178 IPC_BEGIN_MESSAGE_MAP(AddToHomescreenDataFetcher, message) | 177 IPC_BEGIN_MESSAGE_MAP(AddToHomescreenDataFetcher, message) |
| 179 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, | 178 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidGetWebApplicationInfo, |
| 180 OnDidGetWebApplicationInfo) | 179 OnDidGetWebApplicationInfo) |
| 181 IPC_MESSAGE_UNHANDLED(handled = false) | 180 IPC_MESSAGE_UNHANDLED(handled = false) |
| 182 IPC_END_MESSAGE_MAP() | 181 IPC_END_MESSAGE_MAP() |
| 183 | 182 |
| 184 return handled; | 183 return handled; |
| 185 } | 184 } |
| 186 | 185 |
| 186 void AddToHomescreenDataFetcher::OnDataTimedout() { |
| 187 if (!web_contents() || !weak_observer_) |
| 188 return; |
| 189 |
| 190 if (!is_installable_check_complete_) { |
| 191 is_installable_check_complete_ = true; |
| 192 if (check_webapk_compatibility_) |
| 193 weak_observer_->OnDidDetermineWebApkCompatibility(false); |
| 194 weak_observer_->OnUserTitleAvailable(base::string16()); |
| 195 } |
| 196 |
| 197 if (!is_icon_saved_) |
| 198 CreateLauncherIcon(SkBitmap()); |
| 199 } |
| 187 | 200 |
| 188 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( | 201 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( |
| 189 const InstallableData& data) { | 202 const InstallableData& data) { |
| 190 if (!web_contents() || !weak_observer_) | 203 if (!web_contents() || !weak_observer_) |
| 191 return; | 204 return; |
| 192 | 205 |
| 193 if (check_installable_) { | 206 is_installable_check_complete_ = true; |
| 194 is_waiting_for_installable_check_ = false; | 207 |
| 208 if (check_webapk_compatibility_) |
| 195 weak_observer_->OnDidDetermineWebApkCompatibility(data.is_installable); | 209 weak_observer_->OnDidDetermineWebApkCompatibility(data.is_installable); |
| 196 } | |
| 197 | 210 |
| 198 if (!data.manifest.IsEmpty()) { | 211 if (!data.manifest.IsEmpty()) { |
| 199 content::RecordAction( | 212 content::RecordAction( |
| 200 base::UserMetricsAction("webapps.AddShortcut.Manifest")); | 213 base::UserMetricsAction("webapps.AddShortcut.Manifest")); |
| 201 shortcut_info_.UpdateFromManifest(data.manifest); | 214 shortcut_info_.UpdateFromManifest(data.manifest); |
| 202 shortcut_info_.manifest_url = data.manifest_url; | 215 shortcut_info_.manifest_url = data.manifest_url; |
| 203 } | 216 } |
| 204 | 217 |
| 205 // Save the splash screen URL for the later download. | 218 // Save the splash screen URL for the later download. |
| 206 splash_screen_url_ = ManifestIconSelector::FindBestMatchingIcon( | 219 splash_screen_url_ = ManifestIconSelector::FindBestMatchingIcon( |
| 207 data.manifest.icons, ideal_splash_image_size_in_dp_, | 220 data.manifest.icons, ideal_splash_image_size_in_dp_, |
| 208 minimum_splash_image_size_in_dp_); | 221 minimum_splash_image_size_in_dp_); |
| 209 | 222 |
| 210 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); | 223 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); |
| 211 | 224 |
| 212 if (data.icon) { | 225 if (data.icon) { |
| 213 shortcut_info_.icon_url = data.icon_url; | 226 shortcut_info_.icon_url = data.icon_url; |
| 214 | 227 |
| 215 // base::Bind copies the arguments internally, so it is safe to pass it | 228 CreateLauncherIcon(*(data.icon)); |
| 216 // data.icon (which is not owned by us). | |
| 217 content::BrowserThread::GetBlockingPool() | |
| 218 ->PostWorkerTaskWithShutdownBehavior( | |
| 219 FROM_HERE, | |
| 220 base::Bind( | |
| 221 &AddToHomescreenDataFetcher::CreateLauncherIconInBackground, | |
| 222 this, *(data.icon)), | |
| 223 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | |
| 224 return; | 229 return; |
| 225 } | 230 } |
| 226 | 231 |
| 227 FetchFavicon(); | 232 FetchFavicon(); |
| 228 } | 233 } |
| 229 | 234 |
| 230 void AddToHomescreenDataFetcher::FetchFavicon() { | 235 void AddToHomescreenDataFetcher::FetchFavicon() { |
| 231 if (!web_contents() || !weak_observer_) | 236 if (!web_contents() || !weak_observer_) |
| 232 return; | 237 return; |
| 233 | 238 |
| 234 if (check_installable_ && is_waiting_for_installable_check_) { | |
| 235 is_waiting_for_installable_check_ = false; | |
| 236 weak_observer_->OnDidDetermineWebApkCompatibility(false); | |
| 237 } | |
| 238 | |
| 239 // Grab the best, largest icon we can find to represent this bookmark. | 239 // Grab the best, largest icon we can find to represent this bookmark. |
| 240 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its | 240 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its |
| 241 // rewrite is further along. | 241 // rewrite is further along. |
| 242 std::vector<int> icon_types{ | 242 std::vector<int> icon_types{ |
| 243 favicon_base::FAVICON, | 243 favicon_base::FAVICON, |
| 244 favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON}; | 244 favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON}; |
| 245 | 245 |
| 246 favicon::FaviconService* favicon_service = | 246 favicon::FaviconService* favicon_service = |
| 247 FaviconServiceFactory::GetForProfile( | 247 FaviconServiceFactory::GetForProfile( |
| 248 Profile::FromBrowserContext(web_contents()->GetBrowserContext()), | 248 Profile::FromBrowserContext(web_contents()->GetBrowserContext()), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 279 SkBitmap raw_icon; | 279 SkBitmap raw_icon; |
| 280 if (bitmap_result.is_valid()) { | 280 if (bitmap_result.is_valid()) { |
| 281 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), | 281 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), |
| 282 bitmap_result.bitmap_data->size(), &raw_icon); | 282 bitmap_result.bitmap_data->size(), &raw_icon); |
| 283 } | 283 } |
| 284 | 284 |
| 285 shortcut_info_.icon_url = bitmap_result.icon_url; | 285 shortcut_info_.icon_url = bitmap_result.icon_url; |
| 286 CreateLauncherIconInBackground(raw_icon); | 286 CreateLauncherIconInBackground(raw_icon); |
| 287 } | 287 } |
| 288 | 288 |
| 289 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& raw_icon) { |
| 290 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 291 content::BrowserThread::GetBlockingPool() |
| 292 ->PostWorkerTaskWithShutdownBehavior( |
| 293 FROM_HERE, |
| 294 base::Bind( |
| 295 &AddToHomescreenDataFetcher::CreateLauncherIconInBackground, |
| 296 this, raw_icon), |
| 297 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 298 } |
| 299 |
| 289 void AddToHomescreenDataFetcher::CreateLauncherIconInBackground( | 300 void AddToHomescreenDataFetcher::CreateLauncherIconInBackground( |
| 290 const SkBitmap& raw_icon) { | 301 const SkBitmap& raw_icon) { |
| 291 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 302 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 292 | 303 |
| 293 SkBitmap icon; | 304 SkBitmap icon; |
| 294 bool is_generated = false; | 305 bool is_generated = false; |
| 295 if (weak_observer_) { | 306 if (weak_observer_) { |
| 296 icon = weak_observer_->FinalizeLauncherIconInBackground( | 307 icon = weak_observer_->FinalizeLauncherIconInBackground( |
| 297 raw_icon, shortcut_info_.url, &is_generated); | 308 raw_icon, shortcut_info_.url, &is_generated); |
| 298 } | 309 } |
| 299 | 310 |
| 300 if (is_generated) | 311 if (is_generated) |
| 301 shortcut_info_.icon_url = GURL(); | 312 shortcut_info_.icon_url = GURL(); |
| 302 | 313 |
| 303 content::BrowserThread::PostTask( | 314 content::BrowserThread::PostTask( |
| 304 content::BrowserThread::UI, FROM_HERE, | 315 content::BrowserThread::UI, FROM_HERE, |
| 305 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, this, icon)); | 316 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, this, icon)); |
| 306 } | 317 } |
| 307 | 318 |
| 308 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& icon) { | 319 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& icon) { |
| 309 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 320 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 310 if (!web_contents() || !weak_observer_ || is_icon_saved_) | 321 if (!web_contents() || !weak_observer_ || is_icon_saved_) |
| 311 return; | 322 return; |
| 312 | 323 |
| 313 is_icon_saved_ = true; | 324 is_icon_saved_ = true; |
| 314 shortcut_icon_ = icon; | 325 shortcut_icon_ = icon; |
| 315 is_ready_ = true; | 326 is_ready_ = true; |
| 316 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); | 327 weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); |
| 317 } | 328 } |
| OLD | NEW |