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