| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_IMAGE_FETCHER_CORE_IMAGE_FETCHER_H_ |
| #define COMPONENTS_IMAGE_FETCHER_CORE_IMAGE_FETCHER_H_ |
| |
| #include <optional> |
| #include <string> |
| #include <utility> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/time/time.h" |
| #include "components/image_fetcher/core/image_fetcher_types.h" |
| #include "net/traffic_annotation/network_traffic_annotation.h" |
| #include "ui/gfx/geometry/size.h" |
| #include "url/gurl.h" |
| |
| namespace data_decoder { |
| class DataDecoder; |
| } // namespace data_decoder |
| |
| namespace image_fetcher { |
| |
| class ImageDecoder; |
| class ReducedModeImageFetcher; |
| |
| // Encapsulates image fetching customization options. |
| // (required) |
| // traffic_annotation |
| // Documents what the network traffic is for, gives you free metrics. |
| // max_download_size |
| // Limits the size of the downloaded image. |
| // frame_size |
| // If multiple sizes of the image are available on the server, choose the one |
| // that's closest to the given size (only useful for .icos). Does NOT resize |
| // the downloaded image to the given dimensions. |
| class ImageFetcherParams { |
| // Allows the bridge to access the private function set_skip_transcoding |
| // used for gif download. |
| friend class ImageFetcherBridge; |
| // Allows ReducedModeImageFetcher to access the private |
| // function set_skip_transcoding and set_allow_needs_transcoding_file because |
| // it ignores the ImageFetcherCallback. |
| friend class ReducedModeImageFetcher; |
| |
| public: |
| // Sets the UMA client name to report feature-specific metrics. Make sure |
| // `uma_client_name` is also present in histograms.xml. |
| ImageFetcherParams( |
| net::NetworkTrafficAnnotationTag network_traffic_annotation_tag, |
| std::string uma_client_name); |
| ImageFetcherParams(const ImageFetcherParams& params); |
| ImageFetcherParams(ImageFetcherParams&& params); |
| |
| ~ImageFetcherParams(); |
| |
| const net::NetworkTrafficAnnotationTag traffic_annotation() const { |
| return network_traffic_annotation_tag_; |
| } |
| |
| void set_max_download_size(std::optional<int64_t> max_download_bytes) { |
| max_download_bytes_ = max_download_bytes; |
| } |
| |
| std::optional<int64_t> max_download_size() const { |
| return max_download_bytes_; |
| } |
| |
| void set_frame_size(gfx::Size desired_frame_size) { |
| desired_frame_size_ = desired_frame_size; |
| } |
| |
| gfx::Size frame_size() const { return desired_frame_size_; } |
| |
| const std::string& uma_client_name() const { return uma_client_name_; } |
| |
| bool skip_transcoding() const { return skip_transcoding_; } |
| |
| bool allow_needs_transcoding_file() const { |
| return allow_needs_transcoding_file_; |
| } |
| |
| // Only to be used in unittests. |
| void set_skip_transcoding_for_testing(bool skip_transcoding) { |
| skip_transcoding_ = skip_transcoding; |
| } |
| |
| bool skip_disk_cache_read() const { return skip_disk_cache_read_; } |
| |
| void set_skip_disk_cache_read(bool skip_disk_cache_read) { |
| skip_disk_cache_read_ = skip_disk_cache_read; |
| } |
| |
| const std::optional<base::TimeDelta>& expiration_interval() const { |
| return expiration_interval_; |
| } |
| |
| void set_hold_for_expiration_interval( |
| const base::TimeDelta& expiration_interval) { |
| expiration_interval_ = expiration_interval; |
| } |
| |
| // Sets the data decoder to use for this image. Using the same data decoder |
| // across multiple image fetches allows them to be decoded in the same |
| // process. |
| void set_data_decoder(data_decoder::DataDecoder* data_decoder) { |
| data_decoder_ = data_decoder; |
| } |
| |
| data_decoder::DataDecoder* data_decoder() const { return data_decoder_; } |
| |
| private: |
| void set_skip_transcoding(bool skip_transcoding) { |
| skip_transcoding_ = skip_transcoding; |
| } |
| |
| void set_allow_needs_transcoding_file(bool allow_needs_transcoding_file) { |
| allow_needs_transcoding_file_ = allow_needs_transcoding_file; |
| } |
| |
| const net::NetworkTrafficAnnotationTag network_traffic_annotation_tag_; |
| |
| std::optional<int64_t> max_download_bytes_; |
| // Only used in rare cases to keep the cache file on disk for certain period |
| // of time. Image files will stay in cache at least for `expiration_interval_` |
| // after last use. |
| std::optional<base::TimeDelta> expiration_interval_; |
| gfx::Size desired_frame_size_; |
| std::string uma_client_name_; |
| // When true, the image fetcher will skip transcoding whenever possible. Only |
| // use this if you've considered the security implications. For instance, in |
| // some java clients we decode GIFs entirely in Java which is safe to do |
| // in-process without transcoding. |
| bool skip_transcoding_; |
| // True if the disk cache should be skipped because it was already checked in |
| // java. |
| bool skip_disk_cache_read_; |
| // True if allowing images that need transcoding to be stored with a prefix in |
| // file names. |
| bool allow_needs_transcoding_file_; |
| |
| // The data decoder to use for decoding this image. If null, a new data |
| // decoder will be created for each fetch. |
| raw_ptr<data_decoder::DataDecoder> data_decoder_ = nullptr; |
| }; |
| |
| // A class used to fetch server images. It can be called from any thread and the |
| // callback will be called on the thread which initiated the fetch. |
| class ImageFetcher { |
| public: |
| ImageFetcher() = default; |
| |
| ImageFetcher(const ImageFetcher&) = delete; |
| ImageFetcher& operator=(const ImageFetcher&) = delete; |
| |
| virtual ~ImageFetcher() = default; |
| |
| // Fetch an image and optionally decode it. `image_data_callback` is called |
| // when the image fetch completes, but `image_data_callback` may be empty. |
| // `image_callback` is called when the image is finished decoding. |
| // `image_callback` may be empty if image decoding is not required. If a |
| // callback is provided, it will be called exactly once. On failure, an empty |
| // string/gfx::Image is returned. |
| virtual void FetchImageAndData(const GURL& image_url, |
| ImageDataFetcherCallback image_data_callback, |
| ImageFetcherCallback image_callback, |
| ImageFetcherParams params) = 0; |
| |
| // Fetch an image and decode it. An empty gfx::Image will be returned to the |
| // callback in case the image could not be fetched. This is the same as |
| // calling FetchImageAndData without an `image_data_callback`. |
| void FetchImage(const GURL& image_url, |
| ImageFetcherCallback callback, |
| ImageFetcherParams params) { |
| FetchImageAndData(image_url, ImageDataFetcherCallback(), |
| std::move(callback), params); |
| } |
| |
| // Just fetch the image data, do not decode. This is the same as |
| // calling FetchImageAndData without an `image_callback`. |
| void FetchImageData(const GURL& image_url, |
| ImageDataFetcherCallback callback, |
| ImageFetcherParams params) { |
| FetchImageAndData(image_url, std::move(callback), ImageFetcherCallback(), |
| params); |
| } |
| |
| virtual ImageDecoder* GetImageDecoder() = 0; |
| }; |
| |
| } // namespace image_fetcher |
| |
| #endif // COMPONENTS_IMAGE_FETCHER_CORE_IMAGE_FETCHER_H_ |