File: download_ui_model.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; 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 (552 lines) | stat: -rw-r--r-- 21,903 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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
// Copyright 2018 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_DOWNLOAD_DOWNLOAD_UI_MODEL_H_
#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UI_MODEL_H_

#include <stdint.h>

#include <optional>
#include <string>

#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/default_clock.h"
#include "build/build_config.h"
#include "components/download/public/common/download_item.h"
#include "components/offline_items_collection/core/offline_item.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/content/common/proto/download_file_types.pb.h"
#include "ui/base/models/image_model.h"
#include "ui/color/color_id.h"
#include "ui/gfx/vector_icon_types.h"

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/download/download_commands.h"
#endif

using offline_items_collection::ContentId;

class Profile;

namespace content {
class WebContents;
}  // namespace content

namespace gfx {
class FontList;
}  // namespace gfx

// This class is an abstraction for common UI tasks and properties associated
// with a download.
class DownloadUIModel {
 public:
  // The type of tailored warning that is shown.
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class TailoredWarningType {
    kNoTailoredWarning = 0,
    // Base cookie theft warning.
    kCookieTheft = 1,
    // Deprecated. Cookie theft warning with account info.
    // kCookieTheftWithAccountInfo = 2,
    // Suspicious archive warning.
    kSuspiciousArchive = 3,
    kMaxValue = kSuspiciousArchive
  };

  // Represents the UI pattern used for the download, based on its danger type.
  // This should be consistent across the download bubble and
  // chrome://downloads, wherever download warnings are displayed.
  enum class DangerUiPattern {
    // The download has no warning and no error conditions.
    kNormal,
    // The download has a warning with a red "dangerous" icon and red text.
    kDangerous,
    // The download has a warning with a gray "warning" icon and gray text.
    // Includes "unverified" and insecure.
    kSuspicious,
    // Some other combination of warning colors/icons, including the "download
    // off" icon for an error or cancellation.
    kOther,
  };

  // Abstract base class for building StatusText
  class StatusTextBuilderBase {
   public:
    virtual ~StatusTextBuilderBase() = default;
    void SetModel(DownloadUIModel* model);

    // Returns a short one-line status string for the download.
    std::u16string GetStatusText(
        download::DownloadItem::DownloadState state) const;

    std::u16string GetCompletedRemovedOrSavedStatusText() const;
    // Returns a string indicating the status of an in-progress download.
    virtual std::u16string GetInProgressStatusText() const = 0;

    // Returns a string indicating the status of a completed download.
    virtual std::u16string GetCompletedStatusText() const = 0;

    // Returns a string representation of the current download progress sizes.
    // If the total size of the download is known, this string looks like:
    // "100/200 MB" where the numerator is the transferred size and the
    // denominator is the total size. If the total isn't known, returns the
    // transferred size as a string (e.g.: "100 MB").
    virtual std::u16string GetProgressSizesString() const = 0;

    // Returns a string indicating the status of an interrupted download.
    virtual std::u16string GetInterruptedStatusText(
        offline_items_collection::FailState fail_state) const;

    // Returns a short string indicating why the download failed.
    virtual std::u16string GetFailStateMessage(
        offline_items_collection::FailState fail_state) const;

    // Unknowned model to create statuses.
    raw_ptr<DownloadUIModel> model_ = nullptr;
  };

  // Used in Download shelf and page, default option.
  class StatusTextBuilder : public StatusTextBuilderBase {
   public:
    std::u16string GetInProgressStatusText() const override;
    std::u16string GetCompletedStatusText() const override;
    std::u16string GetProgressSizesString() const override;
  };

  // Used in Download bubble.
  class BubbleStatusTextBuilder : public StatusTextBuilderBase {
   public:
    std::u16string GetInProgressStatusText() const override;
    std::u16string GetCompletedStatusText() const override;
    std::u16string GetInterruptedStatusText(
        offline_items_collection::FailState fail_state) const override;
    std::u16string GetProgressSizesString() const override;

