// 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 #include #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, base::ListValue* list) { DCHECK(list); std::unique_ptr converter = content::V8ValueConverter::Create(); ActivityLogConverterStrategy strategy; converter->SetFunctionAllowed(true); converter->SetStrategy(&strategy); std::unique_ptr 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(int32_t 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::make_unique()); } void DOMActivityLogger::LogSetter(const WebString& api_name, const v8::Local& new_value, const WebURL& url, const WebString& title) { logSetter(api_name, new_value, v8::Local(), url, title); } void DOMActivityLogger::logSetter(const WebString& api_name, const v8::Local& new_value, const v8::Local& old_value, const WebURL& url, const WebString& title) { std::unique_ptr 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* argv, const WebURL& url, const WebString& title) { std::unique_ptr 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 args(new base::ListValue); std::string event_name_utf8 = event_name.Utf8(); for (int i = 0; i < argc; ++i) args->Append(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 std::u16string& url_title, DomActionType::Type call_type, std::unique_ptr 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