Chromium Code Reviews| Index: extensions/renderer/script_injection.cc |
| diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc |
| index 121def13fc31c357257b9ab2bbfe4261a805228d..b61fe9b888422173d027b7538e6a8645df96f877 100644 |
| --- a/extensions/renderer/script_injection.cc |
| +++ b/extensions/renderer/script_injection.cc |
| @@ -15,6 +15,7 @@ |
| #include "content/public/child/v8_value_converter.h" |
| #include "content/public/renderer/render_frame.h" |
| #include "extensions/common/extension_messages.h" |
| +#include "extensions/common/feature_switch.h" |
| #include "extensions/common/host_id.h" |
| #include "extensions/renderer/dom_activity_logger.h" |
| #include "extensions/renderer/extension_frame_helper.h" |
| @@ -77,6 +78,30 @@ int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host, |
| return id; |
| } |
| +// This class manages its own lifetime. |
| +class TimedScriptInjectionCallback : public ScriptInjectionCallback { |
| + public: |
| + TimedScriptInjectionCallback(base::WeakPtr<ScriptInjection> injection) |
| + : ScriptInjectionCallback( |
| + base::Bind(&TimedScriptInjectionCallback::OnCompleted, |
| + base::Unretained(this))), |
| + injection_(injection) {} |
| + ~TimedScriptInjectionCallback() override {} |
| + |
| + void OnCompleted(const std::vector<v8::Local<v8::Value>>& result) { |
| + if (injection_) { |
| + base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_; |
| + injection_->OnJsInjectionCompleted(result, elapsed); |
| + } |
| + } |
| + |
| + void willExecute() override { start_time_ = base::TimeTicks::Now(); } |
| + |
| + private: |
| + base::WeakPtr<ScriptInjection> injection_; |
| + base::TimeTicks start_time_; |
| +}; |
| + |
| } // namespace |
| // Watches for the deletion of a RenderFrame, after which is_valid will return |
| @@ -258,9 +283,7 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts, |
| bool is_user_gesture = injector_->IsUserGesture(); |
| std::unique_ptr<blink::WebScriptExecutionCallback> callback( |
| - new ScriptInjectionCallback( |
| - base::Bind(&ScriptInjection::OnJsInjectionCompleted, |
| - weak_ptr_factory_.GetWeakPtr()))); |
| + new TimedScriptInjectionCallback(weak_ptr_factory_.GetWeakPtr())); |
| base::ElapsedTimer exec_timer; |
| if (injection_host_->id().type() == HostID::EXTENSIONS && log_activity_) |
| @@ -273,11 +296,23 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts, |
| is_user_gesture, |
| callback.release()); |
| } else { |
| + blink::WebLocalFrame::ScriptExecutionType option; |
| + if (injector_->script_type() == UserScript::CONTENT_SCRIPT && |
| + FeatureSwitch::yield_between_content_script_runs()->IsEnabled()) { |
| + switch (run_location_) { |
| + case UserScript::DOCUMENT_END: |
| + case UserScript::DOCUMENT_IDLE: |
| + option = blink::WebLocalFrame::AsyncBlockingOnload; |
| + break; |
| + default: |
| + option = blink::WebLocalFrame::Synchronous; |
| + break; |
| + } |
| + } else { |
| + option = blink::WebLocalFrame::Synchronous; |
| + } |
| web_frame->requestExecuteScriptInIsolatedWorld( |
| - world_id, |
| - &sources.front(), |
| - sources.size(), |
| - is_user_gesture, |
| + world_id, &sources.front(), sources.size(), is_user_gesture, option, |
| callback.release()); |
| } |
| @@ -286,9 +321,13 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts, |
| } |
| void ScriptInjection::OnJsInjectionCompleted( |
| - const std::vector<v8::Local<v8::Value>>& results) { |
| + const std::vector<v8::Local<v8::Value>>& results, |
| + base::TimeDelta elapsed) { |
| DCHECK(!did_inject_js_); |
| + if (injection_host_->id().type() == HostID::EXTENSIONS) |
| + UMA_HISTOGRAM_TIMES("Extensions.InjectedScriptExecutionTime", elapsed); |
|
Devlin
2017/03/02 02:33:17
Did you forget to add this metric to histograms.xm
Kunihiko Sakamoto
2017/03/06 09:11:05
Oops, added.
|
| + |
| bool expects_results = injector_->ExpectsResults(); |
| if (expects_results) { |
| if (!results.empty() && !results[0].IsEmpty()) { |
| @@ -311,6 +350,7 @@ void ScriptInjection::OnJsInjectionCompleted( |
| // If |async_completion_callback_| is set, it means the script finished |
| // asynchronously, and we should run it. |
| if (!async_completion_callback_.is_null()) { |
| + complete_ = true; |
| injector_->OnInjectionComplete(std::move(execution_result_), run_location_, |
| render_frame_); |
| // Warning: this object can be destroyed after this line! |