   private:
    FRIEND_TEST_ALL_PREFIXES(DownloadItemModelTest,
                             GetBubbleStatusMessageWithBytes);

    static std::u16string GetBubbleStatusMessageWithBytes(
        const std::u16string& bytes_substring,
        const std::u16string& detail_message,
        bool is_active);
    std::u16string GetBubbleWarningStatusText() const;
  };

  using DownloadUIModelPtr = std::unique_ptr<DownloadUIModel>;

  DownloadUIModel();

  explicit DownloadUIModel(
      std::unique_ptr<StatusTextBuilderBase> status_text_builder);

  DownloadUIModel(const DownloadUIModel&) = delete;
  DownloadUIModel& operator=(const DownloadUIModel&) = delete;

  virtual ~DownloadUIModel();

  // Delegate for a single DownloadUIModel.
  class Delegate {
   public:
    virtual void OnDownloadUpdated() {}
    virtual void OnDownloadOpened() {}
    virtual void OnDownloadDestroyed(const ContentId& id) {}

    virtual ~Delegate() = default;
  };

  void SetDelegate(Delegate* delegate);

  base::WeakPtr<DownloadUIModel> GetWeakPtr();

  // Does this download have a MIME type (either explicit or inferred from its
  // extension) suggesting that it is a supported image type?
  bool HasSupportedImageMimeType() const;

  // Returns a string representation of the current download progress sizes.
  // If the total size of the download is known, this string looks like:
  // "100/200 MB" where the numerator is the transferred size and the
  // denominator is the total size. If the total isn't known, returns the
  // transferred size as a string (e.g.: "100 MB").
  std::u16string GetProgressSizesString() const;

  // Returns a long descriptive string for a download that's in the INTERRUPTED
  // state. For other downloads, the returned string will be empty.
  std::u16string GetInterruptDescription() const;

  // Returns a status string for the download history page.
  std::u16string GetHistoryPageStatusText() const;

  // Returns a short one-line status string for the download.
  std::u16string GetStatusText() const;
#if !BUILDFLAG(IS_ANDROID)
  std::u16string GetStatusTextForLabel(const gfx::FontList& font_list,
                                       float available_pixel_width) const;
#endif

  // Returns a string suitable for use as a tooltip. For a regular download, the
  // tooltip is the filename. For an interrupted download, the string states the
  // filename and a short description of the reason for interruption. For
  // example:
  //    Report.pdf
  //    Network disconnected
  std::u16string GetTooltipText() const;

  // Get the warning text to display for a dangerous download. |filename| is the
  // (possibly-elided) filename; if it is present in the resulting string,
  // |offset| will be set to the starting position of the filename.
  std::u16string GetWarningText(const std::u16string& filename,
                                size_t* offset) const;

  // Get the caption text for a button for confirming a dangerous download
  // warning.
  std::u16string GetWarningConfirmButtonText() const;

  // Get the text to display for the button to show item in folder on download
  // history page.
  std::u16string GetShowInFolderText() const;

  // Returns the profile associated with this download.
  virtual Profile* profile() const;

  // Returns the content id associated with this download.
  virtual ContentId GetContentId() const;

  // Returns the localized status text for an in-progress download. This
  // is the progress status used in the WebUI interface.
  virtual std::u16string GetTabProgressStatusText() const;

  // Get the number of bytes that has completed so far.
  virtual int64_t GetCompletedBytes() const;

  // Get the total number of bytes for this download. Should return 0 if the
  // total size of the download is not known. Virtual for testing.
  virtual int64_t GetTotalBytes() const;

  // Returns the total number of bytes uploaded to the cloud. Returns 0 if the
  // upload has not started.
  virtual int64_t GetUploadedBytes() const;

  // Rough percent complete. Returns -1 if the progress is unknown.
  virtual int PercentComplete() const;

