File: intent_picker_tab_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 (178 lines) | stat: -rw-r--r-- 7,469 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
// 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_UI_INTENT_PICKER_TAB_HELPER_H_
#define CHROME_BROWSER_UI_INTENT_PICKER_TAB_HELPER_H_

#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/apps/link_capturing/apps_intent_picker_delegate.h"
#include "chrome/browser/apps/link_capturing/intent_picker_info.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "ui/base/models/image_model.h"
#include "url/origin.h"

// Controls the visibility of IntentPickerView by updating the visibility based
// on stored state. This class is instantiated for both web apps and SWAs.
class IntentPickerTabHelper
    : public content::WebContentsObserver,
      public content::WebContentsUserData<IntentPickerTabHelper>,
      public web_app::WebAppInstallManagerObserver {
 public:
  using ShowIntentPickerBubbleCallback = base::OnceCallback<void(bool)>;

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

  // Updates visibility of the intent picker page action based on the current
  // tab and whether the icon should be showed.
  void UpdatePageAction(tabs::TabInterface* tab_interface,
                        bool should_show_icon);

  ~IntentPickerTabHelper() override;

  // Starts an async icon update before maybe showing the intent picker icon in
  // the omnibox, based on the last committed URL for the current web_contents.
  void MaybeShowIntentPickerIcon();

  // Shows the intent picker bubble to present a choice between apps to handle
  // |url|. May launch directly into an app based on user preferences and
  // installed apps. The callback will always be called asynchronously, and is
  // called with true if the user chooses to launch the app, otherwise, false
  // is called.
  void ShowIntentPickerBubbleOrLaunchApp(
      const GURL& url,
      bool always_show = false,
      ShowIntentPickerBubbleCallback callback = base::DoNothing());

  // Shows or hides the intent picker icon for |web_contents|. Always shows a
  // generic picker icon, even if MaybeShowIconForApps() had previously applied
  // app-specific customizations.
  static void ShowOrHideIcon(content::WebContents* web_contents,
                             bool should_show_icon);

  // Returns the size, in dp, of app icons shown in the intent picker bubble.
  static int GetIntentPickerBubbleIconSize();

  // Shows or hides the intent picker icon for this tab a list of |apps| which
  // can handle a link intent. Visible for testing.
  void MaybeShowIconForApps(std::vector<apps::IntentPickerAppInfo> apps);

  bool should_show_icon() const { return should_show_icon_; }

  // Returns true if the icon should be shown using an expanded chip-style
  // button.
  bool ShouldShowExpandedChip() const {
    return show_expanded_chip_from_usage_ || current_app_is_preferred_;
  }

  const ui::ImageModel& app_icon() const { return current_app_icon_; }

  // Sets a OnceClosure callback which will be called next time the icon is
  // updated. If include_latest_navigation is true, and the latest navigation
  // was finished, the callback is called immediately.
  void SetIconUpdateCallbackForTesting(base::OnceClosure callback,
                                       bool include_latest_navigation = false);

  WEB_CONTENTS_USER_DATA_KEY_DECL();

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

  using IntentPickerIconLoaderCallback =
      base::OnceCallback<void(std::vector<apps::IntentPickerAppInfo> apps)>;

  // Logic to load icons etc for apps in the intent picker:

  void OnAppIconLoaded(std::vector<apps::IntentPickerAppInfo> apps,
                       IntentPickerIconLoaderCallback callback,
                       size_t index,
                       ui::ImageModel app_icon);

  void LoadAppIcon(std::vector<apps::IntentPickerAppInfo> apps,
                   size_t index,
                   IntentPickerIconLoaderCallback callback);

  void UpdateExpandedState(bool should_show_icon);
  void OnAppIconLoadedForChip(const std::string& app_id,
                              ui::ImageModel app_icon);
  // Shows or hides the intent icon, with customizations specific to link intent
  // handling.
  void ShowIconForLinkIntent(bool should_show_icon);
  void ShowOrHideIconInternal(bool should_show_icon);

  // Logic to launch the app from the intent picker:

  void ShowIntentPickerOrLaunchAppImpl(
      const GURL& url,
      bool always_show,
      ShowIntentPickerBubbleCallback callback,
      std::vector<apps::IntentPickerAppInfo> apps);

  void OnIntentPickerClosedMaybeLaunch(
      const GURL& url,
      ShowIntentPickerBubbleCallback callback,
      const std::string& launch_name,
      apps::PickerEntryType entry_type,
      apps::IntentPickerCloseReason close_reason,
      bool should_persist);

  // content::WebContentsObserver:
  void DidStartNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;

  // web_app::WebAppInstallManagerObserver:
  void OnWebAppWillBeUninstalled(const webapps::AppId& app_id) override;
  void OnWebAppInstallManagerDestroyed() override;

  const raw_ptr<web_app::WebAppRegistrar, DanglingUntriaged> registrar_;
  const raw_ptr<web_app::WebAppInstallManager> install_manager_;

  bool should_show_icon_ = false;
  bool icon_resolved_ = false;
  url::Origin last_shown_origin_;
  // True if the icon should be shown as in an expanded chip style due to usage
  // on this origin.
  bool show_expanded_chip_from_usage_ = false;

  // Tracks the number of commits on this page, to allow for checking to make
  // sure that asynchronous invocations do not cause a stale intent picker.
  int commit_count_ = 0;

  // Contains the app ID of an app which can be opened through the intent
  // picker. This is only set when MaybeShowIconForApps() is called with a
  // single app. Will be set to the empty string in all other cases (e.g. when
  // there are multiple apps available, or when the icon is not visible).
  std::string current_app_id_;
  // True if |current_app_id_| is set as the preferred app for its http/https
  // links.
  bool current_app_is_preferred_ = false;
  ui::ImageModel current_app_icon_;

  base::OnceClosure icon_update_closure_for_testing_;

  std::unique_ptr<apps::AppsIntentPickerDelegate> intent_picker_delegate_;

  base::ScopedObservation<web_app::WebAppInstallManager,
                          web_app::WebAppInstallManagerObserver>
      install_manager_observation_{this};

  // This weak ptr factory is invalidated when a new navigation finishes.
  base::WeakPtrFactory<IntentPickerTabHelper> per_navigation_weak_factory_{
      this};
};

#endif  // CHROME_BROWSER_UI_INTENT_PICKER_TAB_HELPER_H_