File: app_icon_loader.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (282 lines) | stat: -rw-r--r-- 10,449 bytes parent folder | download | duplicates (6)
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
279
280
281
282
// Copyright 2021 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_APPS_APP_SERVICE_APP_ICON_APP_ICON_LOADER_H_
#define CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_APP_ICON_LOADER_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "components/services/app_service/public/cpp/icon_types.h"
#include "extensions/common/constants.h"
#include "ui/gfx/image/image_skia.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/ash/experiences/arc/mojom/intent_helper.mojom.h"
#include "ui/base/resource/resource_scale_factor.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace arc {
class IconDecodeRequest;
}

namespace extensions {
class Extension;
}

class ArcAppListPrefs;
class Profile;

namespace web_app {
class WebAppIconManager;
}

class SkBitmap;

namespace apps {

class SvgIconTranscoder;

// This struct is used to record the icon paths for the adaptive icon.
struct AdaptiveIconPaths {
  // Returns true when all paths are empty. Otherwise, returns false.
  bool IsEmpty();

  // The raw icon path for the non-adaptive icon.
  base::FilePath icon_path;
  // The foreground icon path for the adaptive icon.
  base::FilePath foreground_icon_path;
  // The background icon path for the adaptive icon.
  base::FilePath background_icon_path;
};

// This class is meant to:
// * Simplify loading icons, as things like effects and type are common
//   to all loading.
// * Allow the caller to halt the process by destructing the loader at any time,
// * Allow easy additions to the icon loader if necessary (like new effects or
// backups).
// Must be created & run from the UI thread.
class AppIconLoader : public base::RefCounted<AppIconLoader>,
                      public ProfileObserver {
 public:
  static const int kFaviconFallbackImagePx =
      extension_misc::EXTENSION_ICON_BITTY;

  AppIconLoader(Profile* profile,
                std::optional<std::string> app_id,
                IconType icon_type,
                int size_hint_in_dip,
                bool is_placeholder_icon,
                apps::IconEffects icon_effects,
                int fallback_icon_resource,
                LoadIconCallback callback);

  AppIconLoader(Profile* profile,
                std::optional<std::string> app_id,
                IconType icon_type,
                int size_hint_in_dip,
                bool is_placeholder_icon,
                apps::IconEffects icon_effects,
                int fallback_icon_resource,
                base::OnceCallback<void(LoadIconCallback)> fallback,
                LoadIconCallback callback);

  AppIconLoader(Profile* profile,
                int size_hint_in_dip,
                LoadIconCallback callback);

  AppIconLoader(int size_hint_in_dip,
                base::OnceCallback<void(const gfx::ImageSkia& icon)> callback);

  explicit AppIconLoader(
      base::OnceCallback<void(const std::vector<gfx::ImageSkia>& icons)>
          callback);

  AppIconLoader(int size_hint_in_dip, LoadIconCallback callback);

  void ApplyIconEffects(IconEffects icon_effects,
                        const std::optional<std::string>& app_id,
                        IconValuePtr iv);

  void ApplyBadges(IconEffects icon_effects,
                   const std::optional<std::string>& app_id,
                   IconValuePtr iv);

  void LoadWebAppIcon(const std::string& web_app_id,
                      const GURL& launch_url,
                      web_app::WebAppIconManager& icon_manager);

  void LoadExtensionIcon(const extensions::Extension* extension);

  // The image file must be compressed using the default encoding.
  void LoadCompressedIconFromFile(const base::FilePath& path);
  void LoadIconFromCompressedData(const std::string& compressed_icon_data);

  void LoadIconFromResource(int icon_resource);

#if BUILDFLAG(IS_CHROMEOS)
  // For ARC icons, converts an icon png data to an ImageSkia using
  // arc::IconDecodeRequest.
  void LoadArcIconPngData(const std::vector<uint8_t>& icon_png_data);

  // For ARC icons, composite the foreground image and the background image,
  // then apply the mask.
  void LoadCompositeImages(const std::vector<uint8_t>& foreground_data,
                           const std::vector<uint8_t>& background_data);

  // Loads icons for ARC activities.
  void LoadArcActivityIcons(
      const std::vector<arc::mojom::ActivityIconPtr>& icons);

  // Requests a compressed icon data with `scale_factor` for an web app
  // identified by `web_app_id`.
  void GetWebAppCompressedIconData(const std::string& web_app_id,
                                   ui::ResourceScaleFactor scale_factor,
                                   web_app::WebAppIconManager& icon_manager);

  // Requests a compressed icon data with `scale_factor` for a chrome app
  // identified by `extension`.
  void GetChromeAppCompressedIconData(const extensions::Extension* extension,
                                      ui::ResourceScaleFactor scale_factor);

  // Requests a compressed icon data with `scale_factor` for an ARC app
  // identified by `app_id`.
  void GetArcAppCompressedIconData(const std::string& app_id,
                                   ArcAppListPrefs* arc_prefs,
                                   ui::ResourceScaleFactor scale_factor);

  // Requests a compressed icon data with `scale_factor` for a Guest OS app
  // identified by `app_id`.
  void GetGuestOSAppCompressedIconData(const std::string& app_id,
                                       ui::ResourceScaleFactor scale_factor);
#endif  // BUILDFLAG(IS_CHROMEOS)

 private:
  friend class base::RefCounted<AppIconLoader>;

  ~AppIconLoader() override;

#if BUILDFLAG(IS_CHROMEOS)
  void OnGetArcAppCompressedIconData(AdaptiveIconPaths app_icon_paths,
                                     arc::mojom::RawIconPngDataPtr icon);

  void OnGetGuestOSAppCompressedIconData(base::FilePath png_path,
                                         base::FilePath svg_path,
                                         std::string icon_data);

  void TranscodeIconFromSvg(base::FilePath svg_path, base::FilePath png_path);

  std::unique_ptr<arc::IconDecodeRequest> CreateArcIconDecodeRequest(
      base::OnceCallback<void(const gfx::ImageSkia& icon)> callback,
      const std::vector<uint8_t>& icon_png_data);

  void ApplyBackgroundAndMask(const gfx::ImageSkia& image);

  void CompositeImagesAndApplyMask(bool is_foreground,
                                   const gfx::ImageSkia& image);

  void OnArcActivityIconLoaded(gfx::ImageSkia* arc_activity_icon,
                               const gfx::ImageSkia& icon);
#endif  // BUILDFLAG(IS_CHROMEOS)

  void MaybeApplyEffectsAndComplete(const gfx::ImageSkia image);

  void CompleteWithCompressed(bool is_maskable_icon, std::vector<uint8_t> data);

  void CompleteWithUncompressed(IconValuePtr iv);

  void CompleteWithIconValue(IconValuePtr iv);

  void OnReadWebAppIcon(std::map<int, SkBitmap> icon_bitmaps);

  void OnReadWebAppForCompressedIconData(bool is_maskable_icon,
                                         std::map<int, SkBitmap> icon_bitmaps);

  void OnGetCompressedIconDataWithSkBitmap(bool is_maskable_icon,
                                           const SkBitmap& bitmap);

  void OnReadChromeAppForCompressedIconData(gfx::ImageSkia image);

  void MaybeLoadFallbackOrCompleteEmpty();

  // ProfileObserver overrides.
  void OnProfileWillBeDestroyed(Profile* profile) override;

  // If non-null, points to the profile necessary to support the icon loading.
  // Not used by all codepaths, so this isn't mandatory in the constructor,
  // and could be reset to null if the profile is torn down whilst async icon
  // loading is in-flight.
  raw_ptr<Profile> profile_ = nullptr;
  base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this};

