diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 16:54:31 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-29 16:54:31 +0000 |
commit | e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54 (patch) | |
tree | 46394d04d84e59b9caf598a7138350c3400762c9 | |
parent | 965b6b2599050aab93cc398630d10ce30f3b4248 (diff) | |
download | chromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.zip chromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.tar.gz chromium_src-e81d4d7c8966f4650ea8041f8d0bad4fe72b4f54.tar.bz2 |
Allow webRequest API extensions to clear the in-memory cache of WebKit.
If the behavior of a webRequest API extension changes (i.e. different URLs are blocked) this effect was not visible instantly due to WebKit's in-memory cache. This CL introduces a means to clear the cache.
BUG=94284
TEST=no
Review URL: http://codereview.chromium.org/7835031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103289 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 1 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_webrequest_api.cc | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_webrequest_api.h | 7 | ||||
-rw-r--r-- | chrome/browser/renderer_host/web_cache_manager.cc | 17 | ||||
-rw-r--r-- | chrome/browser/renderer_host/web_cache_manager.h | 17 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 8 | ||||
-rw-r--r-- | chrome/common/extensions/docs/experimental.webRequest.html | 133 | ||||
-rw-r--r-- | chrome/common/extensions/docs/samples.json | 1 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 3 | ||||
-rw-r--r-- | chrome/renderer/chrome_content_renderer_client.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_process_observer.cc | 18 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_process_observer.h | 10 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.cc | 9 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_view_observer.h | 7 |
14 files changed, 226 insertions, 14 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 619d841..9d7b435 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -361,6 +361,7 @@ void FactoryRegistry::ResetFunctions() { // WebRequest. RegisterFunction<WebRequestAddEventListener>(); RegisterFunction<WebRequestEventHandled>(); + RegisterFunction<WebRequestHandlerBehaviorChanged>(); // Preferences. RegisterFunction<GetPreferenceFunction>(); diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc index cf13a52..1e80edd 100644 --- a/chrome/browser/extensions/extension_webrequest_api.cc +++ b/chrome/browser/extensions/extension_webrequest_api.cc @@ -20,6 +20,7 @@ #include "chrome/browser/extensions/extension_webrequest_time_tracker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/chrome_render_message_filter.h" +#include "chrome/browser/renderer_host/web_cache_manager.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_error_utils.h" #include "chrome/common/extensions/url_pattern.h" @@ -1498,3 +1499,8 @@ bool WebRequestEventHandled::RunImpl() { return true; } + +bool WebRequestHandlerBehaviorChanged::RunImpl() { + WebCacheManager::GetInstance()->ClearCacheOnNavigation(); + return true; +} diff --git a/chrome/browser/extensions/extension_webrequest_api.h b/chrome/browser/extensions/extension_webrequest_api.h index f44d5b7..8a131c0 100644 --- a/chrome/browser/extensions/extension_webrequest_api.h +++ b/chrome/browser/extensions/extension_webrequest_api.h @@ -370,4 +370,11 @@ class WebRequestEventHandled : public SyncIOThreadExtensionFunction { DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.eventHandled"); }; +class WebRequestHandlerBehaviorChanged : public AsyncExtensionFunction { + public: + virtual bool RunImpl(); + DECLARE_EXTENSION_FUNCTION_NAME( + "experimental.webRequest.handlerBehaviorChanged"); +}; + #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ diff --git a/chrome/browser/renderer_host/web_cache_manager.cc b/chrome/browser/renderer_host/web_cache_manager.cc index 5a3a0ff..8ee268d 100644 --- a/chrome/browser/renderer_host/web_cache_manager.cc +++ b/chrome/browser/renderer_host/web_cache_manager.cc @@ -146,8 +146,15 @@ void WebCacheManager::SetGlobalSizeLimit(size_t bytes) { void WebCacheManager::ClearCache() { // Tell each renderer process to clear the cache. - ClearRendederCache(active_renderers_); - ClearRendederCache(inactive_renderers_); + ClearRendederCache(active_renderers_, INSTANTLY); + ClearRendederCache(inactive_renderers_, INSTANTLY); +} + +void WebCacheManager::ClearCacheOnNavigation() { + // Tell each renderer process to clear the cache when a tab is reloaded or + // the user navigates to a new website. + ClearRendederCache(active_renderers_, ON_NAVIGATION); + ClearRendederCache(inactive_renderers_, ON_NAVIGATION); } void WebCacheManager::Observe(int type, @@ -321,12 +328,14 @@ void WebCacheManager::EnactStrategy(const AllocationStrategy& strategy) { } } -void WebCacheManager::ClearRendederCache(const std::set<int>& renderers) { +void WebCacheManager::ClearRendederCache( + const std::set<int>& renderers, + WebCacheManager::ClearCacheOccasion occasion) { std::set<int>::const_iterator iter = renderers.begin(); for (; iter != renderers.end(); ++iter) { RenderProcessHost* host = RenderProcessHost::FromID(*iter); if (host) - host->Send(new ChromeViewMsg_ClearCache()); + host->Send(new ChromeViewMsg_ClearCache(occasion == ON_NAVIGATION)); } } diff --git a/chrome/browser/renderer_host/web_cache_manager.h b/chrome/browser/renderer_host/web_cache_manager.h index 02c6958..0006572 100644 --- a/chrome/browser/renderer_host/web_cache_manager.h +++ b/chrome/browser/renderer_host/web_cache_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -70,6 +70,10 @@ class WebCacheManager : public NotificationObserver { // Clears all in-memory caches. void ClearCache(); + // Clears all in-memory caches when a tab is reloaded or the user navigates + // to a different website. + void ClearCacheOnNavigation(); + // NotificationObserver implementation: virtual void Observe(int type, const NotificationSource& source, @@ -179,8 +183,17 @@ class WebCacheManager : public NotificationObserver { // allocations according to |strategy|. void EnactStrategy(const AllocationStrategy& strategy); + enum ClearCacheOccasion { + // Instructs to clear the cache instantly. + INSTANTLY, + // Instructs to clear the cache when a navigation takes place (this + // includes reloading a tab). + ON_NAVIGATION + }; + // Inform all |renderers| to clear their cache. - void ClearRendederCache(const std::set<int>& renderers); + void ClearRendederCache(const std::set<int>& renderers, + ClearCacheOccasion occation); // Check to see if any active renderers have fallen inactive. void FindInactiveRenderers(); diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 4f4077a..a0e91fe8 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -5704,6 +5704,14 @@ "name": "response" } ] + }, + { + "name": "handlerBehaviorChanged", + "type": "function", + "description": "Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.", + "parameters": [ + {"type": "function", "name": "callback", "optional": true, "parameters": []} + ] } ], "events": [ diff --git a/chrome/common/extensions/docs/experimental.webRequest.html b/chrome/common/extensions/docs/experimental.webRequest.html index 6b0847e..7b1f2cd 100644 --- a/chrome/common/extensions/docs/experimental.webRequest.html +++ b/chrome/common/extensions/docs/experimental.webRequest.html @@ -319,6 +319,8 @@ <a href="#method-anchor">methodName</a> </li><li style="display: none; "> <a href="#method-anchor">methodName</a> + </li><li> + <a href="#method-handlerBehaviorChanged">handlerBehaviorChanged</a> </li> </ol> </li> @@ -806,6 +808,137 @@ chrome.windows.onRemoved.addListener( </p> </div> <!-- /description --> + </div><div class="apiItem"> + <a name="method-handlerBehaviorChanged"></a> <!-- method-anchor --> + <h4>handlerBehaviorChanged</h4> + + <div class="summary"><span style="display: none; ">void</span> + <!-- Note: intentionally longer 80 columns --> + <span>chrome.experimental.webRequest.handlerBehaviorChanged</span>(<span class="optional"><span style="display: none; ">, </span><span>function</span> + <var><span>callback</span></var></span>)</div> + + <div class="description"> + <p class="todo" style="display: none; ">Undocumented.</p> + <p>Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.</p> + + <!-- PARAMETERS --> + <h4>Parameters</h4> + <dl> + <div> + <div> + <dt> + <var>callback</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>function</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo"> + Undocumented. + </dd> + <dd style="display: none; "> + Description of this parameter from the json schema. + </dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- OBJECT METHODS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- OBJECT EVENT FIELDS --> + <dd style="display: none; "> + <div></div> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div> + </dl> + + <!-- RETURNS --> + <h4 style="display: none; ">Returns</h4> + <dl> + <div style="display: none; "> + <div> + </div> + </div> + </dl> + + <!-- CALLBACK --> + <div> + <div> + <h4>Callback function</h4> + <p style="display: none; "> + The callback <em>parameter</em> should specify a function + that looks like this: + </p> + <p> + If you specify the <em>callback</em> parameter, it should + specify a function that looks like this: + </p> + + <!-- Note: intentionally longer 80 columns --> + <pre>function(<span></span>) <span class="subdued">{...}</span>;</pre> + <dl> + <div style="display: none; "> + <div> + </div> + </div> + </dl> + </div> + </div> + + <!-- MIN_VERSION --> + <p style="display: none; "> + This function was added in version <b><span></span></b>. + If you require this function, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </p> + </div> <!-- /description --> + </div> <!-- /apiItem --> </div> <!-- /apiGroup --> diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json index 66f22ed..5614d6d 100644 --- a/chrome/common/extensions/docs/samples.json +++ b/chrome/common/extensions/docs/samples.json @@ -89,6 +89,7 @@ "chrome.experimental.webNavigation.onReferenceFragmentUpdated": "experimental.webNavigation.html#event-onReferenceFragmentUpdated", "chrome.experimental.webRequest.addEventListener": "experimental.webRequest.html#method-addEventListener", "chrome.experimental.webRequest.eventHandled": "experimental.webRequest.html#method-eventHandled", + "chrome.experimental.webRequest.handlerBehaviorChanged": "experimental.webRequest.html#method-handlerBehaviorChanged", "chrome.experimental.webRequest.onAuthRequired": "experimental.webRequest.html#event-onAuthRequired", "chrome.experimental.webRequest.onBeforeRedirect": "experimental.webRequest.html#event-onBeforeRedirect", "chrome.experimental.webRequest.onBeforeRequest": "experimental.webRequest.html#event-onBeforeRequest", diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 7d92fa2..84d1cff 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -138,7 +138,8 @@ IPC_MESSAGE_CONTROL3(ChromeViewMsg_SetCacheCapacities, size_t /* capacity */) // Tells the renderer to clear the cache. -IPC_MESSAGE_CONTROL0(ChromeViewMsg_ClearCache) +IPC_MESSAGE_CONTROL1(ChromeViewMsg_ClearCache, + bool /* on_navigation */) // Tells the renderer to dump as much memory as it can, perhaps because we // have memory pressure or the renderer is (or will be) paged out. This diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 91841cf..88d41cf 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -243,7 +243,8 @@ void ChromeContentRendererClient::RenderViewCreated(RenderView* render_view) { TranslateHelper* translate = new TranslateHelper(render_view, autofill_agent); new ChromeRenderViewObserver( - render_view, content_settings, extension_dispatcher_.get(), translate); + render_view, content_settings, chrome_observer_.get(), + extension_dispatcher_.get(), translate); // Used only for testing/automation. if (CommandLine::ForCurrentProcess()->HasSwitch( diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index 93d1fa8..ad41476 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc @@ -196,7 +196,8 @@ bool ChromeRenderProcessObserver::is_incognito_process_ = false; ChromeRenderProcessObserver::ChromeRenderProcessObserver( chrome::ChromeContentRendererClient* client) - : client_(client) { + : client_(client), + clear_cache_pending_(false) { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kEnableWatchdog)) { // TODO(JAR): Need to implement renderer IO msgloop watchdog. @@ -314,8 +315,12 @@ void ChromeRenderProcessObserver::OnSetCacheCapacities(size_t min_dead_capacity, min_dead_capacity, max_dead_capacity, capacity); } -void ChromeRenderProcessObserver::OnClearCache() { - WebCache::clear(); +void ChromeRenderProcessObserver::OnClearCache(bool on_navigation) { + if (on_navigation) { + clear_cache_pending_ = true; + } else { + WebCache::clear(); + } } void ChromeRenderProcessObserver::OnGetCacheResourceStats() { @@ -409,3 +414,10 @@ void ChromeRenderProcessObserver::OnPurgeMemory() { if (client_) client_->OnPurgeMemory(); } + +void ChromeRenderProcessObserver::ExecutePendingClearCache() { + if (clear_cache_pending_) { + clear_cache_pending_ = false; + WebCache::clear(); + } +} diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h index 80bf18ef..615b6c3 100644 --- a/chrome/renderer/chrome_render_process_observer.h +++ b/chrome/renderer/chrome_render_process_observer.h @@ -33,6 +33,10 @@ class ChromeRenderProcessObserver : public RenderProcessObserver { static bool is_incognito_process() { return is_incognito_process_; } + // Needs to be called by RenderViews in case of navigations to execute + // any 'clear cache' commands that were delayed until the next navigation. + void ExecutePendingClearCache(); + private: // RenderProcessObserver implementation. virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE; @@ -45,7 +49,9 @@ class ChromeRenderProcessObserver : public RenderProcessObserver { void OnSetCacheCapacities(size_t min_dead_capacity, size_t max_dead_capacity, size_t capacity); - void OnClearCache(); + // If |on_navigation| is true, the clearing is delayed until the next + // navigation event. + void OnClearCache(bool on_navigation); void OnGetCacheResourceStats(); void OnSetFieldTrialGroup(const std::string& fiel_trial_name, const std::string& group_name); @@ -58,6 +64,8 @@ class ChromeRenderProcessObserver : public RenderProcessObserver { static bool is_incognito_process_; scoped_ptr<ResourceDispatcherDelegate> resource_delegate_; chrome::ChromeContentRendererClient* client_; + // If true, the web cache shall be cleared before the next navigation event. + bool clear_cache_pending_; DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessObserver); }; diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index b913137..f4648fbc 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -16,6 +16,7 @@ #include "chrome/common/url_constants.h" #include "chrome/renderer/about_handler.h" #include "chrome/renderer/automation/dom_automation_controller.h" +#include "chrome/renderer/chrome_render_process_observer.h" #include "chrome/renderer/content_settings_observer.h" #include "chrome/renderer/extensions/extension_dispatcher.h" #include "chrome/renderer/external_host_bindings.h" @@ -198,11 +199,13 @@ GURL StripRef(const GURL& url) { ChromeRenderViewObserver::ChromeRenderViewObserver( RenderView* render_view, ContentSettingsObserver* content_settings, + ChromeRenderProcessObserver* chrome_render_process_observer, ExtensionDispatcher* extension_dispatcher, TranslateHelper* translate_helper) : RenderViewObserver(render_view), - content_settings_(content_settings), + chrome_render_process_observer_(chrome_render_process_observer), extension_dispatcher_(extension_dispatcher), + content_settings_(content_settings), translate_helper_(translate_helper), phishing_classifier_(NULL), last_indexed_page_id_(-1), @@ -336,6 +339,10 @@ void ChromeRenderViewObserver::OnSetAllowRunningInsecureContent(bool allow) { } void ChromeRenderViewObserver::Navigate(const GURL& url) { + // Execute cache clear operations that were postponed until a navigation + // event (including tab reload). + if (chrome_render_process_observer_) + chrome_render_process_observer_->ExecutePendingClearCache(); AboutHandler::MaybeHandle(url); } diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h index fa2946a..cf1497e 100644 --- a/chrome/renderer/chrome_render_view_observer.h +++ b/chrome/renderer/chrome_render_view_observer.h @@ -16,6 +16,7 @@ #include "googleurl/src/gurl.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPermissionClient.h" +class ChromeRenderProcessObserver; class ContentSettingsObserver; class DomAutomationController; class ExtensionDispatcher; @@ -43,6 +44,7 @@ class ChromeRenderViewObserver : public RenderViewObserver, ChromeRenderViewObserver( RenderView* render_view, ContentSettingsObserver* content_settings, + ChromeRenderProcessObserver* chrome_render_process_observer, ExtensionDispatcher* extension_dispatcher, TranslateHelper* translate_helper); virtual ~ChromeRenderViewObserver(); @@ -171,9 +173,12 @@ class ChromeRenderViewObserver : public RenderViewObserver, // Save the JavaScript to preload if a ViewMsg_WebUIJavaScript is received. scoped_ptr<WebUIJavaScript> webui_javascript_; + // Owned by ChromeContentRendererClient and outlive us. + ChromeRenderProcessObserver* chrome_render_process_observer_; + ExtensionDispatcher* extension_dispatcher_; + // Have the same lifetime as us. ContentSettingsObserver* content_settings_; - ExtensionDispatcher* extension_dispatcher_; TranslateHelper* translate_helper_; safe_browsing::PhishingClassifierDelegate* phishing_classifier_; |