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_
|