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
|
// 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 CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_ICON_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_ICON_MANAGER_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
#include "components/webapps/common/web_app_id.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image_skia.h"
#include "web_app_install_info.h"
class Profile;
namespace base {
class SequencedTaskRunner;
class Time;
} // namespace base
namespace web_app {
class WebAppInstallManager;
class WebAppProvider;
using HomeTabIconBitmaps = std::vector<SkBitmap>;
using SquareSizeDip = int;
// Exclusively used from the UI thread.
class WebAppIconManager : public WebAppInstallManagerObserver {
public:
using FaviconReadCallback =
base::RepeatingCallback<void(const webapps::AppId& app_id)>;
using ReadImageSkiaCallback =
base::OnceCallback<void(gfx::ImageSkia image_skia)>;
explicit WebAppIconManager(Profile* profile);
WebAppIconManager(const WebAppIconManager&) = delete;
WebAppIconManager& operator=(const WebAppIconManager&) = delete;
~WebAppIconManager() override;
using WriteDataCallback = base::OnceCallback<void(bool success)>;
// Writes all data (icons) for an app.
void WriteData(webapps::AppId app_id,
IconBitmaps icon_bitmaps,
ShortcutsMenuIconBitmaps shortcuts_menu_icons,
IconsMap other_icons_map,
WriteDataCallback callback);
void DeleteData(webapps::AppId app_id, WriteDataCallback callback);
void SetProvider(base::PassKey<WebAppProvider>, WebAppProvider& provider);
void Start();
void Shutdown();
// Returns false if any icon in |icon_sizes_in_px| is missing from downloaded
// icons for a given app and |purpose|.
bool HasIcons(const webapps::AppId& app_id,
IconPurpose purpose,
const SortedSizesPx& icon_sizes) const;
struct IconSizeAndPurpose {
SquareSizePx size_px = 0;
IconPurpose purpose = IconPurpose::ANY;
};
// For each of |purposes|, in the given order, looks for an icon with size at
// least |min_icon_size|. Returns information on the first icon found.
std::optional<IconSizeAndPurpose> FindIconMatchBigger(
const webapps::AppId& app_id,
const std::vector<IconPurpose>& purposes,
SquareSizePx min_size) const;
// Returns whether there is a downloaded icon of at least |min_size| for any
// of the given |purposes|.
bool HasSmallestIcon(const webapps::AppId& app_id,
const std::vector<IconPurpose>& purposes,
SquareSizePx min_size) const;
using ReadIconsCallback =
base::OnceCallback<void(std::map<SquareSizePx, SkBitmap> icon_bitmaps)>;
// Reads specified icon bitmaps for an app and |purpose|. Returns empty map in
// |callback| if IO error.
void ReadIcons(const webapps::AppId& app_id,
IconPurpose purpose,
const SortedSizesPx& icon_sizes,
ReadIconsCallback callback);
// Mimics WebAppShortcutsMenuItemInfo but stores timestamps instead of icons
// for os integration.
using ShortcutMenuIconTimes =
base::flat_map<IconPurpose, base::flat_map<SquareSizePx, base::Time>>;
using ShortcutIconDataVector = std::vector<ShortcutMenuIconTimes>;
using ShortcutIconDataCallback =
base::OnceCallback<void(ShortcutIconDataVector)>;
void ReadAllShortcutMenuIconsWithTimestamp(const webapps::AppId& app_id,
ShortcutIconDataCallback callback);
using ReadIconsUpdateTimeCallback = base::OnceCallback<void(
base::flat_map<SquareSizePx, base::Time> time_map)>;
// Reads all the last updated time for all icons in the app. Returns empty map
// in |callback| if IO error.
void ReadIconsLastUpdateTime(const webapps::AppId& app_id,
ReadIconsUpdateTimeCallback callback);
// TODO (crbug.com/1102701): Callback with const ref instead of value.
using ReadIconBitmapsCallback =
base::OnceCallback<void(IconBitmaps icon_bitmaps)>;
// Reads all icon bitmaps for an app. Returns empty |icon_bitmaps| in
// |callback| if IO error.
void ReadAllIcons(const webapps::AppId& app_id,
ReadIconBitmapsCallback callback);
using ReadShortcutsMenuIconsCallback = base::OnceCallback<void(
ShortcutsMenuIconBitmaps shortcuts_menu_icon_bitmaps)>;
// Reads bitmaps for all shortcuts menu icons for an app. Returns a vector of
// map<SquareSizePx, SkBitmap>. The index of a map in the vector is the same
// as that of its corresponding shortcut in the manifest's shortcuts vector.
// Returns empty vector in |callback| if we hit any error.
void ReadAllShortcutsMenuIcons(const webapps::AppId& app_id,
ReadShortcutsMenuIconsCallback callback);
using ReadHomeTabIconsCallback =
base::OnceCallback<void(SkBitmap home_tab_icon_bitmap)>;
// Reads bitmap for the home tab icon. Returns a SkBitmap
// in |callback| if the icon exists. Otherwise, if it doesn't
// exist, the SkBitmap is empty.
void ReadBestHomeTabIcon(
const webapps::AppId& app_id,
const std::vector<blink::Manifest::ImageResource>& icons,
const SquareSizePx min_home_tab_icon_size_px,
ReadHomeTabIconsCallback callback);
using ReadIconWithPurposeCallback =
base::OnceCallback<void(IconPurpose, SkBitmap)>;
// For each of |purposes|, in the given order, looks for an icon with size at
// least |min_icon_size|. Returns the first icon found, as a bitmap. Returns
// an empty SkBitmap in |callback| if IO error.
void ReadSmallestIcon(const webapps::AppId& app_id,
const std::vector<IconPurpose>& purposes,
SquareSizePx min_size_in_px,
ReadIconWithPurposeCallback callback);
using ReadCompressedIconWithPurposeCallback =
base::OnceCallback<void(IconPurpose, std::vector<uint8_t> data)>;
// For each of |purposes|, in the given order, looks for an icon with size at
// least |min_icon_size|. Returns the first icon found, compressed as PNG.
// Returns empty |data| in |callback| if IO error.
void ReadSmallestCompressedIcon(
const webapps::AppId& app_id,
const std::vector<IconPurpose>& purposes,
SquareSizePx min_size_in_px,
ReadCompressedIconWithPurposeCallback callback);
using ReadCompressedIconsSizeCallback =
base::OnceCallback<void(const webapps::AppId& app_id, uint64_t size)>;
using GetIconsSizeCallback = base::OnceCallback<void(uint64_t)>;
void GetIconsSizeForApp(const webapps::AppId& app_id,
GetIconsSizeCallback callback) const;
// Returns a square icon of gfx::kFaviconSize px, or an empty bitmap if not
// found.
SkBitmap GetFavicon(const webapps::AppId& app_id) const;
gfx::ImageSkia GetFaviconImageSkia(const webapps::AppId& app_id) const;
gfx::ImageSkia GetMonochromeFavicon(const webapps::AppId& app_id) const;
// WebAppInstallManagerObserver:
void OnWebAppInstalled(const webapps::AppId& app_id) override;
void OnWebAppInstallManagerDestroyed() override;
// Calls back with an icon of the |desired_icon_size| and |purpose|, resizing
// an icon of a different size if necessary. If no icons were available, calls
// back with an empty map. Prefers resizing a large icon smaller over resizing
// a small icon larger.
void ReadIconAndResize(const webapps::AppId& app_id,
IconPurpose purpose,
SquareSizePx desired_icon_size,
ReadIconsCallback callback);
// Reads multiple densities of the icon for each supported UI scale factor.
// See ui/base/resource/resource_scale_factor.h. Returns null image in
// `callback` if no icons found for all supported UI scale factors (matches
// only bigger icons, no upscaling).
void ReadFavicons(const webapps::AppId& app_id,
IconPurpose purpose,
ReadImageSkiaCallback callback);
struct IconFilesCheck {
size_t empty = 0;
size_t missing = 0;
};
void CheckForEmptyOrMissingIconFiles(
const webapps::AppId& app_id,
base::OnceCallback<void(IconFilesCheck)> callback) const;
void SetFaviconReadCallbackForTesting(FaviconReadCallback callback);
void SetFaviconMonochromeReadCallbackForTesting(FaviconReadCallback callback);
base::FilePath GetIconFilePathForTesting(const webapps::AppId& app_id,
IconPurpose purpose,
SquareSizePx size);
// Collects icon read/write errors (unbounded) if the |kRecordWebAppDebugInfo|
// flag is enabled to be used by: chrome://web-app-internals
const std::vector<std::string>* error_log() const { return error_log_.get(); }
std::vector<std::string>* error_log() { return error_log_.get(); }
private:
base::WeakPtr<const WebAppIconManager> GetWeakPtr() const;
base::WeakPtr<WebAppIconManager> GetWeakPtr();
std::optional<IconSizeAndPurpose> FindIconMatchSmaller(
const webapps::AppId& app_id,
const std::vector<IconPurpose>& purposes,
SquareSizePx max_size) const;
void OnReadFavicons(ReadImageSkiaCallback callback,
std::map<SquareSizePx, SkBitmap> icon_bitmaps);
void ReadFavicon(const webapps::AppId& app_id);
void OnReadFavicon(const webapps::AppId& app_id, gfx::ImageSkia image_skia);
void ReadMonochromeFavicon(const webapps::AppId& app_id);
void OnReadMonochromeFavicon(const webapps::AppId& app_id,
gfx::ImageSkia manifest_monochrome_image);
void OnMonochromeIconConverted(const webapps::AppId& app_id,
gfx::ImageSkia converted_image);
raw_ptr<WebAppProvider> provider_ = nullptr;
base::FilePath web_apps_directory_;
scoped_refptr<base::SequencedTaskRunner> icon_task_runner_;
base::ScopedObservation<WebAppInstallManager, WebAppInstallManagerObserver>
install_manager_observation_{this};
// We cache different densities for high-DPI displays per each app.
std::map<webapps::AppId, gfx::ImageSkia> favicon_cache_;
std::map<webapps::AppId, gfx::ImageSkia> favicon_monochrome_cache_;
FaviconReadCallback favicon_read_callback_;
FaviconReadCallback favicon_monochrome_read_callback_;
std::unique_ptr<std::vector<std::string>> error_log_;
base::WeakPtrFactory<WebAppIconManager> weak_ptr_factory_{this};
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_ICON_MANAGER_H_
|