  // Is this considered a dangerous download?
  virtual bool IsDangerous() const;

  // Is this considered a malicious download? Implies IsDangerous().
  virtual bool MightBeMalicious() const;

  // Is this considered a malicious download with very high confidence?
  // Implies IsDangerous() and MightBeMalicious().
  virtual bool IsMalicious() const;

  // Is this download an insecure download, but not something more severe?
  // Implies IsDangerous() and !IsMalicious().
  virtual bool IsInsecure() const;

  // Returns |true| if this download is expected to complete successfully and
  // thereafter be removed from the shelf.  Downloads that are opened
  // automatically or are temporary will be removed from the shelf on successful
  // completion.
  //
  // Returns |false| if the download is not expected to complete (interrupted,
  // cancelled, dangerous, malicious), or won't be removed on completion.
  //
  // Since the expectation of successful completion may change, the return value
  // of this function will change over the course of a download.
  virtual bool ShouldRemoveFromShelfWhenComplete() const;

  // Returns |true| if the download started animation (big download arrow
  // animates down towards the shelf) should be displayed for this download.
  // Downloads that were initiated via "Save As" or are extension installs don't
  // show the animation.
  virtual bool ShouldShowDownloadStartedAnimation() const;

  // Returns |true| if this download should be displayed in the downloads shelf.
  virtual bool ShouldShowInShelf() const;

  // Change whether the download should be displayed on the downloads
  // shelf. Setting this is only effective if the download hasn't already been
  // displayed in the shelf.
  virtual void SetShouldShowInShelf(bool should_show);

  // Returns |true| if the UI should be notified when the download is ready to
  // be presented in the UI. Note that this is independent of
  // ShouldShowInShelf() since there might be actions other than showing in the
  // shelf that the UI must perform.
  virtual bool ShouldNotifyUI() const;

  // Returns |true| if the UI has been notified about this download. By default,
  // this value is |false| and should be changed explicitly using
  // SetWasUINotified().
  virtual bool WasUINotified() const;

  // Change what's returned by WasUINotified().
  virtual void SetWasUINotified(bool should_notify);

  // Returns |true| if the download was actioned on. This governs if the
  // download should be shown in the Download Bubble's partial view.
  virtual bool WasActionedOn() const;

  // Change what's returned by WasActionedOn().
  virtual void SetActionedOn(bool actioned_on);

  // Returns |true| if the UI (download bubble, downloads page, notification)
  // has shown this download warning. By default, this value is |false| and
  // should be changed explicitly using SetWasUIWarningShown(). Used to prevent
  // double-logging of download warnings.
  virtual bool WasUIWarningShown() const;

  // Change what's returned by WasUIWarningShown().
  virtual void SetWasUIWarningShown(bool was_ui_warning_shown);

  // If this is an ephemeral warning, returns when the bubble first displayed
  // the warning. If the warning has not yet shown (or this isn't an ephemeral
  // warning), it returns no value. This does not persist across restarts.
  virtual std::optional<base::Time> GetEphemeralWarningUiShownTime() const;

  virtual void SetEphemeralWarningUiShownTime(std::optional<base::Time> time);

  // Returns |true| if opening in the browser is preferred for this download. If
  // |false|, the download should be opened with the system default application.
  virtual bool ShouldPreferOpeningInBrowser();

  // Change what's returned by ShouldPreferOpeningInBrowser to |preference|.
  virtual void SetShouldPreferOpeningInBrowser(bool preference);

  // Return the danger level determined during download target determination.
  // The value returned here is independent of the danger level as determined by
  // the Safe Browsing.
  virtual safe_browsing::DownloadFileType::DangerLevel GetDangerLevel() const;

  // Change what's returned by GetDangerLevel().
  virtual void SetDangerLevel(
      safe_browsing::DownloadFileType::DangerLevel danger_level);

