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

Unified Diff: extensions/renderer/user_script_slave.cc

Issue 321993003: Refactor renderer-side script injection (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Missing files Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/user_script_slave.cc
diff --git a/extensions/renderer/user_script_slave.cc b/extensions/renderer/user_script_slave.cc
deleted file mode 100644
index 7e465c65d4e294b37e14444e12633c2cc2d076c6..0000000000000000000000000000000000000000
--- a/extensions/renderer/user_script_slave.cc
+++ /dev/null
@@ -1,298 +0,0 @@
-// 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 "extensions/renderer/user_script_slave.h"
-
-#include <map>
-
-#include "base/logging.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/histogram.h"
-#include "base/pickle.h"
-#include "base/timer/elapsed_timer.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/common/extension_set.h"
-#include "extensions/common/manifest_handlers/csp_info.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/renderer/extension_helper.h"
-#include "extensions/renderer/extensions_renderer_client.h"
-#include "extensions/renderer/script_context.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
-#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "url/gurl.h"
-
-using blink::WebFrame;
-using blink::WebSecurityOrigin;
-using blink::WebSecurityPolicy;
-using blink::WebString;
-using content::RenderThread;
-
-namespace extensions {
-
-int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension,
- WebFrame* frame) {
- static int g_next_isolated_world_id =
- ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId();
-
- int id = 0;
- IsolatedWorldMap::iterator iter = isolated_world_ids_.find(extension->id());
- if (iter != isolated_world_ids_.end()) {
- id = iter->second;
- } else {
- id = g_next_isolated_world_id++;
- // This map will tend to pile up over time, but realistically, you're never
- // going to have enough extensions for it to matter.
- isolated_world_ids_[extension->id()] = id;
- }
-
- // We need to set the isolated world origin and CSP even if it's not a new
- // world since these are stored per frame, and we might not have used this
- // isolated world in this frame before.
- frame->setIsolatedWorldSecurityOrigin(
- id, WebSecurityOrigin::create(extension->url()));
- frame->setIsolatedWorldContentSecurityPolicy(
- id, WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
-
- return id;
-}
-
-std::string UserScriptSlave::GetExtensionIdForIsolatedWorld(
- int isolated_world_id) {
- for (IsolatedWorldMap::iterator iter = isolated_world_ids_.begin();
- iter != isolated_world_ids_.end();
- ++iter) {
- if (iter->second == isolated_world_id)
- return iter->first;
- }
- return std::string();
-}
-
-void UserScriptSlave::RemoveIsolatedWorld(const std::string& extension_id) {
- isolated_world_ids_.erase(extension_id);
-}
-
-UserScriptSlave::UserScriptSlave(const ExtensionSet* extensions)
- : extensions_(extensions) {
-}
-
-UserScriptSlave::~UserScriptSlave() {
-}
-
-void UserScriptSlave::GetActiveExtensions(
- std::set<std::string>* extension_ids) {
- DCHECK(extension_ids);
- for (ScopedVector<ScriptInjection>::const_iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();
- ++iter) {
- DCHECK(!(*iter)->extension_id().empty());
- extension_ids->insert((*iter)->extension_id());
- }
-}
-
-const Extension* UserScriptSlave::GetExtension(
- const std::string& extension_id) {
- return extensions_->GetByID(extension_id);
-}
-
-bool UserScriptSlave::UpdateScripts(
- base::SharedMemoryHandle shared_memory,
- const std::set<std::string>& changed_extensions) {
- bool only_inject_incognito =
- ExtensionsRendererClient::Get()->IsIncognitoProcess();
-
- // Create the shared memory object (read only).
- shared_memory_.reset(new base::SharedMemory(shared_memory, true));
- if (!shared_memory_.get())
- return false;
-
- // First get the size of the memory block.
- if (!shared_memory_->Map(sizeof(Pickle::Header)))
- return false;
- Pickle::Header* pickle_header =
- reinterpret_cast<Pickle::Header*>(shared_memory_->memory());
-
- // Now map in the rest of the block.
- int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
- shared_memory_->Unmap();
- if (!shared_memory_->Map(pickle_size))
- return false;
-
- // Unpickle scripts.
- uint64 num_scripts = 0;
- Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()), pickle_size);
- PickleIterator iter(pickle);
- CHECK(pickle.ReadUInt64(&iter, &num_scripts));
-
- // If we pass no explicit extension ids, we should refresh all extensions.
- bool include_all_extensions = changed_extensions.empty();
-
- // If we include all extensions, then we clear the script injections and
- // start from scratch. If not, then clear only the scripts for extension ids
- // that we are updating. This is important to maintain pending script
- // injection state for each ScriptInjection.
- if (include_all_extensions) {
- script_injections_.clear();
- } else {
- for (ScopedVector<ScriptInjection>::iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();) {
- if (changed_extensions.count((*iter)->extension_id()) > 0)
- iter = script_injections_.erase(iter);
- else
- ++iter;
- }
- }
-
- script_injections_.reserve(num_scripts);
- for (uint64 i = 0; i < num_scripts; ++i) {
- scoped_ptr<UserScript> script(new UserScript());
- script->Unpickle(pickle, &iter);
-
- // Note that this is a pointer into shared memory. We don't own it. It gets
- // cleared up when the last renderer or browser process drops their
- // reference to the shared memory.
- for (size_t j = 0; j < script->js_scripts().size(); ++j) {
- const char* body = NULL;
- int body_length = 0;
- CHECK(pickle.ReadData(&iter, &body, &body_length));
- script->js_scripts()[j].set_external_content(
- base::StringPiece(body, body_length));
- }
- for (size_t j = 0; j < script->css_scripts().size(); ++j) {
- const char* body = NULL;
- int body_length = 0;
- CHECK(pickle.ReadData(&iter, &body, &body_length));
- script->css_scripts()[j].set_external_content(
- base::StringPiece(body, body_length));
- }
-
- if (only_inject_incognito && !script->is_incognito_enabled())
- continue; // This script shouldn't run in an incognito tab.
-
- // If we include all extensions or the given extension changed, we add a
- // new script injection.
- if (include_all_extensions ||
- changed_extensions.count(script->extension_id()) > 0) {
- script_injections_.push_back(new ScriptInjection(script.Pass(), this));
- } else {
- // Otherwise, we need to update the existing script injection with the
- // new user script (since the old content was invalidated).
- //
- // Note: Yes, this is O(n^2). But vectors are faster than maps for
- // relatively few elements, and less than 1% of our users actually have
- // enough content scripts for it to matter. If this changes, or if
- // std::maps get a much faster implementation, we should look into
- // making a map for script injections.
- for (ScopedVector<ScriptInjection>::iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();
- ++iter) {
- if ((*iter)->script()->id() == script->id()) {
- (*iter)->SetScript(script.Pass());
- break;
- }
- }
- }
- }
- return true;
-}
-
-void UserScriptSlave::InjectScripts(WebFrame* frame,
- UserScript::RunLocation location) {
- GURL document_url = ScriptInjection::GetDocumentUrlForFrame(frame);
- if (document_url.is_empty())
- return;
-
- ScriptInjection::ScriptsRunInfo scripts_run_info;
- for (ScopedVector<ScriptInjection>::const_iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();
- ++iter) {
- (*iter)->InjectIfAllowed(frame, location, document_url, &scripts_run_info);
- }
-
- LogScriptsRun(frame, location, scripts_run_info);
-}
-
-void UserScriptSlave::OnContentScriptGrantedPermission(
- content::RenderView* render_view, int request_id) {
- ScriptInjection::ScriptsRunInfo run_info;
- blink::WebFrame* frame = NULL;
- // Notify the injections that a request to inject has been granted.
- for (ScopedVector<ScriptInjection>::iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();
- ++iter) {
- if ((*iter)->NotifyScriptPermitted(request_id,
- render_view,
- &run_info,
- &frame)) {
- DCHECK(frame);
- LogScriptsRun(frame, UserScript::RUN_DEFERRED, run_info);
- break;
- }
- }
-}
-
-void UserScriptSlave::FrameDetached(blink::WebFrame* frame) {
- for (ScopedVector<ScriptInjection>::iterator iter =
- script_injections_.begin();
- iter != script_injections_.end();
- ++iter) {
- (*iter)->FrameDetached(frame);
- }
-}
-
-void UserScriptSlave::LogScriptsRun(
- blink::WebFrame* frame,
- UserScript::RunLocation location,
- const ScriptInjection::ScriptsRunInfo& info) {
- // Notify the browser if any extensions are now executing scripts.
- if (!info.executing_scripts.empty()) {
- content::RenderView* render_view =
- content::RenderView::FromWebView(frame->view());
- render_view->Send(new ExtensionHostMsg_ContentScriptsExecuting(
- render_view->GetRoutingID(),
- info.executing_scripts,
- render_view->GetPageId(),
- ScriptContext::GetDataSourceURLForFrame(frame)));
- }
-
- switch (location) {
- case UserScript::DOCUMENT_START:
- UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount",
- info.num_css);
- UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount",
- info.num_js);
- if (info.num_css || info.num_js)
- UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time",
- info.timer.Elapsed());
- break;
- case UserScript::DOCUMENT_END:
- UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", info.num_js);
- if (info.num_js)
- UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", info.timer.Elapsed());
- break;
- case UserScript::DOCUMENT_IDLE:
- UMA_HISTOGRAM_COUNTS_100("Extensions.InjectIdle_ScriptCount",
- info.num_js);
- if (info.num_js)
- UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", info.timer.Elapsed());
- break;
- case UserScript::RUN_DEFERRED:
- // TODO(rdevlin.cronin): Add histograms.
- break;
- case UserScript::UNDEFINED:
- case UserScript::RUN_LOCATION_LAST:
- NOTREACHED();
- }
-}
-
-} // namespace extensions
« extensions/renderer/user_script_injection_list.cc ('K') | « extensions/renderer/user_script_slave.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698