File: extensions_menu_view.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (176 lines) | stat: -rw-r--r-- 7,081 bytes parent folder | download | duplicates (5)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright 2019 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_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_VIEW_H_

#include <memory>
#include <string>
#include <vector>

#include "base/auto_reset.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/extensions/permissions/site_permissions_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/label_button.h"

namespace views {
class Button;
class View;
}  // namespace views

class Browser;
class ExtensionsContainer;
class ExtensionMenuItemView;

// This bubble view displays a list of user extensions and a button to get to
// managing the user's extensions (chrome://extensions).
class ExtensionsMenuView : public views::BubbleDialogDelegateView,
                           public TabStripModelObserver,
                           public ToolbarActionsModel::Observer {
  METADATA_HEADER(ExtensionsMenuView, views::BubbleDialogDelegateView)

 public:
  ExtensionsMenuView(views::View* anchor_view,
                     Browser* browser,
                     ExtensionsContainer* extensions_container);
  ExtensionsMenuView(const ExtensionsMenuView&) = delete;
  ExtensionsMenuView& operator=(const ExtensionsMenuView&) = delete;
  ~ExtensionsMenuView() override;

  // Displays the ExtensionsMenu under |anchor_view|, attached to |browser|, and
  // with the associated |extensions_container|.
  // Only one menu is allowed to be shown at a time (outside of tests).
  static views::Widget* ShowBubble(views::View* anchor_view,
                                   Browser* browser,
                                   ExtensionsContainer* extensions_container);

  // Returns true if there is currently an ExtensionsMenuView showing (across
  // all browsers and profiles).
  static bool IsShowing();

  // Hides the currently-showing ExtensionsMenuView, if any exists.
  static void Hide();

  // Returns the currently-showing ExtensionsMenuView, if any exists.
  static ExtensionsMenuView* GetExtensionsMenuViewForTesting();

  // Returns the children of a section for the given `site_interaction`.
  static std::vector<ExtensionMenuItemView*> GetSortedItemsForSectionForTesting(
      extensions::SitePermissionsHelper::SiteInteraction site_interaction);

  // views::BubbleDialogDelegateView:
  std::u16string GetAccessibleWindowTitle() const override;

  // TabStripModelObserver:
  void TabChangedAt(content::WebContents* contents,
                    int index,
                    TabChangeType change_type) override;
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override;

  // ToolbarActionsModel::Observer:
  void OnToolbarActionAdded(const ToolbarActionsModel::ActionId& item) override;
  void OnToolbarActionRemoved(
      const ToolbarActionsModel::ActionId& action_id) override;
  void OnToolbarActionUpdated(
      const ToolbarActionsModel::ActionId& action_id) override;
  void OnToolbarModelInitialized() override;
  void OnToolbarPinnedActionsChanged() override;

  // For testing.
  base::flat_set<raw_ptr<ExtensionMenuItemView, CtnExperimental>>
  extensions_menu_items_for_testing();
  views::Button* manage_extensions_button_for_testing();
  // Returns a scoped object allowing test dialogs to be created (i.e.,
  // instances of the ExtensionsMenuView that are not created through
  // ShowBubble()).
  // We don't just use ShowBubble() in tests because a) there can be more than
  // one instance of the menu, and b) the menu, when shown, is dismissed by
  // changes in focus, which isn't always desirable. Additionally, constructing
  // the view directly is more friendly to unit test setups.
  static base::AutoReset<bool> AllowInstancesForTesting();

 private:
  // A "section" within the menu, based on the extension's current access to
  // the page.
  struct Section {
    // The root view for this section; this is used to toggle the visibility of
    // the entire section (depending on whether there are any menu items).
    raw_ptr<views::View> container;

    // The view containing only the extension menu items for this section. This
    // is separated for easy sorting, insertion, and iteration of menu items.
    // The children are guaranteed to only be ExtensionMenuItemViews.
    raw_ptr<views::View> menu_items;

    // The id of the string to use for the section heading.
    const int header_string_id;

    // The id of the string to use for the longer description of the section.
    const int description_string_id;

    // The site interaction that this section is handling.
    const extensions::SitePermissionsHelper::SiteInteraction site_interaction;
  };

  // Initially populates the menu by creating sections with menu items for all
  // extensions.
  void Populate();

  std::unique_ptr<views::View> CreateExtensionButtonsContainer();

  // Returns the appropriate section for the given `site_interaction`.
  Section* GetSectionForSiteInteraction(
      extensions::SitePermissionsHelper::SiteInteraction site_interaction);

  // Sorts the views within all sections by the name of the action.
  void SortMenuItemsByName();

  // Inserts the menu item into the appropriate section (but not necessarily at
  // the right spot).
  void InsertMenuItem(ExtensionMenuItemView* menu_item);

  // Adds a menu item for a newly-added extension.
  void CreateAndInsertNewItem(const ToolbarActionsModel::ActionId& id);

  // Updates the visibility of the menu sections. A given section should be
  // visible if there are any extensions displayed in it.
  void UpdateSectionVisibility();

  // Updates the menu.
  void Update();

  // Runs a set of sanity checks on the appearance of the menu. This is a no-op
  // if DCHECKs are disabled.
  void SanityCheck();

  const raw_ptr<Browser> browser_;
  const raw_ptr<ExtensionsContainer> extensions_container_;
  const raw_ptr<ToolbarActionsModel> toolbar_model_;
  base::ScopedObservation<ToolbarActionsModel, ToolbarActionsModel::Observer>
      toolbar_model_observation_{this};

  // A collection of all menu item views in the menu. Note that this is
  // *unordered*, since the menu puts extensions into different sections.
  base::flat_set<raw_ptr<ExtensionMenuItemView, CtnExperimental>>
      extensions_menu_items_;

  raw_ptr<views::LabelButton> manage_extensions_button_ = nullptr;

  // The different sections in the menu.
  Section cant_access_;
  Section wants_access_;
  Section has_access_;
};

#endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_VIEW_H_