File: sanitized_image_source.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (156 lines) | stat: -rw-r--r-- 6,078 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_WEBUI_SANITIZED_IMAGE_SOURCE_H_
#define CHROME_BROWSER_UI_WEBUI_SANITIZED_IMAGE_SOURCE_H_

#include <memory>

#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "components/signin/public/identity_manager/access_token_info.h"
#include "content/public/browser/url_data_source.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/data_decoder/public/cpp/decode_image.h"
#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
#include "url/gurl.h"

class Profile;
class SkBitmap;

namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}  // namespace network

namespace signin {
class IdentityManager;
}  // namespace signin

// The sanitized image source provides a convenient mean to embed images into
// WebUIs. For security reasons WebUIs are not allowed to download and decode
// external images in their renderer process. The sanitized image source allows
// external images in WebUIs by downloading the image in the browser process,
// decoding the image in an isolated utility process, re-encoding the image and
// sending the now sanitized image back to the requesting WebUI. You can reach
// the image source in the following ways:
//
//   chrome://image?<external image URL>
//   chrome://image?url=<external image URL>
//
// If `static-encode` attribute is set, the image will be re-encoded as a static
// PNG, or a static WebP image depending on if `encode-type` attribute is set to
// `webp`. You can use these attributes in the following ways:
//
//   chrome://image?url=<external image URL>&staticEncode=true
//   chrome://image?url=<external image URL>&encodeType=webp
//   chrome://image?url=<external image URL>&staticEncode=true&encodeType=webp
//
// If the image source points to Google Photos storage, meaning it needs an auth
// token, you can use the `is-google-photos` attribute in the following way:
//
//   chrome://image?url=<external image URL>&isGooglePhotos=true
//
// [CrOS only]: If the source is an animated image, it will be re-encoded as an
// animated WebP image; otherwise it will be re-encoded as a static image as
// though `static-encode` attribute had been set.
class SanitizedImageSource : public content::URLDataSource {
 public:
  using DecodeImageCallback = data_decoder::DecodeImageCallback;
  using DecodeAnimationCallback =
      data_decoder::mojom::ImageDecoder::DecodeAnimationCallback;

  // A delegate class that is faked out for testing purposes.
  class DataDecoderDelegate {
   public:
    DataDecoderDelegate() = default;
    virtual ~DataDecoderDelegate() = default;

    virtual void DecodeImage(const std::string& data,
                             DecodeImageCallback callback);

    virtual void DecodeAnimation(const std::string& data,
                                 DecodeAnimationCallback callback);

   private:
    // The instance of the Data Decoder used by this DataDecoderDelegate to
    // perform any image decoding operations. The underlying service instance is
    // started lazily when needed and torn down when not in use.
    data_decoder::DataDecoder data_decoder_;
  };

  explicit SanitizedImageSource(Profile* profile);
  // This constructor lets us pass mock dependencies for testing.
  SanitizedImageSource(
      Profile* profile,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      std::unique_ptr<DataDecoderDelegate> delegate);
  SanitizedImageSource(const SanitizedImageSource&) = delete;
  SanitizedImageSource& operator=(const SanitizedImageSource&) = delete;
  ~SanitizedImageSource() override;

  // content::URLDataSource:
  std::string GetSource() override;
  void StartDataRequest(
      const GURL& url,
      const content::WebContents::Getter& wc_getter,
      content::URLDataSource::GotDataCallback callback) override;
  std::string GetMimeType(const GURL& url) override;
  bool ShouldReplaceExistingSource() override;

  void set_identity_manager_for_test(
      signin::IdentityManager* identity_manager) {
    identity_manager_ = identity_manager;
  }

 private:
  struct RequestAttributes {
    enum EncodeType {
      kPng = 0,
      kWebP = 1,
    };

    RequestAttributes();
    RequestAttributes(const RequestAttributes&);
    ~RequestAttributes();

    GURL image_url = GURL();
    bool static_encode = false;
    EncodeType encode_type = EncodeType::kPng;
    std::optional<signin::AccessTokenInfo> access_token_info;
  };

  void StartImageDownload(RequestAttributes request_attributes,
                          content::URLDataSource::GotDataCallback callback);
  void OnImageLoaded(std::unique_ptr<network::SimpleURLLoader> loader,
                     RequestAttributes request_attributes,
                     content::URLDataSource::GotDataCallback callback,
                     std::unique_ptr<std::string> body);
  void OnAnimationDecoded(
      RequestAttributes request_attributes,
      content::URLDataSource::GotDataCallback callback,
      std::vector<data_decoder::mojom::AnimationFramePtr> mojo_frames);

  void EncodeAndReplyStaticImage(
      RequestAttributes request_attributes,
      content::URLDataSource::GotDataCallback callback,
      const SkBitmap& bitmap);
  void EncodeAndReplyAnimatedImage(
      content::URLDataSource::GotDataCallback callback,
      std::vector<data_decoder::mojom::AnimationFramePtr> mojo_frames);

  // Owned by `IdentityManagerFactory` or `IdentityTestEnvironment`.
  raw_ptr<signin::IdentityManager, DanglingUntriaged> identity_manager_;

  const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;

  std::unique_ptr<DataDecoderDelegate> data_decoder_delegate_;

  SEQUENCE_CHECKER(sequence_checker_);
  base::WeakPtrFactory<SanitizedImageSource> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_WEBUI_SANITIZED_IMAGE_SOURCE_H_