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
0770c3c1
Commit
0770c3c1
authored
Apr 27, 2017
by
Zachary Anderson
Committed by
GitHub
Apr 27, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] Adds some support for '-d all' (#9585)
parent
9558ac7d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
653 additions
and
347 deletions
+653
-347
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+5
-3
fuchsia_reload.dart
packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
+10
-6
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+30
-15
device.dart
packages/flutter_tools/lib/src/device.dart
+16
-1
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+363
-102
run_cold.dart
packages/flutter_tools/lib/src/run_cold.dart
+45
-73
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+139
-140
flutter_command.dart
packages/flutter_tools/lib/src/runner/flutter_command.dart
+28
-6
context.dart
packages/flutter_tools/test/src/context.dart
+17
-1
No files found.
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
0770c3c1
...
@@ -353,11 +353,13 @@ class AppDomain extends Domain {
...
@@ -353,11 +353,13 @@ class AppDomain extends Domain {
final
Directory
cwd
=
fs
.
currentDirectory
;
final
Directory
cwd
=
fs
.
currentDirectory
;
fs
.
currentDirectory
=
fs
.
directory
(
projectDirectory
);
fs
.
currentDirectory
=
fs
.
directory
(
projectDirectory
);
final
FlutterDevice
flutterDevice
=
new
FlutterDevice
(
device
);
ResidentRunner
runner
;
ResidentRunner
runner
;
if
(
enableHotReload
)
{
if
(
enableHotReload
)
{
runner
=
new
HotRunner
(
runner
=
new
HotRunner
(
device
,
<
FlutterDevice
>[
flutterDevice
]
,
target:
target
,
target:
target
,
debuggingOptions:
options
,
debuggingOptions:
options
,
usesTerminalUI:
false
,
usesTerminalUI:
false
,
...
@@ -368,7 +370,7 @@ class AppDomain extends Domain {
...
@@ -368,7 +370,7 @@ class AppDomain extends Domain {
);
);
}
else
{
}
else
{
runner
=
new
ColdRunner
(
runner
=
new
ColdRunner
(
device
,
<
FlutterDevice
>[
flutterDevice
]
,
target:
target
,
target:
target
,
debuggingOptions:
options
,
debuggingOptions:
options
,
usesTerminalUI:
false
,
usesTerminalUI:
false
,
...
@@ -448,7 +450,7 @@ class AppDomain extends Domain {
...
@@ -448,7 +450,7 @@ class AppDomain extends Domain {
if
(
app
==
null
)
if
(
app
==
null
)
throw
"app '
$appId
' not found"
;
throw
"app '
$appId
' not found"
;
final
Isolate
isolate
=
app
.
runner
.
currentView
.
uiIsolate
;
final
Isolate
isolate
=
app
.
runner
.
flutterDevices
.
first
.
views
.
first
.
uiIsolate
;
final
Map
<
String
,
dynamic
>
result
=
await
isolate
.
invokeFlutterExtensionRpcRaw
(
methodName
,
params:
params
);
final
Map
<
String
,
dynamic
>
result
=
await
isolate
.
invokeFlutterExtensionRpcRaw
(
methodName
,
params:
params
);
if
(
result
==
null
)
if
(
result
==
null
)
return
new
OperationResult
(
1
,
'method not available:
$methodName
'
);
return
new
OperationResult
(
1
,
'method not available:
$methodName
'
);
...
...
packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
View file @
0770c3c1
...
@@ -16,6 +16,7 @@ import '../device.dart';
...
@@ -16,6 +16,7 @@ import '../device.dart';
import
'../flx.dart'
as
flx
;
import
'../flx.dart'
as
flx
;
import
'../fuchsia/fuchsia_device.dart'
;
import
'../fuchsia/fuchsia_device.dart'
;
import
'../globals.dart'
;
import
'../globals.dart'
;
import
'../resident_runner.dart'
;
import
'../run_hot.dart'
;
import
'../run_hot.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../vmservice.dart'
;
import
'../vmservice.dart'
;
...
@@ -112,18 +113,21 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -112,18 +113,21 @@ class FuchsiaReloadCommand extends FlutterCommand {
final
List
<
String
>
fullAddresses
=
targetPorts
.
map
(
final
List
<
String
>
fullAddresses
=
targetPorts
.
map
(
(
int
p
)
=>
'
$_address
:
$p
'
(
int
p
)
=>
'
$_address
:
$p
'
).
toList
();
).
toList
();
final
List
<
Uri
>
observatoryUris
=
fullAddresses
.
map
(
(
String
a
)
=>
Uri
.
parse
(
'http://
$a
'
)
).
toList
();
final
FuchsiaDevice
device
=
new
FuchsiaDevice
(
fullAddresses
[
0
]);
final
FuchsiaDevice
device
=
new
FuchsiaDevice
(
fullAddresses
[
0
]);
final
FlutterDevice
flutterDevice
=
new
FlutterDevice
(
device
);
flutterDevice
.
observatoryUris
=
observatoryUris
;
final
HotRunner
hotRunner
=
new
HotRunner
(
final
HotRunner
hotRunner
=
new
HotRunner
(
device
,
<
FlutterDevice
>[
flutterDevice
]
,
debuggingOptions:
new
DebuggingOptions
.
enabled
(
getBuildMode
()),
debuggingOptions:
new
DebuggingOptions
.
enabled
(
getBuildMode
()),
target:
_target
,
target:
_target
,
projectRootPath:
_fuchsiaProjectPath
,
projectRootPath:
_fuchsiaProjectPath
,
packagesFilePath:
_dotPackagesPath
packagesFilePath:
_dotPackagesPath
);
);
final
List
<
Uri
>
observatoryUris
=
fullAddresses
.
map
((
String
a
)
=>
Uri
.
parse
(
'http://
$a
'
)).
toList
();
printStatus
(
'Connecting to
$_binaryName
'
);
printStatus
(
'Connecting to
$_binaryName
'
);
await
hotRunner
.
attach
(
observatoryUris
,
isolate
Filter:
isolateName
);
await
hotRunner
.
attach
(
view
Filter:
isolateName
);
}
}
// A cache of VMService connections.
// A cache of VMService connections.
...
@@ -151,12 +155,12 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -151,12 +155,12 @@ class FuchsiaReloadCommand extends FlutterCommand {
}
}
// Find ports where there is a view isolate with the given name
// Find ports where there is a view isolate with the given name
Future
<
List
<
int
>>
_filterPorts
(
List
<
int
>
ports
,
String
isolate
Filter
)
async
{
Future
<
List
<
int
>>
_filterPorts
(
List
<
int
>
ports
,
String
view
Filter
)
async
{
final
List
<
int
>
result
=
<
int
>[];
final
List
<
int
>
result
=
<
int
>[];
for
(
FlutterView
v
in
await
_getViews
(
ports
))
{
for
(
FlutterView
v
in
await
_getViews
(
ports
))
{
final
Uri
addr
=
v
.
owner
.
vmService
.
httpAddress
;
final
Uri
addr
=
v
.
owner
.
vmService
.
httpAddress
;
printTrace
(
'At
$addr
, found view:
${v.uiIsolate.name}
'
);
printTrace
(
'At
$addr
, found view:
${v.uiIsolate.name}
'
);
if
(
v
.
uiIsolate
.
name
.
indexOf
(
isolate
Filter
)
==
0
)
if
(
v
.
uiIsolate
.
name
.
indexOf
(
view
Filter
)
==
0
)
result
.
add
(
addr
.
port
);
result
.
add
(
addr
.
port
);
}
}
return
result
;
return
result
;
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
0770c3c1
...
@@ -150,17 +150,20 @@ class RunCommand extends RunCommandBase {
...
@@ -150,17 +150,20 @@ class RunCommand extends RunCommandBase {
};
};
}
}
Device
device
;
List
<
Device
>
devices
;
@override
@override
Future
<
String
>
get
usagePath
async
{
Future
<
String
>
get
usagePath
async
{
final
String
command
=
shouldUseHotMode
()
?
'hotrun'
:
name
;
final
String
command
=
shouldUseHotMode
()
?
'hotrun'
:
name
;
if
(
device
==
null
)
if
(
device
s
==
null
)
return
command
;
return
command
;
// Return 'run/ios'.
// Return 'run/ios'.
return
'
$command
/
${getNameForTargetPlatform(await device.targetPlatform)}
'
;
if
(
devices
.
length
>
1
)
return
'
$command
/all'
;
else
return
'
$command
/
${getNameForTargetPlatform(await devices[0].targetPlatform)}
'
;
}
}
@override
@override
...
@@ -199,9 +202,11 @@ class RunCommand extends RunCommandBase {
...
@@ -199,9 +202,11 @@ class RunCommand extends RunCommandBase {
@override
@override
Future
<
Null
>
verifyThenRunCommand
()
async
{
Future
<
Null
>
verifyThenRunCommand
()
async
{
commandValidator
();
commandValidator
();
device
=
await
findTargetDevice
();
device
s
=
await
findAllTargetDevices
();
if
(
device
==
null
)
if
(
device
s
==
null
)
throwToolExit
(
null
);
throwToolExit
(
null
);
if
(
deviceManager
.
hasSpecifiedAllDevices
&&
runningWithPrebuiltApplication
)
throwToolExit
(
'Using -d all with --use-application-binary is not supported'
);
return
super
.
verifyThenRunCommand
();
return
super
.
verifyThenRunCommand
();
}
}
...
@@ -221,7 +226,6 @@ class RunCommand extends RunCommandBase {
...
@@ -221,7 +226,6 @@ class RunCommand extends RunCommandBase {
@override
@override
Future
<
Null
>
runCommand
()
async
{
Future
<
Null
>
runCommand
()
async
{
Cache
.
releaseLockEarly
();
Cache
.
releaseLockEarly
();
// Enable hot mode by default if `--no-hot` was not passed and we are in
// Enable hot mode by default if `--no-hot` was not passed and we are in
...
@@ -229,17 +233,20 @@ class RunCommand extends RunCommandBase {
...
@@ -229,17 +233,20 @@ class RunCommand extends RunCommandBase {
final
bool
hotMode
=
shouldUseHotMode
();
final
bool
hotMode
=
shouldUseHotMode
();
if
(
argResults
[
'machine'
])
{
if
(
argResults
[
'machine'
])
{
if
(
devices
.
length
>
1
)
throwToolExit
(
'--machine does not support -d all.'
);
final
Daemon
daemon
=
new
Daemon
(
stdinCommandStream
,
stdoutCommandResponse
,
final
Daemon
daemon
=
new
Daemon
(
stdinCommandStream
,
stdoutCommandResponse
,
notifyingLogger:
new
NotifyingLogger
(),
logToStdout:
true
);
notifyingLogger:
new
NotifyingLogger
(),
logToStdout:
true
);
AppInstance
app
;
AppInstance
app
;
try
{
try
{
app
=
await
daemon
.
appDomain
.
startApp
(
app
=
await
daemon
.
appDomain
.
startApp
(
device
,
fs
.
currentDirectory
.
path
,
targetFile
,
route
,
device
s
.
first
,
fs
.
currentDirectory
.
path
,
targetFile
,
route
,
_createDebuggingOptions
(),
hotMode
,
_createDebuggingOptions
(),
hotMode
,
applicationBinary:
argResults
[
'use-application-binary'
],
applicationBinary:
argResults
[
'use-application-binary'
],
projectRootPath:
argResults
[
'project-root'
],
projectRootPath:
argResults
[
'project-root'
],
packagesFilePath:
argResults
[
'packages'
],
packagesFilePath:
argResults
[
'packages'
],
projectAssets:
argResults
[
'project-assets'
]);
projectAssets:
argResults
[
'project-assets'
]
);
}
catch
(
error
)
{
}
catch
(
error
)
{
throwToolExit
(
error
.
toString
());
throwToolExit
(
error
.
toString
());
}
}
...
@@ -249,12 +256,16 @@ class RunCommand extends RunCommandBase {
...
@@ -249,12 +256,16 @@ class RunCommand extends RunCommandBase {
return
null
;
return
null
;
}
}
if
(
await
device
.
isLocalEmulator
&&
!
isEmulatorBuildMode
(
getBuildMode
()))
for
(
Device
device
in
devices
)
{
throwToolExit
(
'
${toTitleCase(getModeName(getBuildMode()))}
mode is not supported for emulators.'
);
if
(
await
device
.
isLocalEmulator
&&
!
isEmulatorBuildMode
(
getBuildMode
()))
throwToolExit
(
'
${toTitleCase(getModeName(getBuildMode()))}
mode is not supported for emulators.'
);
}
if
(
hotMode
)
{
if
(
hotMode
)
{
if
(!
device
.
supportsHotMode
)
for
(
Device
device
in
devices
)
{
throwToolExit
(
'Hot mode is not supported by this device. Run with --no-hot.'
);
if
(!
device
.
supportsHotMode
)
throwToolExit
(
'Hot mode is not supported by
${device.name}
. Run with --no-hot.'
);
}
}
}
final
String
pidFile
=
argResults
[
'pid-file'
];
final
String
pidFile
=
argResults
[
'pid-file'
];
...
@@ -262,11 +273,15 @@ class RunCommand extends RunCommandBase {
...
@@ -262,11 +273,15 @@ class RunCommand extends RunCommandBase {
// Write our pid to the file.
// Write our pid to the file.
fs
.
file
(
pidFile
).
writeAsStringSync
(
pid
.
toString
());
fs
.
file
(
pidFile
).
writeAsStringSync
(
pid
.
toString
());
}
}
ResidentRunner
runner
;
final
List
<
FlutterDevice
>
flutterDevices
=
devices
.
map
((
Device
device
)
{
return
new
FlutterDevice
(
device
);
}).
toList
();
ResidentRunner
runner
;
if
(
hotMode
)
{
if
(
hotMode
)
{
runner
=
new
HotRunner
(
runner
=
new
HotRunner
(
device
,
flutterDevices
,
target:
targetFile
,
target:
targetFile
,
debuggingOptions:
_createDebuggingOptions
(),
debuggingOptions:
_createDebuggingOptions
(),
benchmarkMode:
argResults
[
'benchmark'
],
benchmarkMode:
argResults
[
'benchmark'
],
...
@@ -279,7 +294,7 @@ class RunCommand extends RunCommandBase {
...
@@ -279,7 +294,7 @@ class RunCommand extends RunCommandBase {
);
);
}
else
{
}
else
{
runner
=
new
ColdRunner
(
runner
=
new
ColdRunner
(
device
,
flutterDevices
,
target:
targetFile
,
target:
targetFile
,
debuggingOptions:
_createDebuggingOptions
(),
debuggingOptions:
_createDebuggingOptions
(),
traceStartup:
traceStartup
,
traceStartup:
traceStartup
,
...
...
packages/flutter_tools/lib/src/device.dart
View file @
0770c3c1
...
@@ -32,11 +32,26 @@ class DeviceManager {
...
@@ -32,11 +32,26 @@ class DeviceManager {
final
List
<
DeviceDiscovery
>
_deviceDiscoverers
=
<
DeviceDiscovery
>[];
final
List
<
DeviceDiscovery
>
_deviceDiscoverers
=
<
DeviceDiscovery
>[];
String
_specifiedDeviceId
;
/// A user-specified device ID.
/// A user-specified device ID.
String
specifiedDeviceId
;
String
get
specifiedDeviceId
{
if
(
_specifiedDeviceId
==
null
||
_specifiedDeviceId
==
'all'
)
return
null
;
return
_specifiedDeviceId
;
}
set
specifiedDeviceId
(
String
id
)
{
_specifiedDeviceId
=
id
;
}
/// True when the user has specified a single specific device.
bool
get
hasSpecifiedDeviceId
=>
specifiedDeviceId
!=
null
;
bool
get
hasSpecifiedDeviceId
=>
specifiedDeviceId
!=
null
;
/// True when the user has specified all devices by setting
/// specifiedDeviceId = 'all'.
bool
get
hasSpecifiedAllDevices
=>
_specifiedDeviceId
==
'all'
;
Stream
<
Device
>
getDevicesById
(
String
deviceId
)
async
*
{
Stream
<
Device
>
getDevicesById
(
String
deviceId
)
async
*
{
final
Stream
<
Device
>
devices
=
getAllConnectedDevices
();
final
Stream
<
Device
>
devices
=
getAllConnectedDevices
();
deviceId
=
deviceId
.
toLowerCase
();
deviceId
=
deviceId
.
toLowerCase
();
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
0770c3c1
...
@@ -18,13 +18,320 @@ import 'build_info.dart';
...
@@ -18,13 +18,320 @@ import 'build_info.dart';
import
'dart/dependencies.dart'
;
import
'dart/dependencies.dart'
;
import
'dart/package_map.dart'
;
import
'dart/package_map.dart'
;
import
'dependency_checker.dart'
;
import
'dependency_checker.dart'
;
import
'devfs.dart'
;
import
'device.dart'
;
import
'device.dart'
;
import
'globals.dart'
;
import
'globals.dart'
;
import
'run_cold.dart'
;
import
'run_hot.dart'
;
import
'vmservice.dart'
;
import
'vmservice.dart'
;
class
FlutterDevice
{
final
Device
device
;
List
<
Uri
>
observatoryUris
;
List
<
VMService
>
vmServices
;
DevFS
devFS
;
ApplicationPackage
package
;
String
_viewFilter
;
StreamSubscription
<
String
>
_loggingSubscription
;
FlutterDevice
(
this
.
device
);
String
get
viewFilter
=>
_viewFilter
;
set
viewFilter
(
String
filter
)
{
_viewFilter
=
filter
;
_viewsCache
=
null
;
}
void
connect
()
{
if
(
vmServices
!=
null
)
return
;
vmServices
=
new
List
<
VMService
>(
observatoryUris
.
length
);
for
(
int
i
=
0
;
i
<
observatoryUris
.
length
;
i
++)
{
vmServices
[
i
]
=
VMService
.
connect
(
observatoryUris
[
i
]);
printTrace
(
'Connected to service protocol:
${observatoryUris[i]}
'
);
}
}
Future
<
Null
>
refreshViews
()
async
{
if
((
vmServices
==
null
)
||
vmServices
.
isEmpty
)
return
;
for
(
VMService
service
in
vmServices
)
await
service
.
vm
.
refreshViews
();
_viewsCache
=
null
;
}
List
<
FlutterView
>
_viewsCache
;
List
<
FlutterView
>
get
views
{
if
(
_viewsCache
==
null
)
{
if
((
vmServices
==
null
)
||
vmServices
.
isEmpty
)
return
null
;
final
List
<
FlutterView
>
result
=
<
FlutterView
>[];
if
(
_viewFilter
==
null
)
{
for
(
VMService
service
in
vmServices
)
{
if
(!
service
.
isClosed
)
result
.
addAll
(
service
.
vm
.
views
.
toList
());
}
}
else
{
for
(
VMService
service
in
vmServices
)
{
if
(!
service
.
isClosed
)
result
.
addAll
(
service
.
vm
.
allViewsWithName
(
_viewFilter
));
}
}
_viewsCache
=
result
;
}
return
_viewsCache
;
}
Future
<
Null
>
getVMs
()
async
{
for
(
VMService
service
in
vmServices
)
await
service
.
getVM
();
}
Future
<
Null
>
waitForViews
()
async
{
// Refresh the view list, and wait a bit for the list to populate.
for
(
VMService
service
in
vmServices
)
await
service
.
waitForViews
();
}
Future
<
Null
>
stopApps
()
async
{
final
List
<
FlutterView
>
flutterViews
=
views
;
if
(
flutterViews
==
null
||
flutterViews
.
isEmpty
)
return
;
for
(
FlutterView
view
in
flutterViews
)
{
if
(
view
!=
null
&&
view
.
uiIsolate
!=
null
)
view
.
uiIsolate
.
flutterExit
();
}
await
new
Future
<
Null
>.
delayed
(
const
Duration
(
milliseconds:
100
));
}
Future
<
Uri
>
setupDevFS
(
String
fsName
,
Directory
rootDirectory
,
{
String
packagesFilePath
})
{
// One devFS per device. Shared by all running instances.
devFS
=
new
DevFS
(
vmServices
[
0
],
fsName
,
rootDirectory
,
packagesFilePath:
packagesFilePath
);
return
devFS
.
create
();
}
List
<
Future
<
Map
<
String
,
dynamic
>>>
reloadSources
(
String
entryPath
,
{
bool
pause:
false
})
{
final
Uri
deviceEntryUri
=
devFS
.
baseUri
.
resolveUri
(
fs
.
path
.
toUri
(
entryPath
));
final
Uri
devicePackagesUri
=
devFS
.
baseUri
.
resolve
(
'.packages'
);
final
List
<
Future
<
Map
<
String
,
dynamic
>>>
reports
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
for
(
FlutterView
view
in
views
)
{
final
Future
<
Map
<
String
,
dynamic
>>
report
=
view
.
uiIsolate
.
reloadSources
(
pause:
pause
,
rootLibUri:
deviceEntryUri
,
packagesUri:
devicePackagesUri
);
reports
.
add
(
report
);
}
return
reports
;
}
Future
<
Null
>
debugDumpApp
()
async
{
for
(
FlutterView
view
in
views
)
await
view
.
uiIsolate
.
flutterDebugDumpApp
();
}
Future
<
Null
>
debugDumpRenderTree
()
async
{
for
(
FlutterView
view
in
views
)
await
view
.
uiIsolate
.
flutterDebugDumpRenderTree
();
}
Future
<
Null
>
toggleDebugPaintSizeEnabled
()
async
{
for
(
FlutterView
view
in
views
)
await
view
.
uiIsolate
.
flutterToggleDebugPaintSizeEnabled
();
}
Future
<
String
>
togglePlatform
({
String
from
})
async
{
String
to
;
switch
(
from
)
{
case
'iOS'
:
to
=
'android'
;
break
;
case
'android'
:
default
:
to
=
'iOS'
;
break
;
}
for
(
FlutterView
view
in
views
)
{
await
view
.
uiIsolate
.
flutterPlatformOverride
(
to
);
}
return
to
;
}
void
startEchoingDeviceLog
()
{
if
(
_loggingSubscription
!=
null
)
return
;
_loggingSubscription
=
device
.
getLogReader
(
app:
package
).
logLines
.
listen
((
String
line
)
{
if
(!
line
.
contains
(
'Observatory listening on http'
)
&&
!
line
.
contains
(
'Diagnostic server listening on http'
))
printStatus
(
line
);
});
}
Future
<
Null
>
stopEchoingDeviceLog
()
async
{
if
(
_loggingSubscription
==
null
)
return
;
await
_loggingSubscription
.
cancel
();
_loggingSubscription
=
null
;
}
void
initLogReader
()
{
device
.
getLogReader
(
app:
package
).
appPid
=
vmServices
.
first
.
vm
.
pid
;
}
Future
<
int
>
runHot
({
HotRunner
hotRunner
,
String
route
,
bool
shouldBuild
,
})
async
{
final
bool
prebuiltMode
=
hotRunner
.
applicationBinary
!=
null
;
final
String
modeName
=
getModeName
(
hotRunner
.
debuggingOptions
.
buildMode
);
printStatus
(
'Launching
${getDisplayPath(hotRunner.mainPath)}
on
${device.name}
in
$modeName
mode...'
);
final
TargetPlatform
targetPlatform
=
await
device
.
targetPlatform
;
package
=
getApplicationPackageForPlatform
(
targetPlatform
,
applicationBinary:
hotRunner
.
applicationBinary
);
if
(
package
==
null
)
{
String
message
=
'No application found for
$targetPlatform
.'
;
final
String
hint
=
getMissingPackageHintForPlatform
(
targetPlatform
);
if
(
hint
!=
null
)
message
+=
'
\n
$hint
'
;
printError
(
message
);
return
1
;
}
final
Map
<
String
,
dynamic
>
platformArgs
=
<
String
,
dynamic
>{};
startEchoingDeviceLog
();
// Start the application.
final
bool
hasDirtyDependencies
=
hotRunner
.
hasDirtyDependencies
(
this
);
final
Future
<
LaunchResult
>
futureResult
=
device
.
startApp
(
package
,
hotRunner
.
debuggingOptions
.
buildMode
,
mainPath:
hotRunner
.
mainPath
,
debuggingOptions:
hotRunner
.
debuggingOptions
,
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
kernelPath:
hotRunner
.
kernelFilePath
,
applicationNeedsRebuild:
shouldBuild
||
hasDirtyDependencies
);
final
LaunchResult
result
=
await
futureResult
;
if
(!
result
.
started
)
{
printError
(
'Error launching application on
${device.name}
.'
);
await
stopEchoingDeviceLog
();
return
2
;
}
observatoryUris
=
<
Uri
>[
result
.
observatoryUri
];
return
0
;
}
Future
<
int
>
runCold
({
ColdRunner
coldRunner
,
String
route
,
bool
shouldBuild:
true
,
})
async
{
final
TargetPlatform
targetPlatform
=
await
device
.
targetPlatform
;
package
=
getApplicationPackageForPlatform
(
targetPlatform
,
applicationBinary:
coldRunner
.
applicationBinary
);
final
String
modeName
=
getModeName
(
coldRunner
.
debuggingOptions
.
buildMode
);
final
bool
prebuiltMode
=
coldRunner
.
applicationBinary
!=
null
;
if
(
coldRunner
.
mainPath
==
null
)
{
assert
(
prebuiltMode
);
printStatus
(
'Launching
${package.displayName}
on
${device.name}
in
$modeName
mode...'
);
}
else
{
printStatus
(
'Launching
${getDisplayPath(coldRunner.mainPath)}
on
${device.name}
in
$modeName
mode...'
);
}
if
(
package
==
null
)
{
String
message
=
'No application found for
$targetPlatform
.'
;
final
String
hint
=
getMissingPackageHintForPlatform
(
targetPlatform
);
if
(
hint
!=
null
)
message
+=
'
\n
$hint
'
;
printError
(
message
);
return
1
;
}
Map
<
String
,
dynamic
>
platformArgs
;
if
(
coldRunner
.
traceStartup
!=
null
)
platformArgs
=
<
String
,
dynamic
>{
'trace-startup'
:
coldRunner
.
traceStartup
};
startEchoingDeviceLog
();
final
bool
hasDirtyDependencies
=
coldRunner
.
hasDirtyDependencies
(
this
);
final
LaunchResult
result
=
await
device
.
startApp
(
package
,
coldRunner
.
debuggingOptions
.
buildMode
,
mainPath:
coldRunner
.
mainPath
,
debuggingOptions:
coldRunner
.
debuggingOptions
,
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
applicationNeedsRebuild:
shouldBuild
||
hasDirtyDependencies
);
if
(!
result
.
started
)
{
printError
(
'Error running application on
${device.name}
.'
);
await
stopEchoingDeviceLog
();
return
2
;
}
if
(
result
.
hasObservatory
)
observatoryUris
=
<
Uri
>[
result
.
observatoryUri
];
return
0
;
}
Future
<
bool
>
updateDevFS
({
DevFSProgressReporter
progressReporter
,
AssetBundle
bundle
,
bool
bundleDirty:
false
,
Set
<
String
>
fileFilter
})
async
{
final
Status
devFSStatus
=
logger
.
startProgress
(
'Syncing files to device
${device.name}
...'
,
expectSlowOperation:
true
);
int
bytes
=
0
;
try
{
bytes
=
await
devFS
.
update
(
progressReporter:
progressReporter
,
bundle:
bundle
,
bundleDirty:
bundleDirty
,
fileFilter:
fileFilter
);
}
on
DevFSException
{
devFSStatus
.
cancel
();
return
false
;
}
devFSStatus
.
stop
();
printTrace
(
'Synced
${getSizeAsMB(bytes)}
.'
);
return
true
;
}
}
// Shared code between different resident application runners.
// Shared code between different resident application runners.
abstract
class
ResidentRunner
{
abstract
class
ResidentRunner
{
ResidentRunner
(
this
.
device
,
{
ResidentRunner
(
this
.
flutterDevices
,
{
this
.
target
,
this
.
target
,
this
.
debuggingOptions
,
this
.
debuggingOptions
,
this
.
usesTerminalUI
:
true
,
this
.
usesTerminalUI
:
true
,
...
@@ -43,7 +350,7 @@ abstract class ResidentRunner {
...
@@ -43,7 +350,7 @@ abstract class ResidentRunner {
_assetBundle
=
new
AssetBundle
();
_assetBundle
=
new
AssetBundle
();
}
}
final
Device
device
;
final
List
<
FlutterDevice
>
flutterDevices
;
final
String
target
;
final
String
target
;
final
DebuggingOptions
debuggingOptions
;
final
DebuggingOptions
debuggingOptions
;
final
bool
usesTerminalUI
;
final
bool
usesTerminalUI
;
...
@@ -58,16 +365,12 @@ abstract class ResidentRunner {
...
@@ -58,16 +365,12 @@ abstract class ResidentRunner {
String
get
mainPath
=>
_mainPath
;
String
get
mainPath
=>
_mainPath
;
AssetBundle
_assetBundle
;
AssetBundle
_assetBundle
;
AssetBundle
get
assetBundle
=>
_assetBundle
;
AssetBundle
get
assetBundle
=>
_assetBundle
;
ApplicationPackage
package
;
bool
get
isRunningDebug
=>
debuggingOptions
.
buildMode
==
BuildMode
.
debug
;
bool
get
isRunningDebug
=>
debuggingOptions
.
buildMode
==
BuildMode
.
debug
;
bool
get
isRunningProfile
=>
debuggingOptions
.
buildMode
==
BuildMode
.
profile
;
bool
get
isRunningProfile
=>
debuggingOptions
.
buildMode
==
BuildMode
.
profile
;
bool
get
isRunningRelease
=>
debuggingOptions
.
buildMode
==
BuildMode
.
release
;
bool
get
isRunningRelease
=>
debuggingOptions
.
buildMode
==
BuildMode
.
release
;
bool
get
supportsServiceProtocol
=>
isRunningDebug
||
isRunningProfile
;
bool
get
supportsServiceProtocol
=>
isRunningDebug
||
isRunningProfile
;
List
<
VMService
>
vmServices
;
StreamSubscription
<
String
>
_loggingSubscription
;
/// Start the app and keep the process running during its lifetime.
/// Start the app and keep the process running during its lifetime.
Future
<
int
>
run
({
Future
<
int
>
run
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
...
@@ -78,25 +381,6 @@ abstract class ResidentRunner {
...
@@ -78,25 +381,6 @@ abstract class ResidentRunner {
bool
get
supportsRestart
=>
false
;
bool
get
supportsRestart
=>
false
;
String
isolateFilter
;
List
<
FlutterView
>
_currentViewsCache
;
List
<
FlutterView
>
get
currentViews
{
if
(
_currentViewsCache
==
null
)
{
if
((
vmServices
==
null
)
||
vmServices
.
isEmpty
)
return
null
;
if
(
isolateFilter
==
null
)
return
vmServices
[
0
].
vm
.
views
.
toList
();
final
List
<
FlutterView
>
result
=
<
FlutterView
>[];
for
(
VMService
service
in
vmServices
)
result
.
addAll
(
service
.
vm
.
allViewsWithName
(
isolateFilter
));
_currentViewsCache
=
result
;
}
return
_currentViewsCache
;
}
FlutterView
get
currentView
=>
(
currentViews
!=
null
)
?
currentViews
[
0
]
:
null
;
Future
<
OperationResult
>
restart
({
bool
fullRestart:
false
,
bool
pauseAfterRestart:
false
})
{
Future
<
OperationResult
>
restart
({
bool
fullRestart:
false
,
bool
pauseAfterRestart:
false
})
{
throw
'unsupported'
;
throw
'unsupported'
;
}
}
...
@@ -115,47 +399,49 @@ abstract class ResidentRunner {
...
@@ -115,47 +399,49 @@ abstract class ResidentRunner {
}
}
Future
<
Null
>
refreshViews
()
async
{
Future
<
Null
>
refreshViews
()
async
{
if
((
vmServices
==
null
)
||
vmServices
.
isEmpty
)
for
(
FlutterDevice
device
in
flutterDevices
)
return
;
await
device
.
refreshViews
();
for
(
VMService
service
in
vmServices
)
await
service
.
vm
.
refreshViews
();
_currentViewsCache
=
null
;
}
}
Future
<
Null
>
_debugDumpApp
()
async
{
Future
<
Null
>
_debugDumpApp
()
async
{
await
refreshViews
();
await
refreshViews
();
await
currentView
.
uiIsolate
.
flutterDebugDumpApp
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpApp
();
}
}
Future
<
Null
>
_debugDumpRenderTree
()
async
{
Future
<
Null
>
_debugDumpRenderTree
()
async
{
await
refreshViews
();
await
refreshViews
();
await
currentView
.
uiIsolate
.
flutterDebugDumpRenderTree
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
debugDumpRenderTree
();
}
}
Future
<
Null
>
_debugToggleDebugPaintSizeEnabled
()
async
{
Future
<
Null
>
_debugToggleDebugPaintSizeEnabled
()
async
{
await
refreshViews
();
await
refreshViews
();
await
currentView
.
uiIsolate
.
flutterToggleDebugPaintSizeEnabled
();
for
(
FlutterDevice
device
in
flutterDevices
)
await
device
.
toggleDebugPaintSizeEnabled
();
}
}
Future
<
Null
>
_screenshot
()
async
{
Future
<
Null
>
_screenshot
(
FlutterDevice
device
)
async
{
final
Status
status
=
logger
.
startProgress
(
'Taking screenshot...'
);
final
Status
status
=
logger
.
startProgress
(
'Taking screenshot
for
${device.device.name}
...'
);
final
File
outputFile
=
getUniqueFile
(
fs
.
currentDirectory
,
'flutter'
,
'png'
);
final
File
outputFile
=
getUniqueFile
(
fs
.
currentDirectory
,
'flutter'
,
'png'
);
try
{
try
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
await
refreshViews
();
await
device
.
refreshViews
();
try
{
try
{
await
currentView
.
uiIsolate
.
flutterDebugAllowBanner
(
false
);
for
(
FlutterView
view
in
device
.
views
)
await
view
.
uiIsolate
.
flutterDebugAllowBanner
(
false
);
}
catch
(
error
)
{
}
catch
(
error
)
{
status
.
stop
();
status
.
stop
();
printError
(
error
);
printError
(
error
);
}
}
}
}
try
{
try
{
await
device
.
takeScreenshot
(
outputFile
);
await
device
.
device
.
takeScreenshot
(
outputFile
);
}
finally
{
}
finally
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
try
{
try
{
await
currentView
.
uiIsolate
.
flutterDebugAllowBanner
(
true
);
for
(
FlutterView
view
in
device
.
views
)
await
view
.
uiIsolate
.
flutterDebugAllowBanner
(
true
);
}
catch
(
error
)
{
}
catch
(
error
)
{
status
.
stop
();
status
.
stop
();
printError
(
error
);
printError
(
error
);
...
@@ -171,15 +457,13 @@ abstract class ResidentRunner {
...
@@ -171,15 +457,13 @@ abstract class ResidentRunner {
}
}
}
}
Future
<
String
>
_debugRotat
ePlatform
()
async
{
Future
<
Null
>
_debugToggl
ePlatform
()
async
{
await
refreshViews
();
await
refreshViews
();
switch
(
await
currentView
.
uiIsolate
.
flutterPlatformOverride
())
{
final
String
from
=
await
flutterDevices
[
0
].
views
[
0
].
uiIsolate
.
flutterPlatformOverride
();
case
'iOS'
:
String
to
;
return
await
currentView
.
uiIsolate
.
flutterPlatformOverride
(
'android'
);
for
(
FlutterDevice
device
in
flutterDevices
)
case
'android'
:
to
=
await
device
.
togglePlatform
(
from:
from
);
default
:
printStatus
(
'Switched operating system to
$to
'
);
return
await
currentView
.
uiIsolate
.
flutterPlatformOverride
(
'iOS'
);
}
}
}
void
registerSignalHandlers
()
{
void
registerSignalHandlers
()
{
...
@@ -215,53 +499,38 @@ abstract class ResidentRunner {
...
@@ -215,53 +499,38 @@ abstract class ResidentRunner {
}
}
}
}
Future
<
Null
>
startEchoingDeviceLog
(
ApplicationPackage
app
)
async
{
if
(
_loggingSubscription
!=
null
)
return
;
_loggingSubscription
=
device
.
getLogReader
(
app:
app
).
logLines
.
listen
((
String
line
)
{
if
(!
line
.
contains
(
'Observatory listening on http'
)
&&
!
line
.
contains
(
'Diagnostic server listening on http'
))
printStatus
(
line
);
});
}
Future
<
Null
>
stopEchoingDeviceLog
()
async
{
Future
<
Null
>
stopEchoingDeviceLog
()
async
{
if
(
_loggingSubscription
!=
null
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
await
_loggingSubscription
.
cancel
();
device
.
stopEchoingDeviceLog
();
}
_loggingSubscription
=
null
;
}
}
Future
<
Null
>
connectToServiceProtocol
(
Future
<
Null
>
connectToServiceProtocol
({
String
viewFilter
})
async
{
List
<
Uri
>
uris
,
{
String
isolateFilter
})
async
{
if
(!
debuggingOptions
.
debuggingEnabled
)
{
if
(!
debuggingOptions
.
debuggingEnabled
)
{
return
new
Future
<
Null
>.
error
(
'Error the service protocol is not enabled.'
);
return
new
Future
<
Null
>.
error
(
'Error the service protocol is not enabled.'
);
}
}
final
List
<
VMService
>
services
=
new
List
<
VMService
>(
uris
.
length
);
for
(
int
i
=
0
;
i
<
uris
.
length
;
i
++)
{
services
[
i
]
=
VMService
.
connect
(
uris
[
i
]);
printTrace
(
'Connected to service protocol:
${uris[i]}
'
);
}
vmServices
=
services
;
for
(
VMService
service
in
services
)
await
service
.
getVM
();
this
.
isolateFilter
=
isolateFilter
;
// Refresh the view list, and wait a bit for the list to populate.
bool
viewFound
=
false
;
for
(
VMService
service
in
services
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
await
service
.
waitForViews
();
device
.
viewFilter
=
viewFilter
;
if
(
currentView
==
null
)
device
.
connect
();
await
device
.
getVMs
();
await
device
.
waitForViews
();
if
(
device
.
views
==
null
)
printStatus
(
'No Flutter views available on
${device.device.name}
'
);
else
viewFound
=
true
;
}
if
(!
viewFound
)
throwToolExit
(
'No Flutter view is available'
);
throwToolExit
(
'No Flutter view is available'
);
// Listen for service protocol connection to close.
// Listen for service protocol connection to close.
for
(
VMService
service
in
services
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
service
.
done
.
then
<
Null
>(
for
(
VMService
service
in
device
.
vmServices
)
{
_serviceProtocolDone
,
service
.
done
.
then
<
Null
>(
onError:
_serviceProtocolError
_serviceProtocolDone
,
).
whenComplete
(
_serviceDisconnected
);
onError:
_serviceProtocolError
).
whenComplete
(
_serviceDisconnected
);
}
}
}
}
}
...
@@ -301,14 +570,14 @@ abstract class ResidentRunner {
...
@@ -301,14 +570,14 @@ abstract class ResidentRunner {
return
true
;
return
true
;
}
}
}
else
if
(
lower
==
's'
)
{
}
else
if
(
lower
==
's'
)
{
if
(
device
.
supportsScreenshot
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
await
_screenshot
();
if
(
device
.
device
.
supportsScreenshot
)
return
true
;
await
_screenshot
(
device
)
;
}
}
return
true
;
}
else
if
(
lower
==
'o'
)
{
}
else
if
(
lower
==
'o'
)
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
if
(
supportsServiceProtocol
&&
isRunningDebug
)
{
final
String
platform
=
await
_debugRotatePlatform
();
await
_debugTogglePlatform
();
print
(
'Switched operating system to:
$platform
'
);
return
true
;
return
true
;
}
}
}
else
if
(
lower
==
'q'
)
{
}
else
if
(
lower
==
'q'
)
{
...
@@ -381,12 +650,12 @@ abstract class ResidentRunner {
...
@@ -381,12 +650,12 @@ abstract class ResidentRunner {
return
exitCode
;
return
exitCode
;
}
}
bool
hasDirtyDependencies
()
{
bool
hasDirtyDependencies
(
FlutterDevice
device
)
{
final
DartDependencySetBuilder
dartDependencySetBuilder
=
final
DartDependencySetBuilder
dartDependencySetBuilder
=
new
DartDependencySetBuilder
(
mainPath
,
packagesFilePath
);
new
DartDependencySetBuilder
(
mainPath
,
packagesFilePath
);
final
DependencyChecker
dependencyChecker
=
final
DependencyChecker
dependencyChecker
=
new
DependencyChecker
(
dartDependencySetBuilder
,
assetBundle
);
new
DependencyChecker
(
dartDependencySetBuilder
,
assetBundle
);
final
String
path
=
package
.
packagePath
;
final
String
path
=
device
.
package
.
packagePath
;
if
(
path
==
null
)
{
if
(
path
==
null
)
{
return
true
;
return
true
;
}
}
...
@@ -404,16 +673,8 @@ abstract class ResidentRunner {
...
@@ -404,16 +673,8 @@ abstract class ResidentRunner {
Future
<
Null
>
preStop
()
async
{
}
Future
<
Null
>
preStop
()
async
{
}
Future
<
Null
>
stopApp
()
async
{
Future
<
Null
>
stopApp
()
async
{
if
(
vmServices
!=
null
&&
for
(
FlutterDevice
device
in
flutterDevices
)
vmServices
.
isNotEmpty
&&
await
device
.
stopApps
();
!
vmServices
[
0
].
isClosed
)
{
// TODO(zra): iterate over all the views.
if
((
currentView
!=
null
)
&&
(
currentView
.
uiIsolate
!=
null
))
{
// TODO(johnmccutchan): Wait for the exit command to complete.
currentView
.
uiIsolate
.
flutterExit
();
await
new
Future
<
Null
>.
delayed
(
const
Duration
(
milliseconds:
100
));
}
}
appFinished
();
appFinished
();
}
}
...
@@ -429,7 +690,7 @@ abstract class ResidentRunner {
...
@@ -429,7 +690,7 @@ abstract class ResidentRunner {
printStatus
(
'To simulate different operating systems, (defaultTargetPlatform), press "o".'
);
printStatus
(
'To simulate different operating systems, (defaultTargetPlatform), press "o".'
);
}
}
}
}
if
(
device
.
supportsScreenshot
)
if
(
flutterDevices
.
any
((
FlutterDevice
d
)
=>
d
.
device
.
supportsScreenshot
)
)
printStatus
(
'To save a screenshot to flutter.png, press "s".'
);
printStatus
(
'To save a screenshot to flutter.png, press "s".'
);
}
}
...
...
packages/flutter_tools/lib/src/run_cold.dart
View file @
0770c3c1
...
@@ -6,10 +6,7 @@ import 'dart:async';
...
@@ -6,10 +6,7 @@ import 'dart:async';
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'application_package.dart'
;
import
'base/file_system.dart'
;
import
'base/file_system.dart'
;
import
'base/utils.dart'
;
import
'build_info.dart'
;
import
'commands/trace.dart'
;
import
'commands/trace.dart'
;
import
'device.dart'
;
import
'device.dart'
;
import
'globals.dart'
;
import
'globals.dart'
;
...
@@ -17,25 +14,22 @@ import 'resident_runner.dart';
...
@@ -17,25 +14,22 @@ import 'resident_runner.dart';
class
ColdRunner
extends
ResidentRunner
{
class
ColdRunner
extends
ResidentRunner
{
ColdRunner
(
ColdRunner
(
Device
device
,
{
List
<
FlutterDevice
>
devices
,
{
String
target
,
String
target
,
DebuggingOptions
debuggingOptions
,
DebuggingOptions
debuggingOptions
,
bool
usesTerminalUI:
true
,
bool
usesTerminalUI:
true
,
this
.
traceStartup
:
false
,
this
.
traceStartup
:
false
,
this
.
applicationBinary
,
this
.
applicationBinary
,
bool
stayResident:
true
,
bool
stayResident:
true
,
})
:
super
(
device
,
})
:
super
(
device
s
,
target:
target
,
target:
target
,
debuggingOptions:
debuggingOptions
,
debuggingOptions:
debuggingOptions
,
usesTerminalUI:
usesTerminalUI
,
usesTerminalUI:
usesTerminalUI
,
stayResident:
stayResident
);
stayResident:
stayResident
);
LaunchResult
_result
;
final
bool
traceStartup
;
final
bool
traceStartup
;
final
String
applicationBinary
;
final
String
applicationBinary
;
bool
get
prebuiltMode
=>
applicationBinary
!=
null
;
@override
@override
Future
<
int
>
run
({
Future
<
int
>
run
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
...
@@ -43,6 +37,7 @@ class ColdRunner extends ResidentRunner {
...
@@ -43,6 +37,7 @@ class ColdRunner extends ResidentRunner {
String
route
,
String
route
,
bool
shouldBuild:
true
bool
shouldBuild:
true
})
async
{
})
async
{
final
bool
prebuiltMode
=
applicationBinary
!=
null
;
if
(!
prebuiltMode
)
{
if
(!
prebuiltMode
)
{
if
(!
fs
.
isFileSync
(
mainPath
))
{
if
(!
fs
.
isFileSync
(
mainPath
))
{
String
message
=
'Tried to run
$mainPath
, but that file does not exist.'
;
String
message
=
'Tried to run
$mainPath
, but that file does not exist.'
;
...
@@ -53,79 +48,49 @@ class ColdRunner extends ResidentRunner {
...
@@ -53,79 +48,49 @@ class ColdRunner extends ResidentRunner {
}
}
}
}
final
String
modeName
=
getModeName
(
debuggingOptions
.
buildMode
);
for
(
FlutterDevice
device
in
flutterDevices
)
{
if
(
mainPath
==
null
)
{
final
int
result
=
await
device
.
runCold
(
assert
(
prebuiltMode
);
coldRunner:
this
,
printStatus
(
'Launching
${package.displayName}
on
${device.name}
in
$modeName
mode...'
);
route:
route
,
}
else
{
shouldBuild:
shouldBuild
,
printStatus
(
'Launching
${getDisplayPath(mainPath)}
on
${device.name}
in
$modeName
mode...'
);
);
}
if
(
result
!=
0
)
return
result
;
final
TargetPlatform
targetPlatform
=
await
device
.
targetPlatform
;
package
=
getApplicationPackageForPlatform
(
targetPlatform
,
applicationBinary:
applicationBinary
);
if
(
package
==
null
)
{
String
message
=
'No application found for
$targetPlatform
.'
;
final
String
hint
=
getMissingPackageHintForPlatform
(
targetPlatform
);
if
(
hint
!=
null
)
message
+=
'
\n
$hint
'
;
printError
(
message
);
return
1
;
}
}
final
Stopwatch
startTime
=
new
Stopwatch
()..
start
();
Map
<
String
,
dynamic
>
platformArgs
;
if
(
traceStartup
!=
null
)
platformArgs
=
<
String
,
dynamic
>{
'trace-startup'
:
traceStartup
};
await
startEchoingDeviceLog
(
package
);
_result
=
await
device
.
startApp
(
package
,
debuggingOptions
.
buildMode
,
mainPath:
mainPath
,
debuggingOptions:
debuggingOptions
,
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
applicationNeedsRebuild:
shouldBuild
||
hasDirtyDependencies
()
);
if
(!
_result
.
started
)
{
printError
(
'Error running application on
${device.name}
.'
);
await
stopEchoingDeviceLog
();
return
2
;
}
startTime
.
stop
();
// Connect to observatory.
// Connect to observatory.
if
(
debuggingOptions
.
debuggingEnabled
)
if
(
debuggingOptions
.
debuggingEnabled
)
await
connectToServiceProtocol
(
<
Uri
>[
_result
.
observatoryUri
]
);
await
connectToServiceProtocol
();
if
(
_result
.
hasObservatory
)
{
if
(
flutterDevices
.
first
.
observatoryUris
!=
null
)
{
// For now, only support one debugger connection.
connectionInfoCompleter
?.
complete
(
new
DebugConnectionInfo
(
connectionInfoCompleter
?.
complete
(
new
DebugConnectionInfo
(
httpUri:
_result
.
observatoryUri
,
httpUri:
flutterDevices
.
first
.
observatoryUris
.
first
,
wsUri:
vmServices
[
0
]
.
wsAddress
,
wsUri:
flutterDevices
.
first
.
vmServices
.
first
.
wsAddress
,
));
));
}
}
printTrace
(
'Application running.'
);
printTrace
(
'Application running.'
);
if
(
vmServices
!=
null
&&
vmServices
.
isNotEmpty
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
device
.
getLogReader
(
app:
package
).
appPid
=
vmServices
[
0
].
vm
.
pid
;
if
(
device
.
vmServices
==
null
)
await
refreshViews
();
continue
;
printTrace
(
'Connected to
$currentView
.'
);
device
.
initLogReader
();
await
device
.
refreshViews
();
printTrace
(
'Connected to
${device.device.name}
'
);
}
}
if
(
vmServices
!=
null
&&
vmServices
.
isNotEmpty
&&
traceStartup
)
{
if
(
traceStartup
)
{
printStatus
(
'Downloading startup trace info...'
);
// Only trace startup for the first device.
try
{
final
FlutterDevice
device
=
flutterDevices
.
first
;
await
downloadStartupTrace
(
vmServices
[
0
]);
if
(
device
.
vmServices
!=
null
&&
device
.
vmServices
.
isNotEmpty
)
{
}
catch
(
error
)
{
printStatus
(
'Downloading startup trace info for
${device.device.name}
'
);
printError
(
error
);
try
{
return
2
;
await
downloadStartupTrace
(
device
.
vmServices
.
first
);
}
catch
(
error
)
{
printError
(
error
);
return
2
;
}
}
}
appFinished
();
appFinished
();
}
else
if
(
stayResident
)
{
}
else
if
(
stayResident
)
{
...
@@ -158,8 +123,13 @@ class ColdRunner extends ResidentRunner {
...
@@ -158,8 +123,13 @@ class ColdRunner extends ResidentRunner {
@override
@override
void
printHelp
({
@required
bool
details
})
{
void
printHelp
({
@required
bool
details
})
{
bool
haveDetails
=
false
;
bool
haveDetails
=
false
;
if
(
_result
.
hasObservatory
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
printStatus
(
'The Observatory debugger and profiler is available at:
${_result.observatoryUri}
'
);
final
String
dname
=
device
.
device
.
name
;
if
(
device
.
observatoryUris
!=
null
)
{
for
(
Uri
uri
in
device
.
observatoryUris
)
printStatus
(
'An Observatory debugger and profiler on
$dname
is available at
$uri
'
);
}
}
if
(
supportsServiceProtocol
)
{
if
(
supportsServiceProtocol
)
{
haveDetails
=
true
;
haveDetails
=
true
;
if
(
details
)
if
(
details
)
...
@@ -174,8 +144,10 @@ class ColdRunner extends ResidentRunner {
...
@@ -174,8 +144,10 @@ class ColdRunner extends ResidentRunner {
@override
@override
Future
<
Null
>
preStop
()
async
{
Future
<
Null
>
preStop
()
async
{
// If we're running in release mode, stop the app using the device logic.
for
(
FlutterDevice
device
in
flutterDevices
)
{
if
(
vmServices
==
null
||
vmServices
.
isEmpty
)
// If we're running in release mode, stop the app using the device logic.
await
device
.
stopApp
(
package
);
if
(
device
.
vmServices
==
null
||
device
.
vmServices
.
isEmpty
)
await
device
.
device
.
stopApp
(
device
.
package
);
}
}
}
}
}
packages/flutter_tools/lib/src/run_hot.dart
View file @
0770c3c1
...
@@ -6,7 +6,6 @@ import 'dart:async';
...
@@ -6,7 +6,6 @@ import 'dart:async';
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'application_package.dart'
;
import
'base/context.dart'
;
import
'base/context.dart'
;
import
'base/file_system.dart'
;
import
'base/file_system.dart'
;
import
'base/logger.dart'
;
import
'base/logger.dart'
;
...
@@ -33,7 +32,7 @@ const bool kHotReloadDefault = true;
...
@@ -33,7 +32,7 @@ const bool kHotReloadDefault = true;
class
HotRunner
extends
ResidentRunner
{
class
HotRunner
extends
ResidentRunner
{
HotRunner
(
HotRunner
(
Device
device
,
{
List
<
FlutterDevice
>
devices
,
{
String
target
,
String
target
,
DebuggingOptions
debuggingOptions
,
DebuggingOptions
debuggingOptions
,
bool
usesTerminalUI:
true
,
bool
usesTerminalUI:
true
,
...
@@ -44,7 +43,7 @@ class HotRunner extends ResidentRunner {
...
@@ -44,7 +43,7 @@ class HotRunner extends ResidentRunner {
String
packagesFilePath
,
String
packagesFilePath
,
String
projectAssets
,
String
projectAssets
,
bool
stayResident:
true
,
bool
stayResident:
true
,
})
:
super
(
device
,
})
:
super
(
device
s
,
target:
target
,
target:
target
,
debuggingOptions:
debuggingOptions
,
debuggingOptions:
debuggingOptions
,
usesTerminalUI:
usesTerminalUI
,
usesTerminalUI:
usesTerminalUI
,
...
@@ -54,9 +53,7 @@ class HotRunner extends ResidentRunner {
...
@@ -54,9 +53,7 @@ class HotRunner extends ResidentRunner {
stayResident:
stayResident
);
stayResident:
stayResident
);
final
String
applicationBinary
;
final
String
applicationBinary
;
bool
get
prebuiltMode
=>
applicationBinary
!=
null
;
Set
<
String
>
_dartDependencies
;
Set
<
String
>
_dartDependencies
;
Uri
_observatoryUri
;
final
bool
benchmarkMode
;
final
bool
benchmarkMode
;
final
Map
<
String
,
int
>
benchmarkData
=
<
String
,
int
>{};
final
Map
<
String
,
int
>
benchmarkData
=
<
String
,
int
>{};
...
@@ -87,30 +84,30 @@ class HotRunner extends ResidentRunner {
...
@@ -87,30 +84,30 @@ class HotRunner extends ResidentRunner {
return
true
;
return
true
;
}
}
Future
<
int
>
attach
(
List
<
Uri
>
observatoryUris
,
{
Future
<
int
>
attach
({
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
DebugConnectionInfo
>
connectionInfoCompleter
,
Completer
<
Null
>
appStartedCompleter
,
Completer
<
Null
>
appStartedCompleter
,
String
isolate
Filter
,
String
view
Filter
,
})
async
{
})
async
{
_observatoryUri
=
observatoryUris
[
0
];
try
{
try
{
await
connectToServiceProtocol
(
await
connectToServiceProtocol
(
viewFilter:
viewFilter
);
observatoryUris
,
isolateFilter:
isolateFilter
);
}
catch
(
error
)
{
}
catch
(
error
)
{
printError
(
'Error connecting to the service protocol:
$error
'
);
printError
(
'Error connecting to the service protocol:
$error
'
);
return
2
;
return
2
;
}
}
device
.
getLogReader
(
app:
package
).
appPid
=
vmServices
[
0
].
vm
.
pid
;
for
(
FlutterDevice
device
in
flutterDevices
)
device
.
initLogReader
();
try
{
try
{
final
Uri
baseUri
=
await
_initDevFS
();
final
List
<
Uri
>
baseUris
=
await
_initDevFS
();
if
(
connectionInfoCompleter
!=
null
)
{
if
(
connectionInfoCompleter
!=
null
)
{
// Only handle one debugger connection.
connectionInfoCompleter
.
complete
(
connectionInfoCompleter
.
complete
(
new
DebugConnectionInfo
(
new
DebugConnectionInfo
(
httpUri:
_observatoryUri
,
httpUri:
flutterDevices
.
first
.
observatoryUris
.
first
,
wsUri:
vmServices
[
0
]
.
wsAddress
,
wsUri:
flutterDevices
.
first
.
vmServices
.
first
.
wsAddress
,
baseUri:
baseUri
.
toString
()
baseUri:
baseUri
s
.
first
.
toString
()
)
)
);
);
}
}
...
@@ -124,8 +121,10 @@ class HotRunner extends ResidentRunner {
...
@@ -124,8 +121,10 @@ class HotRunner extends ResidentRunner {
}
}
await
refreshViews
();
await
refreshViews
();
for
(
FlutterView
view
in
currentViews
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
printTrace
(
'Connected to
$view
.'
);
for
(
FlutterView
view
in
device
.
views
)
printTrace
(
'Connected to
$view
.'
);
}
if
(
stayResident
)
{
if
(
stayResident
)
{
setupTerminal
();
setupTerminal
();
...
@@ -174,55 +173,27 @@ class HotRunner extends ResidentRunner {
...
@@ -174,55 +173,27 @@ class HotRunner extends ResidentRunner {
return
1
;
return
1
;
}
}
final
String
modeName
=
getModeName
(
debuggingOptions
.
buildMode
);
printStatus
(
'Launching
${getDisplayPath(mainPath)}
on
${device.name}
in
$modeName
mode...'
);
final
TargetPlatform
targetPlatform
=
await
device
.
targetPlatform
;
package
=
getApplicationPackageForPlatform
(
targetPlatform
,
applicationBinary:
applicationBinary
);
if
(
package
==
null
)
{
String
message
=
'No application found for
$targetPlatform
.'
;
final
String
hint
=
getMissingPackageHintForPlatform
(
targetPlatform
);
if
(
hint
!=
null
)
message
+=
'
\n
$hint
'
;
printError
(
message
);
return
1
;
}
// Determine the Dart dependencies eagerly.
// Determine the Dart dependencies eagerly.
if
(!
_refreshDartDependencies
())
{
if
(!
_refreshDartDependencies
())
{
// Some kind of source level error or missing file in the Dart code.
// Some kind of source level error or missing file in the Dart code.
return
1
;
return
1
;
}
}
final
Map
<
String
,
dynamic
>
platformArgs
=
<
String
,
dynamic
>{};
for
(
FlutterDevice
device
in
flutterDevices
)
{
final
int
result
=
await
device
.
runHot
(
await
startEchoingDeviceLog
(
package
);
hotRunner:
this
,
route:
route
,
// Start the application.
shouldBuild:
shouldBuild
,
final
Future
<
LaunchResult
>
futureResult
=
device
.
startApp
(
);
package
,
if
(
result
!=
0
)
{
debuggingOptions
.
buildMode
,
return
result
;
mainPath:
mainPath
,
}
debuggingOptions:
debuggingOptions
,
platformArgs:
platformArgs
,
route:
route
,
prebuiltApplication:
prebuiltMode
,
kernelPath:
kernelFilePath
,
applicationNeedsRebuild:
shouldBuild
||
hasDirtyDependencies
()
);
final
LaunchResult
result
=
await
futureResult
;
if
(!
result
.
started
)
{
printError
(
'Error launching application on
${device.name}
.'
);
await
stopEchoingDeviceLog
();
return
2
;
}
}
return
attach
(<
Uri
>[
result
.
observatoryUri
],
return
attach
(
connectionInfoCompleter:
connectionInfoCompleter
,
connectionInfoCompleter:
connectionInfoCompleter
,
appStartedCompleter:
appStartedCompleter
);
appStartedCompleter:
appStartedCompleter
);
}
}
@override
@override
...
@@ -238,15 +209,18 @@ class HotRunner extends ResidentRunner {
...
@@ -238,15 +209,18 @@ class HotRunner extends ResidentRunner {
}
}
}
}
DevFS
_devFS
;
Future
<
List
<
Uri
>>
_initDevFS
()
async
{
Future
<
Uri
>
_initDevFS
()
{
final
String
fsName
=
fs
.
path
.
basename
(
projectRootPath
);
final
String
fsName
=
fs
.
path
.
basename
(
projectRootPath
);
_devFS
=
new
DevFS
(
vmServices
[
0
],
final
List
<
Uri
>
devFSUris
=
<
Uri
>[];
fsName
,
for
(
FlutterDevice
device
in
flutterDevices
)
{
fs
.
directory
(
projectRootPath
),
final
Uri
uri
=
await
device
.
setupDevFS
(
packagesFilePath:
packagesFilePath
);
fsName
,
return
_devFS
.
create
();
fs
.
directory
(
projectRootPath
),
packagesFilePath:
packagesFilePath
);
devFSUris
.
add
(
uri
);
}
return
devFSUris
;
}
}
Future
<
bool
>
_updateDevFS
({
DevFSProgressReporter
progressReporter
})
async
{
Future
<
bool
>
_updateDevFS
({
DevFSProgressReporter
progressReporter
})
async
{
...
@@ -261,67 +235,72 @@ class HotRunner extends ResidentRunner {
...
@@ -261,67 +235,72 @@ class HotRunner extends ResidentRunner {
if
(
result
!=
0
)
if
(
result
!=
0
)
return
false
;
return
false
;
}
}
final
Status
devFSStatus
=
logger
.
startProgress
(
'Syncing files to device...'
,
expectSlowOperation:
true
);
for
(
FlutterDevice
device
in
flutterDevices
)
{
int
bytes
=
0
;
final
bool
result
=
await
device
.
updateDevFS
(
try
{
progressReporter:
progressReporter
,
bytes
=
await
_devFS
.
update
(
progressReporter:
progressReporter
,
bundle:
assetBundle
,
bundle:
assetBundle
,
bundleDirty:
rebuildBundle
,
bundleDirty:
rebuildBundle
,
fileFilter:
_dartDependencies
,
fileFilter:
_dartDependencies
);
);
}
on
DevFSException
{
if
(!
result
)
devFSStatus
.
cancel
();
return
false
;
return
false
;
}
}
devFSStatus
.
stop
();
if
(!
hotRunnerConfig
.
stableDartDependencies
)
{
if
(!
hotRunnerConfig
.
stableDartDependencies
)
{
// Clear the set after the sync so they are recomputed next time.
// Clear the set after the sync so they are recomputed next time.
_dartDependencies
=
null
;
_dartDependencies
=
null
;
}
}
printTrace
(
'Synced
${getSizeAsMB(bytes)}
.'
);
return
true
;
return
true
;
}
}
Future
<
Null
>
_evictDirtyAssets
()
async
{
Future
<
Null
>
_evictDirtyAssets
()
async
{
if
(
_devFS
.
assetPathsToEvict
.
isEmpty
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
return
;
if
(
device
.
devFS
.
assetPathsToEvict
.
isEmpty
)
if
(
currentView
.
uiIsolate
==
null
)
return
;
throw
'Application isolate not found'
;
if
(
device
.
views
.
first
.
uiIsolate
==
null
)
for
(
String
assetPath
in
_devFS
.
assetPathsToEvict
)
{
throw
'Application isolate not found'
;
await
currentView
.
uiIsolate
.
flutterEvictAsset
(
assetPath
);
for
(
String
assetPath
in
device
.
devFS
.
assetPathsToEvict
)
}
await
device
.
views
.
first
.
uiIsolate
.
flutterEvictAsset
(
assetPath
);
_devFS
.
assetPathsToEvict
.
clear
();
device
.
devFS
.
assetPathsToEvict
.
clear
();
}
}
}
Future
<
Null
>
_cleanupDevFS
()
async
{
Future
<
Null
>
_cleanupDevFS
()
async
{
if
(
_devFS
!=
null
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
// Cleanup the devFS; don't wait indefinitely, and ignore any errors.
if
(
device
.
devFS
!=
null
)
{
await
_devFS
.
destroy
()
// Cleanup the devFS; don't wait indefinitely, and ignore any errors.
.
timeout
(
const
Duration
(
milliseconds:
250
))
await
device
.
devFS
.
destroy
()
.
catchError
((
dynamic
error
)
{
.
timeout
(
const
Duration
(
milliseconds:
250
))
printTrace
(
'
$error
'
);
.
catchError
((
dynamic
error
)
{
});
printTrace
(
'
$error
'
);
}
});
_devFS
=
null
;
}
device
.
devFS
=
null
;
}
}
}
Future
<
Null
>
_launchInView
(
Uri
entryUri
,
Future
<
Null
>
_launchInView
(
FlutterDevice
device
,
Uri
entryUri
,
Uri
packagesUri
,
Uri
packagesUri
,
Uri
assetsDirectoryUri
)
async
{
Uri
assetsDirectoryUri
)
async
{
f
inal
FlutterView
view
=
currentView
;
f
or
(
FlutterView
view
in
device
.
views
)
return
view
.
runFromSource
(
entryUri
,
packagesUri
,
assetsDirectoryUri
);
await
view
.
runFromSource
(
entryUri
,
packagesUri
,
assetsDirectoryUri
);
}
}
Future
<
Null
>
_launchFromDevFS
(
ApplicationPackage
package
,
Future
<
Null
>
_launchFromDevFS
(
String
mainScript
)
async
{
String
mainScript
)
async
{
final
String
entryUri
=
fs
.
path
.
relative
(
mainScript
,
from:
projectRootPath
);
final
String
entryUri
=
fs
.
path
.
relative
(
mainScript
,
from:
projectRootPath
);
final
Uri
deviceEntryUri
=
_devFS
.
baseUri
.
resolveUri
(
fs
.
path
.
toUri
(
entryUri
));
for
(
FlutterDevice
device
in
flutterDevices
)
{
final
Uri
devicePackagesUri
=
_devFS
.
baseUri
.
resolve
(
'.packages'
);
final
Uri
deviceEntryUri
=
device
.
devFS
.
baseUri
.
resolveUri
(
final
Uri
deviceAssetsDirectoryUri
=
fs
.
path
.
toUri
(
entryUri
));
_devFS
.
baseUri
.
resolveUri
(
fs
.
path
.
toUri
(
getAssetBuildDirectory
()));
final
Uri
devicePackagesUri
=
device
.
devFS
.
baseUri
.
resolve
(
'.packages'
);
await
_launchInView
(
deviceEntryUri
,
final
Uri
deviceAssetsDirectoryUri
=
device
.
devFS
.
baseUri
.
resolveUri
(
devicePackagesUri
,
fs
.
path
.
toUri
(
getAssetBuildDirectory
()));
deviceAssetsDirectoryUri
);
await
_launchInView
(
device
,
deviceEntryUri
,
devicePackagesUri
,
deviceAssetsDirectoryUri
);
}
}
}
Future
<
OperationResult
>
_restartFromSources
()
async
{
Future
<
OperationResult
>
_restartFromSources
()
async
{
...
@@ -333,18 +312,22 @@ class HotRunner extends ResidentRunner {
...
@@ -333,18 +312,22 @@ class HotRunner extends ResidentRunner {
if
(!
updatedDevFS
)
if
(!
updatedDevFS
)
return
new
OperationResult
(
1
,
'DevFS Synchronization Failed'
);
return
new
OperationResult
(
1
,
'DevFS Synchronization Failed'
);
// Check if the isolate is paused and resume it.
// Check if the isolate is paused and resume it.
if
(
currentView
?.
uiIsolate
!=
null
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
// Reload the isolate.
for
(
FlutterView
view
in
device
.
views
)
{
await
currentView
.
uiIsolate
.
reload
();
if
(
view
.
uiIsolate
!=
null
)
{
final
ServiceEvent
pauseEvent
=
currentView
.
uiIsolate
.
pauseEvent
;
// Reload the isolate.
if
((
pauseEvent
!=
null
)
&&
pauseEvent
.
isPauseEvent
)
{
await
view
.
uiIsolate
.
reload
();
// Resume the isolate so that it can be killed by the embedder.
final
ServiceEvent
pauseEvent
=
view
.
uiIsolate
.
pauseEvent
;
await
currentView
.
uiIsolate
.
resume
();
if
((
pauseEvent
!=
null
)
&&
pauseEvent
.
isPauseEvent
)
{
// Resume the isolate so that it can be killed by the embedder.
await
view
.
uiIsolate
.
resume
();
}
}
}
}
}
}
// We are now running from source.
// We are now running from source.
_runningFromSnapshot
=
false
;
_runningFromSnapshot
=
false
;
await
_launchFromDevFS
(
package
,
mainPath
);
await
_launchFromDevFS
(
mainPath
);
restartTimer
.
stop
();
restartTimer
.
stop
();
printTrace
(
'Restart performed in '
printTrace
(
'Restart performed in '
'
${getElapsedAsMilliseconds(restartTimer.elapsed)}
.'
);
'
${getElapsedAsMilliseconds(restartTimer.elapsed)}
.'
);
...
@@ -380,7 +363,10 @@ class HotRunner extends ResidentRunner {
...
@@ -380,7 +363,10 @@ class HotRunner extends ResidentRunner {
@override
@override
Future
<
OperationResult
>
restart
({
bool
fullRestart:
false
,
bool
pauseAfterRestart:
false
})
async
{
Future
<
OperationResult
>
restart
({
bool
fullRestart:
false
,
bool
pauseAfterRestart:
false
})
async
{
if
(
fullRestart
)
{
if
(
fullRestart
)
{
final
Status
status
=
logger
.
startProgress
(
'Performing full restart...'
,
progressId:
'hot.restart'
);
final
Status
status
=
logger
.
startProgress
(
'Performing full restart...'
,
progressId:
'hot.restart'
);
try
{
try
{
final
Stopwatch
timer
=
new
Stopwatch
()..
start
();
final
Stopwatch
timer
=
new
Stopwatch
()..
start
();
await
_restartFromSources
();
await
_restartFromSources
();
...
@@ -395,7 +381,10 @@ class HotRunner extends ResidentRunner {
...
@@ -395,7 +381,10 @@ class HotRunner extends ResidentRunner {
}
else
{
}
else
{
final
bool
reloadOnTopOfSnapshot
=
_runningFromSnapshot
;
final
bool
reloadOnTopOfSnapshot
=
_runningFromSnapshot
;
final
String
progressPrefix
=
reloadOnTopOfSnapshot
?
'Initializing'
:
'Performing'
;
final
String
progressPrefix
=
reloadOnTopOfSnapshot
?
'Initializing'
:
'Performing'
;
final
Status
status
=
logger
.
startProgress
(
'
$progressPrefix
hot reload...'
,
progressId:
'hot.reload'
);
final
Status
status
=
logger
.
startProgress
(
'
$progressPrefix
hot reload...'
,
progressId:
'hot.reload'
);
try
{
try
{
final
Stopwatch
timer
=
new
Stopwatch
()..
start
();
final
Stopwatch
timer
=
new
Stopwatch
()..
start
();
final
OperationResult
result
=
await
_reloadSources
(
pause:
pauseAfterRestart
);
final
OperationResult
result
=
await
_reloadSources
(
pause:
pauseAfterRestart
);
...
@@ -414,8 +403,12 @@ class HotRunner extends ResidentRunner {
...
@@ -414,8 +403,12 @@ class HotRunner extends ResidentRunner {
Future
<
OperationResult
>
_reloadSources
({
bool
pause:
false
})
async
{
Future
<
OperationResult
>
_reloadSources
({
bool
pause:
false
})
async
{
printTrace
(
'Refreshing active FlutterViews before reloading.'
);
printTrace
(
'Refreshing active FlutterViews before reloading.'
);
await
refreshViews
();
await
refreshViews
();
if
(
currentView
.
uiIsolate
==
null
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
throw
'Application isolate not found'
;
for
(
FlutterView
view
in
device
.
views
)
{
if
(
view
.
uiIsolate
==
null
)
throw
'Application isolate not found'
;
}
}
// The initial launch is from a script snapshot. When we reload from source
// The initial launch is from a script snapshot. When we reload from source
// on top of a script snapshot, the first reload will be a worst case reload
// on top of a script snapshot, the first reload will be a worst case reload
// because all of the sources will end up being dirty (library paths will
// because all of the sources will end up being dirty (library paths will
...
@@ -448,22 +441,19 @@ class HotRunner extends ResidentRunner {
...
@@ -448,22 +441,19 @@ class HotRunner extends ResidentRunner {
String
reloadMessage
;
String
reloadMessage
;
try
{
try
{
final
String
entryPath
=
fs
.
path
.
relative
(
mainPath
,
from:
projectRootPath
);
final
String
entryPath
=
fs
.
path
.
relative
(
mainPath
,
from:
projectRootPath
);
final
Uri
deviceEntryUri
=
_devFS
.
baseUri
.
resolveUri
(
fs
.
path
.
toUri
(
entryPath
));
final
Uri
devicePackagesUri
=
_devFS
.
baseUri
.
resolve
(
'.packages'
);
if
(
benchmarkMode
)
if
(
benchmarkMode
)
vmReloadTimer
.
start
();
vmReloadTimer
.
start
();
Map
<
String
,
dynamic
>
reloadReport
;
Map
<
String
,
dynamic
>
reloadReport
;
f
or
(
FlutterView
view
in
currentViews
)
{
f
inal
List
<
Future
<
Map
<
String
,
dynamic
>>>
reloadReports
=
<
Future
<
Map
<
String
,
dynamic
>>>[];
final
Map
<
String
,
dynamic
>
report
=
await
view
.
uiIsolate
.
reloadSources
(
for
(
FlutterDevice
device
in
flutterDevices
)
{
pause:
pause
,
final
List
<
Future
<
Map
<
String
,
dynamic
>>>
reports
=
device
.
reloadSources
(
rootLibUri:
deviceEntryUri
,
entryPath
,
pa
ckagesUri:
devicePackagesUri
pa
use:
pause
);
);
// Just take the first one until we think of something smart to do.
reloadReports
.
addAll
(
reports
);
if
(
reloadReport
==
null
)
reloadReport
=
report
;
}
}
reloadReport
=
(
await
Future
.
wait
(
reloadReports
)).
first
;
if
(!
validateReloadReport
(
reloadReport
))
{
if
(!
validateReloadReport
(
reloadReport
))
{
// Reload failed.
// Reload failed.
flutterUsage
.
sendEvent
(
'hot'
,
'reload-reject'
);
flutterUsage
.
sendEvent
(
'hot'
,
'reload-reject'
);
...
@@ -476,6 +466,7 @@ class HotRunner extends ResidentRunner {
...
@@ -476,6 +466,7 @@ class HotRunner extends ResidentRunner {
reloadMessage
=
'
$loadedLibraryCount
of
$finalLibraryCount
libraries'
;
reloadMessage
=
'
$loadedLibraryCount
of
$finalLibraryCount
libraries'
;
}
}
}
catch
(
error
,
st
)
{
}
catch
(
error
,
st
)
{
printError
(
"Hot reload failed:
$error
\n
$st
"
);
final
int
errorCode
=
error
[
'code'
];
final
int
errorCode
=
error
[
'code'
];
final
String
errorMessage
=
error
[
'message'
];
final
String
errorMessage
=
error
[
'message'
];
if
(
errorCode
==
Isolate
.
kIsolateReloadBarred
)
{
if
(
errorCode
==
Isolate
.
kIsolateReloadBarred
)
{
...
@@ -498,20 +489,24 @@ class HotRunner extends ResidentRunner {
...
@@ -498,20 +489,24 @@ class HotRunner extends ResidentRunner {
if
(
benchmarkMode
)
if
(
benchmarkMode
)
reassembleTimer
.
start
();
reassembleTimer
.
start
();
// Reload the isolate.
// Reload the isolate.
for
(
FlutterView
view
in
currentViews
)
for
(
FlutterDevice
device
in
flutterDevices
)
{
await
view
.
uiIsolate
.
reload
();
for
(
FlutterView
view
in
device
.
views
)
await
view
.
uiIsolate
.
reload
();
}
// We are now running from source.
// We are now running from source.
_runningFromSnapshot
=
false
;
_runningFromSnapshot
=
false
;
// Check if the isolate is paused.
// Check if the isolate is paused.
final
List
<
FlutterView
>
reassembleViews
=
<
FlutterView
>[];
final
List
<
FlutterView
>
reassembleViews
=
<
FlutterView
>[];
for
(
FlutterView
view
in
currentViews
)
{
for
(
FlutterDevice
device
in
flutterDevices
)
{
final
ServiceEvent
pauseEvent
=
view
.
uiIsolate
.
pauseEvent
;
for
(
FlutterView
view
in
device
.
views
)
{
if
((
pauseEvent
!=
null
)
&&
(
pauseEvent
.
isPauseEvent
))
{
final
ServiceEvent
pauseEvent
=
view
.
uiIsolate
.
pauseEvent
;
// Isolate is paused. Don't reassemble.
if
((
pauseEvent
!=
null
)
&&
(
pauseEvent
.
isPauseEvent
))
{
continue
;
// Isolate is paused. Don't reassemble.
continue
;
}
reassembleViews
.
add
(
view
);
}
}
reassembleViews
.
add
(
view
);
}
}
if
(
reassembleViews
.
isEmpty
)
{
if
(
reassembleViews
.
isEmpty
)
{
printTrace
(
'Skipping reassemble because all isolates are paused.'
);
printTrace
(
'Skipping reassemble because all isolates are paused.'
);
...
@@ -579,7 +574,11 @@ class HotRunner extends ResidentRunner {
...
@@ -579,7 +574,11 @@ class HotRunner extends ResidentRunner {
ansiAlternative:
'
$red$fire$bold
To hot reload your app on the fly, '
ansiAlternative:
'
$red$fire$bold
To hot reload your app on the fly, '
'press "r". To restart the app entirely, press "R".
$reset
'
'press "r". To restart the app entirely, press "R".
$reset
'
);
);
printStatus
(
'The Observatory debugger and profiler is available at:
$_observatoryUri
'
);
for
(
FlutterDevice
device
in
flutterDevices
)
{
final
String
dname
=
device
.
device
.
name
;
for
(
Uri
uri
in
device
.
observatoryUris
)
printStatus
(
'An Observatory debugger and profiler on
$dname
is available at:
$uri
'
);
}
if
(
details
)
{
if
(
details
)
{
printHelpDetails
();
printHelpDetails
();
printStatus
(
'To repeat this help message, press "h". To quit, press "q".'
);
printStatus
(
'To repeat this help message, press "h". To quit, press "q".'
);
...
...
packages/flutter_tools/lib/src/runner/flutter_command.dart
View file @
0770c3c1
...
@@ -154,11 +154,11 @@ abstract class FlutterCommand extends Command<Null> {
...
@@ -154,11 +154,11 @@ abstract class FlutterCommand extends Command<Null> {
/// Subclasses must implement this to execute the command.
/// Subclasses must implement this to execute the command.
Future
<
Null
>
runCommand
();
Future
<
Null
>
runCommand
();
/// Find and return
the target [Device]
based upon currently connected
/// Find and return
all target [Device]s
based upon currently connected
/// devices and criteria entered by the user on the command line.
/// devices and criteria entered by the user on the command line.
/// If
a device cannot
be found that meets specified criteria,
/// If
no device can
be found that meets specified criteria,
/// then print an error message and return `null`.
/// then print an error message and return `null`.
Future
<
Device
>
findTargetDevice
()
async
{
Future
<
List
<
Device
>>
findAllTargetDevices
()
async
{
if
(!
doctor
.
canLaunchAnything
)
{
if
(!
doctor
.
canLaunchAnything
)
{
printError
(
"Unable to locate a development device; please run 'flutter doctor' "
printError
(
"Unable to locate a development device; please run 'flutter doctor' "
"for information about installing additional components."
);
"for information about installing additional components."
);
...
@@ -171,6 +171,9 @@ abstract class FlutterCommand extends Command<Null> {
...
@@ -171,6 +171,9 @@ abstract class FlutterCommand extends Command<Null> {
printStatus
(
"No devices found with name or id "
printStatus
(
"No devices found with name or id "
"matching '
${deviceManager.specifiedDeviceId}
'"
);
"matching '
${deviceManager.specifiedDeviceId}
'"
);
return
null
;
return
null
;
}
else
if
(
devices
.
isEmpty
&&
deviceManager
.
hasSpecifiedAllDevices
)
{
printStatus
(
"No devices found"
);
return
null
;
}
else
if
(
devices
.
isEmpty
)
{
}
else
if
(
devices
.
isEmpty
)
{
printNoConnectedDevices
();
printNoConnectedDevices
();
return
null
;
return
null
;
...
@@ -181,20 +184,39 @@ abstract class FlutterCommand extends Command<Null> {
...
@@ -181,20 +184,39 @@ abstract class FlutterCommand extends Command<Null> {
if
(
devices
.
isEmpty
)
{
if
(
devices
.
isEmpty
)
{
printStatus
(
'No supported devices connected.'
);
printStatus
(
'No supported devices connected.'
);
return
null
;
return
null
;
}
else
if
(
devices
.
length
>
1
)
{
}
else
if
(
devices
.
length
>
1
&&
!
deviceManager
.
hasSpecifiedAllDevices
)
{
if
(
deviceManager
.
hasSpecifiedDeviceId
)
{
if
(
deviceManager
.
hasSpecifiedDeviceId
)
{
printStatus
(
"Found
${devices.length}
devices with name or id matching "
printStatus
(
"Found
${devices.length}
devices with name or id matching "
"'
${deviceManager.specifiedDeviceId}
':"
);
"'
${deviceManager.specifiedDeviceId}
':"
);
}
else
{
}
else
{
printStatus
(
"More than one device connected; please specify a device with "
printStatus
(
"More than one device connected; please specify a device with "
"the '-d <deviceId>' flag."
);
"the '-d <deviceId>' flag
, or use '-d all' to act on all devices
."
);
devices
=
await
deviceManager
.
getAllConnectedDevices
().
toList
();
devices
=
await
deviceManager
.
getAllConnectedDevices
().
toList
();
}
}
printStatus
(
''
);
printStatus
(
''
);
await
Device
.
printDevices
(
devices
);
await
Device
.
printDevices
(
devices
);
return
null
;
return
null
;
}
}
return
devices
.
single
;
return
devices
;
}
/// Find and return the target [Device] based upon currently connected
/// devices and criteria entered by the user on the command line.
/// If a device cannot be found that meets specified criteria,
/// then print an error message and return `null`.
Future
<
Device
>
findTargetDevice
()
async
{
List
<
Device
>
deviceList
=
await
findAllTargetDevices
();
if
(
deviceList
==
null
)
return
null
;
if
(
deviceList
.
length
>
1
)
{
printStatus
(
"More than one device connected; please specify a device with "
"the '-d <deviceId>' flag."
);
deviceList
=
await
deviceManager
.
getAllConnectedDevices
().
toList
();
printStatus
(
''
);
await
Device
.
printDevices
(
deviceList
);
return
null
;
}
return
deviceList
.
single
;
}
}
void
printNoConnectedDevices
()
{
void
printNoConnectedDevices
()
{
...
...
packages/flutter_tools/test/src/context.dart
View file @
0770c3c1
...
@@ -127,12 +127,28 @@ class MockPortScanner extends PortScanner {
...
@@ -127,12 +127,28 @@ class MockPortScanner extends PortScanner {
class
MockDeviceManager
implements
DeviceManager
{
class
MockDeviceManager
implements
DeviceManager
{
List
<
Device
>
devices
=
<
Device
>[];
List
<
Device
>
devices
=
<
Device
>[];
String
_specifiedDeviceId
;
@override
String
get
specifiedDeviceId
{
if
(
_specifiedDeviceId
==
null
||
_specifiedDeviceId
==
'all'
)
return
null
;
return
_specifiedDeviceId
;
}
@override
@override
String
specifiedDeviceId
;
set
specifiedDeviceId
(
String
id
)
{
_specifiedDeviceId
=
id
;
}
@override
@override
bool
get
hasSpecifiedDeviceId
=>
specifiedDeviceId
!=
null
;
bool
get
hasSpecifiedDeviceId
=>
specifiedDeviceId
!=
null
;
@override
bool
get
hasSpecifiedAllDevices
{
return
_specifiedDeviceId
!=
null
&&
_specifiedDeviceId
==
'all'
;
}
@override
@override
Stream
<
Device
>
getAllConnectedDevices
()
=>
new
Stream
<
Device
>.
fromIterable
(
devices
);
Stream
<
Device
>
getAllConnectedDevices
()
=>
new
Stream
<
Device
>.
fromIterable
(
devices
);
...
...
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