Skip to content

Commit 60d3c91

Browse files
committed
Android 7.0 and later doesn't do the line transform anymore. Auto detect that where required. Fixed ##59. Fixes #68. Closes #60.
1 parent fd1c994 commit 60d3c91

File tree

9 files changed

+78
-15
lines changed

9 files changed

+78
-15
lines changed

src/adb/command/host-transport/getproperties.coffee

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Command = require '../../command'
22
Protocol = require '../../protocol'
3-
LineTransform = require '../../linetransform'
43

54
class GetPropertiesCommand extends Command
65
RE_KEYVAL = /^\[([\s\S]*?)\]: \[([\s\S]*?)\]\r?$/gm

src/adb/command/host-transport/logcat.coffee

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ class LogcatCommand extends Command
99
# all events on all devices.
1010
cmd = 'logcat -B *:I 2>/dev/null'
1111
cmd = "logcat -c 2>/dev/null && #{cmd}" if options.clear
12-
this._send "shell:#{cmd}"
12+
this._send "shell:echo && #{cmd}"
1313
@parser.readAscii 4
1414
.then (reply) =>
1515
switch reply
1616
when Protocol.OKAY
17-
@parser.raw().pipe new LineTransform
17+
@parser.raw().pipe new LineTransform autoDetect: true
1818
when Protocol.FAIL
1919
@parser.readError()
2020
else

src/adb/command/host-transport/screencap.coffee

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ LineTransform = require '../../linetransform'
77

88
class ScreencapCommand extends Command
99
execute: ->
10-
this._send 'shell:screencap -p 2>/dev/null'
10+
this._send 'shell:echo && screencap -p 2>/dev/null'
1111
@parser.readAscii 4
1212
.then (reply) =>
1313
switch reply
1414
when Protocol.OKAY
1515
transform = new LineTransform
1616
@parser.readBytes 1
1717
.then (chunk) =>
18-
transform = new LineTransform
18+
transform = new LineTransform autoDetect: true
1919
transform.write chunk
2020
@parser.raw().pipe transform
2121
.catch Parser.PrematureEOFError, ->

src/adb/command/host-transport/tcpip.coffee

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Command = require '../../command'
22
Protocol = require '../../protocol'
3-
LineTransform = require '../../linetransform'
43

54
class TcpIpCommand extends Command
65
RE_OK = /restarting in/

src/adb/command/host-transport/usb.coffee

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Command = require '../../command'
22
Protocol = require '../../protocol'
3-
LineTransform = require '../../linetransform'
43

54
class UsbCommand extends Command
65
RE_OK = /restarting in/

src/adb/linetransform.coffee

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
11
Stream = require 'stream'
22

33
class LineTransform extends Stream.Transform
4-
constructor: (options) ->
4+
constructor: (options = {}) ->
55
@savedR = null
6+
@autoDetect = options.autoDetect or false
7+
@checkedFirstByte = false
8+
@transformNeeded = true
9+
delete options.autoDetect
610
super options
711

12+
_nullTransform: (chunk, encoding, done) ->
13+
this.push chunk
14+
done()
15+
return
16+
817
# Sadly, the ADB shell is not very smart. It automatically converts every
918
# 0x0a ('\n') it can find to 0x0d 0x0a ('\r\n'). This also applies to binary
1019
# content. We could get rid of this behavior by setting `stty raw`, but
1120
# unfortunately it's not available by default (you'd have to install busybox)
1221
# or something similar. On the up side, it really does do this for all line
1322
# feeds, so a simple transform works fine.
1423
_transform: (chunk, encoding, done) ->
24+
unless @checkedFirstByte
25+
@transformNeeded = false if chunk[0] is 0x0a
26+
@checkedFirstByte = true
27+
return this._nullTransform(chunk, encoding, done) unless @transformNeeded
1528
lo = 0
1629
hi = 0
1730
if @savedR

test/adb/command/host-transport/logcat.coffee

+20-5
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,27 @@ LogcatCommand = require '../../../../src/adb/command/host-transport/logcat'
1212

1313
describe 'LogcatCommand', ->
1414

