Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js

Issue 2441933002: [DevTools] Refactor connection-related classes. (Closed)
Patch Set: test fixes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 clientCallback(new constructor(value)); 195 clientCallback(new constructor(value));
196 else 196 else
197 clientCallback(value); 197 clientCallback(value);
198 } 198 }
199 return callbackWrapper; 199 return callbackWrapper;
200 } 200 }
201 } 201 }
202 202
203 /** 203 /**
204 * @constructor 204 * @constructor
205 * @extends {WebInspector.Object} 205 * @param {!InspectorBackendClass.Channel} channel
206 * @param {function(string)} disconnectedCallback
206 */ 207 */
207 InspectorBackendClass.Connection = function() 208 InspectorBackendClass.Connection = function(channel, disconnectedCallback)
208 { 209 {
210 this._channel = channel;
211 this._disconnectedCallback = disconnectedCallback;
209 this._lastMessageId = 1; 212 this._lastMessageId = 1;
210 this._pendingResponsesCount = 0; 213 this._pendingResponsesCount = 0;
211 this._agents = {}; 214 this._agents = {};
212 this._dispatchers = {}; 215 this._dispatchers = {};
213 this._callbacks = {}; 216 this._callbacks = {};
214 this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispat cherPrototypes); 217 this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispat cherPrototypes);
215 this._isConnected = true; 218 this._isConnected = true;
219 this._eventListeners = [
220 this._channel.addEventListener(InspectorBackendClass.Channel.Events.Chan nelClosed, this._channelClosed, this),
221 this._channel.addEventListener(InspectorBackendClass.Channel.Events.Mess ageReceived, this._messageReceived, this)
222 ];
223 if (!InspectorBackendClass.mainConnectionForTesting)
224 InspectorBackendClass.mainConnectionForTesting = this;
216 } 225 }
217 226
218 /** @enum {symbol} */ 227 /** @type {?InspectorBackendClass.Connection} */
219 InspectorBackendClass.Connection.Events = { 228 InspectorBackendClass.mainConnectionForTesting = null;
220 Disconnected: Symbol("Disconnected")
221 }
222 229
223 InspectorBackendClass.Connection.prototype = { 230 InspectorBackendClass.Connection.prototype = {
224 /** 231 /**
232 * @return {!Object.<string, !Object>}
233 */
234 agentsMap: function()
235 {
236 return this._agents;
237 },
238
239 /**
240 * @param {string} domain
241 * @param {!Object} dispatcher
242 */
243 registerDispatcher: function(domain, dispatcher)
244 {
245 if (!this._dispatchers[domain])
246 return;
247
248 this._dispatchers[domain].setDomainDispatcher(dispatcher);
249 },
250
251 /**
225 * @param {!Object.<string, !InspectorBackendClass.AgentPrototype>} agentPro totypes 252 * @param {!Object.<string, !InspectorBackendClass.AgentPrototype>} agentPro totypes
226 * @param {!Object.<string, !InspectorBackendClass.DispatcherPrototype>} dis patcherPrototypes 253 * @param {!Object.<string, !InspectorBackendClass.DispatcherPrototype>} dis patcherPrototypes
227 */ 254 */
228 _initialize: function(agentPrototypes, dispatcherPrototypes) 255 _initialize: function(agentPrototypes, dispatcherPrototypes)
229 { 256 {
230 for (var domain in agentPrototypes) { 257 for (var domain in agentPrototypes) {
231 this._agents[domain] = Object.create(agentPrototypes[domain]); 258 this._agents[domain] = Object.create(agentPrototypes[domain]);
232 this._agents[domain].setConnection(this); 259 this._agents[domain].setConnection(this);
233 } 260 }
234 261
235 for (var domain in dispatcherPrototypes) 262 for (var domain in dispatcherPrototypes)
236 this._dispatchers[domain] = Object.create(dispatcherPrototypes[domai n]); 263 this._dispatchers[domain] = Object.create(dispatcherPrototypes[domai n]);
237 }, 264 },
238 265
239 /** 266 /**
240 * @return {number} 267 * @return {number}
241 */ 268 */
242 nextMessageId: function() 269 _nextMessageId: function()
243 { 270 {
244 return this._lastMessageId++; 271 return this._lastMessageId++;
245 }, 272 },
246 273
247 /** 274 /**
248 * @param {string} domain 275 * @param {string} domain
249 * @return {!InspectorBackendClass.AgentPrototype} 276 * @return {!InspectorBackendClass.AgentPrototype}
250 */ 277 */
251 agent: function(domain) 278 _agent: function(domain)
252 { 279 {
253 return this._agents[domain]; 280 return this._agents[domain];
254 }, 281 },
255 282
256 /** 283 /**
257 * @return {!Object.<string, !Object>}
258 */
259 agentsMap: function()
260 {
261 return this._agents;
262 },
263
264 /**
265 * @param {string} domain 284 * @param {string} domain
266 * @param {string} method 285 * @param {string} method
267 * @param {?Object} params 286 * @param {?Object} params
268 * @param {?function(*)} callback 287 * @param {?function(*)} callback
269 */ 288 */
270 _wrapCallbackAndSendMessageObject: function(domain, method, params, callback ) 289 _wrapCallbackAndSendMessageObject: function(domain, method, params, callback )
271 { 290 {
272 if (!this._isConnected && callback) { 291 if (!this._isConnected) {
273 this._dispatchConnectionErrorResponse(domain, method, callback); 292 if (callback)
293 this._dispatchConnectionErrorResponse(domain, method, callback);
274 return; 294 return;
275 } 295 }
276 296
277 var messageObject = {}; 297 var messageObject = {};
278 var messageId = this.nextMessageId(); 298 var messageId = this._nextMessageId();
279 messageObject.id = messageId; 299 messageObject.id = messageId;
280 messageObject.method = method; 300 messageObject.method = method;
281 if (params) 301 if (params)
282 messageObject.params = params; 302 messageObject.params = params;
283 303
284 var wrappedCallback = this._wrap(callback, domain, method); 304 var wrappedCallback = this._wrap(callback, domain, method);
285 305
286 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages) 306 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
287 this._dumpProtocolMessage("frontend: " + JSON.stringify(messageObjec t)); 307 this._dumpProtocolMessage("frontend: " + JSON.stringify(messageObjec t));
288 308
289 this.sendMessage(messageObject); 309 this._channel.sendMessage(JSON.stringify(messageObject));
290 ++this._pendingResponsesCount; 310 ++this._pendingResponsesCount;
291 this._callbacks[messageId] = wrappedCallback; 311 this._callbacks[messageId] = wrappedCallback;
292 }, 312 },
293 313
294 /** 314 /**
295 * @param {?function(*)} callback 315 * @param {?function(*)} callback
296 * @param {string} method 316 * @param {string} method
297 * @param {string} domain 317 * @param {string} domain
298 * @return {function(*)} 318 * @return {function(*)}
299 */ 319 */
300 _wrap: function(callback, domain, method) 320 _wrap: function(callback, domain, method)
301 { 321 {
302 if (!callback) 322 if (!callback)
303 callback = function() {}; 323 callback = function() {};
304 324
305 callback.methodName = method; 325 callback.methodName = method;
306 callback.domain = domain; 326 callback.domain = domain;
307 if (InspectorBackendClass.Options.dumpInspectorTimeStats) 327 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
308 callback.sendRequestTime = Date.now(); 328 callback.sendRequestTime = Date.now();
309 329
310 return callback; 330 return callback;
311 }, 331 },
312 332
313 /** 333 /**
314 * @param {!Object} messageObject
315 */
316 sendMessage: function(messageObject)
317 {
318 throw "Not implemented";
319 },
320
321 /**
322 * @param {string} method 334 * @param {string} method
323 * @param {?Object} params 335 * @param {?Object} params
324 * @param {?function(...*)} callback 336 * @param {?function(...*)} callback
325 */ 337 */
326 sendRawMessageForTesting: function(method, params, callback) 338 _sendRawMessageForTesting: function(method, params, callback)
327 { 339 {
328 var domain = method.split(".")[0]; 340 var domain = method.split(".")[0];
329 this._wrapCallbackAndSendMessageObject(domain, method, params, callback) ; 341 this._wrapCallbackAndSendMessageObject(domain, method, params, callback) ;
330 }, 342 },
331 343
332 /** 344 /**
333 * @param {!Object|string} message 345 * @param {!WebInspector.Event} event
334 */ 346 */
335 dispatch: function(message) 347 _messageReceived: function(event)
336 { 348 {
349 var message = /** @type {!Object|string} */ (event.data);
337 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages) 350 if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
338 this._dumpProtocolMessage("backend: " + ((typeof message === "string ") ? message : JSON.stringify(message))); 351 this._dumpProtocolMessage("backend: " + ((typeof message === "string ") ? message : JSON.stringify(message)));
339 352
340 var messageObject = /** @type {!Object} */ ((typeof message === "string" ) ? JSON.parse(message) : message); 353 var messageObject = /** @type {!Object} */ ((typeof message === "string" ) ? JSON.parse(message) : message);
341 354
342 if ("id" in messageObject) { // just a response for some request 355 if ("id" in messageObject) { // just a response for some request
343 var callback = this._callbacks[messageObject.id]; 356 var callback = this._callbacks[messageObject.id];
344 if (!callback) { 357 if (!callback) {
345 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage with wrong id", messageObject); 358 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage with wrong id", messageObject);
346 return; 359 return;
347 } 360 }
348 361
349 var processingStartTime; 362 var processingStartTime;
350 if (InspectorBackendClass.Options.dumpInspectorTimeStats) 363 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
351 processingStartTime = Date.now(); 364 processingStartTime = Date.now();
352 365
353 this.agent(callback.domain).dispatchResponse(messageObject, callback .methodName, callback); 366 this._agent(callback.domain).dispatchResponse(messageObject, callbac k.methodName, callback);
354 --this._pendingResponsesCount; 367 --this._pendingResponsesCount;
355 delete this._callbacks[messageObject.id]; 368 delete this._callbacks[messageObject.id];
356 369
357 if (InspectorBackendClass.Options.dumpInspectorTimeStats) 370 if (InspectorBackendClass.Options.dumpInspectorTimeStats)
358 console.log("time-stats: " + callback.methodName + " = " + (proc essingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingSt artTime)); 371 console.log("time-stats: " + callback.methodName + " = " + (proc essingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingSt artTime));
359 372
360 if (this._scripts && !this._pendingResponsesCount) 373 if (this._scripts && !this._pendingResponsesCount)
361 this.deprecatedRunAfterPendingDispatches(); 374 this.deprecatedRunAfterPendingDispatches();
362 return;
363 } else { 375 } else {
376 if (!("method" in messageObject)) {
377 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage without method", messageObject);
378 return;
379 }
380
364 var method = messageObject.method.split("."); 381 var method = messageObject.method.split(".");
365 var domainName = method[0]; 382 var domainName = method[0];
366 if (!(domainName in this._dispatchers)) { 383 if (!(domainName in this._dispatchers)) {
367 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage " + messageObject.method + " is for non-existing domain '" + domainName + "'", messageObject); 384 InspectorBackendClass.reportProtocolError("Protocol Error: the m essage " + messageObject.method + " is for non-existing domain '" + domainName + "'", messageObject);
368 return; 385 return;
369 } 386 }
370 387
371 this._dispatchers[domainName].dispatch(method[1], messageObject); 388 this._dispatchers[domainName].dispatch(method[1], messageObject);
372 } 389 }
373
374 }, 390 },
375 391
376 /** 392 /**
377 * @param {string} domain
378 * @param {!Object} dispatcher
379 */
380 registerDispatcher: function(domain, dispatcher)
381 {
382 if (!this._dispatchers[domain])
383 return;
384
385 this._dispatchers[domain].setDomainDispatcher(dispatcher);
386 },
387
388 /**
389 * @param {function()=} script 393 * @param {function()=} script
390 */ 394 */
391 deprecatedRunAfterPendingDispatches: function(script) 395 deprecatedRunAfterPendingDispatches: function(script)
392 { 396 {
393 if (!this._scripts) 397 if (!this._scripts)
394 this._scripts = []; 398 this._scripts = [];
395 399
396 if (script) 400 if (script)
397 this._scripts.push(script); 401 this._scripts.push(script);
398 402
399 // Execute all promises. 403 // Execute all promises.
400 setTimeout(function() { 404 setTimeout(function() {
401 if (!this._pendingResponsesCount) 405 if (!this._pendingResponsesCount)
402 this._executeAfterPendingDispatches(); 406 this._executeAfterPendingDispatches();
403 else 407 else
404 this.deprecatedRunAfterPendingDispatches(); 408 this.deprecatedRunAfterPendingDispatches();
405 }.bind(this), 0); 409 }.bind(this), 0);
406 }, 410 },
407 411
408 _executeAfterPendingDispatches: function() 412 _executeAfterPendingDispatches: function()
409 { 413 {
410 if (!this._pendingResponsesCount) { 414 if (!this._pendingResponsesCount) {
411 var scripts = this._scripts; 415 var scripts = this._scripts;
412 this._scripts = []; 416 this._scripts = [];
413 for (var id = 0; id < scripts.length; ++id) 417 for (var id = 0; id < scripts.length; ++id)
414 scripts[id].call(this); 418 scripts[id].call(this);
415 } 419 }
416 }, 420 },
417 421
422 /**
423 * @param {!Object|string} message
424 */
418 _dumpProtocolMessage: function(message) 425 _dumpProtocolMessage: function(message)
419 { 426 {
420 console.log(message); 427 console.log(message);
421 }, 428 },
422 429
423 close: function() 430 /**
431 * @param {!WebInspector.Event} event
432 */
433 _channelClosed: function(event)
424 { 434 {
425 this.forceClose(); 435 WebInspector.EventTarget.removeEventListeners(this._eventListeners);
426 this.connectionClosed("force close"); 436 var reason = /** @type {string} */ (event.data);
427 },
428
429 /**
430 * @protected
431 */
432 forceClose: function()
433 {
434 },
435
436 /**
437 * @protected
438 * @param {string} reason
439 */
440 connectionClosed: function(reason)
441 {
442 this._isConnected = false; 437 this._isConnected = false;
443 this._runPendingCallbacks(); 438 this._runPendingCallbacks();
444 this.dispatchEventToListeners(InspectorBackendClass.Connection.Events.Di sconnected, {reason: reason}); 439 this._disconnectedCallback.call(null, reason);
440 this._disconnectedCallback = null;
445 }, 441 },
446 442
447 _runPendingCallbacks: function() 443 _runPendingCallbacks: function()
448 { 444 {
449 var keys = Object.keys(this._callbacks).map(function(num) { return parse Int(num, 10); }); 445 var keys = Object.keys(this._callbacks).map(function(num) { return parse Int(num, 10); });
450 for (var i = 0; i < keys.length; ++i) { 446 for (var i = 0; i < keys.length; ++i) {
451 var callback = this._callbacks[keys[i]]; 447 var callback = this._callbacks[keys[i]];
452 this._dispatchConnectionErrorResponse(callback.domain, callback.meth odName, callback); 448 this._dispatchConnectionErrorResponse(callback.domain, callback.meth odName, callback);
453 } 449 }
454 this._callbacks = {}; 450 this._callbacks = {};
455 }, 451 },
456 452
457 /** 453 /**
458 * @param {string} domain 454 * @param {string} domain
459 * @param {string} methodName 455 * @param {string} methodName
460 * @param {function(*)} callback 456 * @param {function(*)} callback
461 */ 457 */
462 _dispatchConnectionErrorResponse: function(domain, methodName, callback) 458 _dispatchConnectionErrorResponse: function(domain, methodName, callback)
463 { 459 {
464 var error = { message: "Connection is closed, can't dispatch pending " + methodName, code: InspectorBackendClass._DevToolsErrorCode, data: null}; 460 var error = { message: "Connection is closed, can't dispatch pending " + methodName, code: InspectorBackendClass._DevToolsErrorCode, data: null};
465 var messageObject = {error: error}; 461 var messageObject = {error: error};
466 setTimeout(InspectorBackendClass.AgentPrototype.prototype.dispatchRespon se.bind(this.agent(domain), messageObject, methodName, callback), 0); 462 setTimeout(InspectorBackendClass.AgentPrototype.prototype.dispatchRespon se.bind(this._agent(domain), messageObject, methodName, callback), 0);
467 }, 463 }
464 }
465
466
467 /**
468 * @interface
469 * @extends {WebInspector.EventTarget}
470 */
471 InspectorBackendClass.Channel = function()
472 {
473 }
474
475 /** @enum {symbol} */
476 InspectorBackendClass.Channel.Events = {
477 MessageReceived: Symbol("MessageReceived"),
478 ChannelClosed: Symbol("ChannelClosed")
479 }
480
481 InspectorBackendClass.Channel.prototype = {
482 /**
483 * @param {string} message
484 */
485 sendMessage: function(message) { },
468 486
469 /** 487 /**
470 * @return {boolean} 488 * @param {function()} callback
471 */ 489 */
472 isClosed: function() 490 reconnect: function(callback) { },
473 { 491 }
474 return !this._isConnected;
475 },
476 492
477 /**
478 * @param {!Array.<string>} domains
479 */
480 suppressErrorsForDomains: function(domains)
481 {
482 domains.forEach(function(domain) { this._agents[domain].suppressErrorLog ging(); }, this);
483 },
484
485 __proto__: WebInspector.Object.prototype
486
487 }
488 493
489 /** 494 /**
490 * @constructor 495 * @constructor
491 * @param {string} domain 496 * @param {string} domain
492 */ 497 */
493 InspectorBackendClass.AgentPrototype = function(domain) 498 InspectorBackendClass.AgentPrototype = function(domain)
494 { 499 {
495 this._replyArgs = {}; 500 this._replyArgs = {};
496 this._hasErrorData = {}; 501 this._hasErrorData = {};
497 this._domain = domain; 502 this._domain = domain;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 } 752 }
748 } 753 }
749 754
750 InspectorBackendClass.Options = { 755 InspectorBackendClass.Options = {
751 dumpInspectorTimeStats: false, 756 dumpInspectorTimeStats: false,
752 dumpInspectorProtocolMessages: false, 757 dumpInspectorProtocolMessages: false,
753 suppressRequestErrors: false 758 suppressRequestErrors: false
754 } 759 }
755 760
756 InspectorBackend = new InspectorBackendClass(); 761 InspectorBackend = new InspectorBackendClass();
762
763 /**
764 * @param {string} method
765 * @param {?Object} params
766 * @return {!Promise}
767 */
768 WebInspector.sendOverProtocol = function(method, params)
769 {
770 var connection = InspectorBackendClass.mainConnectionForTesting;
771 return new Promise((resolve, reject) => {
772 connection._sendRawMessageForTesting(method, params, (err, result) => {
773 if (err)
774 return reject(err);
775 return resolve(result);
776 });
777 });
778 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698