blob: 841f6ae644cf007887b4433cf6a52e93881bc519 [file] [log] [blame]
khmel8c1f6622017-05-11 19:14:501// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_
6#define CHROME_BROWSER_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_
7
8#include <map>
9#include <memory>
10#include <set>
11
Vladislav Kaznacheev6ae79b42018-09-13 06:11:1112#include "base/callback.h"
khmel8c1f6622017-05-11 19:14:5013#include "base/macros.h"
14#include "base/memory/weak_ptr.h"
15#include "base/scoped_observer.h"
16#include "components/keyed_service/core/keyed_service.h"
Evan Stade75872a62019-09-06 21:17:3817#include "extensions/browser/extension_registry.h"
khmel8c1f6622017-05-11 19:14:5018#include "extensions/browser/extension_registry_observer.h"
19
20#if defined(OS_CHROMEOS)
21#include "chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h"
22#endif
23
24namespace content {
25class BrowserContext;
26}
27
Vladislav Kaznacheev6ae79b42018-09-13 06:11:1128namespace gfx {
29class ImageSkia;
30class Size;
31} // namespace gfx
32
khmel8c1f6622017-05-11 19:14:5033namespace extensions {
34
35class ChromeAppIcon;
36class ChromeAppIconDelegate;
37
38// Factory for ChromeAppIcon. Each created icon is tracked by this service.
39// Once some condition that affects how extension app icon should look is
40// changed then corresponded app icons are automatically updated. This service
41// is bound to content::BrowserContext.
42// Usage: ChromeAppIconService::Get(context)->CreateIcon().
43class ChromeAppIconService : public KeyedService,
44#if defined(OS_CHROMEOS)
45 public LauncherAppUpdater::Delegate,
46#endif
47 public ExtensionRegistryObserver {
48 public:
Vladislav Kaznacheev6ae79b42018-09-13 06:11:1149 using ResizeFunction =
50 base::RepeatingCallback<void(const gfx::Size&, gfx::ImageSkia*)>;
51
khmel8c1f6622017-05-11 19:14:5052 explicit ChromeAppIconService(content::BrowserContext* context);
53
54 ~ChromeAppIconService() override;
55
56 // Convenience function to get the ChromeAppIconService for a
57 // BrowserContext.
58 static ChromeAppIconService* Get(content::BrowserContext* context);
59
60 // Creates extension app icon for requested app and size. Icon updates are
61 // dispatched via |delegate|.
Vladislav Kaznacheev6ae79b42018-09-13 06:11:1162 // |resize_function| overrides icon resizing behavior if non-null. Otherwise
63 // IconLoader with perform the resizing. In both cases |resource_size_in_dip|
64 // is used to pick the correct icon representation from resources.
65 std::unique_ptr<ChromeAppIcon> CreateIcon(
66 ChromeAppIconDelegate* delegate,
67 const std::string& app_id,
68 int resource_size_in_dip,
69 const ResizeFunction& resize_function);
70
khmel8c1f6622017-05-11 19:14:5071 std::unique_ptr<ChromeAppIcon> CreateIcon(ChromeAppIconDelegate* delegate,
72 const std::string& app_id,
73 int resource_size_in_dip);
74
75 // KeyedService:
76 void Shutdown() override;
77
78 private:
79 class Updater;
80
81 // System may have multiple icons for the same app id with different
82 // dimensions. For example icon in shelf and app launcher.
83 using IconMap = std::map<std::string, std::set<ChromeAppIcon*>>;
84
85 // Called from ChromeAppIcon DTOR.
86 void OnIconDestroyed(ChromeAppIcon* icon);
87
88 // Called from Updater when corresponded app icons need to be updated.
89 void OnAppUpdated(const std::string& app_id);
90
91 // ExtensionRegistryObserver:
92 void OnExtensionLoaded(content::BrowserContext* browser_context,
93 const Extension* extension) override;
94 void OnExtensionUnloaded(content::BrowserContext* browser_context,
95 const Extension* extension,
96 UnloadedExtensionReason reason) override;
97
98#if defined(OS_CHROMEOS)
99 // LauncherAppUpdater::Delegate:
100 void OnAppUpdated(content::BrowserContext* browser_context,
101 const std::string& app_id) override;
102#endif
103
104 // Unowned pointer.
105 content::BrowserContext* context_;
106
107#if defined(OS_CHROMEOS)
108 // On Chrome OS this handles Chrome app life-cycle events that may change how
109 // extension based app icon looks like.
110 std::unique_ptr<LauncherExtensionAppUpdater> app_updater_;
111#endif
112
khmel0df822022017-06-23 02:02:56113 // Deletes the icon set for |app_id| from the map if it is empty.
114 void MaybeCleanupIconSet(const std::string& app_id);
115
khmel8c1f6622017-05-11 19:14:50116 IconMap icon_map_;
117
Evan Stade75872a62019-09-06 21:17:38118 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> observer_{this};
khmel8c1f6622017-05-11 19:14:50119
Jeremy Roman495db682019-07-12 16:03:24120 base::WeakPtrFactory<ChromeAppIconService> weak_ptr_factory_{this};
khmel8c1f6622017-05-11 19:14:50121
122 DISALLOW_COPY_AND_ASSIGN(ChromeAppIconService);
123};
124
125} // namespace extensions
126
127#endif // CHROME_BROWSER_EXTENSIONS_CHROME_APP_ICON_SERVICE_H_