diff options
author | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-02 01:35:22 +0000 |
---|---|---|
committer | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-02 01:35:22 +0000 |
commit | 54aa17b1e77346c84d068be5d6eaddf576c440b7 (patch) | |
tree | 2dae52bf7eb8209d0224b679b311ccb17d810eb7 /chrome/browser/external_protocol | |
parent | 9e04fe63a65381f35b40902719e7d6c776c2de90 (diff) | |
download | chromium_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')
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_ |