  std::optional<std::string> app_id_ = std::nullopt;

  const IconType icon_type_ = IconType::kUnknown;

  const int size_hint_in_dip_ = 0;
  int icon_size_in_px_ = 0;
  // The scale factor the icon is intended for. See gfx::ImageSkiaRep::scale
  // comments.
  float icon_scale_ = 0.0f;
  // A scale factor to take as input for the IconType::kCompressed response. See
  // gfx::ImageSkia::GetRepresentation() comments.
  float icon_scale_for_compressed_response_ = 1.0f;

  const bool is_placeholder_icon_ = false;
  apps::IconEffects icon_effects_;
  bool is_maskable_icon_ = false;

  // If |fallback_favicon_url_| is populated, then the favicon service is the
  // first fallback method attempted in MaybeLoadFallbackOrCompleteEmpty().
  GURL fallback_favicon_url_;

  // If |fallback_icon_resource_| is not |kInvalidIconResource|, then it is the
  // second fallback method attempted in MaybeLoadFallbackOrCompleteEmpty()
  // (after the favicon service).
  int fallback_icon_resource_ = kInvalidIconResource;

  LoadIconCallback callback_;

  // A custom fallback operation to try.
  base::OnceCallback<void(LoadIconCallback)> fallback_callback_;

  base::CancelableTaskTracker cancelable_task_tracker_;

  // A sequenced task runner to create standard icons and not spamming the
  // thread pool.
  scoped_refptr<base::SequencedTaskRunner> standard_icon_task_runner_;

  gfx::ImageSkia foreground_image_;
  gfx::ImageSkia background_image_;
  bool foreground_is_set_ = false;
  bool background_is_set_ = false;
  base::OnceCallback<void(const gfx::ImageSkia& icon)> image_skia_callback_;

  std::vector<gfx::ImageSkia> arc_activity_icons_;
  size_t count_ = 0;
  base::OnceCallback<void(const std::vector<gfx::ImageSkia>& icon)>
      arc_activity_icons_callback_;

#if BUILDFLAG(IS_CHROMEOS)
  std::unique_ptr<arc::IconDecodeRequest> arc_icon_decode_request_;
  std::unique_ptr<arc::IconDecodeRequest> arc_foreground_icon_decode_request_;
  std::unique_ptr<arc::IconDecodeRequest> arc_background_icon_decode_request_;
  std::unique_ptr<SvgIconTranscoder> svg_icon_transcoder_;
#endif  // BUILDFLAG(IS_CHROMEOS)
};

}  // namespace apps

#endif  // CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_APP_ICON_LOADER_H_