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
adf45d1e
Unverified
Commit
adf45d1e
authored
Jul 09, 2019
by
Jonah Williams
Committed by
GitHub
Jul 09, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor signal and command line handler from resident runner (#35406)
parent
a429991a
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
700 additions
and
336 deletions
+700
-336
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+1
-1
attach.dart
packages/flutter_tools/lib/src/commands/attach.dart
+12
-4
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+2
-2
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+11
-3
device.dart
packages/flutter_tools/lib/src/device.dart
+1
-1
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+220
-191
resident_web_runner.dart
packages/flutter_tools/lib/src/resident_web_runner.dart
+2
-3
run_cold.dart
packages/flutter_tools/lib/src/run_cold.dart
+4
-13
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+3
-33
attach_test.dart
packages/flutter_tools/test/commands/attach_test.dart
+16
-12
resident_runner_test.dart
packages/flutter_tools/test/resident_runner_test.dart
+96
-73
terminal_handler_test.dart
packages/flutter_tools/test/terminal_handler_test.dart
+332
-0
No files found.
packages/flutter_tools/lib/src/android/android_device.dart
View file @
adf45d1e
...
...
@@ -437,8 +437,8 @@ class AndroidDevice extends Device {
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
,
bool
prebuiltApplication
=
false
,
bool
usesTerminalUi
=
true
,
bool
ipv6
=
false
,
bool
usesTerminalUi
=
true
,
})
async
{
if
(!
await
_checkForSupportedAdbVersion
()
||
!
await
_checkForSupportedAndroidVersion
())
return
LaunchResult
.
failed
();
...
...
packages/flutter_tools/lib/src/commands/attach.dart
View file @
adf45d1e
...
...
@@ -277,7 +277,7 @@ class AttachCommand extends FlutterCommand {
target:
targetFile
,
debuggingOptions:
debuggingOptions
,
packagesFilePath:
globalResults
[
'packages'
],
usesTerminalU
I
:
daemon
==
null
,
usesTerminalU
i
:
daemon
==
null
,
projectRootPath:
argResults
[
'project-root'
],
dillOutputPath:
argResults
[
'output-dill'
],
ipv6:
usesIpv6
,
...
...
@@ -312,7 +312,15 @@ class AttachCommand extends FlutterCommand {
result
=
await
app
.
runner
.
waitForAppToFinish
();
assert
(
result
!=
null
);
}
else
{
result
=
await
runner
.
attach
();
final
Completer
<
void
>
onAppStart
=
Completer
<
void
>.
sync
();
unawaited
(
onAppStart
.
future
.
whenComplete
(()
{
TerminalHandler
(
runner
)
..
setupTerminal
()
..
registerSignalHandlers
();
}));
result
=
await
runner
.
attach
(
appStartedCompleter:
onAppStart
,
);
assert
(
result
!=
null
);
}
if
(
result
!=
0
)
{
...
...
@@ -350,7 +358,7 @@ class HotRunnerFactory {
List
<
FlutterDevice
>
devices
,
{
String
target
,
DebuggingOptions
debuggingOptions
,
bool
usesTerminalU
I
=
true
,
bool
usesTerminalU
i
=
true
,
bool
benchmarkMode
=
false
,
File
applicationBinary
,
bool
hostIsIde
=
false
,
...
...
@@ -364,7 +372,7 @@ class HotRunnerFactory {
devices
,
target:
target
,
debuggingOptions:
debuggingOptions
,
usesTerminalU
I:
usesTerminalUI
,
usesTerminalU
i:
usesTerminalUi
,
benchmarkMode:
benchmarkMode
,
applicationBinary:
applicationBinary
,
hostIsIde:
hostIsIde
,
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
adf45d1e
...
...
@@ -419,7 +419,7 @@ class AppDomain extends Domain {
<
FlutterDevice
>[
flutterDevice
],
target:
target
,
debuggingOptions:
options
,
usesTerminalU
I
:
false
,
usesTerminalU
i
:
false
,
applicationBinary:
applicationBinary
,
projectRootPath:
projectRootPath
,
packagesFilePath:
packagesFilePath
,
...
...
@@ -432,8 +432,8 @@ class AppDomain extends Domain {
<
FlutterDevice
>[
flutterDevice
],
target:
target
,
debuggingOptions:
options
,
usesTerminalUI:
false
,
applicationBinary:
applicationBinary
,
usesTerminalUi:
false
,
ipv6:
ipv6
,
);
}
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
adf45d1e
...
...
@@ -450,8 +450,8 @@ class RunCommand extends RunCommandBase {
applicationBinary:
applicationBinaryPath
==
null
?
null
:
fs
.
file
(
applicationBinaryPath
),
stayResident:
stayResident
,
ipv6:
ipv6
,
stayResident:
stayResident
,
);
}
...
...
@@ -463,7 +463,14 @@ class RunCommand extends RunCommandBase {
final
Completer
<
void
>
appStartedTimeRecorder
=
Completer
<
void
>.
sync
();
// This callback can't throw.
unawaited
(
appStartedTimeRecorder
.
future
.
then
<
void
>(
(
_
)
{
appStartedTime
=
systemClock
.
now
();
}
(
_
)
{
appStartedTime
=
systemClock
.
now
();
if
(
stayResident
)
{
TerminalHandler
(
runner
)
..
setupTerminal
()
..
registerSignalHandlers
();
}
}
));
final
int
result
=
await
runner
.
run
(
...
...
@@ -471,8 +478,9 @@ class RunCommand extends RunCommandBase {
route:
route
,
shouldBuild:
!
runningWithPrebuiltApplication
&&
argResults
[
'build'
],
);
if
(
result
!=
0
)
if
(
result
!=
0
)
{
throwToolExit
(
null
,
exitCode:
result
);
}
return
FlutterCommandResult
(
ExitStatus
.
success
,
timingLabelParts:
<
String
>[
...
...
packages/flutter_tools/lib/src/device.dart
View file @
adf45d1e
...
...
@@ -406,8 +406,8 @@ abstract class Device {
DebuggingOptions
debuggingOptions
,
Map
<
String
,
dynamic
>
platformArgs
,
bool
prebuiltApplication
=
false
,
bool
usesTerminalUi
=
true
,
bool
ipv6
=
false
,
bool
usesTerminalUi
=
true
,
});
/// Whether this device implements support for hot reload.
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
adf45d1e
...
...
@@ -115,7 +115,7 @@ class FlutterDevice {
/// expressions requested during debugging of the application.
/// This ensures that the reload process follows the normal orchestration of
/// the Flutter Tools and not just the VM internal service.
Future
<
void
>
_
connect
({
Future
<
void
>
connect
({
ReloadSources
reloadSources
,
Restart
restart
,
CompileExpression
compileExpression
,
...
...
@@ -375,7 +375,7 @@ class FlutterDevice {
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
usesTerminalUi:
hotRunner
.
usesTerminalU
I
,
usesTerminalUi:
hotRunner
.
usesTerminalU
i
,
ipv6:
hotRunner
.
ipv6
,
);
...
...
@@ -437,7 +437,7 @@ class FlutterDevice {
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
usesTerminalUi:
coldRunner
.
usesTerminalU
I
,
usesTerminalUi:
coldRunner
.
usesTerminalU
i
,
ipv6:
coldRunner
.
ipv6
,
);
...
...
@@ -509,11 +509,12 @@ abstract class ResidentRunner {
this
.
flutterDevices
,
{
this
.
target
,
this
.
debuggingOptions
,
this
.
usesTerminalUI
=
true
,
String
projectRootPath
,
String
packagesFilePath
,
this
.
stayResident
,
this
.
ipv6
,
this
.
usesTerminalUi
=
true
,
this
.
stayResident
=
true
,
this
.
hotMode
=
true
,
})
{
_mainPath
=
findMainDartFile
(
target
);
_projectRootPath
=
projectRootPath
??
fs
.
currentDirectory
.
path
;
...
...
@@ -525,11 +526,12 @@ abstract class ResidentRunner {
final
List
<
FlutterDevice
>
flutterDevices
;
final
String
target
;
final
DebuggingOptions
debuggingOptions
;
final
bool
usesTerminalU
I
;
final
bool
usesTerminalU
i
;
final
bool
stayResident
;
final
bool
ipv6
;
final
Completer
<
int
>
_finished
=
Completer
<
int
>();
bool
_exited
=
false
;
bool
hotMode
;
String
_packagesFilePath
;
String
get
packagesFilePath
=>
_packagesFilePath
;
String
_projectRootPath
;
...
...
@@ -601,68 +603,68 @@ abstract class ResidentRunner {
await
Future
.
wait
(
futures
);
}
Future
<
void
>
_
debugDumpApp
()
async
{
Future
<
void
>
debugDumpApp
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpApp
();
}
Future
<
void
>
_
debugDumpRenderTree
()
async
{
Future
<
void
>
debugDumpRenderTree
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpRenderTree
();
}
Future
<
void
>
_
debugDumpLayerTree
()
async
{
Future
<
void
>
debugDumpLayerTree
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpLayerTree
();
}
Future
<
void
>
_
debugDumpSemanticsTreeInTraversalOrder
()
async
{
Future
<
void
>
debugDumpSemanticsTreeInTraversalOrder
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpSemanticsTreeInTraversalOrder
();
}
Future
<
void
>
_
debugDumpSemanticsTreeInInverseHitTestOrder
()
async
{
Future
<
void
>
debugDumpSemanticsTreeInInverseHitTestOrder
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpSemanticsTreeInInverseHitTestOrder
();
}
Future
<
void
>
_
debugToggleDebugPaintSizeEnabled
()
async
{
Future
<
void
>
debugToggleDebugPaintSizeEnabled
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
toggleDebugPaintSizeEnabled
();
}
Future
<
void
>
_
debugToggleDebugCheckElevationsEnabled
()
async
{
Future
<
void
>
debugToggleDebugCheckElevationsEnabled
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
toggleDebugCheckElevationsEnabled
();
}
Future
<
void
>
_
debugTogglePerformanceOverlayOverride
()
async
{
Future
<
void
>
debugTogglePerformanceOverlayOverride
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugTogglePerformanceOverlayOverride
();
}
Future
<
void
>
_
debugToggleWidgetInspector
()
async
{
Future
<
void
>
debugToggleWidgetInspector
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
toggleWidgetInspector
();
}
Future
<
void
>
_
debugToggleProfileWidgetBuilds
()
async
{
Future
<
void
>
debugToggleProfileWidgetBuilds
()
async
{
await
refreshViews
();
for
(
FlutterDevice
device
in
flutterDevices
)
{
await
device
.
toggleProfileWidgetBuilds
();
}
}
Future
<
void
>
_
screenshot
(
FlutterDevice
device
)
async
{
Future
<
void
>
screenshot
(
FlutterDevice
device
)
async
{
final
Status
status
=
logger
.
startProgress
(
'Taking screenshot for
${device.device.name}
...'
,
timeout:
timeoutConfiguration
.
fastOperation
);
final
File
outputFile
=
getUniqueFile
(
fs
.
currentDirectory
,
'flutter'
,
'png'
);
try
{
...
...
@@ -700,7 +702,7 @@ abstract class ResidentRunner {
}
}
Future
<
void
>
_
debugTogglePlatform
()
async
{
Future
<
void
>
debugTogglePlatform
()
async
{
await
refreshViews
();
final
String
from
=
await
flutterDevices
[
0
].
views
[
0
].
uiIsolate
.
flutterPlatformOverride
();
String
to
;
...
...
@@ -709,39 +711,6 @@ abstract class ResidentRunner {
printStatus
(
'Switched operating system to
$to
'
);
}
void
registerSignalHandlers
()
{
assert
(
stayResident
);
io
.
ProcessSignal
.
SIGINT
.
watch
().
listen
(
_cleanUpAndExit
);
io
.
ProcessSignal
.
SIGTERM
.
watch
().
listen
(
_cleanUpAndExit
);
if
(!
supportsServiceProtocol
||
!
supportsRestart
)
return
;
io
.
ProcessSignal
.
SIGUSR1
.
watch
().
listen
(
_handleSignal
);
io
.
ProcessSignal
.
SIGUSR2
.
watch
().
listen
(
_handleSignal
);
}
Future
<
void
>
_cleanUpAndExit
(
io
.
ProcessSignal
signal
)
async
{
_resetTerminal
();
await
cleanupAfterSignal
();
io
.
exit
(
0
);
}
bool
_processingUserRequest
=
false
;
Future
<
void
>
_handleSignal
(
io
.
ProcessSignal
signal
)
async
{
if
(
_processingUserRequest
)
{
printTrace
(
'Ignoring signal: "
$signal
" because we are busy.'
);
return
;
}
_processingUserRequest
=
true
;
final
bool
fullRestart
=
signal
==
io
.
ProcessSignal
.
SIGUSR2
;
try
{
await
restart
(
fullRestart:
fullRestart
);
}
finally
{
_processingUserRequest
=
false
;
}
}
Future
<
void
>
stopEchoingDeviceLog
()
async
{
await
Future
.
wait
<
void
>(
flutterDevices
.
map
<
Future
<
void
>>((
FlutterDevice
device
)
=>
device
.
stopEchoingDeviceLog
())
...
...
@@ -764,7 +733,7 @@ abstract class ResidentRunner {
bool
viewFound
=
false
;
for
(
FlutterDevice
device
in
flutterDevices
)
{
await
device
.
_
connect
(
await
device
.
connect
(
reloadSources:
reloadSources
,
restart:
restart
,
compileExpression:
compileExpression
,
...
...
@@ -805,125 +774,6 @@ abstract class ResidentRunner {
return
Future
<
void
>.
error
(
error
,
stack
);
}
/// Returns [true] if the input has been handled by this function.
Future
<
bool
>
_commonTerminalInputHandler
(
String
character
)
async
{
printStatus
(
''
);
// the key the user tapped might be on this line
switch
(
character
)
{
case
'a'
:
if
(
supportsServiceProtocol
)
{
await
_debugToggleProfileWidgetBuilds
();
return
true
;
}
return
false
;
case
'd'
:
case
'D'
:
await
detach
();
return
true
;
case
'h'
:
case
'H'
:
case
'?'
:
// help
printHelp
(
details:
true
);
return
true
;
case
'i'
:
case
'I'
:
if
(
supportsServiceProtocol
)
{
await
_debugToggleWidgetInspector
();
return
true
;
}
return
false
;
case
'L'
:
if
(
supportsServiceProtocol
)
{
await
_debugDumpLayerTree
();
return
true
;
}
return
false
;
case
'o'
:
case
'O'
:
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
await
_debugTogglePlatform
();
return
true
;
}
return
false
;
case
'p'
:
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
await
_debugToggleDebugPaintSizeEnabled
();
return
true
;
}
return
false
;
case
'P'
:
if
(
supportsServiceProtocol
)
{
await
_debugTogglePerformanceOverlayOverride
();
return
true
;
}
return
false
;
case
'q'
:
case
'Q'
:
// exit
await
exit
();
return
true
;
case
's'
:
for
(
FlutterDevice
device
in
flutterDevices
)
{
if
(
device
.
device
.
supportsScreenshot
)
await
_screenshot
(
device
);
}
return
true
;
case
'S'
:
if
(
supportsServiceProtocol
)
{
await
_debugDumpSemanticsTreeInTraversalOrder
();
return
true
;
}
return
false
;
case
't'
:
case
'T'
:
if
(
supportsServiceProtocol
)
{
await
_debugDumpRenderTree
();
return
true
;
}
return
false
;
case
'U'
:
if
(
supportsServiceProtocol
)
{
await
_debugDumpSemanticsTreeInInverseHitTestOrder
();
return
true
;
}
return
false
;
case
'w'
:
case
'W'
:
if
(
supportsServiceProtocol
)
{
await
_debugDumpApp
();
return
true
;
}
return
false
;
case
'z'
:
case
'Z'
:
await
_debugToggleDebugCheckElevationsEnabled
();
return
true
;
}
return
false
;
}
Future
<
void
>
processTerminalInput
(
String
command
)
async
{
// When terminal doesn't support line mode, '\n' can sneak into the input.
command
=
command
.
trim
();
if
(
_processingUserRequest
)
{
printTrace
(
'Ignoring terminal input: "
$command
" because we are busy.'
);
return
;
}
_processingUserRequest
=
true
;
try
{
final
bool
handled
=
await
_commonTerminalInputHandler
(
command
);
if
(!
handled
)
await
handleTerminalCommand
(
command
);
}
catch
(
error
,
st
)
{
printError
(
'
$error
\n
$st
'
);
await
_cleanUpAndExit
(
null
);
}
finally
{
_processingUserRequest
=
false
;
}
}
void
_serviceDisconnected
()
{
if
(
_exited
)
{
// User requested the application exit.
...
...
@@ -932,7 +782,6 @@ abstract class ResidentRunner {
if
(
_finished
.
isCompleted
)
return
;
printStatus
(
'Lost connection to device.'
);
_resetTerminal
();
_finished
.
complete
(
0
);
}
...
...
@@ -940,27 +789,9 @@ abstract class ResidentRunner {
if
(
_finished
.
isCompleted
)
return
;
printStatus
(
'Application finished.'
);
_resetTerminal
();
_finished
.
complete
(
0
);
}
void
_resetTerminal
()
{
if
(
usesTerminalUI
)
terminal
.
singleCharMode
=
false
;
}
void
setupTerminal
()
{
assert
(
stayResident
);
if
(
usesTerminalUI
)
{
if
(!
logger
.
quiet
)
{
printStatus
(
''
);
printHelp
(
details:
false
);
}
terminal
.
singleCharMode
=
true
;
terminal
.
keystrokes
.
listen
(
processTerminalInput
);
}
}
Future
<
int
>
waitForAppToFinish
()
async
{
final
int
exitCode
=
await
_finished
.
future
;
assert
(
exitCode
!=
null
);
...
...
@@ -1004,10 +835,38 @@ abstract class ResidentRunner {
/// Called when a signal has requested we exit.
Future
<
void
>
cleanupAfterSignal
();
/// Called right before we exit.
Future
<
void
>
cleanupAtFinish
();
/// Called when the runner should handle a terminal command.
Future
<
void
>
handleTerminalCommand
(
String
code
);
Future
<
void
>
handleTerminalCommand
(
String
code
)
async
{
switch
(
code
)
{
case
'r'
:
final
OperationResult
result
=
await
restart
(
fullRestart:
false
);
if
(!
result
.
isOk
)
{
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
return
;
case
'R'
:
// If hot restart is not supported for all devices, ignore the command.
if
(!
canHotRestart
)
{
return
;
}
final
OperationResult
result
=
await
restart
(
fullRestart:
true
);
if
(!
result
.
isOk
)
{
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
return
;
case
'l'
:
case
'L'
:
final
List
<
FlutterView
>
views
=
flutterDevices
.
expand
((
FlutterDevice
d
)
=>
d
.
views
).
toList
();
printStatus
(
'Connected
${pluralize('view', views.length)}
:'
);
for
(
FlutterView
v
in
views
)
{
printStatus
(
'
${v.uiIsolate.name}
(
${v.uiIsolate.id}
)'
,
indent:
2
);
}
}
}
}
class
OperationResult
{
...
...
@@ -1051,6 +910,176 @@ Future<String> getMissingPackageHintForPlatform(TargetPlatform platform) async {
}
}
/// Redirects terminal commands to the correct resident runner methods.
class
TerminalHandler
{
TerminalHandler
(
this
.
residentRunner
);
final
ResidentRunner
residentRunner
;
bool
_processingUserRequest
=
false
;
StreamSubscription
<
void
>
subscription
;
void
setupTerminal
()
{
if
(!
logger
.
quiet
)
{
printStatus
(
''
);
residentRunner
.
printHelp
(
details:
false
);
}
terminal
.
singleCharMode
=
true
;
subscription
=
terminal
.
keystrokes
.
listen
(
processTerminalInput
);
}
void
registerSignalHandlers
()
{
assert
(
residentRunner
.
stayResident
);
io
.
ProcessSignal
.
SIGINT
.
watch
().
listen
(
_cleanUpAndExit
);
io
.
ProcessSignal
.
SIGTERM
.
watch
().
listen
(
_cleanUpAndExit
);
if
(!
residentRunner
.
supportsServiceProtocol
||
!
residentRunner
.
supportsRestart
)
return
;
io
.
ProcessSignal
.
SIGUSR1
.
watch
().
listen
(
_handleSignal
);
io
.
ProcessSignal
.
SIGUSR2
.
watch
().
listen
(
_handleSignal
);
}
/// Returns [true] if the input has been handled by this function.
Future
<
bool
>
_commonTerminalInputHandler
(
String
character
)
async
{
printStatus
(
''
);
// the key the user tapped might be on this line
switch
(
character
)
{
case
'a'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugToggleProfileWidgetBuilds
();
return
true
;
}
return
false
;
case
'd'
:
case
'D'
:
await
residentRunner
.
detach
();
return
true
;
case
'h'
:
case
'H'
:
case
'?'
:
// help
residentRunner
.
printHelp
(
details:
true
);
return
true
;
case
'i'
:
case
'I'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugToggleWidgetInspector
();
return
true
;
}
return
false
;
case
'L'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugDumpLayerTree
();
return
true
;
}
return
false
;
case
'o'
:
case
'O'
:
if
(
residentRunner
.
supportsServiceProtocol
&&
residentRunner
.
isRunningDebug
)
{
await
residentRunner
.
debugTogglePlatform
();
return
true
;
}
return
false
;
case
'p'
:
if
(
residentRunner
.
supportsServiceProtocol
&&
residentRunner
.
isRunningDebug
)
{
await
residentRunner
.
debugToggleDebugPaintSizeEnabled
();
return
true
;
}
return
false
;
case
'P'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugTogglePerformanceOverlayOverride
();
return
true
;
}
return
false
;
case
'q'
:
case
'Q'
:
// exit
await
residentRunner
.
exit
();
return
true
;
case
's'
:
for
(
FlutterDevice
device
in
residentRunner
.
flutterDevices
)
{
if
(
device
.
device
.
supportsScreenshot
)
await
residentRunner
.
screenshot
(
device
);
}
return
true
;
case
'S'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugDumpSemanticsTreeInTraversalOrder
();
return
true
;
}
return
false
;
case
't'
:
case
'T'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugDumpRenderTree
();
return
true
;
}
return
false
;
case
'U'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugDumpSemanticsTreeInInverseHitTestOrder
();
return
true
;
}
return
false
;
case
'w'
:
case
'W'
:
if
(
residentRunner
.
supportsServiceProtocol
)
{
await
residentRunner
.
debugDumpApp
();
return
true
;
}
return
false
;
case
'z'
:
case
'Z'
:
await
residentRunner
.
debugToggleDebugCheckElevationsEnabled
();
return
true
;
}
return
false
;
}
Future
<
void
>
processTerminalInput
(
String
command
)
async
{
// When terminal doesn't support line mode, '\n' can sneak into the input.
command
=
command
.
trim
();
if
(
_processingUserRequest
)
{
printTrace
(
'Ignoring terminal input: "
$command
" because we are busy.'
);
return
;
}
_processingUserRequest
=
true
;
try
{
final
bool
handled
=
await
_commonTerminalInputHandler
(
command
);
if
(!
handled
)
await
residentRunner
.
handleTerminalCommand
(
command
);
}
catch
(
error
,
st
)
{
printError
(
'
$error
\n
$st
'
);
await
_cleanUpAndExit
(
null
);
}
finally
{
_processingUserRequest
=
false
;
}
}
Future
<
void
>
_handleSignal
(
io
.
ProcessSignal
signal
)
async
{
if
(
_processingUserRequest
)
{
printTrace
(
'Ignoring signal: "
$signal
" because we are busy.'
);
return
;
}
_processingUserRequest
=
true
;
final
bool
fullRestart
=
signal
==
io
.
ProcessSignal
.
SIGUSR2
;
try
{
await
residentRunner
.
restart
(
fullRestart:
fullRestart
);
}
finally
{
_processingUserRequest
=
false
;
}
}
Future
<
void
>
_cleanUpAndExit
(
io
.
ProcessSignal
signal
)
async
{
terminal
.
singleCharMode
=
false
;
await
subscription
.
cancel
();
await
residentRunner
.
cleanupAfterSignal
();
io
.
exit
(
0
);
}
}
class
DebugConnectionInfo
{
DebugConnectionInfo
({
this
.
httpUri
,
this
.
wsUri
,
this
.
baseUri
});
...
...
packages/flutter_tools/lib/src/resident_web_runner.dart
View file @
adf45d1e
...
...
@@ -37,10 +37,10 @@ class ResidentWebRunner extends ResidentRunner {
})
:
super
(
flutterDevices
,
target:
target
,
usesTerminalUI:
true
,
stayResident:
true
,
debuggingOptions:
debuggingOptions
,
ipv6:
ipv6
,
usesTerminalUi:
true
,
stayResident:
true
,
);
WebAssetServer
_server
;
...
...
@@ -54,7 +54,6 @@ class ResidentWebRunner extends ResidentRunner {
{
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
void
>
appStartedCompleter
})
async
{
connectionInfoCompleter
?.
complete
(
DebugConnectionInfo
());
setupTerminal
();
final
int
result
=
await
waitForAppToFinish
();
await
cleanupAtFinish
();
return
result
;
...
...
packages/flutter_tools/lib/src/run_cold.dart
View file @
adf45d1e
...
...
@@ -19,16 +19,17 @@ class ColdRunner extends ResidentRunner {
List
<
FlutterDevice
>
devices
,
{
String
target
,
DebuggingOptions
debuggingOptions
,
bool
usesTerminalUI
=
true
,
this
.
traceStartup
=
false
,
this
.
awaitFirstFrameWhenTracing
=
true
,
this
.
applicationBinary
,
bool
stayResident
=
true
,
bool
ipv6
=
false
,
bool
usesTerminalUi
=
false
,
bool
stayResident
=
true
,
})
:
super
(
devices
,
target:
target
,
debuggingOptions:
debuggingOptions
,
usesTerminalUI:
usesTerminalUI
,
hotMode:
false
,
usesTerminalUi:
usesTerminalUi
,
stayResident:
stayResident
,
ipv6:
ipv6
);
...
...
@@ -104,9 +105,6 @@ class ColdRunner extends ResidentRunner {
);
}
appFinished
();
}
else
if
(
stayResident
)
{
setupTerminal
();
registerSignalHandlers
();
}
appStartedCompleter
?.
complete
();
...
...
@@ -138,10 +136,6 @@ class ColdRunner extends ResidentRunner {
printTrace
(
'Connected to
$view
.'
);
}
}
if
(
stayResident
)
{
setupTerminal
();
registerSignalHandlers
();
}
appStartedCompleter
?.
complete
();
if
(
stayResident
)
{
return
waitForAppToFinish
();
...
...
@@ -150,9 +144,6 @@ class ColdRunner extends ResidentRunner {
return
0
;
}
@override
Future
<
void
>
handleTerminalCommand
(
String
code
)
async
{
}
@override
Future
<
void
>
cleanupAfterSignal
()
async
{
await
stopEchoingDeviceLog
();
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
adf45d1e
...
...
@@ -57,7 +57,7 @@ class HotRunner extends ResidentRunner {
List
<
FlutterDevice
>
devices
,
{
String
target
,
DebuggingOptions
debuggingOptions
,
bool
usesTerminalU
I
=
true
,
bool
usesTerminalU
i
=
true
,
this
.
benchmarkMode
=
false
,
this
.
applicationBinary
,
this
.
hostIsIde
=
false
,
...
...
@@ -69,10 +69,11 @@ class HotRunner extends ResidentRunner {
})
:
super
(
devices
,
target:
target
,
debuggingOptions:
debuggingOptions
,
usesTerminalU
I:
usesTerminalUI
,
usesTerminalU
i:
usesTerminalUi
,
projectRootPath:
projectRootPath
,
packagesFilePath:
packagesFilePath
,
stayResident:
stayResident
,
hotMode:
true
,
ipv6:
ipv6
);
final
bool
benchmarkMode
;
...
...
@@ -194,11 +195,6 @@ class HotRunner extends ResidentRunner {
printTrace
(
'Connected to
$view
.'
);
}
if
(
stayResident
)
{
setupTerminal
();
registerSignalHandlers
();
}
appStartedCompleter
?.
complete
();
if
(
benchmarkMode
)
{
...
...
@@ -264,32 +260,6 @@ class HotRunner extends ResidentRunner {
);
}
@override
Future
<
void
>
handleTerminalCommand
(
String
code
)
async
{
final
String
lower
=
code
.
toLowerCase
();
if
(
lower
==
'r'
)
{
OperationResult
result
;
if
(
code
==
'R'
)
{
// If hot restart is not supported for all devices, ignore the command.
if
(!
canHotRestart
)
{
return
;
}
result
=
await
restart
(
fullRestart:
true
);
}
else
{
result
=
await
restart
(
fullRestart:
false
);
}
if
(!
result
.
isOk
)
{
printStatus
(
'Try again after fixing the above error(s).'
,
emphasis:
true
);
}
}
else
if
(
lower
==
'l'
)
{
final
List
<
FlutterView
>
views
=
flutterDevices
.
expand
((
FlutterDevice
d
)
=>
d
.
views
).
toList
();
printStatus
(
'Connected
${pluralize('view', views.length)}
:'
);
for
(
FlutterView
v
in
views
)
{
printStatus
(
'
${v.uiIsolate.name}
(
${v.uiIsolate.id}
)'
,
indent:
2
);
}
}
}
Future
<
List
<
Uri
>>
_initDevFS
()
async
{
final
String
fsName
=
fs
.
path
.
basename
(
projectRootPath
);
final
List
<
Uri
>
devFSUris
=
<
Uri
>[];
...
...
packages/flutter_tools/test/commands/attach_test.dart
View file @
adf45d1e
...
...
@@ -24,15 +24,18 @@ import '../src/context.dart';
import
'../src/mocks.dart'
;
void
main
(
)
{
final
StreamLogger
logger
=
StreamLogger
();
group
(
'attach'
,
()
{
final
FileSystem
testFileSystem
=
MemoryFileSystem
(
style:
platform
.
isWindows
?
FileSystemStyle
.
windows
:
FileSystemStyle
.
posix
,
);
StreamLogger
logger
;
FileSystem
testFileSystem
;
setUp
(()
{
Cache
.
disableLocking
();
logger
=
StreamLogger
();
testFileSystem
=
MemoryFileSystem
(
style:
platform
.
isWindows
?
FileSystemStyle
.
windows
:
FileSystemStyle
.
posix
,
);
testFileSystem
.
directory
(
'lib'
).
createSync
();
testFileSystem
.
file
(
testFileSystem
.
path
.
join
(
'lib'
,
'main.dart'
)).
createSync
();
});
...
...
@@ -108,7 +111,8 @@ void main() {
const
String
outputDill
=
'/tmp/output.dill'
;
final
MockHotRunner
mockHotRunner
=
MockHotRunner
();
when
(
mockHotRunner
.
attach
()).
thenAnswer
((
_
)
async
=>
0
);
when
(
mockHotRunner
.
attach
(
appStartedCompleter:
anyNamed
(
'appStartedCompleter'
)))
.
thenAnswer
((
_
)
async
=>
0
);
final
MockHotRunnerFactory
mockHotRunnerFactory
=
MockHotRunnerFactory
();
when
(
...
...
@@ -119,7 +123,7 @@ void main() {
dillOutputPath:
anyNamed
(
'dillOutputPath'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalU
I:
anyNamed
(
'usesTerminalUI
'
),
usesTerminalU
i:
anyNamed
(
'usesTerminalUi
'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
),
...
...
@@ -151,7 +155,7 @@ void main() {
dillOutputPath:
outputDill
,
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalU
I:
anyNamed
(
'usesTerminalUI
'
),
usesTerminalU
i:
anyNamed
(
'usesTerminalUi
'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
),
...
...
@@ -219,14 +223,14 @@ void main() {
.
thenReturn
(<
ForwardedPort
>[
ForwardedPort
(
hostPort
,
devicePort
)]);
when
(
portForwarder
.
unforward
(
any
))
.
thenAnswer
((
_
)
async
=>
null
);
when
(
mockHotRunner
.
attach
())
.
thenAnswer
((
_
)
async
=>
0
);
when
(
mockHotRunner
.
attach
(
appStartedCompleter:
anyNamed
(
'appStartedCompleter'
)
))
.
thenAnswer
((
_
)
async
=>
0
);
when
(
mockHotRunnerFactory
.
build
(
any
,
target:
anyNamed
(
'target'
),
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalU
I:
anyNamed
(
'usesTerminalUI
'
),
usesTerminalU
i:
anyNamed
(
'usesTerminalUi
'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
)).
thenReturn
(
mockHotRunner
);
...
...
@@ -256,7 +260,7 @@ void main() {
target:
foo
.
path
,
debuggingOptions:
anyNamed
(
'debuggingOptions'
),
packagesFilePath:
anyNamed
(
'packagesFilePath'
),
usesTerminalU
I:
anyNamed
(
'usesTerminalUI
'
),
usesTerminalU
i:
anyNamed
(
'usesTerminalUi
'
),
flutterProject:
anyNamed
(
'flutterProject'
),
ipv6:
false
,
)).
called
(
1
);
...
...
packages/flutter_tools/test/resident_runner_test.dart
View file @
adf45d1e
...
...
@@ -3,91 +3,114 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:flutter_tools/src/run_hot.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
import
'package:mockito/mockito.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
class
TestRunner
extends
ResidentRunner
{
TestRunner
(
List
<
FlutterDevice
>
devices
)
:
super
(
devices
);
bool
hasHelpBeenPrinted
=
false
;
String
receivedCommand
;
@override
Future
<
void
>
cleanupAfterSignal
()
async
{
}
import
'src/testbed.dart'
;
@override
Future
<
void
>
cleanupAtFinish
()
async
{
}
@override
Future
<
void
>
handleTerminalCommand
(
String
code
)
async
{
receivedCommand
=
code
;
}
void
main
(
)
{
group
(
'ResidentRunner'
,
()
{
final
Uri
testUri
=
Uri
.
parse
(
'foo://bar'
);
Testbed
testbed
;
MockDevice
mockDevice
;
MockVMService
mockVMService
;
MockDevFS
mockDevFS
;
ResidentRunner
residentRunner
;
@override
void
printHelp
({
bool
details
})
{
hasHelpBeenPrinted
=
true
;
}
setUp
(()
{
testbed
=
Testbed
(
setup:
()
{
residentRunner
=
HotRunner
(
<
FlutterDevice
>[
mockDevice
,
],
stayResident:
false
,
debuggingOptions:
DebuggingOptions
.
enabled
(
BuildInfo
.
debug
),
);
});
mockDevice
=
MockDevice
();
mockVMService
=
MockVMService
();
mockDevFS
=
MockDevFS
();
// DevFS Mocks
when
(
mockDevFS
.
lastCompiled
).
thenReturn
(
DateTime
(
2000
));
when
(
mockDevFS
.
sources
).
thenReturn
(<
Uri
>[]);
when
(
mockDevFS
.
destroy
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
// FlutterDevice Mocks.
when
(
mockDevice
.
updateDevFS
(
// Intentionally provide empty list to match above mock.
invalidatedFiles:
<
Uri
>[],
mainPath:
anyNamed
(
'mainPath'
),
target:
anyNamed
(
'target'
),
bundle:
anyNamed
(
'bundle'
),
firstBuildTime:
anyNamed
(
'firstBuildTime'
),
bundleFirstUpload:
anyNamed
(
'bundleFirstUpload'
),
bundleDirty:
anyNamed
(
'bundleDirty'
),
fullRestart:
anyNamed
(
'fullRestart'
),
projectRootPath:
anyNamed
(
'projectRootPath'
),
pathToReload:
anyNamed
(
'pathToReload'
),
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
UpdateFSReport
(
success:
true
,
syncedBytes:
0
,
invalidatedSourcesCount:
0
,
);
});
when
(
mockDevice
.
devFS
).
thenReturn
(
mockDevFS
);
when
(
mockDevice
.
views
).
thenReturn
(<
FlutterView
>[
MockFlutterView
(),
]);
when
(
mockDevice
.
stopEchoingDeviceLog
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockDevice
.
observatoryUris
).
thenReturn
(<
Uri
>[
testUri
,
]);
when
(
mockDevice
.
connect
(
reloadSources:
anyNamed
(
'reloadSources'
),
restart:
anyNamed
(
'restart'
),
compileExpression:
anyNamed
(
'compileExpression'
)
)).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockDevice
.
setupDevFS
(
any
,
any
,
packagesFilePath:
anyNamed
(
'packagesFilePath'
)))
.
thenAnswer
((
Invocation
invocation
)
async
{
return
testUri
;
});
when
(
mockDevice
.
vmServices
).
thenReturn
(<
VMService
>[
mockVMService
,
]);
when
(
mockDevice
.
refreshViews
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
// VMService mocks.
when
(
mockVMService
.
wsAddress
).
thenReturn
(
testUri
);
when
(
mockVMService
.
done
).
thenAnswer
((
Invocation
invocation
)
{
final
Completer
<
void
>
result
=
Completer
<
void
>.
sync
();
return
result
.
future
;
});
});
@override
Future
<
int
>
run
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
void
>
appStartedCompleter
,
String
route
,
bool
shouldBuild
=
true
,
})
async
=>
null
;
test
(
'Can attach to device successfully'
,
()
=>
testbed
.
run
(()
async
{
final
Completer
<
DebugConnectionInfo
>
onConnectionInfo
=
Completer
<
DebugConnectionInfo
>.
sync
();
final
Completer
<
void
>
onAppStart
=
Completer
<
void
>.
sync
();
final
Future
<
int
>
result
=
residentRunner
.
attach
(
appStartedCompleter:
onAppStart
,
connectionInfoCompleter:
onConnectionInfo
,
);
final
Future
<
DebugConnectionInfo
>
connectionInfo
=
onConnectionInfo
.
future
;
@override
Future
<
int
>
attach
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
void
>
appStartedCompleter
,
})
async
=>
null
;
}
expect
(
await
result
,
0
);
void
main
(
)
{
TestRunner
createTestRunner
()
{
// TODO(jacobr): make these tests run with `trackWidgetCreation: true` as
// well as the default flags.
return
TestRunner
(
<
FlutterDevice
>[
FlutterDevice
(
MockDevice
(),
trackWidgetCreation:
false
,
buildMode:
BuildMode
.
debug
)],
);
}
verify
(
mockDevice
.
initLogReader
()).
called
(
1
);
group
(
'keyboard input handling'
,
()
{
testUsingContext
(
'single help character'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
expect
(
testRunner
.
hasHelpBeenPrinted
,
isFalse
);
await
testRunner
.
processTerminalInput
(
'h'
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isTrue
);
});
testUsingContext
(
'help character surrounded with newlines'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
expect
(
testRunner
.
hasHelpBeenPrinted
,
isFalse
);
await
testRunner
.
processTerminalInput
(
'
\n
h
\n
'
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isTrue
);
});
testUsingContext
(
'reload character with trailing newline'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
expect
(
testRunner
.
receivedCommand
,
isNull
);
await
testRunner
.
processTerminalInput
(
'r
\n
'
);
expect
(
testRunner
.
receivedCommand
,
equals
(
'r'
));
});
testUsingContext
(
'newlines'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
expect
(
testRunner
.
receivedCommand
,
isNull
);
await
testRunner
.
processTerminalInput
(
'
\n\n
'
);
expect
(
testRunner
.
receivedCommand
,
equals
(
''
));
});
expect
(
onConnectionInfo
.
isCompleted
,
true
);
expect
((
await
connectionInfo
).
baseUri
,
'foo://bar'
);
expect
(
onAppStart
.
isCompleted
,
true
);
}));
});
}
class
MockDevice
extends
Mock
implements
Device
{
MockDevice
()
{
when
(
isSupported
()).
thenReturn
(
true
);
}
}
class
MockDevice
extends
Mock
implements
FlutterDevice
{}
class
MockFlutterView
extends
Mock
implements
FlutterView
{}
class
MockVMService
extends
Mock
implements
VMService
{}
class
MockDevFS
extends
Mock
implements
DevFS
{}
packages/flutter_tools/test/terminal_handler_test.dart
0 → 100644
View file @
adf45d1e
// Copyright 2017 The Chromium 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
'dart:async'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:mockito/mockito.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
void
main
(
)
{
TestRunner
createTestRunner
()
{
// TODO(jacobr): make these tests run with `trackWidgetCreation: true` as
// well as the default flags.
return
TestRunner
(
<
FlutterDevice
>[
FlutterDevice
(
MockDevice
(),
trackWidgetCreation:
false
,
buildMode:
BuildMode
.
debug
)],
);
}
group
(
'keyboard input handling'
,
()
{
testUsingContext
(
'single help character'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
final
TerminalHandler
terminalHandler
=
TerminalHandler
(
testRunner
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isFalse
);
await
terminalHandler
.
processTerminalInput
(
'h'
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isTrue
);
});
testUsingContext
(
'help character surrounded with newlines'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
final
TerminalHandler
terminalHandler
=
TerminalHandler
(
testRunner
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isFalse
);
await
terminalHandler
.
processTerminalInput
(
'
\n
h
\n
'
);
expect
(
testRunner
.
hasHelpBeenPrinted
,
isTrue
);
});
testUsingContext
(
'reload character with trailing newline'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
final
TerminalHandler
terminalHandler
=
TerminalHandler
(
testRunner
);
expect
(
testRunner
.
receivedCommand
,
isNull
);
await
terminalHandler
.
processTerminalInput
(
'r
\n
'
);
expect
(
testRunner
.
receivedCommand
,
equals
(
'r'
));
});
testUsingContext
(
'newlines'
,
()
async
{
final
TestRunner
testRunner
=
createTestRunner
();
final
TerminalHandler
terminalHandler
=
TerminalHandler
(
testRunner
);
expect
(
testRunner
.
receivedCommand
,
isNull
);
await
terminalHandler
.
processTerminalInput
(
'
\n\n
'
);
expect
(
testRunner
.
receivedCommand
,
equals
(
''
));
});
});
group
(
'keycode verification, brought to you by the letter r'
,
()
{
MockResidentRunner
mockResidentRunner
;
TerminalHandler
terminalHandler
;
setUp
(()
{
mockResidentRunner
=
MockResidentRunner
();
terminalHandler
=
TerminalHandler
(
mockResidentRunner
);
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
handleTerminalCommand
(
any
)).
thenReturn
(
null
);
});
testUsingContext
(
'a - debugToggleProfileWidgetBuilds with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'a'
);
verify
(
mockResidentRunner
.
debugToggleProfileWidgetBuilds
()).
called
(
1
);
});
testUsingContext
(
'a - debugToggleProfileWidgetBuilds without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'a'
);
verifyNever
(
mockResidentRunner
.
debugToggleProfileWidgetBuilds
());
});
testUsingContext
(
'a - debugToggleProfileWidgetBuilds'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'a'
);
verify
(
mockResidentRunner
.
debugToggleProfileWidgetBuilds
()).
called
(
1
);
});
testUsingContext
(
'd,D - detach'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'd'
);
await
terminalHandler
.
processTerminalInput
(
'D'
);
verify
(
mockResidentRunner
.
detach
()).
called
(
2
);
});
testUsingContext
(
'h,H,? - printHelp'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'h'
);
await
terminalHandler
.
processTerminalInput
(
'H'
);
await
terminalHandler
.
processTerminalInput
(
'?'
);
verify
(
mockResidentRunner
.
printHelp
(
details:
true
)).
called
(
3
);
});
testUsingContext
(
'i, I - debugToggleWidgetInspector with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'i'
);
await
terminalHandler
.
processTerminalInput
(
'I'
);
verify
(
mockResidentRunner
.
debugToggleWidgetInspector
()).
called
(
2
);
});
testUsingContext
(
'i, I - debugToggleWidgetInspector without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'i'
);
await
terminalHandler
.
processTerminalInput
(
'I'
);
verifyNever
(
mockResidentRunner
.
debugToggleWidgetInspector
());
});
testUsingContext
(
'L - debugDumpLayerTree with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'L'
);
verify
(
mockResidentRunner
.
debugDumpLayerTree
()).
called
(
1
);
});
testUsingContext
(
'L - debugDumpLayerTree without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'L'
);
verifyNever
(
mockResidentRunner
.
debugDumpLayerTree
());
});
testUsingContext
(
'o,O - debugTogglePlatform with service protocol and debug mode'
,
()
async
{
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'o'
);
await
terminalHandler
.
processTerminalInput
(
'O'
);
verify
(
mockResidentRunner
.
debugTogglePlatform
()).
called
(
2
);
});
testUsingContext
(
'o,O - debugTogglePlatform without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'o'
);
await
terminalHandler
.
processTerminalInput
(
'O'
);
verifyNever
(
mockResidentRunner
.
debugTogglePlatform
());
});
testUsingContext
(
'p - debugToggleDebugPaintSizeEnabled with service protocol and debug mode'
,
()
async
{
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'p'
);
verify
(
mockResidentRunner
.
debugToggleDebugPaintSizeEnabled
()).
called
(
1
);
});
testUsingContext
(
'p - debugTogglePlatform without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'p'
);
verifyNever
(
mockResidentRunner
.
debugToggleDebugPaintSizeEnabled
());
});
testUsingContext
(
'p - debugToggleDebugPaintSizeEnabled with service protocol and debug mode'
,
()
async
{
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'p'
);
verify
(
mockResidentRunner
.
debugToggleDebugPaintSizeEnabled
()).
called
(
1
);
});
testUsingContext
(
'p - debugTogglePlatform without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
'p'
);
verifyNever
(
mockResidentRunner
.
debugToggleDebugPaintSizeEnabled
());
});
testUsingContext
(
'P - debugTogglePerformanceOverlayOverride with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'P'
);
verify
(
mockResidentRunner
.
debugTogglePerformanceOverlayOverride
()).
called
(
1
);
});
testUsingContext
(
'P - debugTogglePerformanceOverlayOverride without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'P'
);
verifyNever
(
mockResidentRunner
.
debugTogglePerformanceOverlayOverride
());
});
testUsingContext
(
'q,Q - exit'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'q'
);
await
terminalHandler
.
processTerminalInput
(
'Q'
);
verify
(
mockResidentRunner
.
exit
()).
called
(
2
);
});
testUsingContext
(
's - screenshot'
,
()
async
{
final
MockDevice
mockDevice
=
MockDevice
();
final
MockFlutterDevice
mockFlutterDevice
=
MockFlutterDevice
();
when
(
mockResidentRunner
.
isRunningDebug
).
thenReturn
(
true
);
when
(
mockResidentRunner
.
flutterDevices
).
thenReturn
(<
FlutterDevice
>[
mockFlutterDevice
]);
when
(
mockFlutterDevice
.
device
).
thenReturn
(
mockDevice
);
when
(
mockDevice
.
supportsScreenshot
).
thenReturn
(
true
);
await
terminalHandler
.
processTerminalInput
(
's'
);
verify
(
mockResidentRunner
.
screenshot
(
mockFlutterDevice
)).
called
(
1
);
});
testUsingContext
(
'S - debugDumpSemanticsTreeInTraversalOrder with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'S'
);
verify
(
mockResidentRunner
.
debugDumpSemanticsTreeInTraversalOrder
()).
called
(
1
);
});
testUsingContext
(
'S - debugDumpSemanticsTreeInTraversalOrder without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'S'
);
verifyNever
(
mockResidentRunner
.
debugDumpSemanticsTreeInTraversalOrder
());
});
testUsingContext
(
't,T - debugDumpRenderTree with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
't'
);
await
terminalHandler
.
processTerminalInput
(
'T'
);
verify
(
mockResidentRunner
.
debugDumpRenderTree
()).
called
(
2
);
});
testUsingContext
(
't,T - debugDumpSemanticsTreeInTraversalOrder without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
't'
);
await
terminalHandler
.
processTerminalInput
(
'T'
);
verifyNever
(
mockResidentRunner
.
debugDumpRenderTree
());
});
testUsingContext
(
'U - debugDumpRenderTree with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'U'
);
verify
(
mockResidentRunner
.
debugDumpSemanticsTreeInInverseHitTestOrder
()).
called
(
1
);
});
testUsingContext
(
'U - debugDumpSemanticsTreeInTraversalOrder without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'U'
);
verifyNever
(
mockResidentRunner
.
debugDumpSemanticsTreeInInverseHitTestOrder
());
});
testUsingContext
(
'w,W - debugDumpApp with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'w'
);
await
terminalHandler
.
processTerminalInput
(
'W'
);
verify
(
mockResidentRunner
.
debugDumpApp
()).
called
(
2
);
});
testUsingContext
(
'w,W - debugDumpApp without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'w'
);
await
terminalHandler
.
processTerminalInput
(
'W'
);
verifyNever
(
mockResidentRunner
.
debugDumpApp
());
});
testUsingContext
(
'z,Z - debugToggleDebugCheckElevationsEnabled with service protocol'
,
()
async
{
await
terminalHandler
.
processTerminalInput
(
'z'
);
await
terminalHandler
.
processTerminalInput
(
'Z'
);
verify
(
mockResidentRunner
.
debugToggleDebugCheckElevationsEnabled
()).
called
(
2
);
});
testUsingContext
(
'z,Z - debugToggleDebugCheckElevationsEnabled without service protocol'
,
()
async
{
when
(
mockResidentRunner
.
supportsServiceProtocol
).
thenReturn
(
false
);
await
terminalHandler
.
processTerminalInput
(
'z'
);
await
terminalHandler
.
processTerminalInput
(
'Z'
);
// This should probably be disable when the service protocol is not enabled.
verify
(
mockResidentRunner
.
debugToggleDebugCheckElevationsEnabled
()).
called
(
2
);
});
});
}
class
MockDevice
extends
Mock
implements
Device
{
MockDevice
()
{
when
(
isSupported
()).
thenReturn
(
true
);
}
}
class
MockResidentRunner
extends
Mock
implements
ResidentRunner
{}
class
MockFlutterDevice
extends
Mock
implements
FlutterDevice
{}
class
TestRunner
extends
ResidentRunner
{
TestRunner
(
List
<
FlutterDevice
>
devices
)
:
super
(
devices
);
bool
hasHelpBeenPrinted
=
false
;
String
receivedCommand
;
@override
Future
<
void
>
cleanupAfterSignal
()
async
{
}
@override
Future
<
void
>
cleanupAtFinish
()
async
{
}
@override
Future
<
void
>
handleTerminalCommand
(
String
code
)
async
{
receivedCommand
=
code
;
}
@override
void
printHelp
({
bool
details
})
{
hasHelpBeenPrinted
=
true
;
}
@override
Future
<
int
>
run
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
void
>
appStartedCompleter
,
String
route
,
bool
shouldBuild
=
true
,
})
async
=>
null
;
@override
Future
<
int
>
attach
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
void
>
appStartedCompleter
,
})
async
=>
null
;
}
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