[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 1 | // Copyright (c) 2013 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 <string> |
| 6 | #include "base/bind.h" |
| 7 | #include "chrome/common/extensions/extension_messages.h" |
| 8 | #include "chrome/renderer/chrome_render_process_observer.h" |
[email protected] | d754cbb0 | 2013-08-12 17:51:36 | [diff] [blame^] | 9 | #include "chrome/renderer/extensions/activity_log_converter_strategy.h" |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 10 | #include "chrome/renderer/extensions/api_activity_logger.h" |
| 11 | #include "content/public/renderer/render_thread.h" |
| 12 | #include "content/public/renderer/v8_value_converter.h" |
| 13 | |
| 14 | using content::V8ValueConverter; |
| 15 | |
| 16 | namespace extensions { |
| 17 | |
| 18 | APIActivityLogger::APIActivityLogger( |
[email protected] | 9a59844 | 2013-06-04 16:39:12 | [diff] [blame] | 19 | Dispatcher* dispatcher, ChromeV8Context* context) |
| 20 | : ChromeV8Extension(dispatcher, context) { |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 21 | RouteFunction("LogEvent", base::Bind(&APIActivityLogger::LogEvent)); |
| 22 | RouteFunction("LogAPICall", base::Bind(&APIActivityLogger::LogAPICall)); |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 23 | RouteFunction("LogBlockedCall", |
| 24 | base::Bind(&APIActivityLogger::LogBlockedCallWrapper)); |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | // static |
[email protected] | d8c5fbb | 2013-06-14 11:35:25 | [diff] [blame] | 28 | void APIActivityLogger::LogAPICall( |
| 29 | const v8::FunctionCallbackInfo<v8::Value>& args) { |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 30 | LogInternal(APICALL, args); |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 31 | } |
| 32 | |
| 33 | // static |
[email protected] | d8c5fbb | 2013-06-14 11:35:25 | [diff] [blame] | 34 | void APIActivityLogger::LogEvent( |
| 35 | const v8::FunctionCallbackInfo<v8::Value>& args) { |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 36 | LogInternal(EVENT, args); |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | // static |
[email protected] | d8c5fbb | 2013-06-14 11:35:25 | [diff] [blame] | 40 | void APIActivityLogger::LogInternal( |
| 41 | const CallType call_type, |
| 42 | const v8::FunctionCallbackInfo<v8::Value>& args) { |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 43 | DCHECK_GT(args.Length(), 2); |
| 44 | DCHECK(args[0]->IsString()); |
| 45 | DCHECK(args[1]->IsString()); |
| 46 | DCHECK(args[2]->IsArray()); |
| 47 | |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 48 | std::string ext_id = *v8::String::AsciiValue(args[0]); |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 49 | ExtensionHostMsg_APIActionOrEvent_Params params; |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 50 | params.api_call = *v8::String::AsciiValue(args[1]); |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 51 | if (args.Length() == 4) // Extras are optional. |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 52 | params.extra = *v8::String::AsciiValue(args[3]); |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 53 | else |
| 54 | params.extra = ""; |
| 55 | |
| 56 | // Get the array of api call arguments. |
| 57 | v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]); |
| 58 | if (arg_array->Length() > 0) { |
| 59 | scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
[email protected] | d754cbb0 | 2013-08-12 17:51:36 | [diff] [blame^] | 60 | ActivityLogConverterStrategy strategy; |
| 61 | converter->SetFunctionAllowed(true); |
| 62 | converter->SetStrategy(&strategy); |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 63 | scoped_ptr<ListValue> arg_list(new ListValue()); |
| 64 | for (size_t i = 0; i < arg_array->Length(); ++i) { |
| 65 | arg_list->Set(i, |
| 66 | converter->FromV8Value(arg_array->Get(i), |
| 67 | v8::Context::GetCurrent())); |
| 68 | } |
| 69 | params.arguments.Swap(arg_list.get()); |
| 70 | } |
| 71 | |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 72 | if (call_type == APICALL) { |
| 73 | content::RenderThread::Get()->Send( |
| 74 | new ExtensionHostMsg_AddAPIActionToActivityLog(ext_id, params)); |
| 75 | } else if (call_type == EVENT) { |
| 76 | content::RenderThread::Get()->Send( |
| 77 | new ExtensionHostMsg_AddEventToActivityLog(ext_id, params)); |
| 78 | } |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 79 | } |
| 80 | |
[email protected] | 78216e1 | 2013-05-17 01:11:25 | [diff] [blame] | 81 | // static |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 82 | void APIActivityLogger::LogBlockedCallWrapper( |
| 83 | const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 84 | DCHECK_EQ(args.Length(), 3); |
| 85 | DCHECK(args[0]->IsString()); |
| 86 | DCHECK(args[1]->IsString()); |
| 87 | DCHECK(args[2]->IsNumber()); |
| 88 | int result; |
| 89 | scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| 90 | converter->FromV8Value(args[2], |
| 91 | v8::Context::GetCurrent())->GetAsInteger(&result); |
| 92 | LogBlockedCall(*v8::String::AsciiValue(args[0]), |
| 93 | *v8::String::AsciiValue(args[1]), |
| 94 | static_cast<Feature::AvailabilityResult>(result)); |
| 95 | } |
| 96 | |
| 97 | // static |
[email protected] | 78216e1 | 2013-05-17 01:11:25 | [diff] [blame] | 98 | void APIActivityLogger::LogBlockedCall(const std::string& extension_id, |
[email protected] | b6708d03 | 2013-07-14 08:18:22 | [diff] [blame] | 99 | const std::string& function_name, |
| 100 | Feature::AvailabilityResult result) { |
| 101 | // We don't really want to bother logging if it isn't permission related. |
| 102 | if (result == Feature::INVALID_MIN_MANIFEST_VERSION || |
| 103 | result == Feature::INVALID_MAX_MANIFEST_VERSION || |
| 104 | result == Feature::UNSUPPORTED_CHANNEL) |
| 105 | return; |
[email protected] | 78216e1 | 2013-05-17 01:11:25 | [diff] [blame] | 106 | content::RenderThread::Get()->Send( |
| 107 | new ExtensionHostMsg_AddBlockedCallToActivityLog(extension_id, |
| 108 | function_name)); |
| 109 | } |
| 110 | |
[email protected] | 302e4ad | 2013-04-12 22:56:43 | [diff] [blame] | 111 | |
[email protected] | 323722d | 2013-03-26 07:21:07 | [diff] [blame] | 112 | } // namespace extensions |