Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
a8014967
Unverified
Commit
a8014967
authored
May 14, 2020
by
Jonah Williams
Committed by
GitHub
May 14, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] allow adb to fail to unforward without crashing (#57173)
parent
bb49a9b0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
222 additions
and
106 deletions
+222
-106
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+60
-25
android_device_port_forwarder_test.dart
...ral.shard/android/android_device_port_forwarder_test.dart
+162
-0
android_device_test.dart
...tools/test/general.shard/android/android_device_test.dart
+0
-81
No files found.
packages/flutter_tools/lib/src/android/android_device.dart
View file @
a8014967
...
...
@@ -214,7 +214,7 @@ class AndroidDevice extends Device {
AdbLogReader
_logReader
;
AdbLogReader
_pastLogReader
;
_
AndroidDevicePortForwarder
_portForwarder
;
AndroidDevicePortForwarder
_portForwarder
;
List
<
String
>
adbCommandForDevice
(
List
<
String
>
args
)
{
return
<
String
>[
getAdbPath
(
globals
.
androidSdk
),
'-s'
,
id
,
...
args
];
...
...
@@ -697,7 +697,12 @@ class AndroidDevice extends Device {
}
@override
DevicePortForwarder
get
portForwarder
=>
_portForwarder
??=
_AndroidDevicePortForwarder
(
this
);
DevicePortForwarder
get
portForwarder
=>
_portForwarder
??=
AndroidDevicePortForwarder
(
processManager:
globals
.
processManager
,
logger:
globals
.
logger
,
deviceId:
id
,
adbPath:
globals
.
androidSdk
.
adbPath
,
);
static
final
RegExp
_timeRegExp
=
RegExp
(
r'^\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}'
,
multiLine:
true
);
...
...
@@ -1088,10 +1093,22 @@ class AdbLogReader extends DeviceLogReader {
}
}
class
_AndroidDevicePortForwarder
extends
DevicePortForwarder
{
_AndroidDevicePortForwarder
(
this
.
device
);
final
AndroidDevice
device
;
/// A [DevicePortForwarder] implemented for Android devices that uses adb.
class
AndroidDevicePortForwarder
extends
DevicePortForwarder
{
AndroidDevicePortForwarder
({
@required
ProcessManager
processManager
,
@required
Logger
logger
,
@required
String
deviceId
,
@required
String
adbPath
,
})
:
_deviceId
=
deviceId
,
_adbPath
=
adbPath
,
_logger
=
logger
,
_processUtils
=
ProcessUtils
(
logger:
logger
,
processManager:
processManager
);
final
String
_deviceId
;
final
String
_adbPath
;
final
Logger
_logger
;
final
ProcessUtils
_processUtils
;
static
int
_extractPort
(
String
portString
)
{
return
int
.
tryParse
(
portString
.
trim
());
...
...
@@ -1103,18 +1120,24 @@ class _AndroidDevicePortForwarder extends DevicePortForwarder {
String
stdout
;
try
{
stdout
=
processUtils
.
runSync
(
device
.
adbCommandForDevice
(<
String
>[
'forward'
,
'--list'
]),
stdout
=
_processUtils
.
runSync
(
<
String
>[
_adbPath
,
'-s'
,
_deviceId
,
'forward'
,
'--list'
,
],
throwOnError:
true
,
).
stdout
.
trim
();
}
on
ProcessException
catch
(
error
)
{
globals
.
printError
(
'Failed to list forwarded ports:
$error
.'
);
_logger
.
printError
(
'Failed to list forwarded ports:
$error
.'
);
return
ports
;
}
final
List
<
String
>
lines
=
LineSplitter
.
split
(
stdout
).
toList
();
for
(
final
String
line
in
lines
)
{
if
(!
line
.
startsWith
(
device
.
i
d
))
{
if
(!
line
.
startsWith
(
_deviceI
d
))
{
continue
;
}
final
List
<
String
>
splitLine
=
line
.
split
(
'tcp:'
);
...
...
@@ -1142,13 +1165,15 @@ class _AndroidDevicePortForwarder extends DevicePortForwarder {
@override
Future
<
int
>
forward
(
int
devicePort
,
{
int
hostPort
})
async
{
hostPort
??=
0
;
final
List
<
String
>
forwardCommand
=
<
String
>[
'forward'
,
'tcp:
$hostPort
'
,
'tcp:
$devicePort
'
,
];
final
RunResult
process
=
await
processUtils
.
run
(
device
.
adbCommandForDevice
(
forwardCommand
),
final
RunResult
process
=
await
_processUtils
.
run
(
<
String
>[
_adbPath
,
'-s'
,
_deviceId
,
'forward'
,
'tcp:
$hostPort
'
,
'tcp:
$devicePort
'
,
],
throwOnError:
true
,
);
...
...
@@ -1195,15 +1220,25 @@ class _AndroidDevicePortForwarder extends DevicePortForwarder {
@override
Future
<
void
>
unforward
(
ForwardedPort
forwardedPort
)
async
{
final
List
<
String
>
unforwardCommand
=
<
String
>[
'forward'
,
'--remove'
,
'tcp:
${forwardedPort.hostPort}
'
,
];
await
processUtils
.
run
(
device
.
adbCommandForDevice
(
unforwardCommand
),
throwOnError:
true
,
final
String
tcpLine
=
'tcp:
${forwardedPort.hostPort}
'
;
final
RunResult
runResult
=
await
_processUtils
.
run
(
<
String
>[
_adbPath
,
'-s'
,
_deviceId
,
'forward'
,
'--remove'
,
tcpLine
,
],
throwOnError:
false
,
);
// The port may have already been unforwarded, for example if there
// are multiple attach process already connected.
if
(
runResult
.
exitCode
==
0
||
runResult
.
stderr
.
contains
(
"listener '
$tcpLine
' not found"
))
{
return
;
}
runResult
.
throwException
(
'Process exited abnormally:
\n
$runResult
'
);
}
@override
...
...
packages/flutter_tools/test/general.shard/android/android_device_port_forwarder_test.dart
0 → 100644
View file @
a8014967
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter_tools/src/android/android_device.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
void
main
(
)
{
testWithoutContext
(
'AndroidDevicePortForwarder returns the generated host '
'port from stdout'
,
()
async
{
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'tcp:0'
,
'tcp:123'
],
stdout:
'456'
,
)
]),
logger:
BufferLogger
.
test
(),
);
expect
(
await
forwarder
.
forward
(
123
),
456
);
});
testWithoutContext
(
'AndroidDevicePortForwarder returns the supplied host '
'port when stdout is empty'
,
()
async
{
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'tcp:456'
,
'tcp:123'
],
stdout:
''
,
)
]),
logger:
BufferLogger
.
test
(),
);
expect
(
await
forwarder
.
forward
(
123
,
hostPort:
456
),
456
);
});
testWithoutContext
(
'AndroidDevicePortForwarder returns the supplied host port '
'when stdout is the host port'
,
()
async
{
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'tcp:456'
,
'tcp:123'
],
stdout:
'456'
,
)
]),
logger:
BufferLogger
.
test
(),
);
expect
(
await
forwarder
.
forward
(
123
,
hostPort:
456
),
456
);
});
testWithoutContext
(
'AndroidDevicePortForwarder throws an exception when stdout '
'is not blank nor the host port'
,
()
async
{
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'tcp:456'
,
'tcp:123'
],
stdout:
'123456'
,
)
]),
logger:
BufferLogger
.
test
(),
);
expect
(
forwarder
.
forward
(
123
,
hostPort:
456
),
throwsA
(
isA
<
ProcessException
>()));
});
testWithoutContext
(
'AndroidDevicePortForwarder forwardedPorts returns empty '
'list when forward failed'
,
()
{
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'--list'
],
exitCode:
1
,
)
]),
logger:
BufferLogger
.
test
(),
);
expect
(
forwarder
.
forwardedPorts
,
isEmpty
);
});
testWithoutContext
(
'disposing device disposes the portForwarder'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'tcp:0'
,
'tcp:123'
],
stdout:
'456'
,
),
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'--list'
],
stdout:
'1234 tcp:456 tcp:123'
,
),
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'--remove'
,
'tcp:456'
],
)
]);
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
processManager
,
logger:
BufferLogger
.
test
(),
);
expect
(
await
forwarder
.
forward
(
123
),
equals
(
456
));
await
forwarder
.
dispose
();
expect
(
processManager
.
hasRemainingExpectations
,
false
);
});
testWithoutContext
(
'failures to unforward port do not throw if the forward is missing'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'--remove'
,
'tcp:456'
],
stderr:
"error: listener 'tcp:456' not found"
,
exitCode:
1
,
)
]);
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
processManager
,
logger:
BufferLogger
.
test
(),
);
await
forwarder
.
unforward
(
ForwardedPort
(
456
,
23
));
});
testWithoutContext
(
'failures to unforward port throw exception if stderr is not recognized'
,
()
async
{
final
FakeProcessManager
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[
const
FakeCommand
(
command:
<
String
>[
'adb'
,
'-s'
,
'1'
,
'forward'
,
'--remove'
,
'tcp:456'
],
stderr:
'error: everything is broken!'
,
exitCode:
1
,
)
]);
final
AndroidDevicePortForwarder
forwarder
=
AndroidDevicePortForwarder
(
adbPath:
'adb'
,
deviceId:
'1'
,
processManager:
processManager
,
logger:
BufferLogger
.
test
(),
);
expect
(()
=>
forwarder
.
unforward
(
ForwardedPort
(
456
,
23
)),
throwsA
(
isA
<
ProcessException
>()));
});
}
packages/flutter_tools/test/general.shard/android/android_device_test.dart
View file @
a8014967
...
...
@@ -387,87 +387,6 @@ flutter:
});
});
group
(
'portForwarder'
,
()
{
final
ProcessManager
mockProcessManager
=
MockProcessManager
();
final
AndroidDevice
device
=
AndroidDevice
(
'1234'
);
final
DevicePortForwarder
forwarder
=
device
.
portForwarder
;
testUsingContext
(
'returns the generated host port from stdout'
,
()
async
{
when
(
mockProcessManager
.
run
(
argThat
(
contains
(
'forward'
))))
.
thenAnswer
((
_
)
async
=>
ProcessResult
(
0
,
0
,
'456'
,
''
));
expect
(
await
forwarder
.
forward
(
123
),
equals
(
456
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
testUsingContext
(
'returns the supplied host port when stdout is empty'
,
()
async
{
when
(
mockProcessManager
.
run
(
argThat
(
contains
(
'forward'
))))
.
thenAnswer
((
_
)
async
=>
ProcessResult
(
0
,
0
,
''
,
''
));
expect
(
await
forwarder
.
forward
(
123
,
hostPort:
456
),
equals
(
456
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
testUsingContext
(
'returns the supplied host port when stdout is the host port'
,
()
async
{
when
(
mockProcessManager
.
run
(
argThat
(
contains
(
'forward'
))))
.
thenAnswer
((
_
)
async
=>
ProcessResult
(
0
,
0
,
'456'
,
''
));
expect
(
await
forwarder
.
forward
(
123
,
hostPort:
456
),
equals
(
456
));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
testUsingContext
(
'throws an error when stdout is not blank nor the host port'
,
()
async
{
when
(
mockProcessManager
.
run
(
argThat
(
contains
(
'forward'
))))
.
thenAnswer
((
_
)
async
=>
ProcessResult
(
0
,
0
,
'123456'
,
''
));
expect
(
forwarder
.
forward
(
123
,
hostPort:
456
),
throwsA
(
isA
<
ProcessException
>()));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
testUsingContext
(
'forwardedPorts returns empty list when forward failed'
,
()
{
when
(
mockProcessManager
.
runSync
(
argThat
(
contains
(
'forward'
))))
.
thenReturn
(
ProcessResult
(
0
,
1
,
''
,
''
));
expect
(
forwarder
.
forwardedPorts
,
equals
(
const
<
ForwardedPort
>[]));
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
testUsingContext
(
'disposing device disposes the portForwarder'
,
()
async
{
bool
unforwardCalled
=
false
;
when
(
mockProcessManager
.
run
(
argThat
(
containsAll
(<
String
>[
'forward'
,
'tcp:0'
,
'tcp:123'
,
])))).
thenAnswer
((
_
)
async
{
return
ProcessResult
(
0
,
0
,
'456'
,
''
);
});
when
(
mockProcessManager
.
runSync
(
argThat
(
containsAll
(<
String
>[
'forward'
,
'--list'
,
])))).
thenReturn
(
ProcessResult
(
0
,
0
,
'1234 tcp:456 tcp:123'
,
''
));
when
(
mockProcessManager
.
run
(
argThat
(
containsAll
(<
String
>[
'forward'
,
'--remove'
,
'tcp:456'
,
])))).
thenAnswer
((
_
)
async
{
unforwardCalled
=
true
;
return
ProcessResult
(
0
,
0
,
''
,
''
);
});
expect
(
await
forwarder
.
forward
(
123
),
equals
(
456
));
await
device
.
dispose
();
expect
(
unforwardCalled
,
isTrue
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
mockProcessManager
,
});
});
group
(
'logcat'
,
()
{
final
ProcessManager
mockProcessManager
=
MockProcessManager
();
final
AndroidDevice
device
=
AndroidDevice
(
'1234'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment