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
16 using content::V8ValueConverter;
17 using blink::WebString;
18 using blink::WebURL;
19
20 namespace extensions {
21
22 namespace {
23
24 // Converts the given |v8_value| and appends it to the given |list|, if the
25 // conversion succeeds.
AppendV8Value(const std::string & api_name,const v8::Handle<v8::Value> & v8_value,base::ListValue * list)26 void 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
DOMActivityLogger(const std::string & extension_id)45 DOMActivityLogger::DOMActivityLogger(const std::string& extension_id)
46 : extension_id_(extension_id) {
47 }
48
~DOMActivityLogger()49 DOMActivityLogger::~DOMActivityLogger() {}
50
AttachToWorld(int world_id,const std::string & extension_id)51 void 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
logGetter(const WebString & api_name,const WebURL & url,const WebString & title)66 void 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
logSetter(const WebString & api_name,const v8::Handle<v8::Value> & new_value,const WebURL & url,const WebString & title)76 void 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
logSetter(const WebString & api_name,const v8::Handle<v8::Value> & new_value,const v8::Handle<v8::Value> & old_value,const WebURL & url,const WebString & title)83 void 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
logMethod(const WebString & api_name,int argc,const v8::Handle<v8::Value> * argv,const WebURL & url,const WebString & title)97 void 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
SendDomActionMessage(const std::string & api_call,const GURL & url,const base::string16 & url_title,DomActionType::Type call_type,scoped_ptr<base::ListValue> args)110 void 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