Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Side by Side Diff: chrome_frame/turndown_prompt/turndown_prompt.cc

Issue 17153006: Chrome Frame turndown prompt. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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_frame/turndown_prompt/turndown_prompt.h"
6
7 #include <atlbase.h>
8 #include <shlguid.h>
9
10 #include "base/bind.h"
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/path_service.h"
15 #include "base/win/scoped_bstr.h"
16 #include "base/win/scoped_comptr.h"
17 #include "base/win/win_util.h"
18 #include "chrome/installer/util/browser_distribution.h"
19 #include "chrome/installer/util/google_update_settings.h"
20 #include "chrome/installer/util/install_util.h"
21 #include "chrome_frame/infobars/infobar_manager.h"
22 #include "chrome_frame/policy_settings.h"
23 #include "chrome_frame/ready_mode/internal/ready_mode_web_browser_adapter.h"
24 #include "chrome_frame/ready_mode/internal/url_launcher.h"
25 #include "chrome_frame/turndown_prompt/reshow_state.h"
26 #include "chrome_frame/turndown_prompt/turndown_prompt_content.h"
27 #include "chrome_frame/utils.h"
28 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
29
30 namespace {
31
32 // Time between showingings of the turndown prompt.
robertshield 2013/06/19 23:36:33 Too many ings
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
33 const int kTurndownPromptReshowDeltaMinutes = 60 * 24 * 7;
34
35 void UninstallChromeFrame();
36
37 // Manages the Turndown UI in response to browsing ChromeFrame-rendered
38 // pages.
39 class BrowserObserver : public ReadyModeWebBrowserAdapter::Observer {
40 public:
41 BrowserObserver(IWebBrowser2* web_browser,
42 ReadyModeWebBrowserAdapter* adapter);
43
44 // ReadyModeWebBrowserAdapter::Observer implementation
45 virtual void OnNavigateTo(const std::wstring& url);
46 virtual void OnRenderInChromeFrame(const std::wstring& url);
47 virtual void OnRenderInHost(const std::wstring& url);
48
49 private:
50 // Shows the turndown prompt if it hasn't been seen since the reshow delta.
robertshield 2013/06/19 23:36:33 reshow delta -> kTurndownPromptReshowDeltaMinutes
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
51 void ShowPrompt();
52 void Hide();
53 InfobarManager* GetInfobarManager();
robertshield 2013/06/19 23:36:33 The pointer this returns has a non-obvious life-cy
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
54
55 GURL rendered_url_;
56 base::win::ScopedComPtr<IWebBrowser2> web_browser_;
57 ReadyModeWebBrowserAdapter* adapter_;
58
59 DISALLOW_COPY_AND_ASSIGN(BrowserObserver);
60 };
61
62 // Implements launching of a URL in an instance of IWebBrowser2.
63 class UrlLauncherImpl : public UrlLauncher {
64 public:
65 explicit UrlLauncherImpl(IWebBrowser2* web_browser);
66
67 // UrlLauncher implementation
68 void LaunchUrl(const std::wstring& url);
69
70 private:
71 base::win::ScopedComPtr<IWebBrowser2> web_browser_;
72 };
73
74 UrlLauncherImpl::UrlLauncherImpl(IWebBrowser2* web_browser) {
75 DCHECK(web_browser);
76 web_browser_ = web_browser;
77 }
78
79 void UrlLauncherImpl::LaunchUrl(const std::wstring& url) {
80 VARIANT flags = { VT_I4 };
81 V_I4(&flags) = navOpenInNewWindow;
82 base::win::ScopedBstr location(url.c_str());
83
84 HRESULT hr = web_browser_->Navigate(location, &flags, NULL, NULL, NULL);
85 DLOG_IF(ERROR, FAILED(hr)) << "Failed to invoke Navigate on IWebBrowser2. "
86 << "Error: " << hr;
87 }
88
89 BrowserObserver::BrowserObserver(IWebBrowser2* web_browser,
90 ReadyModeWebBrowserAdapter* adapter)
91 : web_browser_(web_browser),
92 adapter_(adapter) {
93 }
94
95 void BrowserObserver::OnNavigateTo(const std::wstring& url) {
96 if (!net::registry_controlled_domains::SameDomainOrHost(
97 GURL(url),
98 rendered_url_,
99 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) {
100 rendered_url_ = GURL();
101 Hide();
102 }
103 }
104
105 void BrowserObserver::OnRenderInChromeFrame(const std::wstring& url) {
106 ShowPrompt();
107 rendered_url_ = GURL(url);
108 }
109
110 void BrowserObserver::OnRenderInHost(const std::wstring& url) {
111 Hide();
112 rendered_url_ = GURL(url);
113 }
114
115 void BrowserObserver::ShowPrompt() {
116 BrowserDistribution* dist =
117 BrowserDistribution::GetSpecificDistribution(
118 BrowserDistribution::CHROME_FRAME);
119 turndown_prompt::ReshowState reshow_state(
120 dist->GetStateKey(),
121 base::TimeDelta::FromMinutes(kTurndownPromptReshowDeltaMinutes));
122
123 // Short-circuit if the prompt shouldn't be shown again yet.
124 if (!reshow_state.HasReshowDeltaExpired(base::Time::Now()))
125 return;
126
127 // This pointer is self-managed and not guaranteed to survive handling of
128 // Windows events.
robertshield 2013/06/19 23:36:33 As an unfamiliar reader, I don't know how to parse
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
129 InfobarManager* infobar_manager = GetInfobarManager();
130
131 if (infobar_manager) {
132 // Owned by infobar_content
133 scoped_ptr<UrlLauncher> url_launcher(new UrlLauncherImpl(web_browser_));
134
135 // Owned by infobar_manager
136 scoped_ptr<InfobarContent> infobar_content(new TurndownPromptContent(
137 url_launcher.release(),
138 base::Bind(&UninstallChromeFrame)));
139
140 if (infobar_manager->Show(infobar_content.release(), TOP_INFOBAR)) {
141 // Update state in the registry that the prompt was shown.
142 reshow_state.MarkShown(base::Time::Now());
robertshield 2013/06/19 23:36:33 Random thought: if I open two tabs both rendering
grt (UTC plus 2) 2013/06/20 19:55:29 I think this is possible.
robertshield 2013/06/20 21:45:10 Yeah, was simply musing. I don't have an immediate
143 }
144 }
145 }
146
147 void BrowserObserver::Hide() {
148 InfobarManager* infobar_manager = GetInfobarManager();
149 if (infobar_manager)
150 infobar_manager->HideAll();
151 }
152
153 InfobarManager* BrowserObserver::GetInfobarManager() {
154 HRESULT hr = NOERROR;
155
156 base::win::ScopedComPtr<IOleWindow> ole_window;
157 hr = DoQueryService(SID_SShellBrowser, web_browser_, ole_window.Receive());
158 if (FAILED(hr) || ole_window == NULL) {
159 DLOG(ERROR) << "Failed to query SID_SShellBrowser from IWebBrowser2. "
160 << "Error: " << hr;
161 return NULL;
162 }
163
164 HWND web_browserhwnd = NULL;
robertshield 2013/06/19 23:36:33 nit: web_browser_hwnd
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
165 hr = ole_window->GetWindow(&web_browserhwnd);
166 if (FAILED(hr) || web_browserhwnd == NULL) {
167 DLOG(ERROR) << "Failed to query HWND from IOleWindow. "
168 << "Error: " << hr;
169 return NULL;
170 }
171
172 return InfobarManager::Get(web_browserhwnd);
173 }
174
175 // Attempts to create a ReadyModeWebBrowserAdapter instance.
176 bool CreateWebBrowserAdapter(ReadyModeWebBrowserAdapter** pointer) {
robertshield 2013/06/19 23:36:33 nit: pointer -> adapter
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
177 *pointer = NULL;
178
179 CComObject<ReadyModeWebBrowserAdapter>* com_object;
180 HRESULT hr =
181 CComObject<ReadyModeWebBrowserAdapter>::CreateInstance(&com_object);
182
183 if (FAILED(hr)) {
184 DLOG(ERROR) << "Failed to create instance of ReadyModeWebBrowserAdapter. "
185 << "Error: " << hr;
186 return false;
187 }
188
189 com_object->AddRef();
190 *pointer = com_object;
191 return true;
192 }
193
194 // Attempts to install Turnown prompts in the provided web browser.
195 bool InstallPrompts(IWebBrowser2* web_browser) {
196 base::win::ScopedComPtr<ReadyModeWebBrowserAdapter, NULL> adapter;
197
198 if (!CreateWebBrowserAdapter(adapter.Receive()))
199 return false;
200
201 // Pass ownership of our delegate to the BrowserObserver
202 scoped_ptr<ReadyModeWebBrowserAdapter::Observer> browser_observer(
203 new BrowserObserver(web_browser, adapter));
204
205 // Owns the BrowserObserver
206 return adapter->Initialize(web_browser, browser_observer.release());
207 }
208
209 // Uninstalls Chrome Frame in response to user action.
210 void UninstallChromeFrame() {
211 // TODO(grt) Find and run the uninstaller.
212 }
213
214 } // namespace
215
216 namespace turndown_prompt {
217
218 bool IsPromptSuppressed() {
219 // See if updates are disabled for Chrome Frame (check the binaries if
220 // multi-install).
robertshield 2013/06/19 23:36:33 I wonder if we should check the MSI bit as well?
grt (UTC plus 2) 2013/06/20 19:55:29 Done.
221 BrowserDistribution* dist =
222 BrowserDistribution::GetSpecificDistribution(
223 BrowserDistribution::CHROME_FRAME);
224
225 base::FilePath dll_path;
226 if (PathService::Get(base::DIR_MODULE, &dll_path)) {
227 bool system_level =
228 !InstallUtil::IsPerUserInstall(dll_path.value().c_str());
229 bool multi_install = InstallUtil::IsMultiInstall(dist, system_level);
230 if (multi_install) {
231 dist =
232 BrowserDistribution::GetSpecificDistribution(
233 BrowserDistribution::CHROME_BINARIES);
234 }
235 if (GoogleUpdateSettings::GetAppUpdatePolicy(dist->GetAppGuid(), NULL) ==
236 GoogleUpdateSettings::UPDATES_DISABLED) {
237 return true;
238 }
239 }
240
241 // See if the prompt is explicitly suppressed via GP.
242 return PolicySettings::GetInstance()->suppress_turndown_prompt();
243 }
244
245 void Configure(IWebBrowser2* web_browser) {
246 if (!IsPromptSuppressed())
247 InstallPrompts(web_browser);
248 }
249
250 } // namespace turndown_prompt
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698