1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
6#define CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/ref_counted.h"
13#include "base/task/cancelable_task_tracker.h"
14#include "chrome/browser/favicon/favicon_service.h"
15#include "content/public/browser/url_data_source.h"
16#include "ui/gfx/favicon_size.h"
17
18class Profile;
19
20// FaviconSource is the gateway between network-level chrome:
21// requests for favicons and the history backend that serves these.
22//
23// Format:
24//   chrome://favicon/size&scalefactor/urlmodifier/url
25// Some parameters are optional as described below. However, the order of the
26// parameters is not interchangeable.
27//
28// Parameter:
29//  'url'               Required
30//    Specifies the page URL of the requested favicon. If the 'urlmodifier'
31//    parameter is 'iconurl', the URL refers to the URL of the favicon image
32//    instead.
33//  'size&scalefactor'  Optional
34//    Values: ['largest', size/aa@bx/]
35//    'largest': Specifies that the largest available favicon is requested.
36//      Example: chrome://favicon/largest/http://www.google.com/
37//    'size/aa@bx/':
38//      Specifies the requested favicon's size in DIP (aa) and the requested
39//      favicon's scale factor. (b).
40//      The supported requested DIP sizes are: 16x16, 32x32 and 64x64.
41//      If the parameter is unspecified, the requested favicon's size defaults
42//      to 16 and the requested scale factor defaults to 1x.
43//      Example: chrome://favicon/size/16@2x/http://www.google.com/
44//  'urlmodifier'      Optional
45//    Values: ['iconurl', 'origin']
46//    'iconurl': Specifies that the url parameter refers to the URL of
47//    the favicon image as opposed to the URL of the page that the favicon is
48//    on.
49//    Example: chrome://favicon/iconurl/http://www.google.com/favicon.ico
50//    'origin': Specifies that the URL should be converted to a form with
51//    an empty path and a valid scheme. The converted URL will be used to
52//    request the favicon from the favicon service.
53//    Examples:
54//      chrome://favicon/origin/http://example.com/a
55//      chrome://favicon/origin/example.com
56//        Both URLs request the favicon for http://example.com from the
57//        favicon service.
58class FaviconSource : public content::URLDataSource {
59 public:
60  // Defines the type of icon the FaviconSource will provide.
61  enum IconType {
62    FAVICON,
63    // Any available icon in the priority of TOUCH_ICON_PRECOMPOSED, TOUCH_ICON,
64    // FAVICON, and default favicon.
65    ANY
66  };
67
68  // |type| is the type of icon this FaviconSource will provide.
69  FaviconSource(Profile* profile, IconType type);
70
71  virtual ~FaviconSource();
72
73  // content::URLDataSource implementation.
74  virtual std::string GetSource() const OVERRIDE;
75  virtual void StartDataRequest(
76      const std::string& path,
77      int render_process_id,
78      int render_frame_id,
79      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
80  virtual std::string GetMimeType(const std::string&) const OVERRIDE;
81  virtual bool ShouldReplaceExistingSource() const OVERRIDE;
82  virtual bool ShouldServiceRequest(
83      const net::URLRequest* request) const OVERRIDE;
84
85 protected:
86  struct IconRequest {
87    IconRequest();
88    IconRequest(const content::URLDataSource::GotDataCallback& cb,
89                const GURL& path,
90                int size,
91                float scale);
92    ~IconRequest();
93
94    content::URLDataSource::GotDataCallback callback;
95    GURL request_path;
96    int size_in_dip;
97    float device_scale_factor;
98  };
99
100  // Called when the favicon data is missing to perform additional checks to
101  // locate the resource.
102  // |request| contains information for the failed request.
103  // Returns true if the missing resource is found.
104  virtual bool HandleMissingResource(const IconRequest& request);
105
106  Profile* profile_;
107
108 private:
109  FRIEND_TEST_ALL_PREFIXES(FaviconSourceTest, InstantParsing);
110  FRIEND_TEST_ALL_PREFIXES(FaviconSourceTest, Parsing);
111
112  // Defines the allowed pixel sizes for requested favicons.
113  enum IconSize {
114    SIZE_16,
115    SIZE_32,
116    SIZE_64,
117    NUM_SIZES
118  };
119
120  // Called when favicon data is available from the history backend.
121  void OnFaviconDataAvailable(
122      const IconRequest& request,
123      const favicon_base::FaviconRawBitmapResult& bitmap_result);
124
125  // Sends the 16x16 DIP 1x default favicon.
126  void SendDefaultResponse(
127      const content::URLDataSource::GotDataCallback& callback);
128
129  // Sends the default favicon.
130  void SendDefaultResponse(const IconRequest& request);
131
132  base::CancelableTaskTracker cancelable_task_tracker_;
133
134  // Raw PNG representations of favicons of each size to show when the favicon
135  // database doesn't have a favicon for a webpage. Indexed by IconSize values.
136  scoped_refptr<base::RefCountedMemory> default_favicons_[NUM_SIZES];
137
138  // The favicon_base::IconTypes of icon that this FaviconSource handles.
139  int icon_types_;
140
141  DISALLOW_COPY_AND_ASSIGN(FaviconSource);
142};
143
144#endif  // CHROME_BROWSER_UI_WEBUI_FAVICON_SOURCE_H_
145