File: download_bubble_row_view.h

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; 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 (256 lines) | stat: -rw-r--r-- 10,282 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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// Copyright 2022 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_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_ROW_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_ROW_VIEW_H_

#include <string_view>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/download/download_commands.h"
#include "chrome/browser/download/download_ui_model.h"
#include "chrome/browser/ui/download/download_bubble_row_view_info.h"
#include "chrome/browser/ui/download/download_item_mode.h"
#include "chrome/browser/ui/views/controls/hover_button.h"
#include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h"
#include "components/download/public/common/download_item.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"

namespace ui {
class Event;
}

namespace views {
class ImageView;
class InputEventActivationProtector;
class Label;
class MdTextButton;
class ImageButton;
class ProgressBar;
class FlexLayoutView;
class InkDropContainerView;
}  // namespace views

class DownloadShelfContextMenuView;
class DownloadBubbleUIController;

class DownloadBubbleRowView : public views::View,
                              public views::ContextMenuController,
                              public views::FocusChangeListener,
                              public DownloadBubbleRowViewInfoObserver {
  METADATA_HEADER(DownloadBubbleRowView, views::View)

 public:
  DownloadBubbleRowView(
      const DownloadBubbleRowViewInfo& info,
      base::WeakPtr<DownloadBubbleUIController> bubble_controller,
      base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler,
      base::WeakPtr<Browser> browser,
      int fixed_width);
  DownloadBubbleRowView(const DownloadBubbleRowView&) = delete;
  DownloadBubbleRowView& operator=(const DownloadBubbleRowView&) = delete;
  ~DownloadBubbleRowView() override;

  // Overrides views::View:
  void AddedToWidget() override;
  void RemovedFromWidget() override;
  void Layout(PassKey) override;
  Views GetChildrenInZOrder() override;
  bool OnMouseDragged(const ui::MouseEvent& event) override;
  void OnMouseCaptureLost() override;
  void OnMouseEntered(const ui::MouseEvent& event) override;
  void OnMouseExited(const ui::MouseEvent& event) override;
  gfx::Size CalculatePreferredSize(
      const views::SizeBounds& /*available_size*/) const override;
  void AddLayerToRegion(ui::Layer* layer, views::LayerRegion region) override;
  void RemoveLayerFromRegions(ui::Layer* layer) override;
  void VisibilityChanged(views::View* starting_from, bool is_visible) override;

  // Overrides views::FocusChangeListener
  void OnWillChangeFocus(views::View* before, views::View* now) override;

  // Update the row and its elements for hover and focus events.
  void UpdateRowForHover(bool hovered);
  void UpdateRowForFocus(bool visible, bool request_focus_on_last_quick_action);

  // Overrides views::ContextMenuController:
  void ShowContextMenuForViewImpl(
      View* source,
      const gfx::Point& point,
      ui::mojom::MenuSourceType source_type) override;

  // Overrides ui::AcceleratorTarget
  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
  bool CanHandleAccelerators() const override;

  // Returns the transparent button that is activated when the row is clicked.
  views::Button* transparent_button() { return transparent_button_; }

  std::u16string_view GetSecondaryLabelTextForTesting();

  DownloadUIModel* model() { return info_->model(); }
  const DownloadBubbleRowViewInfo& info() const { return *info_; }

  void SimulateMainButtonClickForTesting(const ui::Event& event);
  bool IsQuickActionButtonVisibleForTesting(DownloadCommands::Command command);
  views::ImageButton* GetQuickActionButtonForTesting(
      DownloadCommands::Command command);
  void SetInputProtectorForTesting(
      std::unique_ptr<views::InputEventActivationProtector> input_protector);

 protected:
  // Overrides ui::LayerDelegate:
  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                  float new_device_scale_factor) override;

 private:
  void AddMainPageButton(DownloadCommands::Command command,
                         const std::u16string& button_string);
  void AddQuickAction(DownloadCommands::Command command);
  std::u16string GetAccessibleNameForQuickAction(
      DownloadCommands::Command command);
  std::u16string GetAccessibleNameForMainPageButton(
      DownloadCommands::Command command);

  // Update the DownloadBubbleRowView's members.
  void UpdateRow(bool initial_setup);

  void UpdateStatusText();
  void UpdateButtons();
  void UpdateProgressBar();
  void UpdateLabels();
  void RecordMetricsOnUpdate();
  void RecordDownloadDisplayed();

  // Load the appropriate |file_icon_| from the IconManager, or a default icon.
  // Returns whether we were able to synchronously set |icon_| to an appropriate
  // icon for the file path.
  bool StartLoadFileIcon();
  // Callback invoked when the IconManager's lookup returns.
  void OnFileIconLoaded(gfx::Image icon);
  // Sets |icon_| to the image in |file_icon_|.
  void SetFileIconAsIcon(bool is_default_icon);

  // Set the |icon_|, which may be an override (warning or incognito icon),
  // default icon, or loaded from the cache or from IconManager::LoadIcon.
  void SetIcon();

  // Sets |icon_| to |icon|, regardless of what kind of icon it is.
  void SetIconFromImage(gfx::Image icon);
  void SetIconFromImageModel(const ui::ImageModel& icon);

  // Called when the transparent button (covering the whole row) is pressed.
  void OnMainButtonPressed(const ui::Event& event);
  // Called when the button on the side of the row (the "main page button") or a
  // quick action button is pressed.
  void OnActionButtonPressed(DownloadCommands::Command command,
                             const ui::Event& event);

  // Registers/unregisters copy accelerator for copy/paste support.
  void RegisterAccelerators(views::FocusManager* focus_manager);
  void UnregisterAccelerators(views::FocusManager* focus_manager);

  // DownloadBubbleRowViewInfoObserver implementation:
  void OnInfoChanged() override;

  // The icon for the file. We get platform-specific file type icons from
  // IconLoader (see below).
  raw_ptr<views::ImageView> icon_ = nullptr;
  raw_ptr<views::ImageView> subpage_icon_ = nullptr;
  raw_ptr<views::FlexLayoutView> subpage_icon_holder_ = nullptr;
  // The icon for the filetype, fetched from the platform-specific IconLoader.
  // This can differ from the image in |icon_| if |icon_| is not the file type
  // icon, e.g. if it is the incognito icon or a warning icon. We cache it here
  // in case |icon_| is different, because it is used when drag-and-dropping.
  // If the IconLoader does not return a file icon, this stores a default icon.
  gfx::Image file_icon_;

  // The primary label.
  raw_ptr<views::Label> primary_label_ = nullptr;

  // The secondary label.
  raw_ptr<views::Label> secondary_label_ = nullptr;

  // Buttons on the main page.
  base::flat_map<DownloadCommands::Command, raw_ptr<views::MdTextButton>>
      main_page_buttons_;

  // Quick Actions on the main page.
  base::flat_map<DownloadCommands::Command, raw_ptr<views::ImageButton>>
      quick_actions_;

  // Holder for the main button.
  raw_ptr<views::FlexLayoutView> main_button_holder_ = nullptr;
  // Holder for the quick actions.
  raw_ptr<views::FlexLayoutView> quick_action_holder_ = nullptr;

  // The progress bar for in-progress downloads.
  raw_ptr<views::ProgressBar> progress_bar_ = nullptr;
  raw_ptr<views::FlexLayoutView> progress_bar_holder_ = nullptr;

  // Device scale factor, used to load icons.
  float current_scale_ = 1.0f;

  // The model controlling this object's state.
  raw_ref<const DownloadBubbleRowViewInfo> info_;

  // Reuse the download shelf context menu in the bubble.
  std::unique_ptr<DownloadShelfContextMenuView> context_menu_;

  // Controller for keeping track of downloads.
  base::WeakPtr<DownloadBubbleUIController> bubble_controller_ = nullptr;

  base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler_ = nullptr;

  base::WeakPtr<Browser> browser_ = nullptr;

  // The last override icon, e.g. an incognito or warning icon. If this is
  // null, we should either use the filetype icon or a default icon.
  raw_ptr<const gfx::VectorIcon> last_overridden_icon_ = nullptr;
  // Whether the currently set |icon_| is the default icon.
  bool has_default_icon_ = false;

  // Button for transparent button click, inkdrop animations and drag and drop
  // events.
  raw_ptr<views::Button> transparent_button_ = nullptr;

  raw_ptr<views::InkDropContainerView> inkdrop_container_;

  // Drag and drop:
  // Whether we are dragging the download bubble row.
  bool dragging_ = false;
  // Position that a possible drag started at.
  std::optional<gfx::Point> drag_start_point_;

  // Whether the download's completion has already been logged. This is used to
  // avoid inaccurate repeated logging.
  bool has_download_completion_been_logged_ = false;

  // A timer for updating the status text string.
  base::RepeatingTimer update_status_text_timer_;

  // Tracks tasks requesting file icons.
  base::CancelableTaskTracker cancelable_task_tracker_;

  // Mitigates the risk of clickjacking by enforcing a delay in click input.
  std::unique_ptr<views::InputEventActivationProtector> input_protector_;

  // TODO(crbug.com/40233803): The size constraint is not passed down from the
  // views tree in the first round of layout, so setting a fixed width to bound
  // the view. This is assuming that the row view is loaded inside a bubble. It
  // will break if the row view is loaded inside a different parent view.
  const int fixed_width_;

  base::WeakPtrFactory<DownloadBubbleRowView> weak_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_ROW_VIEW_H_