• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
AppendV8Value(const std::string & api_name,const v8::Handle<v8::Value> & v8_value,base::ListValue * list)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 
DOMActivityLogger(const std::string & extension_id)42 DOMActivityLogger::DOMActivityLogger(const std::string& extension_id)
43     : extension_id_(extension_id) {
44 }
45 
~DOMActivityLogger()46 DOMActivityLogger::~DOMActivityLogger() {}
47 
AttachToWorld(int world_id,const std::string & extension_id)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 
logGetter(const WebString & api_name,const WebURL & url,const WebString & title)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 
logSetter(const WebString & api_name,const v8::Handle<v8::Value> & new_value,const WebURL & url,const WebString & title)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 
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)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 
logMethod(const WebString & api_name,int argc,const v8::Handle<v8::Value> * argv,const WebURL & url,const WebString & title)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 
logEvent(const WebString & event_name,int argc,const WebString * argv,const WebURL & url,const WebString & title)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 
SendDomActionMessage(const std::string & api_call,const GURL & url,const base::string16 & url_title,DomActionType::Type call_type,scoped_ptr<base::ListValue> args)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