diff -r 000000000000 -r 6474c204b198 browser/devtools/app-manager/device-store.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browser/devtools/app-manager/device-store.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,122 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const ObservableObject = require("devtools/shared/observable-object"); +const {getDeviceFront} = require("devtools/server/actors/device"); +const {Connection} = require("devtools/client/connection-manager"); + +const {Cu} = require("chrome"); + +const _knownDeviceStores = new WeakMap(); + +let DeviceStore; + +module.exports = DeviceStore = function(connection) { + // If we already know about this connection, + // let's re-use the existing store. + if (_knownDeviceStores.has(connection)) { + return _knownDeviceStores.get(connection); + } + + _knownDeviceStores.set(connection, this); + + ObservableObject.call(this, {}); + + this._resetStore(); + + this.destroy = this.destroy.bind(this); + this._onStatusChanged = this._onStatusChanged.bind(this); + + this._connection = connection; + this._connection.once(Connection.Events.DESTROYED, this.destroy); + this._connection.on(Connection.Events.STATUS_CHANGED, this._onStatusChanged); + this._onTabListChanged = this._onTabListChanged.bind(this); + this._onStatusChanged(); + return this; +}; + +DeviceStore.prototype = { + destroy: function() { + if (this._connection) { + // While this.destroy is bound using .once() above, that event may not + // have occurred when the DeviceStore client calls destroy, so we + // manually remove it here. + this._connection.off(Connection.Events.DESTROYED, this.destroy); + this._connection.off(Connection.Events.STATUS_CHANGED, this._onStatusChanged); + _knownDeviceStores.delete(this._connection); + this._connection = null; + } + }, + + _resetStore: function() { + this.object.description = {}; + this.object.permissions = []; + this.object.tabs = []; + }, + + _onStatusChanged: function() { + if (this._connection.status == Connection.Status.CONNECTED) { + // Watch for changes to remote browser tabs + this._connection.client.addListener("tabListChanged", + this._onTabListChanged); + this._listTabs(); + } else { + if (this._connection.client) { + this._connection.client.removeListener("tabListChanged", + this._onTabListChanged); + } + this._resetStore(); + } + }, + + _onTabListChanged: function() { + this._listTabs(); + }, + + _listTabs: function() { + if (!this._connection) { + return; + } + this._connection.client.listTabs((resp) => { + if (resp.error) { + this._connection.disconnect(); + return; + } + this._deviceFront = getDeviceFront(this._connection.client, resp); + // Save remote browser's tabs + this.object.tabs = resp.tabs; + this._feedStore(); + }); + }, + + _feedStore: function() { + this._getDeviceDescription(); + this._getDevicePermissionsTable(); + }, + + _getDeviceDescription: function() { + return this._deviceFront.getDescription() + .then(json => { + json.dpi = Math.ceil(json.dpi); + this.object.description = json; + }); + }, + + _getDevicePermissionsTable: function() { + return this._deviceFront.getRawPermissionsTable() + .then(json => { + let permissionsTable = json.rawPermissionsTable; + let permissionsArray = []; + for (let name in permissionsTable) { + permissionsArray.push({ + name: name, + app: permissionsTable[name].app, + privileged: permissionsTable[name].privileged, + certified: permissionsTable[name].certified, + }); + } + this.object.permissions = permissionsArray; + }); + } +};