From a47de40088671d89869465a86cf7918b4fe090d7 Mon Sep 17 00:00:00 2001 From: adelphes Date: Wed, 1 Feb 2017 12:22:25 +0000 Subject: [PATCH] More configuration settings Added autoStartADB and logcatPort launch config settings Moved AndroidContentProvider into it's own file. --- extension.js | 19 ++++------ package.json | 10 ++++++ src/contentprovider.js | 78 ++++++++++++++++++++++++++++++++++++++++++ src/debugMain.js | 4 +-- src/logcat.js | 75 +++++++--------------------------------- 5 files changed, 110 insertions(+), 76 deletions(-) create mode 100644 src/contentprovider.js diff --git a/extension.js b/extension.js index 6e9cc79..35e563e 100644 --- a/extension.js +++ b/extension.js @@ -1,20 +1,15 @@ // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below const vscode = require('vscode'); -const { AndroidContentProvider, openLogcatWindow } = require('./src/logcat'); +const { AndroidContentProvider } = require('./src/contentprovider'); +const { openLogcatWindow } = require('./src/logcat'); function getADBPort() { - var adbPort = 5037; - // there's surely got to be a better way than this... - var configs = vscode.workspace.getConfiguration('launch.configurations'); - for (var i=0,config; config=configs.get(''+i); i++) { - if (config.type!=='android') continue; - if (config.request!=='launch') continue; - if (typeof config.adbPort === 'number' && config.adbPort === (config.adbPort|0)) - adbPort = config.adbPort; - break; - } - return adbPort; + var defaultPort = 5037; + var adbPort = AndroidContentProvider.getLaunchConfigSetting('adbPort', defaultPort); + if (typeof adbPort === 'number' && adbPort === (adbPort|0)) + return adbPort; + return defaultPort; } // this method is called when your extension is activated diff --git a/package.json b/package.json index f2cd58f..57c1a5d 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,16 @@ "description": "Port number to connect to the local ADB (Android Debug Bridge) instance. Default: 5037", "default": 5037 }, + "autoStartADB": { + "type": "boolean", + "description": "Automatically launch 'adb start-server' if not already started. Default: true", + "default": true + }, + "logcatPort": { + "type": "integer", + "description": "Port number to use for the internal logcat websocket link. Changes to this value only apply when the extension is restarted. Default: 7038", + "default": 7038 + }, "staleBuild": { "type": "string", "description": "Launch behaviour if source files have been saved after the APK was built. One of: [\"ignore\" \"warn\" \"stop\"]. Default: \"warn\"", diff --git a/src/contentprovider.js b/src/contentprovider.js new file mode 100644 index 0000000..8dc9de0 --- /dev/null +++ b/src/contentprovider.js @@ -0,0 +1,78 @@ +'use strict' +// vscode stuff +const { workspace, EventEmitter, Uri } = require('vscode'); + +class AndroidContentProvider /*extends TextDocumentContentProvider*/ { + + constructor() { + this._docs = {}; // hashmap + this._onDidChange = new EventEmitter(); + } + + dispose() { + this._onDidChange.dispose(); + } + + /** + * An event to signal a resource has changed. + */ + get onDidChange() { + return this._onDidChange.event; + } + + /** + * Provide textual content for a given uri. + * + * The editor will use the returned string-content to create a readonly + * [document](TextDocument). Resources allocated should be released when + * the corresponding document has been [closed](#workspace.onDidCloseTextDocument). + * + * @param uri An uri which scheme matches the scheme this provider was [registered](#workspace.registerTextDocumentContentProvider) for. + * @param token A cancellation token. + * @return A string or a thenable that resolves to such. + */ + provideTextDocumentContent(uri/*: Uri*/, token/*: CancellationToken*/)/*: string | Thenable;*/ { + var doc = this._docs[uri]; + if (doc) return this._docs[uri].content; + switch (uri.authority) { + // android-dev-ext://logcat/read? + case 'logcat': return this.provideLogcatDocumentContent(uri); + } + throw new Error('Document Uri not recognised'); + } + + provideLogcatDocumentContent(uri) { + // LogcatContent depends upon AndroidContentProvider, so we must delay-load this + const { LogcatContent } = require('./logcat'); + var doc = this._docs[uri] = new LogcatContent(this, uri); + return doc.content; + } +} + +// the statics +AndroidContentProvider.SCHEME = 'android-dev-ext'; +AndroidContentProvider.register = (ctx, workspace) => { + var provider = new AndroidContentProvider(); + var registration = workspace.registerTextDocumentContentProvider(AndroidContentProvider.SCHEME, provider); + ctx.subscriptions.push(registration); + ctx.subscriptions.push(provider); +} +AndroidContentProvider.getReadLogcatUri = (deviceId) => { + var uri = Uri.parse(`${AndroidContentProvider.SCHEME}://logcat/logcat-${deviceId}.txt`); + return uri.with({ + query: deviceId + }); +} +AndroidContentProvider.getLaunchConfigSetting = (name, defvalue) => { + // there's surely got to be a better way than this... + var configs = workspace.getConfiguration('launch.configurations'); + for (var i=0,config; config=configs.get(''+i); i++) { + if (config.type!=='android') continue; + if (config.request!=='launch') continue; + if (config[name]) return config[name]; + break; + } + return defvalue; +} + +exports.AndroidContentProvider = AndroidContentProvider; diff --git a/src/debugMain.js b/src/debugMain.js index 2dbc794..ba64a3d 100644 --- a/src/debugMain.js +++ b/src/debugMain.js @@ -312,7 +312,7 @@ class AndroidDebugSession extends DebugSession { .then(err => { // if adb is not running, see if we can start it ourselves using ANDROID_HOME (and a sensible port number) var adbport = ws_proxy.adbport; - if (err && process.env.ANDROID_HOME && typeof adbport === 'number' && adbport > 0 && adbport < 65536) { + if (err && args.autoStartADB!==false && process.env.ANDROID_HOME && typeof adbport === 'number' && adbport > 0 && adbport < 65536) { var adbpath = path.join(process.env.ANDROID_HOME, 'platform-tools', /^win/.test(process.platform)?'adb.exe':'adb'); var adbargs = ['-P',''+adbport,'start-server']; try { @@ -396,7 +396,7 @@ class AndroidDebugSession extends DebugSession { this.LOG('Launch failed: '+(e.message||e.msg||'No additional information is available')); // more info for adb connect errors if (/^ADB server is not running/.test(e.msg)) { - this.LOG('Make sure the Android SDK tools are installed and run:'); + this.LOG('Make sure the Android SDK Platform Tools are installed and run:'); this.LOG(' adb start-server'); this.LOG('If you are running ADB on a non-default port, also make sure the adbPort value in your launch.json is correct.'); } diff --git a/src/logcat.js b/src/logcat.js index cfb1009..a0fa9a9 100644 --- a/src/logcat.js +++ b/src/logcat.js @@ -8,6 +8,7 @@ const path = require('path'); const WebSocketServer = require('ws').Server; // our stuff const { ADBClient } = require('./adbclient'); +const { AndroidContentProvider } = require('./contentprovider'); const $ = require('./jq-promise'); const { D } = require('./util'); @@ -171,19 +172,29 @@ class LogcatContent { LogcatContent.byLogcatID = {}; LogcatContent.initWebSocketServer = function () { + if (LogcatContent._wssdone) { // already inited return LogcatContent._wssdone; } + + // retrieve the logcat websocket port + var default_wssport = 7038; + var wssport = AndroidContentProvider.getLaunchConfigSetting('logcatPort', default_wssport); + if (typeof wssport !== 'number' || wssport <= 0 || wssport >= 65536 || wssport !== (wssport|0)) + wssport = default_wssport; + LogcatContent._wssdone = $.Deferred(); ({ wss: null, - port: 31100, + startport: wssport, + port: wssport, retries: 0, tryCreateWSS() { this.wss = new WebSocketServer({ host: '127.0.0.1', port: this.port }, () => { // success - save the info and resolve the deferred LogcatContent._wssport = this.port; + LogcatContent._wssstartport = this.startport; LogcatContent._wss = this.wss; this.wss.on('connection', client => { // the client uses the url path to signify which logcat data it wants @@ -216,66 +227,6 @@ LogcatContent.initWebSocketServer = function () { return LogcatContent._wssdone; } -class AndroidContentProvider /*extends TextDocumentContentProvider*/ { - - constructor() { - this._logs = {}; // hashmap - this._onDidChange = new EventEmitter(); - } - - dispose() { - this._onDidChange.dispose(); - } - - /** - * An event to signal a resource has changed. - */ - get onDidChange() { - return this._onDidChange.event; - } - - /** - * Provide textual content for a given uri. - * - * The editor will use the returned string-content to create a readonly - * [document](TextDocument). Resources allocated should be released when - * the corresponding document has been [closed](#workspace.onDidCloseTextDocument). - * - * @param uri An uri which scheme matches the scheme this provider was [registered](#workspace.registerTextDocumentContentProvider) for. - * @param token A cancellation token. - * @return A string or a thenable that resolves to such. - */ - provideTextDocumentContent(uri/*: Uri*/, token/*: CancellationToken*/)/*: string | Thenable;*/ { - var doc = this._logs[uri]; - if (doc) return this._logs[uri].content; - switch (uri.authority) { - // android-dev-ext://logcat/read? - case 'logcat': return this.provideLogcatDocumentContent(uri); - } - throw new Error('Document Uri not recognised'); - } - - provideLogcatDocumentContent(uri) { - var doc = this._logs[uri] = new LogcatContent(this, uri); - return doc.content; - } -} - -// the statics -AndroidContentProvider.SCHEME = 'android-dev-ext'; -AndroidContentProvider.register = (ctx, workspace) => { - var provider = new AndroidContentProvider(); - var registration = workspace.registerTextDocumentContentProvider(AndroidContentProvider.SCHEME, provider); - ctx.subscriptions.push(registration); - ctx.subscriptions.push(provider); -} -AndroidContentProvider.getReadLogcatUri = (deviceId) => { - var uri = Uri.parse(`${AndroidContentProvider.SCHEME}://logcat/logcat-${deviceId}.txt`); - return uri.with({ - query: deviceId - }); -} - function openLogcatWindow(vscode) { new ADBClient().list_devices().then(devices => { switch(devices.length) { @@ -314,5 +265,5 @@ function openLogcatWindow(vscode) { }); } -exports.AndroidContentProvider = AndroidContentProvider; +exports.LogcatContent = LogcatContent; exports.openLogcatWindow = openLogcatWindow;