  // Return the mixed content status determined during download target
  // determination.
  virtual download::DownloadItem::InsecureDownloadStatus
  GetInsecureDownloadStatus() const;

  // Open the download using the platform handler for the download. The behavior
  // of this method will be different from DownloadItem::OpenDownload() if
  // ShouldPreferOpeningInBrowser().
  virtual void OpenUsingPlatformHandler();

#if BUILDFLAG(IS_CHROMEOS)
  // Returns the Media App action (open or edit) we should show for the item if
  // one should be shown.
  virtual std::optional<DownloadCommands::Command> MaybeGetMediaAppAction()
      const;

  // Open the download using the media app ('Gallery').
  virtual void OpenUsingMediaApp();
#endif

  // Whether the download was removed and this is currently being undone.
  virtual bool IsBeingRevived() const;

  // Set whether the download is being revived.
  virtual void SetIsBeingRevived(bool is_being_revived);

  // Returns the DownloadItem if this is a regular download, or nullptr
  // otherwise.
  virtual const download::DownloadItem* GetDownloadItem() const;
  download::DownloadItem* GetDownloadItem();

  // Returns the file-name that should be reported to the user.
  virtual base::FilePath GetFileNameToReportUser() const;

  // Target path of an in-progress download.
  // May be empty if the target path hasn't yet been determined.
  virtual base::FilePath GetTargetFilePath() const;

  // Opens the file associated with this download.  If the download is
  // still in progress, marks the download to be opened when it is complete.
  virtual void OpenDownload();

  // Returns the current state of the download.
  virtual download::DownloadItem::DownloadState GetState() const;

  // Returns whether the download is currently paused.
  virtual bool IsPaused() const;

  // Returns the danger type associated with this download.
  virtual download::DownloadDangerType GetDangerType() const;

  // Returns true if the download will be auto-opened when complete.
  virtual bool GetOpenWhenComplete() const;

  // Returns true if the download will be auto-opened when complete by policy.
  virtual bool IsOpenWhenCompleteByPolicy() const;

  // Simple calculation of the amount of time remaining to completion. Fills
  // |*remaining| with the amount of time remaining if successful. Fails and
  // returns false if we do not have the number of bytes or the download speed,
  // and so can't give an estimate.
  virtual bool TimeRemaining(base::TimeDelta* remaining) const;

  // Returns the creation time for a download.
  virtual base::Time GetStartTime() const;

  // Returns the end/completion time for a completed download. base::Time()
  // if the download has not completed yet.
  virtual base::Time GetEndTime() const;

  // Returns true if the download has been opened.
  virtual bool GetOpened() const;

  // Marks the download as having been opened (without actually opening it).
  virtual void SetOpened(bool opened);

  // Returns true if the download is in a terminal state. This includes
  // completed downloads, cancelled downloads, and interrupted downloads that
  // can't be resumed.
  virtual bool IsDone() const;

  // Pauses a download.  Will have no effect if the download is already
  // paused.
  virtual void Pause();

  // Resumes a download that has been paused or interrupted. Will have no effect
  // if the download is neither. Only does something if CanResume() returns
  // true.
  virtual void Resume();

  // Cancels the download operation. Set |user_cancel| to true if the
  // cancellation was triggered by an explicit user action.
  virtual void Cancel(bool user_cancel);

  // Removes the download from the views and history. If the download was
  // in-progress or interrupted, then the intermediate file will also be
  // deleted.
  virtual void Remove();

  // Marks the download to be auto-opened when completed.
  virtual void SetOpenWhenComplete(bool open);

  // Returns the full path to the downloaded or downloading file. This is the
  // path to the physical file, if one exists.
  virtual base::FilePath GetFullPath() const;

  // Returns whether the download can be resumed.
  virtual bool CanResume() const;

  // Returns whether this download has saved all of its data.
  virtual bool AllDataSaved() const;

  // Returns whether the file associated with the download has been removed by
  // external action.
  virtual bool GetFileExternallyRemoved() const;

