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
|
// Copyright 2017 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_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_
#define CHROME_BROWSER_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_
#include <map>
#include <memory>
#include <set>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "build/chromeos_buildflags.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/buildflags/buildflags.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ui/ash/shelf/shelf_extension_app_updater.h"
#endif
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
namespace content {
class BrowserContext;
}
namespace gfx {
class ImageSkia;
class Size;
} // namespace gfx
namespace extensions {
class ChromeAppIcon;
class ChromeAppIconDelegate;
// Factory for ChromeAppIcon. Each created icon is tracked by this service.
// Once some condition that affects how extension app icon should look is
// changed then corresponded app icons are automatically updated. This service
// is bound to content::BrowserContext.
// Usage: ChromeAppIconService::Get(context)->CreateIcon().
class ChromeAppIconService : public KeyedService,
#if BUILDFLAG(IS_CHROMEOS)
public ShelfAppUpdater::Delegate,
#endif
public ExtensionRegistryObserver {
public:
using ResizeFunction =
base::RepeatingCallback<void(const gfx::Size&, gfx::ImageSkia*)>;
explicit ChromeAppIconService(content::BrowserContext* context);
ChromeAppIconService(const ChromeAppIconService&) = delete;
ChromeAppIconService& operator=(const ChromeAppIconService&) = delete;
~ChromeAppIconService() override;
// Convenience function to get the ChromeAppIconService for a
// BrowserContext.
static ChromeAppIconService* Get(content::BrowserContext* context);
// Creates extension app icon for requested app and size. Icon updates are
// dispatched via `delegate`.
// `resize_function` overrides icon resizing behavior if non-null. Otherwise
// IconLoader with perform the resizing. In both cases `resource_size_in_dip`
// is used to pick the correct icon representation from resources.
std::unique_ptr<ChromeAppIcon> CreateIcon(
ChromeAppIconDelegate* delegate,
const std::string& app_id,
int resource_size_in_dip,
const ResizeFunction& resize_function);
std::unique_ptr<ChromeAppIcon> CreateIcon(ChromeAppIconDelegate* delegate,
const std::string& app_id,
int resource_size_in_dip);
// KeyedService:
void Shutdown() override;
private:
class Updater;
// System may have multiple icons for the same app id with different
// dimensions. For example icon in shelf and app launcher.
using IconMap =
std::map<std::string, std::set<raw_ptr<ChromeAppIcon, SetExperimental>>>;
// Called from ChromeAppIcon DTOR.
void OnIconDestroyed(ChromeAppIcon* icon);
// Called from Updater when corresponded app icons need to be updated.
void OnAppUpdated(const std::string& app_id);
// ExtensionRegistryObserver:
void OnExtensionLoaded(content::BrowserContext* browser_context,
const Extension* extension) override;
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionReason reason) override;
#if BUILDFLAG(IS_CHROMEOS)
// ShelfAppUpdater::Delegate:
void OnAppUpdated(content::BrowserContext* browser_context,
const std::string& app_id,
bool reload_icon) override;
#endif
// Unowned pointer.
raw_ptr<content::BrowserContext> context_;
#if BUILDFLAG(IS_CHROMEOS)
// On Chrome OS this handles Chrome app life-cycle events that may change how
// extension based app icon looks like.
std::unique_ptr<ShelfExtensionAppUpdater> app_updater_;
#endif
// Deletes the icon set for `app_id` from the map if it is empty.
void MaybeCleanupIconSet(const std::string& app_id);
IconMap icon_map_;
base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
observation_{this};
base::WeakPtrFactory<ChromeAppIconService> weak_ptr_factory_{this};
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_
|