Home | History | Annotate | Download | only in renderer
      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