Index: chrome/browser/external_protocol/external_protocol_handler.cc |
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc |
index b414261cb32dd576f655e6e8529eba46d817e917..528d21d82f801e5fff1c8c1f2cbd9d5dd756051e 100644 |
--- a/chrome/browser/external_protocol/external_protocol_handler.cc |
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc |
@@ -27,10 +27,10 @@ |
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; |
+// User gesture counter. This is increased when a user gesture is available, and |
+// decreased when the gesture is consumed or goes out of scope. This variable |
+// should only be accessed from the UI thread. |
+static size_t g_consumable_user_gestures = 0; |
namespace { |
@@ -204,8 +204,8 @@ void ExternalProtocolHandler::PrepopulateDictionary( |
// static |
ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( |
const std::string& scheme) { |
- // If we are being carpet bombed, block the request. |
- if (!g_accept_requests) |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!g_consumable_user_gestures) |
return BLOCK; |
if (scheme.length() == 1) { |
@@ -270,8 +270,6 @@ void ExternalProtocolHandler::LaunchUrlWithDelegate(const GURL& url, |
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. |
@@ -309,8 +307,12 @@ void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { |
registry->RegisterDictionaryPref(prefs::kExcludedSchemes); |
} |
-// static |
-void ExternalProtocolHandler::PermitLaunchUrl() { |
- DCHECK(base::MessageLoopForUI::IsCurrent()); |
- g_accept_requests = true; |
+ExternalProtocolHandler::ScopedUserGesture::ScopedUserGesture() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ g_consumable_user_gestures++; |
+} |
+ |
+ExternalProtocolHandler::ScopedUserGesture::~ScopedUserGesture() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ g_consumable_user_gestures--; |
} |