Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / send_request.js
blob9117e96006710000fbea1cb417fc7595c4f00b69
1 // Copyright (c) 2012 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.
5 var lastError = require('lastError');
6 var logging = requireNative('logging');
7 var natives = requireNative('sendRequest');
8 var processNatives = requireNative('process');
9 var validate = require('schemaUtils').validate;
11 // All outstanding requests from sendRequest().
12 var requests = {};
14 // Used to prevent double Activity Logging for API calls that use both custom
15 // bindings and ExtensionFunctions (via sendRequest).
16 var calledSendRequest = false;
18 // Runs a user-supplied callback safely.
19 function safeCallbackApply(name, request, callback, args) {
20   try {
21     $Function.apply(callback, request, args);
22   } catch (e) {
23     var errorMessage = "Error in response to " + name + ": " + e;
24     if (request.stack && request.stack != '')
25       errorMessage += "\n" + request.stack;
26     console.error(errorMessage);
27   }
30 // Callback handling.
31 function handleResponse(requestId, name, success, responseList, error) {
32   // The chrome objects we will set lastError on. Really we should only be
33   // setting this on the callback's chrome object, but set on ours too since
34   // it's conceivable that something relies on that.
35   var callerChrome = chrome;
37   try {
38     var request = requests[requestId];
39     logging.DCHECK(request != null);
41     // lastError needs to be set on the caller's chrome object no matter what,
42     // though chances are it's the same as ours (it will be different when
43     // calling API methods on other contexts).
44     if (request.callback)
45       callerChrome = natives.GetGlobal(request.callback).chrome;
47     lastError.clear(chrome);
48     if (callerChrome !== chrome)
49       lastError.clear(callerChrome);
51     if (!success) {
52       if (!error)
53         error = "Unknown error.";
54       lastError.set(name, error, request.stack, chrome);
55       if (callerChrome !== chrome)
56         lastError.set(name, error, request.stack, callerChrome);
57     }
59     if (request.customCallback) {
60       safeCallbackApply(name,
61                         request,
62                         request.customCallback,
63                         $Array.concat([name, request], responseList));
64     }
66     if (request.callback) {
67       // Validate callback in debug only -- and only when the
68       // caller has provided a callback. Implementations of api
69       // calls may not return data if they observe the caller
70       // has not provided a callback.
71       if (logging.DCHECK_IS_ON() && !error) {
72         if (!request.callbackSchema.parameters)
73           throw new Error(name + ": no callback schema defined");
74         validate(responseList, request.callbackSchema.parameters);
75       }
76       safeCallbackApply(name, request, request.callback, responseList);
77     }
79     if (error &&
80         !lastError.hasAccessed(chrome) &&
81         !lastError.hasAccessed(callerChrome)) {
82       // The native call caused an error, but the developer didn't check
83       // runtime.lastError.
84       // Notify the developer of the error via the (error) console.
85       console.error("Unchecked runtime.lastError while running " +
86           (name || "unknown") + ": " + error +
87           (request.stack ? "\n" + request.stack : ""));
88     }
89   } finally {
90     delete requests[requestId];
91     lastError.clear(chrome);
92     if (callerChrome !== chrome)
93       lastError.clear(callerChrome);
94   }
97 function getExtensionStackTrace(call_name) {
98   var stack = $String.split(new Error().stack, '\n');
99   var id = processNatives.GetExtensionId();
101   // Remove stack frames before and after that weren't associated with the
102   // extension.
103   return $Array.join(stack.filter(function(line) {
104     return line.indexOf(id) != -1;
105   }), '\n');
108 function prepareRequest(args, argSchemas) {
109   var request = {};
110   var argCount = args.length;
112   // Look for callback param.
113   if (argSchemas.length > 0 &&
114       argSchemas[argSchemas.length - 1].type == "function") {
115     request.callback = args[args.length - 1];
116     request.callbackSchema = argSchemas[argSchemas.length - 1];
117     --argCount;
118   }
120   request.args = [];
121   for (var k = 0; k < argCount; k++) {
122     request.args[k] = args[k];
123   }
125   return request;
128 // Send an API request and optionally register a callback.
129 // |optArgs| is an object with optional parameters as follows:
130 // - customCallback: a callback that should be called instead of the standard
131 //   callback.
132 // - nativeFunction: the v8 native function to handle the request, or
133 //   StartRequest if missing.
134 // - forIOThread: true if this function should be handled on the browser IO
135 //   thread.
136 // - preserveNullInObjects: true if it is safe for null to be in objects.
137 function sendRequest(functionName, args, argSchemas, optArgs) {
138   calledSendRequest = true;
139   if (!optArgs)
140     optArgs = {};
141   var request = prepareRequest(args, argSchemas);
142   request.stack = getExtensionStackTrace();
143   if (optArgs.customCallback) {
144     request.customCallback = optArgs.customCallback;
145   }
147   var nativeFunction = optArgs.nativeFunction || natives.StartRequest;
149   var requestId = natives.GetNextRequestId();
150   request.id = requestId;
151   requests[requestId] = request;
153   var hasCallback = request.callback || optArgs.customCallback;
154   return nativeFunction(functionName,
155                         request.args,
156                         requestId,
157                         hasCallback,
158                         optArgs.forIOThread,
159                         optArgs.preserveNullInObjects);
162 function getCalledSendRequest() {
163   return calledSendRequest;
166 function clearCalledSendRequest() {
167   calledSendRequest = false;
170 exports.sendRequest = sendRequest;
171 exports.getCalledSendRequest = getCalledSendRequest;
172 exports.clearCalledSendRequest = clearCalledSendRequest;
173 exports.safeCallbackApply = safeCallbackApply;
174 exports.getExtensionStackTrace = getExtensionStackTrace;
176 // Called by C++.
177 exports.handleResponse = handleResponse;