File: auto_pip_setting_helper.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 (174 lines) | stat: -rw-r--r-- 6,939 bytes parent folder | download | duplicates (6)
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
// Copyright 2023 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_PICTURE_IN_PICTURE_AUTO_PIP_SETTING_HELPER_H_
#define CHROME_BROWSER_PICTURE_IN_PICTURE_AUTO_PIP_SETTING_HELPER_H_

#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/picture_in_picture/auto_pip_setting_overlay_view.h"
#include "components/content_settings/core/common/content_settings.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "media/base/picture_in_picture_events_info.h"
#include "url/gurl.h"

namespace content {
class WebContents;
}  // namespace content

namespace permissions {
class PermissionDecisionAutoBlockerBase;
}  // namespace permissions

namespace views {
class View;
}  // namespace views

class HostContentSettingsMap;

// Helper class to manage the content setting for AutoPiP, including the
// permissions embargo.  It's intended to be kept around for the duration of the
// visit to the site, so that 'allow once' can be sticky until navigation.  It
// does not detect navigation; somebody else should get a new instance.
class AutoPipSettingHelper {
 public:
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class PromptResult {
    // The user closed the PiP window before selecting a choice. Note that this
    // will not be recorded when the PiP window is closed automatically by the
    // user focusing the original tab.
    kIgnored = 0,

    // The user chose to block automatic picture-in-picture.
    kBlock = 1,

    // The user chose to allow automatic picture-in-picture on every visit.
    kAllowOnEveryVisit = 2,

    // The user chose to allow automatic picture-in-picture this time.
    kAllowOnce = 3,

    // The prompt was not shown because the user has already allowed automatic
    // picture-in-picture for every visit.
    kNotShownAllowedOnEveryVisit = 4,

    // The prompt was not shown because the user has already allowed automatic
    // picture-in-picture for this visit.
    kNotShownAllowedOnce = 5,

    // The prompt was not shown because the user has already blocked automatic
    // picture-in-picture (and therefore no picture-in-picture was shown at
    // all).
    kNotShownBlocked = 6,

    // The prompt was not shown because automatic picture-in-picture was blocked
    // due to the user being in incognito mode.
    kNotShownIncognito = 7,

    kMaxValue = kNotShownIncognito,
  };

  using ResultCb =
      base::OnceCallback<void(AutoPipSettingView::UiResult result)>;
  // Convenience function.
  static std::unique_ptr<AutoPipSettingHelper> CreateForWebContents(
      content::WebContents* web_contents,
      HostContentSettingsMap* settings_map,
      permissions::PermissionDecisionAutoBlockerBase* auto_blocker);

  // We'll use `close_pip_cb` to close the pip window as needed.  It should be
  // safe to call at any time.  It is up to our caller to make sure that we are
  // destroyed if `settings_map` is.
  AutoPipSettingHelper(
      const GURL& origin,
      HostContentSettingsMap* settings_map,
      permissions::PermissionDecisionAutoBlockerBase* auto_blocker);
  ~AutoPipSettingHelper();

  AutoPipSettingHelper(const AutoPipSettingHelper&) = delete;
  AutoPipSettingHelper(AutoPipSettingHelper&&) = delete;

  // Notify us that the user has closed the window.  This will cause the embargo
  // to be updated if needed.
  void OnUserClosedWindow(
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id);

  // Create an AutoPipSettingOverlayView that should be used as the overlay view
  // when the content setting is ASK.  This view will call back to us, so we
  // should outlive it.  Will return nullptr if no UI is needed, and will
  // optionally call `close_pip_cb_` if AutoPiP is blocked.
  std::unique_ptr<AutoPipSettingOverlayView> CreateOverlayViewIfNeeded(
      base::OnceClosure close_pip_cb,
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id,
      views::View* anchor_view,
      views::BubbleBorder::Arrow arrow);

  // Called by the AutoPictureInPictureTabHelper when automatic
  // picture-in-picture has been preemptively blocked. Used to record various
  // `PromptResultV2` metrics.
  void OnAutoPipBlockedByPermission(
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id);
  void OnAutoPipBlockedByIncognito(
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason);

 private:
  // Returns the content setting, modified as needed by any embargo.
  ContentSetting GetEffectiveContentSetting();

  // Update the content setting to `new_setting`, and clear any embargo.
  void UpdateContentSetting(ContentSetting new_setting);

  // Notify us that the user has interacted with the content settings UI that's
  // displayed in the pip window.  `close_pip_cb` will be called if the result
  // is 'block'.
  //
  // `auto_pip_reason` and `source_id` are used for recording various tab helper
  // related metrics.
  void OnUiResult(
      base::OnceClosure close_pip_cb,
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id,
      AutoPipSettingView::UiResult result);

  // Return a new ResultCb, and invalidate any previous ones.
  ResultCb CreateResultCb(
      base::OnceClosure close_pip_cb,
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id);

  // Record metrics for the result of the prompt.
  //
  // Records the various prompt results and the prompt results for each of the
  // reasons for entering auto picture in picture: video conferencing or media
  // playback.
  void RecordResult(
      PromptResult result,
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id);
  void RecordUkms(
      media::PictureInPictureEventsInfo::AutoPipReason auto_pip_reason,
      std::optional<ukm::SourceId> source_id,
      PromptResult result) const;

  GURL origin_;
  const raw_ptr<HostContentSettingsMap> settings_map_ = nullptr;
  base::OnceClosure close_pip_cb_;
  const raw_ptr<permissions::PermissionDecisionAutoBlockerBase> auto_blocker_ =
      nullptr;

  // If true, then we've shown the UI but the user hasn't picked an option yet.
  bool ui_was_shown_but_not_acknowledged_ = false;

  // Has the user clicked 'allow once' on any permission UI we've created?
  bool already_selected_allow_once_ = false;

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

#endif  // CHROME_BROWSER_PICTURE_IN_PICTURE_AUTO_PIP_SETTING_HELPER_H_