  // Returns the URL represented by this download.
  virtual GURL GetURL() const;

  // Returns whether the download request was initiated in response to a user
  // gesture.
  virtual bool HasUserGesture() const;

  // Returns the most recent failure reason for this download. Returns
  // |FailState::NO_FAILURE| if there is no previous failure reason.
  virtual offline_items_collection::FailState GetLastFailState() const;

  // Returns the URL of the orginiating request.
  virtual GURL GetOriginalURL() const;

  // Whether the Origin should be clearly displayed in the notification for
  // security reasons.
  virtual bool ShouldPromoteOrigin() const;

#if !BUILDFLAG(IS_ANDROID)
  // Methods related to DownloadCommands.
  // Returns whether the given download command is enabled for this download.
  virtual bool IsCommandEnabled(const DownloadCommands* download_commands,
                                DownloadCommands::Command command) const;

  // Returns whether the given download command is checked for this download.
  virtual bool IsCommandChecked(const DownloadCommands* download_commands,
                                DownloadCommands::Command command) const;

  // Executes the given download command on this download.
  virtual void ExecuteCommand(DownloadCommands* download_commands,
                              DownloadCommands::Command command);

  // Returns |true| if this download should be displayed in the download bubble.
  // Note that this may return true even if the download bubble is not enabled
  // on the platform.
  virtual bool ShouldShowInBubble() const;

  // Returns the type of tailored warning. Returns kNoTailoredWarning if this
  // download shouldn't trigger a tailored warning.
  virtual TailoredWarningType GetTailoredWarningType() const;

  // Returns the UI pattern to be used for the download, e.g. dangerous or
  // suspicious. Returns kNoWarning if the download has no warning.
  virtual DangerUiPattern GetDangerUiPattern() const;
#endif

  // Ephemeral warnings are ones that are quickly removed from the UI if the
  // user has not acted on them, and later deleted altogether. Is this that kind
  // of warning?
  virtual bool IsEphemeralWarning() const;

#if BUILDFLAG(SAFE_BROWSING_DOWNLOAD_PROTECTION)
  // Complete the Safe Browsing scan early.
  virtual void CompleteSafeBrowsingScan();

  // Open a dialog to review a scan verdict.
  virtual void ReviewScanningVerdict(content::WebContents* web_contents);
#endif

  // Whether the dropdown menu button should be shown or not.
  virtual bool ShouldShowDropdown() const;

  // Determines if a download should be preferably opened in the browser instead
  // of the platform. Use |is_filetype_handled_safely| indicating if opening a
  // file of this type is safe in the current BrowserContext, |target_path| to
  // see if files of this type should be opened in the browser, and set whether
  // the download should be preferred opening in the browser.
  virtual void DetermineAndSetShouldPreferOpeningInBrowser(
      const base::FilePath& target_path,
      bool is_filetype_handled_safely);

  // Returns the accessible alert text that should be announced when the
  // download is in progress.
  virtual std::u16string GetInProgressAccessibleAlertText() const;

  // Determines whether the file is an encrypted archive at the top
  // level (i.e. the encryption is not within a nested archive). This is
  // used to specialize certain strings.
  virtual bool IsTopLevelEncryptedArchive() const;

  // Returns whether the download is triggered by an extension.
  virtual bool IsExtensionDownload() const;

 protected:
  // Returns the MIME type of the download.
  virtual std::string GetMimeType() const;

  raw_ptr<Delegate> delegate_ = nullptr;

 private:
  friend class DownloadItemModelTest;

  void set_clock_for_testing(base::Clock* clock);

  void set_status_text_builder_for_testing(bool for_bubble);

  // Unowned Clock to override the time of "Now".
  raw_ptr<base::Clock> clock_ = base::DefaultClock::GetInstance();

  std::unique_ptr<StatusTextBuilderBase> status_text_builder_;

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

#endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UI_MODEL_H_