File: side_search_tab_contents_helper.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (223 lines) | stat: -rw-r--r-- 9,049 bytes parent folder | download
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
// Copyright 2021 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_SIDE_SEARCH_SIDE_SEARCH_TAB_CONTENTS_HELPER_H_
#define CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_TAB_CONTENTS_HELPER_H_

#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/elapsed_timer.h"
#include "chrome/browser/ui/side_search/side_search_config.h"
#include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"

namespace content {
class NavigationHandle;
class WebContents;
}  // namespace content

class GURL;
class SideSearchConfig;

// Side Search helper for the WebContents hosted in the browser's main tab area.
class SideSearchTabContentsHelper
    : public SideSearchSideContentsHelper::Delegate,
      public content::WebContentsObserver,
      public SideSearchConfig::Observer,
      public content::WebContentsUserData<SideSearchTabContentsHelper> {
 public:
  class Delegate {
   public:
    virtual bool HandleKeyboardEvent(
        content::WebContents* source,
        const content::NativeWebKeyboardEvent& event) = 0;

    virtual content::WebContents* OpenURLFromTab(
        content::WebContents* source,
        const content::OpenURLParams& params) = 0;

    // Notifies the delegate that the side panel's availability has changed.
    // `should_close` determines whether the side panel should be closed. This
    // allows the helper to signal delegates that they should close the feature
    // when something exceptional has happened.
    virtual void SidePanelAvailabilityChanged(bool should_close) = 0;

    virtual void OpenSidePanel() = 0;
  };

  // Holds state reflecting the current current navigation that is the result of
  // a redirect from the side panel to this helper's tab.
  struct SidePanelRedirectInfo {
    GURL initiated_redirect_url;
    bool initiated_via_link;
  };

  ~SideSearchTabContentsHelper() override;

  // SideContentsWrapper::Delegate:
  void NavigateInTabContents(const content::OpenURLParams& params) override;
  void LastSearchURLUpdated(const GURL& url) override;
  void SidePanelProcessGone() override;
  bool HandleKeyboardEvent(
      content::WebContents* source,
      const content::NativeWebKeyboardEvent& event) override;
  content::WebContents* OpenURLFromTab(
      content::WebContents* source,
      const content::OpenURLParams& params) override;
  content::WebContents* GetTabWebContents() override;
  void CarryOverSideSearchStateToNewTab(
      const GURL& search_url,
      content::WebContents* new_web_contents) override;

  // content::WebContentsObserver:
  void DidOpenRequestedURL(content::WebContents* new_contents,
                           content::RenderFrameHost* source_render_frame_host,
                           const GURL& url,
                           const content::Referrer& referrer,
                           WindowOpenDisposition disposition,
                           ui::PageTransition transition,
                           bool started_from_context_menu,
                           bool renderer_initiated) override;
  void DidStartNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;

  // SideSearchConfig::Observer:
  void OnSideSearchConfigChanged() override;

  // Gets the `side_panel_contents_` for the tab. Creates one if it does not
  // currently exist.
  content::WebContents* GetSidePanelContents();

  // Flags whether or not the current search journey was automatically triggered
  // (i.e. the user did not explicitly open the side panel).
  void SetAutoTriggered(bool auto_triggered);

  // Called by clients as a hint to the tab helper to clear away its
  // `side_panel_contents_` if it exists. Caching strategies can leverage this
  // hint and reset the `side_panel_contents_` at some later point in time.
  void ClearSidePanelContents();

  // Returns true if the side panel can be shown for the currently committed
  // navigation entry.
  bool CanShowSidePanelForCommittedNavigation();

  // This is called to log the duration between when the side panel was made
  // available to the first time it was opened for the `last_search_url_`. This
  // resets the `available_timer_` to avoid logging multiple times in the case a
  // user closes and opens the panel repeatedly for the same `last_search_url_`.
  void MaybeRecordDurationSidePanelAvailableToFirstOpen();

  void SetDelegate(base::WeakPtr<Delegate> delegate);

  const absl::optional<SidePanelRedirectInfo>&
  side_panel_initiated_redirect_info() const {
    return side_panel_initiated_redirect_info_;
  }

  int returned_to_previous_srp_count() const {
    return returned_to_previous_srp_count_;
  }

  bool toggled_open() const { return toggled_open_; }
  void set_toggled_open(bool toggled_open) { toggled_open_ = toggled_open; }

  void SetSidePanelContentsForTesting(
      std::unique_ptr<content::WebContents> side_panel_contents);

  content::WebContents* side_panel_contents_for_testing() const {
    return side_panel_contents_.get();
  }

  const absl::optional<GURL>& last_search_url() { return last_search_url_; }

  // Takes the search URL passed from context menu and opens search results in
  // side panel.
  void OpenSidePanelFromContextMenuSearch(const GURL& url);

  // Returns true when the side panel can be actually opened from context menu
  // option.
  bool CanShowSidePanelFromContextMenuSearch();

 private:
  friend class content::WebContentsUserData<SideSearchTabContentsHelper>;
  explicit SideSearchTabContentsHelper(content::WebContents* web_contents);

  // Gets the helper for the side contents.
  SideSearchSideContentsHelper* GetSideContentsHelper();

  // Creates the `side_panel_contents_` associated with this helper's tab
  // contents.
  void CreateSidePanelContents();

  // Navigates `side_panel_contents_` to the tab's `last_search_url_` if needed.
  // Should only be called when `side_contents_active_`.
  void UpdateSideContentsNavigation();

  // Closes the side panel and resets all helper state.
  void ClearHelperState();

  SideSearchConfig* GetConfig();

  // Use a weak ptr for the delegate to avoid issues whereby the tab contents
  // could outlive the delegate.
  base::WeakPtr<Delegate> delegate_;

  // The last Google search URL encountered by this tab contents.
  absl::optional<GURL> last_search_url_;

  // Counts the number of times the user has returned to the `last_search_url_`
  // via back navigation. This is used to detect cases where the side search
  // panel would be of use to the user and is used to show an IPH promo and
  // automatically trigger the side panel.
  int returned_to_previous_srp_count_ = 0;

  // A flag to track whether the current tab has its side panel toggled open.
  // Only used with the kSideSearchStatePerTab flag.
  bool toggled_open_ = false;

  // Tracks the URL and initiation state for the side panel initiated redirect.
  // This is used to determine if any redirects that follow belong to the
  // initial redirected request from the side panel. It is not sufficient to
  // rely on NavigationHandles as redirects may be client initiated and new
  // NavigationHandles are created in these cases.
  absl::optional<SidePanelRedirectInfo> side_panel_initiated_redirect_info_;

  // The side panel contents associated with this tab contents.
  // TODO(tluk): Update the way we manage the `side_panel_contents_` to avoid
  // keeping the object around when not needed by the feature.
  std::unique_ptr<content::WebContents> side_panel_contents_;

  // Time since the side panel became available for the `last_search_url_`.
  absl::optional<base::ElapsedTimer> available_timer_;

  // True if the side panel could be shown for the previously committed
  // navigation.
  bool could_show_for_last_committed_navigation_ = false;

  // Tracks whether the page action icon has animated-in its label text. Track
  // this to ensure we only show the label at most once per tab.
  bool page_action_label_shown_ = false;

  // Tracks the number of times the page action icon has animated-in its label
  // text for this tab.
  int page_action_label_shown_count_ = 0;

  // Tracks if we can show the page action label when the entrypoint is
  // revealed. This is set to true after a navigation to a SRP and reset when
  // the entrypoint for the current SRP is shown. This is done to ensure we only
  // show the label text at most once for a given SRP.
  bool can_show_page_action_label_ = false;

  base::ScopedObservation<SideSearchConfig, SideSearchConfig::Observer>
      config_observation_{this};

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

  WEB_CONTENTS_USER_DATA_KEY_DECL();
};

#endif  // CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_TAB_CONTENTS_HELPER_H_