1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "extensions/renderer/dom_activity_logger.h" 6 7#include "content/public/renderer/render_thread.h" 8#include "content/public/renderer/v8_value_converter.h" 9#include "extensions/common/dom_action_types.h" 10#include "extensions/common/extension_messages.h" 11#include "extensions/renderer/activity_log_converter_strategy.h" 12#include "third_party/WebKit/public/platform/WebString.h" 13#include "third_party/WebKit/public/platform/WebURL.h" 14 15using content::V8ValueConverter; 16using blink::WebString; 17using blink::WebURL; 18 19namespace extensions { 20 21namespace { 22 23// Converts the given |v8_value| and appends it to the given |list|, if the 24// conversion succeeds. 25void AppendV8Value(const std::string& api_name, 26 const v8::Handle<v8::Value>& v8_value, 27 base::ListValue* list) { 28 DCHECK(list); 29 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 30 ActivityLogConverterStrategy strategy; 31 converter->SetFunctionAllowed(true); 32 converter->SetStrategy(&strategy); 33 scoped_ptr<base::Value> value(converter->FromV8Value( 34 v8_value, v8::Isolate::GetCurrent()->GetCurrentContext())); 35 36 if (value.get()) 37 list->Append(value.release()); 38} 39 40} // namespace 41 42DOMActivityLogger::DOMActivityLogger(const std::string& extension_id) 43 : extension_id_(extension_id) { 44} 45 46DOMActivityLogger::~DOMActivityLogger() {} 47 48void DOMActivityLogger::AttachToWorld(int world_id, 49 const std::string& extension_id) { 50#if defined(ENABLE_EXTENSIONS) 51 // If there is no logger registered for world_id, construct a new logger 52 // and register it with world_id. 53 if (!blink::hasDOMActivityLogger(world_id, 54 WebString::fromUTF8(extension_id))) { 55 DOMActivityLogger* logger = new DOMActivityLogger(extension_id); 56 blink::setDOMActivityLogger(world_id, 57 WebString::fromUTF8(extension_id), 58 logger); 59 } 60#endif 61} 62 63void DOMActivityLogger::logGetter(const WebString& api_name, 64 const WebURL& url, 65 const WebString& title) { 66 SendDomActionMessage(api_name.utf8(), 67 url, 68 title, 69 DomActionType::GETTER, 70 scoped_ptr<base::ListValue>(new base::ListValue())); 71} 72 73void DOMActivityLogger::logSetter(const WebString& api_name, 74 const v8::Handle<v8::Value>& new_value, 75 const WebURL& url, 76 const WebString& title) { 77 logSetter(api_name, new_value, v8::Handle<v8::Value>(), url, title); 78} 79 80void DOMActivityLogger::logSetter(const WebString& api_name, 81 const v8::Handle<v8::Value>& new_value, 82 const v8::Handle<v8::Value>& old_value, 83 const WebURL& url, 84 const WebString& title) { 85 scoped_ptr<base::ListValue> args(new base::ListValue); 86 std::string api_name_utf8 = api_name.utf8(); 87 AppendV8Value(api_name_utf8, new_value, args.get()); 88 if (!old_value.IsEmpty()) 89 AppendV8Value(api_name_utf8, old_value, args.get()); 90 SendDomActionMessage( 91 api_name_utf8, url, title, DomActionType::SETTER, args.Pass()); 92} 93 94void DOMActivityLogger::logMethod(const WebString& api_name, 95 int argc, 96 const v8::Handle<v8::Value>* argv, 97 const WebURL& url, 98 const WebString& title) { 99 scoped_ptr<base::ListValue> args(new base::ListValue); 100 std::string api_name_utf8 = api_name.utf8(); 101 for (int i = 0; i < argc; ++i) 102 AppendV8Value(api_name_utf8, argv[i], args.get()); 103 SendDomActionMessage( 104 api_name_utf8, url, title, DomActionType::METHOD, args.Pass()); 105} 106 107void DOMActivityLogger::logEvent(const WebString& event_name, 108 int argc, 109 const WebString* argv, 110 const WebURL& url, 111 const WebString& title) { 112 scoped_ptr<base::ListValue> args(new base::ListValue); 113 std::string event_name_utf8 = event_name.utf8(); 114 for (int i = 0; i < argc; ++i) 115 args->Append(new base::StringValue(argv[i])); 116 SendDomActionMessage( 117 event_name_utf8, url, title, DomActionType::METHOD, args.Pass()); 118} 119 120void DOMActivityLogger::SendDomActionMessage(const std::string& api_call, 121 const GURL& url, 122 const base::string16& url_title, 123 DomActionType::Type call_type, 124 scoped_ptr<base::ListValue> args) { 125 ExtensionHostMsg_DOMAction_Params params; 126 params.api_call = api_call; 127 params.url = url; 128 params.url_title = url_title; 129 params.call_type = call_type; 130 params.arguments.Swap(args.get()); 131 content::RenderThread::Get()->Send( 132 new ExtensionHostMsg_AddDOMActionToActivityLog(extension_id_, params)); 133} 134 135} // namespace extensions 136