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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
|
// Copyright 2018 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_THEMES_NTP_BACKGROUND_SERVICE_H_
#define COMPONENTS_THEMES_NTP_BACKGROUND_SERVICE_H_
#include <list>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ref.h"
#include "base/observer_list.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/public/identity_manager/access_token_info.h"
#include "components/themes/ntp_background_data.h"
#include "components/themes/ntp_background_service_observer.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "url/gurl.h"
namespace network {
class SimpleURLLoader;
class SharedURLLoaderFactory;
} // namespace network
class ApplicationLocaleStorage;
/**
* Types of images that are shown on the New Tab Page's frontend.
* This enum must match the numbering for NtpImageType in
* enums.xml. These values are persisted to logs. Entries should not be
* renumbered, removed or reused.
*/
enum class NtpImageType {
kBackgroundImage = 0,
kCollections = 1,
kCollectionImages = 2,
kMaxValue = kCollectionImages,
};
// A service that connects to backends that provide background image
// information, including collection names, image urls and descriptions.
class NtpBackgroundService : public KeyedService {
public:
NtpBackgroundService(
ApplicationLocaleStorage* application_locale_storage,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
NtpBackgroundService(const NtpBackgroundService&) = delete;
NtpBackgroundService& operator=(const NtpBackgroundService&) = delete;
~NtpBackgroundService() override;
// KeyedService implementation.
void Shutdown() override;
// Requests an asynchronous fetch from the network. After the update
// completes, OnCollectionInfoAvailable will be called on the observers.
// Requests that are made while an asynchronous fetch is in progress will be
// dropped until the currently active loader completes. `filtering_label` is
// provided to guide the fetch.
virtual void FetchCollectionInfo(const std::string& filtering_label);
// Requests an asynchronous fetch from network by calling
// `FetchCollectionInfo(const std::string& filtering_label)` with
// filtering_label set to the default label.
virtual void FetchCollectionInfo();
// Callback type for fetching collection images, invoked with a vector of
// CollectionImage.
using FetchCollectionImageCallback =
base::OnceCallback<void(const std::vector<CollectionImage>&, ErrorType)>;
// Requests an asynchronous fetch of metadata about images in the specified
// collection. After the update completes, a callback will be executed with
// the images metadata.
virtual void FetchCollectionImageInfo(const std::string& collection_id,
FetchCollectionImageCallback callback);
// Requests an asynchronous fetch of metadata about images in the specified
// collection. After the update completes, OnCollectionImagesAvailable will be
// called on the observers. Requests that are made while an asynchronous fetch
// is in progress will be dropped until the currently active loader completes.
virtual void FetchCollectionImageInfo(const std::string& collection_id);
using FetchReplacementImageCallback =
base::OnceCallback<void(const std::optional<GURL>&)>;
// Requests an asynchronous fetch of a replacement preview image for a
// collection.
virtual void FetchReplacementCollectionPreviewImage(
const std::string& collection_id,
FetchReplacementImageCallback fetch_replacement_image_callback);
// Requests an asynchronous fetch of metadata about the 'next' image in the
// specified collection. The resume_token, where available, is an opaque value
// saved from a previous GetImageFromCollectionResponse. After the update
// completes, OnNextCollectionImageAvailable will be called on the observers.
// Requests that are made while an asynchronous fetch is in progress will be
// dropped until the currently active loader completes.
void FetchNextCollectionImage(const std::string& collection_id,
const std::optional<std::string>& resume_token);
// Requests an asynchronous fetch of an image's URL headers.
virtual void VerifyImageURL(
const GURL& url,
base::OnceCallback<void(int)> image_url_headers_received_callback);
// Add/remove observers. All observers must unregister themselves before the
// NtpBackgroundService is destroyed.
virtual void AddObserver(NtpBackgroundServiceObserver* observer);
void RemoveObserver(NtpBackgroundServiceObserver* observer);
// Check that |url| is contained in collection_images.
bool IsValidBackdropUrl(const GURL& url) const;
// Check that |collection_id| is one of the fetched collections.
virtual bool IsValidBackdropCollection(
const std::string& collection_id) const;
void AddValidBackdropUrlForTesting(const GURL& url);
void AddValidBackdropCollectionForTesting(const std::string& collection_id);
void AddValidBackdropUrlWithThumbnailForTesting(const GURL& url,
const GURL& thumbnail_url);
void SetNextCollectionImageForTesting(const CollectionImage& image);
// Returns thumbnail url for the given image url if its valid. Otherwise,
// returns empty url.
const GURL& GetThumbnailUrl(const GURL& image_url);
// Returns the currently cached CollectionInfo, if any.
virtual const std::vector<CollectionInfo>& collection_info() const;
// Returns the currently cached CollectionImages, if any.
virtual const std::vector<CollectionImage>& collection_images() const;
// Returns the cached 'next' CollectionImage.
const CollectionImage& next_image() const { return next_image_; }
// Returns the cached resume_token to get the 'next' CollectionImage.
const std::string& next_image_resume_token() const {
return next_image_resume_token_;
}
// Returns the error info associated with the collections request.
const ErrorInfo& collection_error_info() const {
return collection_error_info_;
}
// Returns the error info associated with the collection images request.
const ErrorInfo& collection_images_error_info() const {
return collection_images_error_info_;
}
// Returns the error info associated with the next images request.
const ErrorInfo& next_image_error_info() const {
return next_image_error_info_;
}
GURL GetCollectionsLoadURLForTesting() const;
GURL GetImagesURLForTesting() const;
GURL GetNextImageURLForTesting() const;
private:
std::string default_image_options_;
std::string thumbnail_image_options_;
GURL collections_api_url_;
GURL collection_images_api_url_;
GURL next_image_api_url_;
using URLLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>;
// Must be non-null and outlive this object.
const raw_ref<ApplicationLocaleStorage> application_locale_storage_;
// Used to download the proto from the Backdrop service.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
std::unique_ptr<network::SimpleURLLoader> collections_loader_;
URLLoaderList pending_collection_image_info_loaders_;
std::unique_ptr<network::SimpleURLLoader> next_image_loader_;
// Used to download the headers of an image in a collection.
URLLoaderList pending_image_url_header_loaders_;
base::ObserverList<NtpBackgroundServiceObserver, true>::Unchecked observers_;
// Callback that processes the response from the FetchCollectionInfo request,
// refreshing the contents of collection_info_ with server-provided data.
void OnCollectionInfoFetchComplete(
std::unique_ptr<std::string> response_body);
// Callback that processes the response from a FetchCollectionImages
// request and then executes a provided callback with the server-provided
// data. This allows for parallel fetching of collection images without
// updating states such as collection_images_, requested_collection_id_, and
// collection_images_error_info_. To update these states,
// use FetchCollectionImageInfo(const std::string& collection_id).
void OnCollectionImageInfoFetchComplete(
const std::string& collection_id,
FetchCollectionImageCallback callback,
ntp::background::GetImagesInCollectionResponse images_responsfe,
ErrorType error_type);
// Callback that processes the response from VerifyCollectionImageURL request.
void OnImageURLHeadersFetchComplete(
URLLoaderList::iterator it,
base::OnceCallback<void(int)> image_url_headers_received_callback,
base::TimeTicks request_start,
scoped_refptr<net::HttpResponseHeaders> headers);
// Callback that processes the response of a FetchImageInfo request made by a
// collection image whose preview image's URL is broken. The images in the
// collection are fetched and then verified using VerifyImageUrl.
void OnFetchReplacementCollectionPreviewImageComplete(
FetchReplacementImageCallback fetch_replacement_image_callback,
ntp::background::GetImagesInCollectionResponse images_response,
ErrorType error_type);
// Callback that processes the response of a VerifyImageUrl request made to
// to replace a collection's preview image URL.
void OnReplacementCollectionPreviewImageHeadersReceived(
FetchReplacementImageCallback fetch_replacement_image_callback,
ntp::background::GetImagesInCollectionResponse images_response,
int replacement_image_index,
const GURL& replacement_image_url,
int headers_response_code);
// Callback that processes the response from the FetchNextCollectionImage
// request, refreshing the contents of next_collection_image_ and
// next_resume_token_ with server-provided data.
void OnNextImageInfoFetchComplete(std::unique_ptr<std::string> response_body);
// Callback that processes the response from the FetchCollectionImages
// request, refreshing the contents of collection_images_ with
// server-provided data.
void OnCollectionImageInfoReceived(
const std::vector<CollectionImage>& collection_images,
ErrorType error_type);
// Requests an asynchronous fetch of metadata about images in the specified
// collection.
void FetchCollectionImageInfoInternal(
const std::string& collection_id,
base::OnceCallback<void(ntp::background::GetImagesInCollectionResponse,
ErrorType)> collection_images_received_callback);
enum class FetchComplete {
// Indicates that asynchronous fetch of CollectionInfo has completed.
COLLECTION_INFO,
// Indicates that asynchronous fetch of CollectionImages has completed.
COLLECTION_IMAGE_INFO,
// Indicates that asynchronous fetch of the next CollectionImage has
// completed.
NEXT_IMAGE_INFO,
};
void NotifyObservers(FetchComplete fetch_complete);
std::vector<CollectionInfo> collection_info_;
std::vector<CollectionImage> collection_images_;
std::string requested_collection_id_;
CollectionImage next_image_;
std::string next_image_resume_token_;
std::string requested_next_image_collection_id_;
std::string requested_next_image_resume_token_;
ErrorInfo collection_error_info_;
ErrorInfo collection_images_error_info_;
ErrorInfo next_image_error_info_;
};
#endif // COMPONENTS_THEMES_NTP_BACKGROUND_SERVICE_H_
|