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