michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * The eventLoopLag actor emits "event-loop-lag" events when the event michael@0: * loop gets unresponsive. The event comes with a "time" property (the michael@0: * duration of the lag in milliseconds). michael@0: */ michael@0: michael@0: const {Ci, Cu} = require("chrome"); michael@0: const Services = require("Services"); michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: const protocol = require("devtools/server/protocol"); michael@0: const {method, Arg, RetVal} = protocol; michael@0: const events = require("sdk/event/core"); michael@0: michael@0: exports.register = function(handle) { michael@0: handle.addGlobalActor(EventLoopLagActor, "eventLoopLagActor"); michael@0: handle.addTabActor(EventLoopLagActor, "eventLoopLagActor"); michael@0: }; michael@0: michael@0: exports.unregister = function(handle) { michael@0: handle.removeGlobalActor(EventLoopLagActor); michael@0: handle.removeTabActor(EventLoopLagActor); michael@0: }; michael@0: michael@0: let EventLoopLagActor = protocol.ActorClass({ michael@0: michael@0: typeName: "eventLoopLag", michael@0: michael@0: _observerAdded: false, michael@0: michael@0: events: { michael@0: "event-loop-lag" : { michael@0: type: "event-loop-lag", michael@0: time: Arg(0, "number") // duration of the lag in milliseconds. michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Start tracking the event loop lags. michael@0: */ michael@0: start: method(function() { michael@0: if (!this._observerAdded) { michael@0: Services.obs.addObserver(this, 'event-loop-lag', false); michael@0: this._observerAdded = true; michael@0: } michael@0: return Services.appShell.startEventLoopLagTracking(); michael@0: }, { michael@0: request: {}, michael@0: response: {success: RetVal("number")} michael@0: }), michael@0: michael@0: /** michael@0: * Stop tracking the event loop lags. michael@0: */ michael@0: stop: method(function() { michael@0: if (this._observerAdded) { michael@0: Services.obs.removeObserver(this, 'event-loop-lag'); michael@0: this._observerAdded = false; michael@0: } michael@0: Services.appShell.stopEventLoopLagTracking(); michael@0: }, {request: {},response: {}}), michael@0: michael@0: destroy: function() { michael@0: this.stop(); michael@0: protocol.Actor.prototype.destroy.call(this); michael@0: }, michael@0: michael@0: // nsIObserver michael@0: michael@0: observe: function (subject, topic, data) { michael@0: if (topic == "event-loop-lag") { michael@0: // Forward event loop lag event michael@0: events.emit(this, "event-loop-lag", data); michael@0: } michael@0: }, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), michael@0: }); michael@0: michael@0: exports.EventLoopLagFront = protocol.FrontClass(EventLoopLagActor, { michael@0: initialize: function(client, form) { michael@0: protocol.Front.prototype.initialize.call(this, client); michael@0: this.actorID = form.eventLoopLagActor; michael@0: client.addActorPool(this); michael@0: this.manage(this); michael@0: }, michael@0: });