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 15 using content::V8ValueConverter; 16 using blink::WebString; 17 using blink::WebURL; 18 19 namespace extensions { 20 21 namespace { 22 23 // Converts the given |v8_value| and appends it to the given |list|, if the 24 // conversion succeeds. 25 void 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 42 DOMActivityLogger::DOMActivityLogger(const std::string& extension_id) 43 : extension_id_(extension_id) { 44 } 45 46 DOMActivityLogger::~DOMActivityLogger() {} 47 48 void 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 63 void 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 73 void 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 80 void 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 94 void 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 107 void 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 120 void 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