15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/url_data_source.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/favicon_size.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FaviconSource is the gateway between network-level chrome:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests for favicons and the history backend that serves these.
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Format:
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   chrome://favicon/size&scalefactor/urlmodifier/url
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Some parameters are optional as described below. However, the order of the
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parameters is not interchangeable.
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parameter:
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  'url'               Required
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Specifies the page URL of the requested favicon. If the 'urlmodifier'
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    parameter is 'iconurl', the URL refers to the URL of the favicon image
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    instead.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  'size&scalefactor'  Optional
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Values: ['largest', size/aa@bx/]
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    'largest': Specifies that the largest available favicon is requested.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      Example: chrome://favicon/largest/http://www.google.com/
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    'size/aa@bx/':
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      Specifies the requested favicon's size in DIP (aa) and the requested
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      favicon's scale factor. (b).
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      The supported requested DIP sizes are: 16x16, 32x32 and 64x64.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      If the parameter is unspecified, the requested favicon's size defaults
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      to 16 and the requested scale factor defaults to 1x.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      Example: chrome://favicon/size/16@2x/http://www.google.com/
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  'urlmodifier'      Optional
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Values: ['iconurl', 'origin']
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    'iconurl': Specifies that the url parameter refers to the URL of
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    the favicon image as opposed to the URL of the page that the favicon is
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    on.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Example: chrome://favicon/iconurl/http://www.google.com/favicon.ico
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    'origin': Specifies that the URL should be converted to a form with
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    an empty path and a valid scheme. The converted URL will be used to
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    request the favicon from the favicon service.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    Examples:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      chrome://favicon/origin/http://example.com/a
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//      chrome://favicon/origin/example.com
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        Both URLs request the favicon for http://example.com from the
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        favicon service.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FaviconSource : public content::URLDataSource {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Defines the type of icon the FaviconSource will provide.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum IconType {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FAVICON,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Any available icon in the priority of TOUCH_ICON_PRECOMPOSED, TOUCH_ICON,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // FAVICON, and default favicon.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ANY
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |type| is the type of icon this FaviconSource will provide.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconSource(Profile* profile, IconType type);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~FaviconSource();
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::URLDataSource implementation.
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::string GetSource() const OVERRIDE;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StartDataRequest(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& path,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int render_process_id,
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int render_frame_id,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetMimeType(const std::string&) const OVERRIDE;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldReplaceExistingSource() const OVERRIDE;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldServiceRequest(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const net::URLRequest* request) const OVERRIDE;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct IconRequest {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IconRequest();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IconRequest(const content::URLDataSource::GotDataCallback& cb,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                const GURL& path,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                int size,
916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                float scale);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~IconRequest();
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::URLDataSource::GotDataCallback callback;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GURL request_path;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int size_in_dip;
976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    float device_scale_factor;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when the favicon data is missing to perform additional checks to
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // locate the resource.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |request| contains information for the failed request.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the missing resource is found.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool HandleMissingResource(const IconRequest& request);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(FaviconSourceTest, InstantParsing);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(FaviconSourceTest, Parsing);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Defines the allowed pixel sizes for requested favicons.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum IconSize {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SIZE_16,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SIZE_32,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SIZE_64,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_SIZES
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when favicon data is available from the history backend.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnFaviconDataAvailable(
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const IconRequest& request,
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const favicon_base::FaviconRawBitmapResult& bitmap_result);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sends the 16x16 DIP 1x default favicon.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendDefaultResponse(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::URLDataSource::GotDataCallback& callback);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sends the default favicon.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendDefaultResponse(const IconRequest& request);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::CancelableTaskTracker cancelable_task_tracker_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Raw PNG representations of favicons of each size to show when the favicon
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database doesn't have a favicon for a webpage. Indexed by IconSize values.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedMemory> default_favicons_[NUM_SIZES];
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The favicon_base::IconTypes of icon that this FaviconSource handles.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int icon_types_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FaviconSource);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
145