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

ash / wallpaper / wallpaper_image_downloader.cc [blame]

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wallpaper/wallpaper_image_downloader.h"

#include <optional>
#include <string>

#include "ash/public/cpp/image_downloader.h"
#include "ash/public/cpp/wallpaper/wallpaper_types.h"
#include "base/functional/callback.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "components/account_id/account_id.h"
#include "net/http/http_request_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"

namespace ash {

namespace {

constexpr net::NetworkTrafficAnnotationTag
    kDownloadGooglePhotoTrafficAnnotation =
        net::DefineNetworkTrafficAnnotation("wallpaper_download_google_photo",
                                            R"(
      semantics {
        sender: "ChromeOS Wallpaper Image Downloader"
        description:
          "When the user selects a photo from their Google Photos collection, "
          "the image must be downloaded at a high enough resolution to display "
          "as a wallpaper. This request fetches that image."
        trigger: "When the user selects a Google Photo as their wallpaper, or "
                 "when that selection reaches this device from cross-device "
                 "sync."
        data: "Stored credentials for the user's Google account."
        destination: GOOGLE_OWNED_SERVICE
        internal {
          contacts {
            email: "assistive-eng@google.com"
          }
        }
        user_data {
          type: ACCESS_TOKEN
        }
        last_reviewed: "2023-03-06"
      }
      policy {
        cookies_allowed: NO
        setting: "The policy if set, controls the wallpaper image and disables "
        "this feature for user."
        chrome_policy {
          WallpaperImage {
            WallpaperImage: "{}"
          }
        }
      })");

constexpr net::NetworkTrafficAnnotationTag
    kDownloadOnlineWallpaperTrafficAnnotation =
        net::DefineNetworkTrafficAnnotation("wallpaper_online_downloader",
                                            R"(
      semantics {
        sender: "ChromeOS Wallpaper Image Downloader"
        description:
          "When the user selects a photo from their desktop wallpaper "
          "collection, the image must be downloaded at a high enough "
          "resolution to display as a wallpaper. This request fetches "
          "that image."
        trigger: "When the user clicks on the wallpaper thumbnail in "
        "the wallpaper collection"
        data: "None. These URLs are publicly accessible."
        destination: GOOGLE_OWNED_SERVICE
        internal {
          contacts {
            email: "assitive-eng@google.com"
          }
        }
        user_data {
          type: NONE
        }
        last_reviewed: "2023-03-06"
      }
     policy {
        cookies_allowed: NO
        setting: "The policy if set, controls the wallpaper image and disables "
        "this feature for user."
        chrome_policy {
          WallpaperImage {
            WallpaperImage: "{}"
          }
        }
      })");

GURL AddDimensionsToGooglePhotosURL(GURL url) {
  // Add a string with size data to the URL to make sure we get back the correct
  // resolution image, within reason and maintaining aspect ratio. See:
  // https://developers.google.com/photos/library/guides/access-media-items
  return GURL(base::StringPrintf("%s=w%d-h%d", url.spec().c_str(),
                                 kLargeWallpaperMaxWidth,
                                 kLargeWallpaperMaxHeight));
}

// Returns a suffix to be appended to the base url of Backdrop (online)
// wallpapers.
std::string GetBackdropWallpaperSuffix() {
  // TODO(b/186807814) handle different display resolutions better.
  // FIFE url is used for Backdrop wallpapers and the desired image size should
  // be specified. Currently we are using two times the display size. This is
  // determined by trial and error and is subject to change.
  gfx::Size display_size =
      display::Screen::GetScreen()->GetPrimaryDisplay().size();
  return "=w" + base::NumberToString(
                    2 * std::max(display_size.width(), display_size.height()));
}

}  // namespace

WallpaperImageDownloaderImpl::WallpaperImageDownloaderImpl() = default;

WallpaperImageDownloaderImpl::~WallpaperImageDownloaderImpl() = default;

void WallpaperImageDownloaderImpl::DownloadGooglePhotosImage(
    const GURL& url,
    const AccountId& account_id,
    const std::optional<std::string>& access_token,
    ImageDownloader::DownloadCallback callback) const {
  GURL url_with_dimensions = AddDimensionsToGooglePhotosURL(url);

  net::HttpRequestHeaders headers;
  if (access_token.has_value()) {
    headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
                      "Bearer " + access_token.value());
  }
  ImageDownloader::Get()->Download(url_with_dimensions,
                                   kDownloadGooglePhotoTrafficAnnotation,
                                   account_id, headers, std::move(callback));
}

void WallpaperImageDownloaderImpl::DownloadBackdropImage(
    const GURL& url,
    const AccountId& account_id,
    ImageDownloader::DownloadCallback callback) const {
  ImageDownloader::Get()->Download(
      GURL(url.spec() + GetBackdropWallpaperSuffix()),
      kDownloadOnlineWallpaperTrafficAnnotation, account_id,
      std::move(callback));
}

}  // namespace ash