blob: 4738e9bc0910a2c25d7c29cab33f21619a96a84a [file] [log] [blame]
[email protected]0f34d9082012-10-08 19:16:441// Copyright (c) 2012 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
Devlin Cronin94832fc2020-08-04 18:39:415#include "extensions/browser/extension_action_manager.h"
[email protected]0f34d9082012-10-08 19:16:446
Devlin Cronin91975c32019-05-01 21:52:487#include "base/memory/singleton.h"
[email protected]b33f0b112014-03-13 17:05:308#include "components/keyed_service/content/browser_context_dependency_manager.h"
Devlin Cronin91975c32019-05-01 21:52:489#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
Devlin Cronin94832fc2020-08-04 18:39:4110#include "content/public/browser/browser_context.h"
Devlin Cronin5911e742020-04-28 15:56:3411#include "extensions/browser/extension_action.h"
rdevlin.cronind09e1c4d5c2016-11-19 01:03:2012#include "extensions/browser/extension_icon_image.h"
[email protected]59b0e602014-01-30 00:41:2413#include "extensions/browser/extension_system.h"
[email protected]175a74d2014-02-08 02:06:2014#include "extensions/browser/extensions_browser_client.h"
[email protected]6a24a0392014-08-12 21:31:3315#include "extensions/common/constants.h"
rdevlin.cronind09e1c4d5c2016-11-19 01:03:2016#include "ui/gfx/image/image_skia.h"
[email protected]0f34d9082012-10-08 19:16:4417
18namespace extensions {
19
[email protected]61e3cbe2012-10-14 22:06:5020namespace {
21
[email protected]f1484c52013-05-22 23:25:4422// BrowserContextKeyedServiceFactory for ExtensionActionManager.
23class ExtensionActionManagerFactory : public BrowserContextKeyedServiceFactory {
[email protected]61e3cbe2012-10-14 22:06:5024 public:
[email protected]f1484c52013-05-22 23:25:4425 // BrowserContextKeyedServiceFactory implementation:
[email protected]41934732014-08-22 21:38:1826 static ExtensionActionManager* GetForBrowserContext(
27 content::BrowserContext* context) {
[email protected]61e3cbe2012-10-14 22:06:5028 return static_cast<ExtensionActionManager*>(
[email protected]41934732014-08-22 21:38:1829 GetInstance()->GetServiceForBrowserContext(context, true));
[email protected]61e3cbe2012-10-14 22:06:5030 }
31
32 static ExtensionActionManagerFactory* GetInstance();
33
34 private:
olli.raula36aa8be2015-09-10 11:14:2235 friend struct base::DefaultSingletonTraits<ExtensionActionManagerFactory>;
[email protected]61e3cbe2012-10-14 22:06:5036
37 ExtensionActionManagerFactory()
[email protected]f1484c52013-05-22 23:25:4438 : BrowserContextKeyedServiceFactory(
Devlin Cronin94832fc2020-08-04 18:39:4139 "ExtensionActionManager",
40 BrowserContextDependencyManager::GetInstance()) {}
[email protected]61e3cbe2012-10-14 22:06:5041
dchengae36a4a2014-10-21 12:36:3642 KeyedService* BuildServiceInstanceFor(
Devlin Cronin94832fc2020-08-04 18:39:4143 content::BrowserContext* browser_context) const override {
44 return new ExtensionActionManager(browser_context);
[email protected]61e3cbe2012-10-14 22:06:5045 }
46
dchengae36a4a2014-10-21 12:36:3647 content::BrowserContext* GetBrowserContextToUse(
mostynba15bee12014-10-04 00:40:3248 content::BrowserContext* context) const override {
[email protected]175a74d2014-02-08 02:06:2049 return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
[email protected]61e3cbe2012-10-14 22:06:5050 }
51};
52
Devlin Cronin94832fc2020-08-04 18:39:4153ExtensionActionManagerFactory* ExtensionActionManagerFactory::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2254 return base::Singleton<ExtensionActionManagerFactory>::get();
[email protected]61e3cbe2012-10-14 22:06:5055}
56
57} // namespace
58
Devlin Cronin94832fc2020-08-04 18:39:4159ExtensionActionManager::ExtensionActionManager(
60 content::BrowserContext* browser_context)
61 : browser_context_(browser_context) {
62 CHECK(!browser_context_->IsOffTheRecord())
63 << "Don't instantiate this with an off-the-record context.";
Sigurdur Asgeirsson834f0572021-03-24 13:24:5864 extension_registry_observation_.Observe(
65 ExtensionRegistry::Get(browser_context_));
[email protected]0f34d9082012-10-08 19:16:4466}
67
68ExtensionActionManager::~ExtensionActionManager() {
Devlin Cronin94832fc2020-08-04 18:39:4169 // Don't assert that the ExtensionAction maps are empty because Extensions
70 // are sometimes (only in tests?) not unloaded before the associated context
71 // is destroyed.
[email protected]0f34d9082012-10-08 19:16:4472}
73
[email protected]41934732014-08-22 21:38:1874ExtensionActionManager* ExtensionActionManager::Get(
75 content::BrowserContext* context) {
76 return ExtensionActionManagerFactory::GetForBrowserContext(context);
[email protected]0f34d9082012-10-08 19:16:4477}
78
[email protected]01d3a962014-04-11 17:54:0779void ExtensionActionManager::OnExtensionUnloaded(
[email protected]e51232f32014-04-18 20:05:3680 content::BrowserContext* browser_context,
81 const Extension* extension,
limasdf0deef2042017-05-03 19:17:1782 UnloadedExtensionReason reason) {
Devlin Croninc7002c22019-05-15 00:46:1683 actions_.erase(extension->id());
[email protected]0f34d9082012-10-08 19:16:4484}
85
Devlin Croninc7002c22019-05-15 00:46:1686ExtensionAction* ExtensionActionManager::GetExtensionAction(
87 const Extension& extension) const {
88 auto iter = actions_.find(extension.id());
89 if (iter != actions_.end())
90 return iter->second.get();
[email protected]5ed5ec52012-10-12 21:28:3091
Devlin Cronin4831bfdb2020-04-15 22:31:3592 const ActionInfo* action_info =
93 ActionInfo::GetExtensionActionInfo(&extension);
[email protected]61e3cbe2012-10-14 22:06:5094 if (!action_info)
limasdf8fc2d0b92016-11-06 04:54:2595 return nullptr;
[email protected]2a88b40b2013-07-31 17:33:5196
97 // Only create action info for enabled extensions.
98 // This avoids bugs where actions are recreated just after being removed
[email protected]01d3a962014-04-11 17:54:0799 // in response to OnExtensionUnloaded().
Devlin Cronin94832fc2020-08-04 18:39:41100 if (!ExtensionRegistry::Get(browser_context_)
101 ->enabled_extensions()
102 .Contains(extension.id())) {
limasdf8fc2d0b92016-11-06 04:54:25103 return nullptr;
[email protected]6a24a0392014-08-12 21:31:33104 }
[email protected]2a88b40b2013-07-31 17:33:51105
Devlin Cronin580d6362019-05-07 20:38:45106 auto action = std::make_unique<ExtensionAction>(extension, *action_info);
rdevlin.cronind09e1c4d5c2016-11-19 01:03:20107
108 if (action->default_icon()) {
Jinho Bangb5216cec2018-01-17 19:43:11109 action->SetDefaultIconImage(std::make_unique<IconImage>(
Devlin Cronin94832fc2020-08-04 18:39:41110 browser_context_, &extension, *action->default_icon(),
rdevlin.cronind09e1c4d5c2016-11-19 01:03:20111 ExtensionAction::ActionIconSize(),
112 ExtensionAction::FallbackIcon().AsImageSkia(), nullptr));
113 }
114
limasdf8fc2d0b92016-11-06 04:54:25115 ExtensionAction* raw_action = action.get();
Devlin Croninc7002c22019-05-15 00:46:16116 actions_[extension.id()] = std::move(action);
limasdf8fc2d0b92016-11-06 04:54:25117 return raw_action;
[email protected]5ed5ec52012-10-12 21:28:30118}
119
[email protected]ad12b6b2012-11-28 23:21:15120} // namespace extensions