File: chip_controller.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (281 lines) | stat: -rw-r--r-- 9,953 bytes parent folder | download | duplicates (3)
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// 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_PERMISSIONS_CHIP_CHIP_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_PERMISSIONS_CHIP_CHIP_CONTROLLER_H_

#include <cstddef>
#include <memory>

#include "base/check_is_test.h"
#include "base/functional/callback_helpers.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/views/permissions/chip/permission_chip_view.h"
#include "components/permissions/permission_prompt.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/permission_util.h"
#include "ui/views/widget/widget_observer.h"

class PermissionPromptChipModel;
class LocationBarView;
class PermissionDashboardView;
class PermissionDashboardController;
// ButtonController that NotifyClick from being called when the
// BubbleOwnerDelegate's bubble is showing. Otherwise the bubble will show again
// immediately after being closed via losing focus.
class BubbleOwnerDelegate {
 public:
  virtual bool IsBubbleShowing() = 0;
  virtual bool IsAnimating() const = 0;
  virtual void RestartTimersOnMouseHover() = 0;
};

// This class controls a chip UI view to surface permission related information
// and prompts. For its creation, the controller expects an object of type
// PermissionChipView which should be a child view of another view. No ownership
// is transferred through the creation, and the controller will never destruct
// the PermissionChipView object. The controller and it's view are intended to
// be long-lived.
class ChipController : public permissions::PermissionRequestManager::Observer,
                       public views::WidgetObserver,
                       public BubbleOwnerDelegate,
                       public PermissionChipView::Observer {
 public:
  ChipController(
      LocationBarView* location_bar_view,
      PermissionChipView* chip_view,
      PermissionDashboardView* permission_dashboard_view = nullptr,
      PermissionDashboardController* permission_dashboard_controller = nullptr);

  ~ChipController() override;
  ChipController(const ChipController&) = delete;
  ChipController& operator=(const ChipController&) = delete;

  // PermissionRequestManager::Observer:
  void OnPermissionRequestManagerDestructed() override;
  void OnTabVisibilityChanged(content::Visibility visibility) override;
  // Called when the currently active permission request was finalized. That
  // could be called independently of `OnRequestDecided`.
  void OnRequestsFinalized() override;
  // Called when currently visible permission prompt was removed. That is called
  // independently from `OnRequestsFinalized` and `OnRequestDecided`.
  void OnPromptRemoved() override;

  // OnBubbleRemoved only triggers when a request chip (bubble) is removed, when
  // the user navigates while a confirmation chip is showing, the request is
  // already finished and hence OnBubbleRemoved is not triggered. Thus we need
  // to handle chip cleanup on navigation events separately.
  void OnNavigation(content::NavigationHandle* navigation_handle) override;

  // Called when there is a decision for a permission request.
  void OnRequestDecided(permissions::PermissionAction permissions) override;

  // BubbleOwnerDelegate:
  bool IsBubbleShowing() override;
  bool IsAnimating() const override;
  void RestartTimersOnMouseHover() override;

  // WidgetObserver:
  void OnWidgetDestroying(views::Widget* widget) override;
  void OnWidgetDestroyed(views::Widget* widget) override;
  void OnWidgetActivationChanged(views::Widget* widget, bool active) override;

  // PermissionChipView::Observer
  void OnChipVisibilityChanged(bool is_visible) override;
  void OnExpandAnimationEnded() override;
  void OnCollapseAnimationEnded() override;

  // Initializes the permission prompt model as well as the permission request
  // manager and observes the prompt bubble.
  void InitializePermissionPrompt(
      base::WeakPtr<permissions::PermissionPrompt::Delegate> delegate,
      base::OnceCallback<void()> = base::DoNothing());

  // Displays a permission chip. Call ShowPermissionPrompt() instead to show
  // both a chip and a prompt.
  void ShowPermissionChip(
      base::WeakPtr<permissions::PermissionPrompt::Delegate> delegate);

  // Displays a permission prompt using the chip UI.
  void ShowPermissionPrompt(
      base::WeakPtr<permissions::PermissionPrompt::Delegate> delegate);

  // Chip View.
  PermissionChipView* chip() { return chip_; }

  // Hide and clean up the chip.
  void ResetPermissionPromptChip();

  // Hide and clean up only if the chip displays a permission request. That
  // method is no-op if the confirmation chip is displayed.
  void ResetPermissionRequestChip();

  bool IsPermissionPromptChipVisible() {
    return chip_ && chip_->GetVisible() && permission_prompt_model_;
  }

  views::Widget* GetBubbleWidget();

  PermissionPromptBubbleBaseView* GetPromptBubbleView();

  void ClosePermissionPrompt();
  void PromptDecided(permissions::PermissionAction action);

  PermissionPromptChipModel* permission_prompt_model() {
    return permission_prompt_model_.get();
  }

  bool should_expand_for_testing();

  bool is_collapse_timer_running_for_testing() const {
    CHECK_IS_TEST();
    return collapse_timer_.IsRunning();
  }

  void fire_collapse_timer_for_testing() {
    CHECK_IS_TEST();
    collapse_timer_.FireNow();
  }

  bool is_dismiss_timer_running_for_testing() const {
    CHECK_IS_TEST();
    return dismiss_timer_.IsRunning();
  }

  void stop_animation_for_test() {
    CHECK_IS_TEST();
    chip_->animation_for_testing()->Stop();
    OnExpandAnimationEnded();
  }

  views::View* get_prompt_bubble_view_for_testing() {
    CHECK_IS_TEST();
    return bubble_tracker_.view();
  }

  std::optional<permissions::PermissionRequestManager*>
  active_permission_request_manager() {
    return active_chip_permission_request_manager_;
  }

  bool is_confirmation_showing() const { return is_confirmation_showing_; }

  bool is_waiting_for_confirmation_collapse_for_testing() const {
    CHECK_IS_TEST();
    return is_waiting_for_confirmation_collapse_;
  }

  void set_is_bubble_suppressed(bool is_bubble_suppressed) {
    is_bubble_suppressed_ = is_bubble_suppressed;
  }

  void DoNotCollapseForTesting() { do_no_collapse_for_testing_ = true; }

 private:
  FRIEND_TEST_ALL_PREFIXES(PermissionChipUnitTest, AccessibleName);

  bool ShouldWaitForConfirmationToComplete() const;
  bool ShouldWaitForLHSIndicatorToCollapse() const;
  void AnimateExpand();

  // Confirmation chip.
  void HandleConfirmation(permissions::PermissionAction permission_action);
  void CollapseConfirmation();

  // Permission prompt chip functionality.
  void AnnouncePermissionRequestForAccessibility(const std::u16string& text);
  void CollapsePrompt(bool allow_restart);

  // Hides the chip and invalidates the layout.
  void HideChip();

  void ShowPermissionUi(
      base::WeakPtr<permissions::PermissionPrompt::Delegate> delegate);

  // Permission prompt bubble functiontionality.
  void OpenPermissionPromptBubble();
  void ClosePermissionPromptBubbleWithReason(
      views::Widget::ClosedReason reason);

  void RecordRequestChipButtonPressed(const char* recordKey);

  // Event handling.
  void ObservePromptBubble();
  void OnPromptBubbleDismissed();
  void OnPromptExpired();
  void OnRequestChipButtonPressed();

  // Updates chip icon, text and theme with model.
  void SyncChipWithModel();

  // Opens the Page Info Dialog.
  void ShowPageInfoDialog();

  // Actions executed when the user closes the page info dialog.
  void OnPageInfoBubbleClosed(views::Widget::ClosedReason closed_reason,
                              bool reload_prompt);

  // Clean up utility.
  void RemoveBubbleObserverAndResetTimersAndChipCallbacks();

  // Timer functionality.
  void StartCollapseTimer();
  void StartDismissTimer();
  void ResetTimers();

  // The location bar view to which the chip is attached.
  LocationBarView* GetLocationBarView() { return location_bar_view_; }

  bool is_confirmation_showing_ = false;
  bool is_waiting_for_confirmation_collapse_ = false;

  // `LocationBarView` owns this.
  raw_ptr<LocationBarView> location_bar_view_ = nullptr;
  // The chip view this controller modifies.
  raw_ptr<PermissionChipView> chip_;

  // `PermissionDashboardView` is an owner of PermissionChipView.
  raw_ptr<PermissionDashboardView> permission_dashboard_view_;
  // `PermissionDashboardController` is an owner of this.
  raw_ptr<PermissionDashboardController> permission_dashboard_controller_;

  // The time when the request chip was displayed.
  base::TimeTicks request_chip_shown_time_;

  // A timer used to dismiss the permission request after it's been collapsed
  // for a while.
  base::OneShotTimer dismiss_timer_;

  // A timer used to collapse the chip after a delay.
  base::OneShotTimer collapse_timer_;

  // A timer used to delay showing a prompt if a confirmation chip is being
  // displayed.
  base::OneShotTimer delay_prompt_timer_;

  bool parent_was_visible_when_activation_changed_ = false;

  // The model of a permission prompt if one is present.
  std::unique_ptr<PermissionPromptChipModel> permission_prompt_model_;

  std::optional<permissions::PermissionRequestManager*>
      active_chip_permission_request_manager_;

  views::ViewTracker bubble_tracker_;
  bool is_bubble_suppressed_ = false;

  bool do_no_collapse_for_testing_ = false;

  // Keep prompt's decision until the prompt's widget is removed.
  std::optional<permissions::PermissionAction> prompt_decision_;

  base::ScopedClosureRunner disallowed_custom_cursors_scope_;

  base::ScopedObservation<PermissionChipView, PermissionChipView::Observer>
      observation_{this};

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

#endif  // CHROME_BROWSER_UI_VIEWS_PERMISSIONS_CHIP_CHIP_CONTROLLER_H_