| Index: chrome/browser/web_app.cc
|
| ===================================================================
|
| --- chrome/browser/web_app.cc (revision 9030)
|
| +++ chrome/browser/web_app.cc (working copy)
|
| @@ -1,281 +0,0 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/web_app.h"
|
| -
|
| -#include "base/gfx/png_decoder.h"
|
| -#include "chrome/browser/profile.h"
|
| -#include "chrome/browser/renderer_host/render_view_host.h"
|
| -#include "chrome/browser/tab_contents/web_contents.h"
|
| -#include "chrome/common/gfx/favicon_size.h"
|
| -#include "net/base/base64.h"
|
| -#include "net/base/data_url.h"
|
| -
|
| -namespace {
|
| -
|
| -static const char kPNGImageMimeType[] = "image/png";
|
| -
|
| -static std::set<GURL> ExtractImageURLs(const GearsShortcutData& data) {
|
| - std::set<GURL> image_urls;
|
| - for (size_t i = 0; i < arraysize(data.icons); ++i) {
|
| - if (data.icons[i].url) {
|
| - GURL image_url(data.icons[i].url);
|
| - if (image_url.is_valid())
|
| - image_urls.insert(image_url);
|
| - else
|
| - NOTREACHED();
|
| - }
|
| - }
|
| - return image_urls;
|
| -}
|
| -
|
| -static SkBitmap DecodePNGEncodedURL(const GURL& url) {
|
| - std::string mime_type, charset, data;
|
| - if (!url.SchemeIs("data") ||
|
| - !net::DataURL::Parse(url, &mime_type, &charset, &data) ||
|
| - mime_type != kPNGImageMimeType) {
|
| - return SkBitmap();
|
| - }
|
| -
|
| - SkBitmap image;
|
| - std::vector<unsigned char> v_data;
|
| - v_data.resize(data.size(), 0);
|
| - memcpy(&v_data.front(), data.c_str(), data.size());
|
| - PNGDecoder::Decode(&v_data, &image);
|
| - return image;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// WebApp ----------------------------------------------------------------------
|
| -
|
| -WebApp::WebApp(Profile* profile,
|
| - const GURL& url,
|
| - const std::wstring& name)
|
| - : web_contents_(NULL),
|
| - profile_(profile),
|
| - url_(url),
|
| - name_(name),
|
| - loaded_images_from_web_data_(false),
|
| - image_load_handle_(0),
|
| - download_images_(false) {
|
| -}
|
| -
|
| -WebApp::WebApp(Profile* profile,
|
| - const GearsShortcutData& shortcut)
|
| - : web_contents_(NULL),
|
| - profile_(profile),
|
| - url_(shortcut.url),
|
| - name_(shortcut.name ? UTF8ToWide(shortcut.name) : std::wstring()),
|
| - loaded_images_from_web_data_(false),
|
| - image_load_handle_(0),
|
| - image_urls_(ExtractImageURLs(shortcut)),
|
| - download_images_(!image_urls_.empty()) {
|
| - ExtractPNGEncodedURLs();
|
| - // If the image urls are all data encoded urls and at least one is favicon
|
| - // sized, then no need to load/store in web data.
|
| - loaded_images_from_web_data_ = (GetFavIconIterator() != images_.end() &&
|
| - image_urls_.empty());
|
| -}
|
| -
|
| -WebApp::~WebApp() {
|
| - if (image_load_handle_) {
|
| - WebDataService* service =
|
| - profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
|
| - if (service)
|
| - service->CancelRequest(image_load_handle_);
|
| - }
|
| -}
|
| -
|
| -void WebApp::SetImage(const GURL& image_url, const SkBitmap& image) {
|
| - std::set<GURL>::iterator i = image_urls_.find(image_url);
|
| - if (i == image_urls_.end())
|
| - return; // We didn't request the url.
|
| -
|
| - if (image.width() == 0 || image.height() == 0) {
|
| - // Assume there was an error downloading. By ignoring this we ensure we
|
| - // attempt to download the image next time user launches the app.
|
| - return;
|
| - }
|
| -
|
| - image_urls_.erase(i);
|
| -
|
| - WebDataService* service =
|
| - profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
|
| -
|
| - if (!image.isNull()) {
|
| - if (image.width() == kFavIconSize && image.height() == kFavIconSize) {
|
| - Images::iterator fav_icon_i = GetFavIconIterator();
|
| - if (fav_icon_i != images_.end())
|
| - images_.erase(fav_icon_i); // Only allow one favicon.
|
| - }
|
| - images_.push_back(image);
|
| - NotifyObservers();
|
| - if (service)
|
| - service->SetWebAppImage(url_, image);
|
| - }
|
| -
|
| - if (service && image_urls_.empty())
|
| - service->SetWebAppHasAllImages(url_, true);
|
| -}
|
| -
|
| -const WebApp::Images& WebApp::GetImages() {
|
| - LoadImagesFromWebData();
|
| -
|
| - return images_;
|
| -}
|
| -
|
| -SkBitmap WebApp::GetFavIcon() {
|
| - // Force a load.
|
| - GetImages();
|
| -
|
| - Images::iterator fav_icon_i = GetFavIconIterator();
|
| - return (fav_icon_i == images_.end()) ? SkBitmap() : *fav_icon_i;
|
| -}
|
| -
|
| -void WebApp::SetWebContents(WebContents* host) {
|
| - web_contents_ = host;
|
| -
|
| - if (host && loaded_images_from_web_data_ && image_load_handle_ == 0 &&
|
| - !image_urls_.empty()) {
|
| - // We haven't downloaded all the images and got a new WebContents. Download
|
| - // the images from it.
|
| - DownloadImagesFromSite();
|
| - }
|
| -}
|
| -
|
| -void WebApp::AddObserver(Observer* obs) {
|
| - observer_list_.AddObserver(obs);
|
| -}
|
| -
|
| -void WebApp::RemoveObserver(Observer* obs) {
|
| - observer_list_.RemoveObserver(obs);
|
| -}
|
| -
|
| -void WebApp::LoadImagesFromWebData() {
|
| - if (loaded_images_from_web_data_)
|
| - return;
|
| -
|
| - loaded_images_from_web_data_ = true;
|
| - WebDataService* service =
|
| - profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
|
| - if (service)
|
| - image_load_handle_ = service->GetWebAppImages(url_, this);
|
| -}
|
| -
|
| -void WebApp::OnWebDataServiceRequestDone(WebDataService::Handle h,
|
| - const WDTypedResult* r) {
|
| - image_load_handle_ = 0;
|
| -
|
| - if (!r) {
|
| - // Results are null if the database went away.
|
| - return;
|
| - }
|
| -
|
| - WDAppImagesResult result = reinterpret_cast<
|
| - const WDResult<WDAppImagesResult>*>(r)->GetValue();
|
| - images_.insert(images_.end(), result.images.begin(), result.images.end());
|
| -
|
| - if (!result.has_all_images) {
|
| - // Not all of the images for the app have been downloaded yet; download them
|
| - // now.
|
| - DownloadImagesFromSite();
|
| - } else {
|
| - // We have all the images. Clear image_urls_ to indicate we've got all the
|
| - // images.
|
| - image_urls_.clear();
|
| - }
|
| -
|
| - if (GetFavIconIterator() == images_.end()) {
|
| - // No favicon. Request one from the history db.
|
| - LoadFavIconFromHistory();
|
| - }
|
| -
|
| - if (!images_.empty())
|
| - NotifyObservers();
|
| -}
|
| -
|
| -void WebApp::OnFavIconFromHistory(HistoryService::Handle handle,
|
| - bool know_favicon,
|
| - scoped_refptr<RefCountedBytes> data,
|
| - bool expired,
|
| - GURL icon_url) {
|
| - // Make sure we still don't have a favicon.
|
| - if (GetFavIconIterator() != images_.end() || !data || data->data.empty())
|
| - return;
|
| -
|
| - SkBitmap fav_icon;
|
| - if (PNGDecoder::Decode(&data->data, &fav_icon)) {
|
| - images_.push_back(fav_icon);
|
| - NotifyObservers();
|
| - }
|
| -}
|
| -
|
| -void WebApp::LoadFavIconFromHistory() {
|
| - HistoryService* service =
|
| - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
|
| - if (!service)
|
| - return;
|
| -
|
| - service->GetFavIconForURL(url_, &request_consumer_,
|
| - NewCallback(this, &WebApp::OnFavIconFromHistory));
|
| -}
|
| -
|
| -void WebApp::DownloadImagesFromSite() {
|
| - if (!download_images_)
|
| - return;
|
| -
|
| - RenderViewHost* rvh =
|
| - web_contents_ ? web_contents_->render_view_host() : NULL;
|
| - if (!rvh)
|
| - return;
|
| -
|
| - // Copy off the images to load as we may need to mutate image_urls_ while
|
| - // iterating.
|
| - std::set<GURL> image_urls = image_urls_;
|
| - for (std::set<GURL>::iterator i = image_urls.begin(); i != image_urls.end();
|
| - ++i) {
|
| - const GURL image_url = *i;
|
| - SkBitmap data_image = DecodePNGEncodedURL(image_url);
|
| - if (!data_image.isNull())
|
| - SetImage(image_url, data_image);
|
| - else if (rvh)
|
| - rvh->DownloadImage(image_url, 0); // Download the image via the renderer.
|
| - }
|
| -
|
| - if (image_urls_.empty()) {
|
| - // We got all the images immediately, notifiy the web db.
|
| - WebDataService* service =
|
| - profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
|
| - if (service)
|
| - service->SetWebAppHasAllImages(url_, true);
|
| - }
|
| -}
|
| -
|
| -WebApp::Images::iterator WebApp::GetFavIconIterator() {
|
| - for (Images::iterator i = images_.begin(); i != images_.end(); ++i) {
|
| - if (i->width() == kFavIconSize && i->height() == kFavIconSize)
|
| - return i;
|
| - }
|
| - return images_.end();
|
| -}
|
| -
|
| -void WebApp::ExtractPNGEncodedURLs() {
|
| - for (std::set<GURL>::iterator i = image_urls_.begin();
|
| - i != image_urls_.end();) {
|
| - const GURL image_url = *i;
|
| - SkBitmap data_image = DecodePNGEncodedURL(image_url);
|
| - if (!data_image.isNull()) {
|
| - i = image_urls_.erase(i);
|
| - images_.push_back(data_image);
|
| - } else {
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WebApp::NotifyObservers() {
|
| - FOR_EACH_OBSERVER(Observer, observer_list_, WebAppImagesChanged(this));
|
| -}
|
| -
|
|
|