OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "extensions/renderer/api_activity_logger.h" |
| 6 |
5 #include <stddef.h> | 7 #include <stddef.h> |
6 | 8 |
7 #include <string> | 9 #include <string> |
8 | 10 |
9 #include "base/bind.h" | 11 #include "base/bind.h" |
10 #include "content/public/child/v8_value_converter.h" | 12 #include "content/public/child/v8_value_converter.h" |
11 #include "content/public/renderer/render_thread.h" | 13 #include "content/public/renderer/render_thread.h" |
12 #include "extensions/common/extension_messages.h" | 14 #include "extensions/common/extension_messages.h" |
13 #include "extensions/renderer/activity_log_converter_strategy.h" | 15 #include "extensions/renderer/activity_log_converter_strategy.h" |
14 #include "extensions/renderer/api_activity_logger.h" | |
15 #include "extensions/renderer/dispatcher.h" | 16 #include "extensions/renderer/dispatcher.h" |
| 17 #include "extensions/renderer/extensions_renderer_client.h" |
16 #include "extensions/renderer/script_context.h" | 18 #include "extensions/renderer/script_context.h" |
17 | 19 |
18 namespace extensions { | 20 namespace extensions { |
19 | 21 |
20 APIActivityLogger::APIActivityLogger(ScriptContext* context, | 22 APIActivityLogger::APIActivityLogger(ScriptContext* context, |
21 Dispatcher* dispatcher) | 23 Dispatcher* dispatcher) |
22 : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) { | 24 : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) { |
23 RouteFunction("LogEvent", base::Bind(&APIActivityLogger::LogEvent, | 25 RouteFunction("LogEvent", base::Bind(&APIActivityLogger::LogForJS, |
24 base::Unretained(this))); | 26 base::Unretained(this), EVENT)); |
25 RouteFunction("LogAPICall", base::Bind(&APIActivityLogger::LogAPICall, | 27 RouteFunction("LogAPICall", base::Bind(&APIActivityLogger::LogForJS, |
26 base::Unretained(this))); | 28 base::Unretained(this), APICALL)); |
27 } | 29 } |
28 | 30 |
29 APIActivityLogger::~APIActivityLogger() {} | 31 APIActivityLogger::~APIActivityLogger() {} |
30 | 32 |
31 // static | 33 // static |
32 void APIActivityLogger::LogAPICall( | 34 void APIActivityLogger::LogAPICall( |
33 const v8::FunctionCallbackInfo<v8::Value>& args) { | 35 v8::Local<v8::Context> context, |
34 LogInternal(APICALL, args); | 36 const std::string& call_name, |
| 37 const std::vector<v8::Local<v8::Value>>& arguments) { |
| 38 const Dispatcher* dispatcher = |
| 39 ExtensionsRendererClient::Get()->GetDispatcher(); |
| 40 if (!dispatcher || // dispatcher can be null in unittests. |
| 41 !dispatcher->activity_logging_enabled()) { |
| 42 return; |
| 43 } |
| 44 |
| 45 ScriptContext* script_context = |
| 46 ScriptContextSet::GetContextByV8Context(context); |
| 47 auto value_args = base::MakeUnique<base::ListValue>(); |
| 48 std::unique_ptr<content::V8ValueConverter> converter = |
| 49 content::V8ValueConverter::Create(); |
| 50 ActivityLogConverterStrategy strategy; |
| 51 converter->SetFunctionAllowed(true); |
| 52 converter->SetStrategy(&strategy); |
| 53 value_args->Reserve(arguments.size()); |
| 54 // TODO(devlin): This doesn't protect against custom properties, so it might |
| 55 // not perfectly reflect the passed arguments. |
| 56 for (const auto& arg : arguments) |
| 57 value_args->Append(converter->FromV8Value(arg, context)); |
| 58 |
| 59 LogInternal(APICALL, script_context->GetExtensionID(), call_name, |
| 60 std::move(value_args), std::string()); |
35 } | 61 } |
36 | 62 |
37 // static | 63 void APIActivityLogger::LogForJS( |
38 void APIActivityLogger::LogEvent( | |
39 const v8::FunctionCallbackInfo<v8::Value>& args) { | |
40 LogInternal(EVENT, args); | |
41 } | |
42 | |
43 // static | |
44 void APIActivityLogger::LogInternal( | |
45 const CallType call_type, | 64 const CallType call_type, |
46 const v8::FunctionCallbackInfo<v8::Value>& args) { | 65 const v8::FunctionCallbackInfo<v8::Value>& args) { |
47 CHECK_GT(args.Length(), 2); | 66 CHECK_GT(args.Length(), 2); |
48 CHECK(args[0]->IsString()); | 67 CHECK(args[0]->IsString()); |
49 CHECK(args[1]->IsString()); | 68 CHECK(args[1]->IsString()); |
50 CHECK(args[2]->IsArray()); | 69 CHECK(args[2]->IsArray()); |
51 | 70 |
52 if (!dispatcher_->activity_logging_enabled()) | 71 if (!dispatcher_->activity_logging_enabled()) |
53 return; | 72 return; |
54 | 73 |
55 std::string ext_id = *v8::String::Utf8Value(args[0]); | 74 v8::Isolate* isolate = args.GetIsolate(); |
56 ExtensionHostMsg_APIActionOrEvent_Params params; | 75 v8::HandleScope handle_scope(isolate); |
57 params.api_call = *v8::String::Utf8Value(args[1]); | 76 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
58 if (args.Length() == 4) // Extras are optional. | |
59 params.extra = *v8::String::Utf8Value(args[3]); | |
60 else | |
61 params.extra = ""; | |
62 | 77 |
63 // Get the array of api call arguments. | 78 std::string extension_id = *v8::String::Utf8Value(args[0]); |
| 79 std::string call_name = *v8::String::Utf8Value(args[1]); |
| 80 std::string extra; |
| 81 if (args.Length() == 4) { // Extras are optional. |
| 82 CHECK(args[3]->IsString()); |
| 83 extra = *v8::String::Utf8Value(args[3]); |
| 84 } |
| 85 |
| 86 // Get the array of call arguments. |
| 87 auto arguments = base::MakeUnique<base::ListValue>(); |
64 v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]); | 88 v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]); |
65 if (arg_array->Length() > 0) { | 89 if (arg_array->Length() > 0) { |
| 90 arguments->Reserve(arg_array->Length()); |
66 std::unique_ptr<content::V8ValueConverter> converter = | 91 std::unique_ptr<content::V8ValueConverter> converter = |
67 content::V8ValueConverter::Create(); | 92 content::V8ValueConverter::Create(); |
68 ActivityLogConverterStrategy strategy; | 93 ActivityLogConverterStrategy strategy; |
69 converter->SetFunctionAllowed(true); | 94 converter->SetFunctionAllowed(true); |
70 converter->SetStrategy(&strategy); | 95 converter->SetStrategy(&strategy); |
71 std::unique_ptr<base::ListValue> arg_list(new base::ListValue()); | 96 for (size_t i = 0; i < arg_array->Length(); ++i) |
72 for (size_t i = 0; i < arg_array->Length(); ++i) { | 97 arguments->Append(converter->FromV8Value(arg_array->Get(i), context)); |
73 arg_list->Set( | |
74 i, | |
75 converter->FromV8Value(arg_array->Get(i), | |
76 args.GetIsolate()->GetCurrentContext())); | |
77 } | |
78 params.arguments.Swap(arg_list.get()); | |
79 } | 98 } |
80 | 99 |
| 100 LogInternal(call_type, extension_id, call_name, std::move(arguments), extra); |
| 101 } |
| 102 |
| 103 // static |
| 104 void APIActivityLogger::LogInternal(const CallType call_type, |
| 105 const std::string& extension_id, |
| 106 const std::string& call_name, |
| 107 std::unique_ptr<base::ListValue> arguments, |
| 108 const std::string& extra) { |
| 109 ExtensionHostMsg_APIActionOrEvent_Params params; |
| 110 params.api_call = call_name; |
| 111 params.arguments.Swap(arguments.get()); |
| 112 params.extra = extra; |
81 if (call_type == APICALL) { | 113 if (call_type == APICALL) { |
82 content::RenderThread::Get()->Send( | 114 content::RenderThread::Get()->Send( |
83 new ExtensionHostMsg_AddAPIActionToActivityLog(ext_id, params)); | 115 new ExtensionHostMsg_AddAPIActionToActivityLog(extension_id, params)); |
84 } else if (call_type == EVENT) { | 116 } else if (call_type == EVENT) { |
85 content::RenderThread::Get()->Send( | 117 content::RenderThread::Get()->Send( |
86 new ExtensionHostMsg_AddEventToActivityLog(ext_id, params)); | 118 new ExtensionHostMsg_AddEventToActivityLog(extension_id, params)); |
87 } | 119 } |
88 } | 120 } |
89 | 121 |
90 } // namespace extensions | 122 } // namespace extensions |
OLD | NEW |