summaryrefslogtreecommitdiffstats
path: root/chrome/browser/external_protocol
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-02 01:35:22 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-02 01:35:22 +0000
commit54aa17b1e77346c84d068be5d6eaddf576c440b7 (patch)
tree2dae52bf7eb8209d0224b679b311ccb17d810eb7 /chrome/browser/external_protocol
parent9e04fe63a65381f35b40902719e7d6c776c2de90 (diff)
downloadchromium_src-54aa17b1e77346c84d068be5d6eaddf576c440b7.zip
chromium_src-54aa17b1e77346c84d068be5d6eaddf576c440b7.tar.gz
chromium_src-54aa17b1e77346c84d068be5d6eaddf576c440b7.tar.bz2
Revert of Fix the handling of user gestures for external protocol handler dialogs. (https://codereview.chromium.org/131783012/)
Reason for revert: Looks like this caused a failure on the build bots. http://build.chromium.org/p/chromium.linux/builders/Linux%20Clang%20%28dbg%29/builds/57837 FAILED: /b/build/goma/gomacc ../../third_party/llvm-build/Release+Asserts/bin/clang++ -MMD -MF obj/apps/shell/browser/app_shell_lib.shell_extensions_browser_client.o.d -DV8_DEPRECATION_WARNINGS -DBLINK_SCALE_FILTERS_AT_RECORD_TIME -D_FILE_OFFSET_BITS=64 -DCHROMIUM_BUILD -DCOMPONENT_BUILD -DTOOLKIT_VIEWS=1 -DUI_COMPOSITOR_IMAGE_TRANSPORT -DUSE_AURA=1 -DUSE_CAIRO=1 -DUSE_GLIB=1 -DUSE_DEFAULT_RENDER_THEME=1 -DUSE_LIBJPEG_TURBO=1 -DUSE_MOJO=1 -DUSE_X11=1 -DUSE_CLIPBOARD_AURAX11=1 -DENABLE_ONE_CLICK_SIGNIN -DUSE_XI2_MT=2 -DENABLE_REMOTING=1 -DENABLE_WEBRTC=1 -DENABLE_PEPPER_CDMS -DENABLE_CONFIGURATION_POLICY -DENABLE_INPUT_SPEECH -DENABLE_NOTIFICATIONS -DUSE_UDEV -DENABLE_EGLIMAGE=1 -DENABLE_TASK_MANAGER=1 -DENABLE_EXTENSIONS=1 -DENABLE_PLUGIN_INSTALLATION=1 -DENABLE_PLUGINS=1 -DENABLE_SESSION_SERVICE=1 -DENABLE_THEMES=1 -DENABLE_AUTOFILL_DIALOG=1 -DENABLE_BACKGROUND=1 -DENABLE_AUTOMATION=1 -DENABLE_GOOGLE_NOW=1 -DCLD_VERSION=2 -DENABLE_FULL_PRINTING=1 -DENABLE_PRINTING=1 -DENABLE_SPELLCHECK=1 -DENABLE_CAPTIVE_PORTAL_DETECTION=1 -DENABLE_APP_LIST=1 -DENABLE_SETTINGS_APP=1 -DENABLE_MANAGED_USERS=1 -DENABLE_MDNS=1 -DENABLE_SERVICE_DISCOVERY=1 -DGL_GLEXT_PROTOTYPES -DGTEST_HAS_POSIX_RE=0 -DLIBPEERCONNECTION_LIB=1 -DU_USING_ICU_NAMESPACE=0 -DV8_SHARED -DUSING_V8_SHARED -DCHROME_PNG_WRITE_SUPPORT -DPNG_USER_CONFIG -DSKIA_DLL -DGR_GL_IGNORE_ES3_MSAA=0 -DSK_ENABLE_INST_COUNT=0 -DSK_SUPPORT_GPU=1 '-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' -DSK_ENABLE_LEGACY_API_ALIASING=1 -DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1 -DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1 -DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT -DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1 -DSK_SUPPORT_LEGACY_GETCLIPTYPE -DSK_SUPPORT_LEGACY_GETTOTALCLIP -DSK_SUPPORT_LEGACY_GETTOPDEVICE -DSK_USE_POSIX_THREADS -DSK_DEFERRED_CANVAS_USES_FACTORIES=1 -DUSE_NSS=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DWTF_USE_DYNAMIC_ANNOTATIONS=1 -D_DEBUG -D_GLIBCXX_DEBUG=1 -I../.. -I../../third_party/khronos -I../../gpu -I../../skia/config -I../../third_party/WebKit/Source -Igen -I../../third_party/WebKit -I../../third_party/icu/source/common -I../../third_party/npapi -I../../third_party/npapi/bindings -I../../v8/include -I../../third_party/libpng -I../../third_party/zlib -I../../third_party/libwebp -I../../third_party/ots/include -I../../third_party/qcms/src -I../../third_party/iccjpeg -I../../third_party/libjpeg_turbo -Igen/policy -Igen/protoc_out -I../../third_party/WebKit -I../../third_party/skia/src/core -I../../third_party/skia/include/core -I../../third_party/skia/include/effects -I../../third_party/skia/include/pdf -I../../third_party/skia/include/gpu -I../../third_party/skia/include/lazy -I../../third_party/skia/include/pathops -I../../third_party/skia/include/pipe -I../../third_party/skia/include/ports -I../../third_party/skia/include/utils -I../../skia/ext -fstack-protector --param=ssp-buffer-size=4 -Werror -pthread -fno-exceptions -fno-strict-aliasing -Wall -Wno-unused-parameter -Wno-missing-field-initializers -fvisibility=hidden -pipe -fPIC -Wheader-hygiene -Wno-char-subscripts -Wno-unneeded-internal-declaration -Wno-covered-switch-default -Wstring-conversion -Wno-c++11-narrowing -Wno-reserved-user-defined-literal -Wno-deprecated-register -Wno-absolute-value -Xclang -load -Xclang /b/build/slave/Linux_Clang__dbg_/build/src/tools/clang/scripts/../../../third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so -Xclang -add-plugin -Xclang find-bad-constructs -fcolor-diagnostics -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -m64 -march=x86-64 -O0 -g -funwind-tables -fno-rtti -fno-threadsafe-statics -fvisibility-inlines-hidden -Wsign-compare -std=gnu++11 -c ../../apps/shell/browser/shell_extensions_browser_client.cc -o obj/apps/shell/browser/app_shell_lib.shell_extensions_browser_client.o In file included from ../../apps/shell/browser/shell_extensions_browser_client.cc:5: ../../apps/shell/browser/shell_extensions_browser_client.h:54:16:error: 'PermitExternalProtocolHandler' marked 'override' but does not override any member functions virtual void PermitExternalProtocolHandler() OVERRIDE; Original issue's description: > Fix the handling of user gestures for external protocol handler dialogs. > > - Remove browser state from external protocol handler. > - Use gesture with a timeout. > > BUG=173557 > > Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=261014 TBR=jyasskin@chromium.org,kalman@chromium.org,mmenke@chromium.org,joi@chromium.org,pkasting@chromium.org,jochen@chromium.org,boliu@chromium.org,meacer@chromium.org NOTREECHECKS=true NOTRY=true BUG=173557 Review URL: https://codereview.chromium.org/221283006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261022 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/external_protocol')
-rw-r--r--chrome/browser/external_protocol/external_protocol_handler.cc40
-rw-r--r--chrome/browser/external_protocol/external_protocol_handler.h28
-rw-r--r--chrome/browser/external_protocol/external_protocol_handler_unittest.cc10
-rw-r--r--chrome/browser/external_protocol/external_protocol_observer.cc22
-rw-r--r--chrome/browser/external_protocol/external_protocol_observer.h29
5 files changed, 102 insertions, 27 deletions
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc
index 78334d9..b414261 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -27,6 +27,11 @@
using content::BrowserThread;
+// Whether we accept requests for launching external protocols. This is set to
+// false every time an external protocol is requested, and set back to true on
+// each user gesture. This variable should only be accessed from the UI thread.
+static bool g_accept_requests = true;
+
namespace {
// Functions enabling unit testing. Using a NULL delegate will use the default
@@ -44,13 +49,11 @@ ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
const std::string& scheme,
- ExternalProtocolHandler::Delegate* delegate,
- bool initiated_by_user_gesture) {
+ ExternalProtocolHandler::Delegate* delegate) {
if (!delegate)
- return ExternalProtocolHandler::GetBlockState(scheme,
- initiated_by_user_gesture);
+ return ExternalProtocolHandler::GetBlockState(scheme);
- return delegate->GetBlockState(scheme, initiated_by_user_gesture);
+ return delegate->GetBlockState(scheme);
}
void RunExternalProtocolDialogWithDelegate(
@@ -200,9 +203,9 @@ void ExternalProtocolHandler::PrepopulateDictionary(
// static
ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState(
- const std::string& scheme,
- bool initiated_by_user_gesture) {
- if (!initiated_by_user_gesture)
+ const std::string& scheme) {
+ // If we are being carpet bombed, block the request.
+ if (!g_accept_requests)
return BLOCK;
if (scheme.length() == 1) {
@@ -249,12 +252,10 @@ void ExternalProtocolHandler::SetBlockState(const std::string& scheme,
}
// static
-void ExternalProtocolHandler::LaunchUrlWithDelegate(
- const GURL& url,
- int render_process_host_id,
- int tab_contents_id,
- Delegate* delegate,
- bool initiated_by_user_gesture) {
+void ExternalProtocolHandler::LaunchUrlWithDelegate(const GURL& url,
+ int render_process_host_id,
+ int tab_contents_id,
+ Delegate* delegate) {
DCHECK(base::MessageLoopForUI::IsCurrent());
// Escape the input scheme to be sure that the command does not
@@ -262,14 +263,15 @@ void ExternalProtocolHandler::LaunchUrlWithDelegate(
std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec());
GURL escaped_url(escaped_url_string);
BlockState block_state = GetBlockStateWithDelegate(escaped_url.scheme(),
- delegate,
- initiated_by_user_gesture);
+ delegate);
if (block_state == BLOCK) {
if (delegate)
delegate->BlockRequest();
return;
}
+ g_accept_requests = false;
+
// The worker creates tasks with references to itself and puts them into
// message loops. When no tasks are left it will delete the observer and
// eventually be deleted itself.
@@ -306,3 +308,9 @@ void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(
void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(prefs::kExcludedSchemes);
}
+
+// static
+void ExternalProtocolHandler::PermitLaunchUrl() {
+ DCHECK(base::MessageLoopForUI::IsCurrent());
+ g_accept_requests = true;
+}
diff --git a/chrome/browser/external_protocol/external_protocol_handler.h b/chrome/browser/external_protocol/external_protocol_handler.h
index 6780d10..7c934c5 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.h
+++ b/chrome/browser/external_protocol/external_protocol_handler.h
@@ -30,8 +30,7 @@ class ExternalProtocolHandler {
virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
ShellIntegration::DefaultWebClientObserver* observer,
const std::string& protocol) = 0;
- virtual BlockState GetBlockState(const std::string& scheme,
- bool initiated_by_user_gesture) = 0;
+ virtual BlockState GetBlockState(const std::string& scheme) = 0;
virtual void BlockRequest() = 0;
virtual void RunExternalProtocolDialog(const GURL& url,
int render_process_host_id,
@@ -42,17 +41,27 @@ class ExternalProtocolHandler {
};
// Returns whether we should block a given scheme.
- static BlockState GetBlockState(const std::string& scheme,
- bool initiated_by_user_gesture);
+ static BlockState GetBlockState(const std::string& scheme);
// Sets whether we should block a given scheme.
static void SetBlockState(const std::string& scheme, BlockState state);
+ // Checks to see if the protocol is allowed, if it is whitelisted,
+ // the application associated with the protocol is launched on the io thread,
+ // if it is blacklisted, returns silently. Otherwise, an
+ // ExternalProtocolDialog is created asking the user. If the user accepts,
+ // LaunchUrlWithoutSecurityCheck is called on the io thread and the
+ // application is launched.
+ // Must run on the UI thread.
+ static void LaunchUrl(const GURL& url, int render_process_host_id,
+ int tab_contents_id) {
+ LaunchUrlWithDelegate(url, render_process_host_id, tab_contents_id, NULL);
+ }
+
// Version of LaunchUrl allowing use of a delegate to facilitate unit
// testing.
static void LaunchUrlWithDelegate(const GURL& url, int render_process_host_id,
- int tab_contents_id, Delegate* delegate,
- bool initiated_by_user_gesture);
+ int tab_contents_id, Delegate* delegate);
// Creates and runs a External Protocol dialog box.
// |url| - The url of the request.
@@ -87,8 +96,11 @@ class ExternalProtocolHandler {
// preferences for them do not already exist.
static void PrepopulateDictionary(base::DictionaryValue* win_pref);
- private:
- DISALLOW_COPY_AND_ASSIGN(ExternalProtocolHandler);
+ // Allows LaunchUrl to proceed with launching an external protocol handler.
+ // This is typically triggered by a user gesture, but is also called for
+ // each extension API function. Note that each call to LaunchUrl resets
+ // the state to false (not allowed).
+ static void PermitLaunchUrl();
};
#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_HANDLER_H_
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
index 0b27465..57a6db6 100644
--- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -51,8 +51,7 @@ class FakeExternalProtocolHandlerDelegate
}
virtual ExternalProtocolHandler::BlockState GetBlockState(
- const std::string& scheme,
- bool initiated_by_user_gesture) OVERRIDE { return block_state_; }
+ const std::string& scheme) OVERRIDE { return block_state_; }
virtual void BlockRequest() OVERRIDE {
ASSERT_TRUE(block_state_ == ExternalProtocolHandler::BLOCK ||
@@ -108,6 +107,11 @@ class ExternalProtocolHandlerTest : public testing::Test {
file_thread_.Start();
}
+ virtual void TearDown() {
+ // Ensure that g_accept_requests gets set back to true after test execution.
+ ExternalProtocolHandler::PermitLaunchUrl();
+ }
+
void DoTest(ExternalProtocolHandler::BlockState block_state,
ShellIntegration::DefaultWebClientState os_state,
bool should_prompt, bool should_launch, bool should_block) {
@@ -118,7 +122,7 @@ class ExternalProtocolHandlerTest : public testing::Test {
delegate_.set_block_state(block_state);
delegate_.set_os_state(os_state);
- ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_, true);
+ ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_);
if (block_state != ExternalProtocolHandler::BLOCK)
base::MessageLoop::current()->Run();
diff --git a/chrome/browser/external_protocol/external_protocol_observer.cc b/chrome/browser/external_protocol/external_protocol_observer.cc
new file mode 100644
index 0000000..8f69517
--- /dev/null
+++ b/chrome/browser/external_protocol/external_protocol_observer.cc
@@ -0,0 +1,22 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/external_protocol/external_protocol_observer.h"
+
+#include "chrome/browser/external_protocol/external_protocol_handler.h"
+
+using content::WebContents;
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(ExternalProtocolObserver);
+
+ExternalProtocolObserver::ExternalProtocolObserver(WebContents* web_contents)
+ : content::WebContentsObserver(web_contents) {
+}
+
+ExternalProtocolObserver::~ExternalProtocolObserver() {
+}
+
+void ExternalProtocolObserver::DidGetUserGesture() {
+ ExternalProtocolHandler::PermitLaunchUrl();
+}
diff --git a/chrome/browser/external_protocol/external_protocol_observer.h b/chrome/browser/external_protocol/external_protocol_observer.h
new file mode 100644
index 0000000..8249c3d
--- /dev/null
+++ b/chrome/browser/external_protocol/external_protocol_observer.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_OBSERVER_H_
+#define CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_OBSERVER_H_
+
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+// ExternalProtocolObserver is responsible for handling messages from
+// WebContents relating to external protocols.
+class ExternalProtocolObserver
+ : public content::WebContentsObserver,
+ public content::WebContentsUserData<ExternalProtocolObserver> {
+ public:
+ virtual ~ExternalProtocolObserver();
+
+ // content::WebContentsObserver overrides.
+ virtual void DidGetUserGesture() OVERRIDE;
+
+ private:
+ explicit ExternalProtocolObserver(content::WebContents* web_contents);
+ friend class content::WebContentsUserData<ExternalProtocolObserver>;
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalProtocolObserver);
+};
+
+#endif // CHROME_BROWSER_EXTERNAL_PROTOCOL_EXTERNAL_PROTOCOL_OBSERVER_H_