1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h"
6
7 #include <utility>
8
9 #include "build/build_config.h"
10 #include "chrome/browser/extensions/ntp_overridden_bubble_delegate.h"
11 #include "chrome/browser/extensions/settings_api_bubble_delegate.h"
12 #include "chrome/browser/extensions/settings_api_helpers.h"
13 #include "chrome/browser/ui/browser_dialogs.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_window.h"
16 #include "chrome/browser/ui/extensions/extension_message_bubble_bridge.h"
17 #include "chrome/browser/ui/extensions/extension_settings_overridden_dialog.h"
18 #include "chrome/browser/ui/extensions/settings_overridden_params_providers.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
21 #include "chrome/browser/ui/ui_features.h"
22 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
23 #include "chrome/common/url_constants.h"
24 #include "content/public/browser/browser_url_handler.h"
25 #include "content/public/browser/navigation_entry.h"
26 #include "extensions/common/constants.h"
27
28 namespace extensions {
29
30 namespace {
31
32 // Whether the NTP post-install UI is enabled. By default, this is limited to
33 // Windows, Mac, and ChromeOS, but can be overridden for testing.
34 #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_CHROMEOS)
35 bool g_ntp_post_install_ui_enabled = true;
36 #else
37 bool g_ntp_post_install_ui_enabled = false;
38 #endif
39
40 #if defined(OS_WIN) || defined(OS_MAC)
ShowSettingsApiBubble(SettingsApiOverrideType type,Browser * browser)41 void ShowSettingsApiBubble(SettingsApiOverrideType type,
42 Browser* browser) {
43 ToolbarActionsModel* model = ToolbarActionsModel::Get(browser->profile());
44 if (model->has_active_bubble())
45 return;
46
47 std::unique_ptr<ExtensionMessageBubbleController> settings_api_bubble(
48 new ExtensionMessageBubbleController(
49 new SettingsApiBubbleDelegate(browser->profile(), type), browser));
50 if (!settings_api_bubble->ShouldShow())
51 return;
52
53 settings_api_bubble->SetIsActiveBubble();
54 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bridge(
55 new ExtensionMessageBubbleBridge(std::move(settings_api_bubble)));
56 browser->window()->GetExtensionsContainer()->ShowToolbarActionBubbleAsync(
57 std::move(bridge));
58 }
59 #endif
60
61 } // namespace
62
SetNtpPostInstallUiEnabledForTesting(bool enabled)63 void SetNtpPostInstallUiEnabledForTesting(bool enabled) {
64 g_ntp_post_install_ui_enabled = enabled;
65 }
66
MaybeShowExtensionControlledHomeNotification(Browser * browser)67 void MaybeShowExtensionControlledHomeNotification(Browser* browser) {
68 #if defined(OS_WIN) || defined(OS_MAC)
69 ShowSettingsApiBubble(BUBBLE_TYPE_HOME_PAGE, browser);
70 #endif
71 }
72
MaybeShowExtensionControlledSearchNotification(content::WebContents * web_contents,AutocompleteMatch::Type match_type)73 void MaybeShowExtensionControlledSearchNotification(
74 content::WebContents* web_contents,
75 AutocompleteMatch::Type match_type) {
76 #if defined(OS_WIN) || defined(OS_MAC)
77 if (!AutocompleteMatch::IsSearchType(match_type) ||
78 match_type == AutocompleteMatchType::SEARCH_OTHER_ENGINE) {
79 return;
80 }
81
82 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
83 if (!browser)
84 return;
85
86 if (base::FeatureList::IsEnabled(
87 features::kExtensionSettingsOverriddenDialogs)) {
88 base::Optional<ExtensionSettingsOverriddenDialog::Params> params =
89 settings_overridden_params::GetSearchOverriddenParams(
90 browser->profile());
91 if (!params)
92 return;
93
94 auto dialog = std::make_unique<ExtensionSettingsOverriddenDialog>(
95 std::move(*params), browser->profile());
96 if (!dialog->ShouldShow())
97 return;
98
99 chrome::ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
100 } else {
101 ShowSettingsApiBubble(BUBBLE_TYPE_SEARCH_ENGINE, browser);
102 }
103 #endif
104 }
105
MaybeShowExtensionControlledNewTabPage(Browser * browser,content::WebContents * web_contents)106 void MaybeShowExtensionControlledNewTabPage(
107 Browser* browser, content::WebContents* web_contents) {
108 if (!g_ntp_post_install_ui_enabled)
109 return;
110
111 // Acknowledge existing extensions if necessary.
112 NtpOverriddenBubbleDelegate::MaybeAcknowledgeExistingNtpExtensions(
113 browser->profile());
114
115 // Jump through a series of hoops to see if the web contents is pointing to
116 // an extension-controlled NTP.
117 // TODO(devlin): Some of this is redundant with the checks in the bubble/
118 // dialog. We should consolidate, but that'll be simpler once we only have
119 // one UI option. In the meantime, extra checks don't hurt.
120 content::NavigationEntry* entry =
121 web_contents->GetController().GetVisibleEntry();
122 if (!entry)
123 return;
124 GURL active_url = entry->GetURL();
125 if (!active_url.SchemeIs(extensions::kExtensionScheme))
126 return; // Not a URL that we care about.
127
128 // See if the current active URL matches a transformed NewTab URL.
129 GURL ntp_url(chrome::kChromeUINewTabURL);
130 content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
131 &ntp_url, web_contents->GetBrowserContext());
132 if (ntp_url != active_url)
133 return; // Not being overridden by an extension.
134
135 Profile* const profile = browser->profile();
136 ToolbarActionsModel* model = ToolbarActionsModel::Get(profile);
137 if (model->has_active_bubble())
138 return;
139
140 if (base::FeatureList::IsEnabled(
141 features::kExtensionSettingsOverriddenDialogs)) {
142 base::Optional<ExtensionSettingsOverriddenDialog::Params> params =
143 settings_overridden_params::GetNtpOverriddenParams(profile);
144 if (!params)
145 return;
146
147 auto dialog = std::make_unique<ExtensionSettingsOverriddenDialog>(
148 std::move(*params), profile);
149 if (!dialog->ShouldShow())
150 return;
151
152 chrome::ShowExtensionSettingsOverriddenDialog(std::move(dialog), browser);
153 return;
154 }
155
156 std::unique_ptr<ExtensionMessageBubbleController> ntp_overridden_bubble(
157 new ExtensionMessageBubbleController(
158 new NtpOverriddenBubbleDelegate(profile), browser));
159 if (!ntp_overridden_bubble->ShouldShow())
160 return;
161
162 ntp_overridden_bubble->SetIsActiveBubble();
163 std::unique_ptr<ToolbarActionsBarBubbleDelegate> bridge(
164 new ExtensionMessageBubbleBridge(std::move(ntp_overridden_bubble)));
165 browser->window()->GetExtensionsContainer()->ShowToolbarActionBubbleAsync(
166 std::move(bridge));
167 }
168
169 } // namespace extensions
170