1 // Copyright 2014 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 #include "chrome/browser/extensions/extension_action_test_util.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/run_loop.h"
11 #include "chrome/browser/extensions/tab_helper.h"
12 #include "chrome/browser/extensions/test_extension_system.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
15 #include "chrome/browser/ui/toolbar/toolbar_actions_model_factory.h"
16 #include "components/sessions/content/session_tab_helper.h"
17 #include "content/public/browser/web_contents.h"
18 #include "extensions/browser/extension_action.h"
19 #include "extensions/browser/extension_action_manager.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/common/extension.h"
22
23 namespace extensions {
24 namespace extension_action_test_util {
25
26 namespace {
27
GetPageActionCount(content::WebContents * web_contents,bool only_count_visible)28 size_t GetPageActionCount(content::WebContents* web_contents,
29 bool only_count_visible) {
30 DCHECK(web_contents);
31 size_t count = 0u;
32 SessionID tab_id = sessions::SessionTabHelper::IdForTab(web_contents);
33 Profile* profile =
34 Profile::FromBrowserContext(web_contents->GetBrowserContext());
35 ToolbarActionsModel* toolbar_model = ToolbarActionsModel::Get(profile);
36 const std::vector<ToolbarActionsModel::ActionId>& toolbar_action_ids =
37 toolbar_model->action_ids();
38 ExtensionActionManager* action_manager =
39 ExtensionActionManager::Get(web_contents->GetBrowserContext());
40 const ExtensionSet& enabled_extensions =
41 ExtensionRegistry::Get(profile)->enabled_extensions();
42 for (const ToolbarActionsModel::ActionId& action_id : toolbar_action_ids) {
43 const Extension* extension = enabled_extensions.GetByID(action_id);
44 ExtensionAction* extension_action =
45 action_manager->GetExtensionAction(*extension);
46 if (extension_action &&
47 extension_action->action_type() == ActionInfo::TYPE_PAGE &&
48 (!only_count_visible || extension_action->GetIsVisible(tab_id.id()))) {
49 ++count;
50 }
51 }
52 return count;
53 }
54
55 // Creates a new ToolbarActionsModel for the given |context|.
BuildToolbarModel(content::BrowserContext * context)56 std::unique_ptr<KeyedService> BuildToolbarModel(
57 content::BrowserContext* context) {
58 return std::make_unique<ToolbarActionsModel>(
59 Profile::FromBrowserContext(context),
60 extensions::ExtensionPrefs::Get(context));
61 }
62
63 // Creates a new ToolbarActionsModel for the given profile, optionally
64 // triggering the extension system's ready signal.
CreateToolbarModelImpl(Profile * profile,bool wait_for_ready)65 ToolbarActionsModel* CreateToolbarModelImpl(Profile* profile,
66 bool wait_for_ready) {
67 ToolbarActionsModel* model = ToolbarActionsModel::Get(profile);
68 if (model)
69 return model;
70
71 // No existing model means it's a new profile (since we, by default, don't
72 // create the ToolbarModel in testing).
73 ToolbarActionsModelFactory::GetInstance()->SetTestingFactory(
74 profile, base::BindRepeating(&BuildToolbarModel));
75 model = ToolbarActionsModel::Get(profile);
76 if (wait_for_ready) {
77 // Fake the extension system ready signal.
78 // HACK ALERT! In production, the ready task on ExtensionSystem (and most
79 // everything else on it, too) is shared between incognito and normal
80 // profiles, but a TestExtensionSystem doesn't have the concept of "shared".
81 // Because of this, we have to set any new profile's TestExtensionSystem's
82 // ready task, too.
83 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile))->
84 SetReady();
85 // Run tasks posted to TestExtensionSystem.
86 base::RunLoop().RunUntilIdle();
87 }
88
89 return model;
90 }
91
92 } // namespace
93
GetVisiblePageActionCount(content::WebContents * web_contents)94 size_t GetVisiblePageActionCount(content::WebContents* web_contents) {
95 return GetPageActionCount(web_contents, true);
96 }
97
GetTotalPageActionCount(content::WebContents * web_contents)98 size_t GetTotalPageActionCount(content::WebContents* web_contents) {
99 return GetPageActionCount(web_contents, false);
100 }
101
CreateToolbarModelForProfile(Profile * profile)102 ToolbarActionsModel* CreateToolbarModelForProfile(Profile* profile) {
103 return CreateToolbarModelImpl(profile, true);
104 }
105
CreateToolbarModelForProfileWithoutWaitingForReady(Profile * profile)106 ToolbarActionsModel* CreateToolbarModelForProfileWithoutWaitingForReady(
107 Profile* profile) {
108 return CreateToolbarModelImpl(profile, false);
109 }
110
111 } // namespace extension_action_test_util
112 } // namespace extensions
113