15-
it "should send 'logcat -B *:I'", (done) ->
15+
it "should send 'echo && logcat -B *:I'", (done) ->
1616
conn = new MockConnection
1717
cmd = new LogcatCommand conn
1818
conn.socket.on 'write', (chunk) ->
1919
expect(chunk.toString()).to.equal \
20-
Protocol.encodeData('shell:logcat -B *:I 2>/dev/null').toString()
20+
Protocol.encodeData('shell:echo &&
21+
logcat -B *:I 2>/dev/null').toString()
2122
setImmediate ->
2223
conn.socket.causeRead Protocol.OKAY
2324
conn.socket.causeEnd()
2425
cmd.execute()
2526
.then (stream) ->
2627
done()
2728

28-
it "should send 'logcat -c && logcat -B *:I' if options.clear
29+
it "should send 'echo && logcat -c && logcat -B *:I' if options.clear
2930
is set", (done) ->
3031
conn = new MockConnection
3132
cmd = new LogcatCommand conn
3233
conn.socket.on 'write', (chunk) ->
3334
expect(chunk.toString()).to.equal \
34-
Protocol.encodeData('shell:logcat -c 2>/dev/null &&
35+
Protocol.encodeData('shell:echo && logcat -c 2>/dev/null &&
3536
logcat -B *:I 2>/dev/null').toString()
3637
setImmediate ->
3738
conn.socket.causeRead Protocol.OKAY
@@ -51,7 +52,7 @@ describe 'LogcatCommand', ->
5152
expect(stream).to.be.an.instanceof Stream.Readable
5253
done()
5354

54-
it "should perform CRLF transformation", (done) ->
55+
it "should perform CRLF transformation by default", (done) ->
5556
conn = new MockConnection
5657
cmd = new LogcatCommand conn
5758
setImmediate ->
@@ -64,3 +65,17 @@ describe 'LogcatCommand', ->
6465
.then (out) ->
6566
expect(out.toString()).to.equal 'foo\n'
6667
done()
68+
69+
it "should not perform CRLF transformation if not needed", (done) ->
70+
conn = new MockConnection
71+
cmd = new LogcatCommand conn
72+
setImmediate ->
73+
conn.socket.causeRead Protocol.OKAY
74+
conn.socket.causeRead '\nfoo\r\n'
75+
conn.socket.causeEnd()
76+
cmd.execute()
77+
.then (stream) ->
78+
new Parser(stream).readAll()
79+
.then (out) ->
80+
expect(out.toString()).to.equal '\nfoo\r\n'
81+
done()

test/adb/command/host-transport/screencap.coffee

+16-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe 'ScreencapCommand', ->
1616
cmd = new ScreencapCommand conn
1717
conn.socket.on 'write', (chunk) ->
1818
expect(chunk.toString()).to.equal \
19-
Protocol.encodeData('shell:screencap -p 2>/dev/null').toString()
19+
Protocol.encodeData('shell:echo && screencap -p 2>/dev/null').toString()
2020
setImmediate ->
2121
conn.socket.causeRead Protocol.OKAY
2222
conn.socket.causeRead 'legit image'
@@ -49,7 +49,7 @@ describe 'ScreencapCommand', ->
4949
.catch (err) ->
5050
done()
5151

52-
it "should perform CRLF transformation", (done) ->
52+
it "should perform CRLF transformation by default", (done) ->
5353
conn = new MockConnection
5454
cmd = new ScreencapCommand conn
5555
setImmediate ->
@@ -62,3 +62,17 @@ describe 'ScreencapCommand', ->
6262
.then (out) ->
6363
expect(out.toString()).to.equal 'foo\n'
6464
done()
65+
66+
it "should not perform CRLF transformation if not needed", (done) ->
67+
conn = new MockConnection
68+
cmd = new ScreencapCommand conn
69+
setImmediate ->
70+
conn.socket.causeRead Protocol.OKAY
71+
conn.socket.causeRead '\nfoo\r\n'
72+
conn.socket.causeEnd()
73+
cmd.execute()
74+
.then (stream) ->
75+
new Parser(stream).readAll()
76+
.then (out) ->
77+
expect(out.toString()).to.equal '\nfoo\r\n'
78+
done()

test/adb/linetransform.coffee

+24
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,30 @@ describe 'LineTransform', ->
1313
expect(new LineTransform).to.be.an.instanceOf Stream.Transform
1414
done()
1515

16+
describe 'with autoDetect', ->
17+
it "should not modify data if first byte is 0x0a", (done) ->
18+
duplex = new MockDuplex
19+
transform = new LineTransform
20+
transform.on 'data', (data) ->
21+
expect(data.toString()).to.equal '\nbar\r\n'
22+
done()
23+
duplex.pipe transform
24+
duplex.causeRead '\nbar\r\n'
25+
duplex.causeEnd()
26+
27+
it "should transform as usual if first byte is not 0x0a", (done) ->
28+
duplex = new MockDuplex
29+
transform = new LineTransform
30+
buffer = new Buffer ''
31+
transform.on 'data', (data) ->
32+
buffer = Buffer.concat [buffer, data]
33+
transform.on 'end', ->
34+
expect(buffer.toString()).to.equal '\nbar\nfoo'
35+
done()
36+
duplex.pipe transform
37+
duplex.causeRead '\r\nbar\r\nfoo'
38+
duplex.causeEnd()
39+
1640
it "should not modify data that does not have 0x0d 0x0a in it", (done) ->
1741
duplex = new MockDuplex
1842
transform = new LineTransform

0 commit comments

Comments
 (0)