File: content_analysis_dialog_controller.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 (204 lines) | stat: -rw-r--r-- 8,621 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
// 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_ENTERPRISE_CONNECTORS_ANALYSIS_CONTENT_ANALYSIS_DIALOG_CONTROLLER_H_
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_CONTENT_ANALYSIS_DIALOG_CONTROLLER_H_

#include <cstddef>
#include <memory>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_base.h"
#include "chrome/browser/enterprise/connectors/analysis/content_analysis_dialog_delegate.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h"
#include "components/download/public/common/download_item.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/views/animation/bounds_animator.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/window/dialog_delegate.h"

namespace content {
class WebContents;
}  // namespace content

namespace views {
class ImageView;
class Label;
class Link;
class Textarea;
class Throbber;
}  // namespace views

namespace enterprise_connectors {

// Dialog shown for Deep Scanning to offer the possibility of cancelling the
// upload to the user.
class ContentAnalysisDialogController
    : public ContentAnalysisDialogDelegate,
      public content::WebContentsObserver,
      public download::DownloadItem::Observer {
 public:
  // TestObserver should be implemented by tests that need to track when certain
  // ContentAnalysisDialogController functions are called. The test can add
  // itself as an observer by using SetObserverForTesting.
  class TestObserver {
   public:
    virtual ~TestObserver() = default;

    // Called at the start of ContentAnalysisDialogController's constructor.
    // `dialog` is a pointer to the newly constructed
    // ContentAnalysisDialogController and should be kept in memory by the test
    // in order to validate its state.
    virtual void ConstructorCalled(ContentAnalysisDialogController* dialog,
                                   base::TimeTicks timestamp) {}

    // Called at the end of ContentAnalysisDialogController::Show. `timestamp`
    // is the time used by ContentAnalysisDialogController to decide whether the
    // pending state has been shown for long enough. The test can keep this time
    // in memory and validate the pending time was sufficient in DialogUpdated.
    virtual void ViewsFirstShown(ContentAnalysisDialogController* dialog,
                                 base::TimeTicks timestamp) {}

    // Called at the end of ContentAnalysisDialogController::UpdateDialog.
    // `result` is the value that UpdatedDialog used to transition from the
    // pending state to the success/failure/warning state.
    virtual void DialogUpdated(ContentAnalysisDialogController* dialog,
                               FinalContentAnalysisResult result) {}

    // Called at the start of CancelDialogAndDelete(). `dialog` is a pointer
    // that will soon be destructed. Along with `result`, it is used by the test
    // to validate the dialog should be canceled or deleted.
    virtual void CancelDialogAndDeleteCalled(
        ContentAnalysisDialogController* dialog,
        FinalContentAnalysisResult result) {}

    // Called at the end of ContentAnalysisDialogController's destructor.
    // `dialog` is a pointer to the ContentAnalysisDialogController being
    // destructed. It can be used to compare it to the pointer obtained from
    // ConstructorCalled to ensure which view is being destroyed.
    virtual void DestructorCalled(ContentAnalysisDialogController* dialog) {}
  };

  static void SetObserverForTesting(TestObserver* observer);

  static void SetMinimumPendingDialogTimeForTesting(base::TimeDelta delta);
  static void SetSuccessDialogTimeoutForTesting(base::TimeDelta delta);
  static void SetShowDialogDelayForTesting(base::TimeDelta delta);

  static base::TimeDelta GetMinimumPendingDialogTime();
  static base::TimeDelta GetSuccessDialogTimeout();
  static base::TimeDelta ShowDialogDelay();

  ContentAnalysisDialogController(
      std::unique_ptr<ContentAnalysisDelegateBase> delegate,
      bool is_cloud,
      content::WebContents* web_contents,
      safe_browsing::DeepScanAccessPoint access_point,
      int files_count,
      FinalContentAnalysisResult final_result =
          FinalContentAnalysisResult::SUCCESS,
      download::DownloadItem* download_item = nullptr);

  // content::WebContentsObserver:
  void WebContentsDestroyed() override;
  void PrimaryPageChanged(content::Page& page) override;

  // Updates the dialog with the result, and simply delete it from memory if
  // nothing should be shown.
  void ShowResult(FinalContentAnalysisResult result);

  inline bool is_cloud() const { return is_cloud_; }

  // Cancels the dialog an schedules it for deletion if visible, otherwise
  // simply deletes it soon.
  void CancelDialogAndDelete();

  // Accessors used to validate the views in tests.
  views::ImageView* GetTopImageForTesting() const;
  views::Throbber* GetSideIconSpinnerForTesting() const;
  views::StyledLabel* GetMessageForTesting() const;
  views::Link* GetLearnMoreLinkForTesting() const;
  views::Label* GetBypassJustificationLabelForTesting() const;
  views::Textarea* GetBypassJustificationTextareaForTesting() const;
  views::Label* GetJustificationTextLengthForTesting() const;

 private:
  // Friend the unit test class for this so it can call the private dtor.
  friend class ContentAnalysisDialogPlainTest;

  // Friend to allow use of TaskRunner::DeleteSoon().
  friend class base::DeleteHelper<ContentAnalysisDialogController>;

  ~ContentAnalysisDialogController() override;

  // Callback function of delayed timer to make the dialog visible.
  void ShowDialogNow();

  // Update the UI depending on `dialog_state_`. This also triggers resizes and
  // fires some events. It's meant to be called to update the entire dialog when
  // it's already showing.
  // This function can only be called after the dialog widget is initialized.
  void UpdateDialog();

  // Helper function to determine whether dialog should be shown immediately.
  bool ShouldShowDialogNow();

  void AcceptButtonCallback();
  void CancelButtonCallback();

  // This callback used by DialogDelegate::SetCancelCallback and is used to
  // ensure the auto-closing success dialog handles focus correctly.
  void SuccessCallback();

  // download::DownloadItem::Observer:
  void OnDownloadUpdated(download::DownloadItem* download) override;
  void OnDownloadOpened(download::DownloadItem* download) override;
  void OnDownloadDestroyed(download::DownloadItem* download) override;

  // Several conditions can lead to the dialog being no longer useful, so this
  // method is shared for those different conditions to close the dialog.
  void CancelDialogWithoutCallback();

  content::WebContents::Getter CreateWebContentsGetter();

  std::unique_ptr<ContentAnalysisDelegateBase> delegate_base_;

  base::TimeTicks first_shown_timestamp_;

  // `DownloadItem` for dialogs corresponding to a download with a reviewable
  // verdict. nullptr otherwise.
  raw_ptr<download::DownloadItem> download_item_ = nullptr;

  // Set to true once the dialog is either accepted or cancelled by the user.
  // This is used to decide whether the dialog should go away without user input
  // or not.
  bool accepted_or_cancelled_ = false;

  // Set to true once `DeleteSoon()` is called in `CancelDialogAndDelete()`.
  // This is used by other pending tasks, such as `ShowDialogNow()` to do
  // nothing if the dialog has been scheduled for deletion.
  bool will_be_deleted_soon_ = false;

  // If input events for our `WebContents` have been ignored, then this is the
  // closure to re-enable them.
  std::optional<content::WebContents::ScopedIgnoreInputEvents>
      scoped_ignore_input_events_;

  // A reference to the top level web contents of the tab whose content is
  // being analyzed.  Input events of this contents are ignored for the life
  // time of the dialog.
  base::WeakPtr<content::WebContents> top_level_contents_;

  base::WeakPtrFactory<ContentAnalysisDialogController> weak_ptr_factory_{this};
};

}  // namespace enterprise_connectors

#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_CONTENT_ANALYSIS_DIALOG_CONTROLLER_H_