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

Side by Side Diff: chrome/browser/external_protocol/external_protocol_handler.cc

Issue 7790021: Open external application dialog should not show for Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nits addressed Created 9 years, 3 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/external_protocol/external_protocol_handler.h" 5 #include "chrome/browser/external_protocol/external_protocol_handler.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/threading/thread.h" 12 #include "base/threading/thread.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "chrome/browser/browser_process_impl.h" 14 #include "chrome/browser/browser_process_impl.h"
15 #include "chrome/browser/platform_util.h" 15 #include "chrome/browser/platform_util.h"
16 #include "chrome/browser/prefs/pref_service.h" 16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/prefs/scoped_user_pref_update.h" 17 #include "chrome/browser/prefs/scoped_user_pref_update.h"
18 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
19 #include "googleurl/src/gurl.h" 19 #include "googleurl/src/gurl.h"
20 #include "net/base/escape.h" 20 #include "net/base/escape.h"
21 21
22 // Whether we accept requests for launching external protocols. This is set to 22 // Whether we accept requests for launching external protocols. This is set to
23 // false every time an external protocol is requested, and set back to true on 23 // false every time an external protocol is requested, and set back to true on
24 // each user gesture. This variable should only be accessed from the UI thread. 24 // each user gesture. This variable should only be accessed from the UI thread.
25 static bool g_accept_requests = true; 25 static bool g_accept_requests = true;
26 26
27 namespace {
28
29 // Functions enabling unit testing. Using a NULL delegate will use the default
30 // behavior; if a delegate is provided it will be used instead.
31 ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
32 ShellIntegration::DefaultWebClientObserver* observer,
33 const std::string& protocol,
34 ExternalProtocolHandler::Delegate* delegate) {
35 if (!delegate)
36 return new ShellIntegration::DefaultProtocolClientWorker(observer,
37 protocol);
38
39 return delegate->CreateShellWorker(observer, protocol);
40 }
41
42 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
43 const std::string& scheme,
44 ExternalProtocolHandler::Delegate* delegate) {
45 if (!delegate)
46 return ExternalProtocolHandler::GetBlockState(scheme);
47
48 return delegate->GetBlockState(scheme);
49 }
50
51 void RunExternalProtocolDialogWithDelegate(
52 const GURL& url,
53 int render_process_host_id,
54 int routing_id,
55 ExternalProtocolHandler::Delegate* delegate) {
56 if (!delegate) {
57 ExternalProtocolHandler::RunExternalProtocolDialog(url,
58 render_process_host_id,
59 routing_id);
60 } else {
61 delegate->RunExternalProtocolDialog(url, render_process_host_id,
62 routing_id);
63 }
64 }
65
66 void LaunchUrlWithoutSecurityCheckWithDelegate(
67 const GURL& url,
68 ExternalProtocolHandler::Delegate* delegate) {
69 if (!delegate)
70 ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url);
71 else
72 delegate->LaunchUrlWithoutSecurityCheck(url);
73 }
74
75 // When we are about to launch a URL with the default OS level application,
76 // we check if that external application will be us. If it is we just ignore
77 // the request.
78 class ExternalDefaultProtocolObserver
79 : public ShellIntegration::DefaultWebClientObserver {
80 public:
81 ExternalDefaultProtocolObserver(const GURL& escaped_url,
82 int render_process_host_id,
83 int tab_contents_id,
84 bool prompt_user,
85 ExternalProtocolHandler::Delegate* delegate)
86 : delegate_(delegate),
87 escaped_url_(escaped_url),
88 render_process_host_id_(render_process_host_id),
89 tab_contents_id_(tab_contents_id),
90 prompt_user_(prompt_user) {}
91
92 virtual void SetDefaultWebClientUIState(
93 ShellIntegration::DefaultWebClientUIState state) OVERRIDE {
94 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
95
96 // If we are still working out if we're the default, or we've found
97 // out we definately are the default, we end here.
98 if (state == ShellIntegration::STATE_PROCESSING) {
99 return;
100 }
101
102 if (delegate_)
103 delegate_->FinishedProcessingCheck();
104
105 if (state == ShellIntegration::STATE_IS_DEFAULT) {
106 if (delegate_)
107 delegate_->BlockRequest();
108 return;
109 }
110
111 // If we get here, either we are not the default or we cannot work out
112 // what the default is, so we proceed.
113 if (prompt_user_) {
114 // Ask the user if they want to allow the protocol. This will call
115 // LaunchUrlWithoutSecurityCheck if the user decides to accept the
116 // protocol.
117 RunExternalProtocolDialogWithDelegate(escaped_url_,
118 render_process_host_id_, tab_contents_id_, delegate_);
119 return;
120 }
121
122 LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url_, delegate_);
123 }
124
125 virtual bool IsOwnedByWorker() OVERRIDE { return true; }
126
127 private:
128 ExternalProtocolHandler::Delegate* delegate_;
129 GURL escaped_url_;
130 int render_process_host_id_;
131 int tab_contents_id_;
132 bool prompt_user_;
133 };
134
135 } // namespace
136
27 // static 137 // static
28 void ExternalProtocolHandler::PrepopulateDictionary(DictionaryValue* win_pref) { 138 void ExternalProtocolHandler::PrepopulateDictionary(DictionaryValue* win_pref) {
29 static bool is_warm = false; 139 static bool is_warm = false;
30 if (is_warm) 140 if (is_warm)
31 return; 141 return;
32 is_warm = true; 142 is_warm = true;
33 143
34 static const char* const denied_schemes[] = { 144 static const char* const denied_schemes[] = {
35 "afp", 145 "afp",
36 "data", 146 "data",
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 if (state == UNKNOWN) { 229 if (state == UNKNOWN) {
120 update_excluded_schemas->Remove(scheme, NULL); 230 update_excluded_schemas->Remove(scheme, NULL);
121 } else { 231 } else {
122 update_excluded_schemas->SetBoolean(scheme, 232 update_excluded_schemas->SetBoolean(scheme,
123 state == BLOCK ? true : false); 233 state == BLOCK ? true : false);
124 } 234 }
125 } 235 }
126 } 236 }
127 237
128 // static 238 // static
129 void ExternalProtocolHandler::LaunchUrl(const GURL& url, 239 void ExternalProtocolHandler::LaunchUrlWithDelegate(const GURL& url,
130 int render_process_host_id, 240 int render_process_host_id,
131 int tab_contents_id) { 241 int tab_contents_id,
242 Delegate* delegate) {
132 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); 243 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
133 244
134 // Escape the input scheme to be sure that the command does not 245 // Escape the input scheme to be sure that the command does not
135 // have parameters unexpected by the external program. 246 // have parameters unexpected by the external program.
136 std::string escaped_url_string = EscapeExternalHandlerValue(url.spec()); 247 std::string escaped_url_string = EscapeExternalHandlerValue(url.spec());
137 GURL escaped_url(escaped_url_string); 248 GURL escaped_url(escaped_url_string);
138 BlockState block_state = GetBlockState(escaped_url.scheme()); 249 BlockState block_state = GetBlockStateWithDelegate(escaped_url.scheme(),
139 if (block_state == BLOCK) 250 delegate);
251 if (block_state == BLOCK) {
252 if (delegate)
253 delegate->BlockRequest();
140 return; 254 return;
255 }
141 256
142 g_accept_requests = false; 257 g_accept_requests = false;
143 258
144 if (block_state == UNKNOWN) { 259 // The worker creates tasks with references to itself and puts them into
145 // Ask the user if they want to allow the protocol. This will call 260 // message loops. When no tasks are left it will delete the observer and
146 // LaunchUrlWithoutSecurityCheck if the user decides to accept the protocol. 261 // eventually be deleted itself.
147 RunExternalProtocolDialog(escaped_url, 262 ShellIntegration::DefaultWebClientObserver* observer =
148 render_process_host_id, 263 new ExternalDefaultProtocolObserver(url,
149 tab_contents_id); 264 render_process_host_id,
150 return; 265 tab_contents_id,
151 } 266 block_state == UNKNOWN,
267 delegate);
268 scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker =
269 CreateShellWorker(observer, escaped_url.scheme(), delegate);
152 270
153 LaunchUrlWithoutSecurityCheck(escaped_url); 271 // Start the check process running. This will send tasks to the FILE thread
272 // and when the answer is known will send the result back to the observer on
273 // the UI thread.
274 worker->StartCheckIsDefault();
154 } 275 }
155 276
156 // static 277 // static
157 void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) { 278 void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) {
158 #if defined(OS_MACOSX) 279 #if defined(OS_MACOSX)
159 // This must run on the UI thread on OS X. 280 // This must run on the UI thread on OS X.
160 platform_util::OpenExternal(url); 281 platform_util::OpenExternal(url);
161 #else 282 #else
162 // Otherwise put this work on the file thread. On Windows ShellExecute may 283 // Otherwise put this work on the file thread. On Windows ShellExecute may
163 // block for a significant amount of time, and it shouldn't hurt on Linux. 284 // block for a significant amount of time, and it shouldn't hurt on Linux.
(...skipping 10 matching lines...) Expand all
174 // static 295 // static
175 void ExternalProtocolHandler::RegisterPrefs(PrefService* prefs) { 296 void ExternalProtocolHandler::RegisterPrefs(PrefService* prefs) {
176 prefs->RegisterDictionaryPref(prefs::kExcludedSchemes); 297 prefs->RegisterDictionaryPref(prefs::kExcludedSchemes);
177 } 298 }
178 299
179 // static 300 // static
180 void ExternalProtocolHandler::PermitLaunchUrl() { 301 void ExternalProtocolHandler::PermitLaunchUrl() {
181 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type()); 302 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
182 g_accept_requests = true; 303 g_accept_requests = true;
183 } 304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698