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: const ObservableObject = require("devtools/shared/observable-object"); michael@0: const {getDeviceFront} = require("devtools/server/actors/device"); michael@0: const {Connection} = require("devtools/client/connection-manager"); michael@0: michael@0: const {Cu} = require("chrome"); michael@0: michael@0: const _knownDeviceStores = new WeakMap(); michael@0: michael@0: let DeviceStore; michael@0: michael@0: module.exports = DeviceStore = function(connection) { michael@0: // If we already know about this connection, michael@0: // let's re-use the existing store. michael@0: if (_knownDeviceStores.has(connection)) { michael@0: return _knownDeviceStores.get(connection); michael@0: } michael@0: michael@0: _knownDeviceStores.set(connection, this); michael@0: michael@0: ObservableObject.call(this, {}); michael@0: michael@0: this._resetStore(); michael@0: michael@0: this.destroy = this.destroy.bind(this); michael@0: this._onStatusChanged = this._onStatusChanged.bind(this); michael@0: michael@0: this._connection = connection; michael@0: this._connection.once(Connection.Events.DESTROYED, this.destroy); michael@0: this._connection.on(Connection.Events.STATUS_CHANGED, this._onStatusChanged); michael@0: this._onTabListChanged = this._onTabListChanged.bind(this); michael@0: this._onStatusChanged(); michael@0: return this; michael@0: }; michael@0: michael@0: DeviceStore.prototype = { michael@0: destroy: function() { michael@0: if (this._connection) { michael@0: // While this.destroy is bound using .once() above, that event may not michael@0: // have occurred when the DeviceStore client calls destroy, so we michael@0: // manually remove it here. michael@0: this._connection.off(Connection.Events.DESTROYED, this.destroy); michael@0: this._connection.off(Connection.Events.STATUS_CHANGED, this._onStatusChanged); michael@0: _knownDeviceStores.delete(this._connection); michael@0: this._connection = null; michael@0: } michael@0: }, michael@0: michael@0: _resetStore: function() { michael@0: this.object.description = {}; michael@0: this.object.permissions = []; michael@0: this.object.tabs = []; michael@0: }, michael@0: michael@0: _onStatusChanged: function() { michael@0: if (this._connection.status == Connection.Status.CONNECTED) { michael@0: // Watch for changes to remote browser tabs michael@0: this._connection.client.addListener("tabListChanged", michael@0: this._onTabListChanged); michael@0: this._listTabs(); michael@0: } else { michael@0: if (this._connection.client) { michael@0: this._connection.client.removeListener("tabListChanged", michael@0: this._onTabListChanged); michael@0: } michael@0: this._resetStore(); michael@0: } michael@0: }, michael@0: michael@0: _onTabListChanged: function() { michael@0: this._listTabs(); michael@0: }, michael@0: michael@0: _listTabs: function() { michael@0: if (!this._connection) { michael@0: return; michael@0: } michael@0: this._connection.client.listTabs((resp) => { michael@0: if (resp.error) { michael@0: this._connection.disconnect(); michael@0: return; michael@0: } michael@0: this._deviceFront = getDeviceFront(this._connection.client, resp); michael@0: // Save remote browser's tabs michael@0: this.object.tabs = resp.tabs; michael@0: this._feedStore(); michael@0: }); michael@0: }, michael@0: michael@0: _feedStore: function() { michael@0: this._getDeviceDescription(); michael@0: this._getDevicePermissionsTable(); michael@0: }, michael@0: michael@0: _getDeviceDescription: function() { michael@0: return this._deviceFront.getDescription() michael@0: .then(json => { michael@0: json.dpi = Math.ceil(json.dpi); michael@0: this.object.description = json; michael@0: }); michael@0: }, michael@0: michael@0: _getDevicePermissionsTable: function() { michael@0: return this._deviceFront.getRawPermissionsTable() michael@0: .then(json => { michael@0: let permissionsTable = json.rawPermissionsTable; michael@0: let permissionsArray = []; michael@0: for (let name in permissionsTable) { michael@0: permissionsArray.push({ michael@0: name: name, michael@0: app: permissionsTable[name].app, michael@0: privileged: permissionsTable[name].privileged, michael@0: certified: permissionsTable[name].certified, michael@0: }); michael@0: } michael@0: this.object.permissions = permissionsArray; michael@0: }); michael@0: } michael@0: };