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