| // 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/dom_activity_logger.h" |
| |
| #include <utility> |
| |
| #include "content/public/renderer/render_thread.h" |
| #include "content/public/renderer/v8_value_converter.h" |
| #include "extensions/common/dom_action_types.h" |
| #include "extensions/common/extension_messages.h" |
| #include "extensions/renderer/activity_log_converter_strategy.h" |
| #include "third_party/blink/public/platform/web_string.h" |
| #include "third_party/blink/public/platform/web_url.h" |
| |
| using blink::WebString; |
| using blink::WebURL; |
| |
| namespace extensions { |
| |
| namespace { |
| |
| // Converts the given |v8_value| and appends it to the given |list|, if the |
| // conversion succeeds. |
| void AppendV8Value(const std::string& api_name, |
| const v8::Local<v8::Value>& v8_value, |
| base::ListValue* list) { |
| DCHECK(list); |
| std::unique_ptr<content::V8ValueConverter> converter = |
| content::V8ValueConverter::Create(); |
| ActivityLogConverterStrategy strategy; |
| converter->SetFunctionAllowed(true); |
| converter->SetStrategy(&strategy); |
| std::unique_ptr<base::Value> value(converter->FromV8Value( |
| v8_value, v8::Isolate::GetCurrent()->GetCurrentContext())); |
| |
| if (value.get()) |
| list->Append(std::move(value)); |
| } |
| |
| } // namespace |
| |
| DOMActivityLogger::DOMActivityLogger(const std::string& extension_id) |
| : extension_id_(extension_id) { |
| } |
| |
| DOMActivityLogger::~DOMActivityLogger() {} |
| |
| void DOMActivityLogger::AttachToWorld(int world_id, |
| const std::string& extension_id) { |
| // If there is no logger registered for world_id, construct a new logger |
| // and register it with world_id. |
| if (!blink::HasDOMActivityLogger(world_id, |
| WebString::FromUTF8(extension_id))) { |
| DOMActivityLogger* logger = new DOMActivityLogger(extension_id); |
| blink::SetDOMActivityLogger(world_id, WebString::FromUTF8(extension_id), |
| logger); |
| } |
| } |
| |
| void DOMActivityLogger::LogGetter(const WebString& api_name, |
| const WebURL& url, |
| const WebString& title) { |
| SendDomActionMessage(api_name.Utf8(), url, title.Utf16(), |
| DomActionType::GETTER, |
| std::unique_ptr<base::ListValue>(new base::ListValue())); |
| } |
| |
| void DOMActivityLogger::LogSetter(const WebString& api_name, |
| const v8::Local<v8::Value>& new_value, |
| const WebURL& url, |
| const WebString& title) { |
| logSetter(api_name, new_value, v8::Local<v8::Value>(), url, title); |
| } |
| |
| void DOMActivityLogger::logSetter(const WebString& api_name, |
| const v8::Local<v8::Value>& new_value, |
| const v8::Local<v8::Value>& old_value, |
| const WebURL& url, |
| const WebString& title) { |
| std::unique_ptr<base::ListValue> args(new base::ListValue); |
| std::string api_name_utf8 = api_name.Utf8(); |
| AppendV8Value(api_name_utf8, new_value, args.get()); |
| if (!old_value.IsEmpty()) |
| AppendV8Value(api_name_utf8, old_value, args.get()); |
| SendDomActionMessage(api_name_utf8, url, title.Utf16(), DomActionType::SETTER, |
| std::move(args)); |
| } |
| |
| void DOMActivityLogger::LogMethod(const WebString& api_name, |
| int argc, |
| const v8::Local<v8::Value>* argv, |
| const WebURL& url, |
| const WebString& title) { |
| std::unique_ptr<base::ListValue> args(new base::ListValue); |
| std::string api_name_utf8 = api_name.Utf8(); |
| for (int i = 0; i < argc; ++i) |
| AppendV8Value(api_name_utf8, argv[i], args.get()); |
| SendDomActionMessage(api_name_utf8, url, title.Utf16(), DomActionType::METHOD, |
| std::move(args)); |
| } |
| |
| void DOMActivityLogger::LogEvent(const WebString& event_name, |
| int argc, |
| const WebString* argv, |
| const WebURL& url, |
| const WebString& title) { |
| std::unique_ptr<base::ListValue> args(new base::ListValue); |
| std::string event_name_utf8 = event_name.Utf8(); |
| for (int i = 0; i < argc; ++i) |
| args->AppendString(argv[i].Utf8()); |
| SendDomActionMessage(event_name_utf8, url, title.Utf16(), |
| DomActionType::METHOD, std::move(args)); |
| } |
| |
| void DOMActivityLogger::SendDomActionMessage( |
| const std::string& api_call, |
| const GURL& url, |
| const base::string16& url_title, |
| DomActionType::Type call_type, |
| std::unique_ptr<base::ListValue> args) { |
| ExtensionHostMsg_DOMAction_Params params; |
| params.api_call = api_call; |
| params.url = url; |
| params.url_title = url_title; |
| params.call_type = call_type; |
| params.arguments.Swap(args.get()); |
| content::RenderThread::Get()->Send( |
| new ExtensionHostMsg_AddDOMActionToActivityLog(extension_id_, params)); |
| } |
| |
| } // namespace extensions |