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
2a113165
Unverified
Commit
2a113165
authored
Dec 05, 2019
by
Jonah Williams
Committed by
GitHub
Dec 05, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support --fast-start for Android applications (as an opt-in) (#45431)
parent
16570759
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
359 additions
and
37 deletions
+359
-37
test.dart
dev/bots/test.dart
+11
-0
gradle_fast_start_test.dart
dev/devicelab/bin/tasks/gradle_fast_start_test.dart
+42
-0
main.dart
examples/splash/lib/main.dart
+16
-0
pubspec.yaml
examples/splash/pubspec.yaml
+41
-0
splash_test.dart
examples/splash/test/splash_test.dart
+16
-0
flutter.gradle
packages/flutter_tools/gradle/flutter.gradle
+23
-3
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+4
-0
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+3
-0
build_info.dart
packages/flutter_tools/lib/src/build_info.dart
+4
-0
resident_web_runner.dart
...utter_tools/lib/src/build_runner/resident_web_runner.dart
+2
-2
android.dart
...s/flutter_tools/lib/src/build_system/targets/android.dart
+20
-4
assemble.dart
packages/flutter_tools/lib/src/commands/assemble.dart
+1
-0
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+3
-3
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+20
-0
device.dart
packages/flutter_tools/lib/src/device.dart
+7
-1
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+1
-1
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+41
-22
run_test.dart
.../flutter_tools/test/commands.shard/hermetic/run_test.dart
+68
-0
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+35
-0
test_driver.dart
...ges/flutter_tools/test/integration.shard/test_driver.dart
+1
-1
No files found.
dev/bots/test.dart
View file @
2a113165
...
...
@@ -273,6 +273,13 @@ Future<void> _runToolTests() async {
await
selectSubshard
(
subshards
);
}
// Example apps that should not be built by _runBuildTests`
const
List
<
String
>
_excludedExampleApplications
=
<
String
>[
// This application contains no platform code and cannot be built, except for
// as a part of a '--fast-start' Android application.
'splash'
,
];
/// Verifies that AOT, APK, and IPA (if on macOS) builds the examples apps
/// without crashing. It does not actually launch the apps. That happens later
/// in the devicelab. This is just a smoke-test. In particular, this will verify
...
...
@@ -284,6 +291,9 @@ Future<void> _runBuildTests() async {
if
(
fileEntity
is
!
Directory
)
{
continue
;
}
if
(
_excludedExampleApplications
.
any
(
fileEntity
.
path
.
endsWith
))
{
continue
;
}
final
String
examplePath
=
fileEntity
.
path
;
await
_flutterBuildAot
(
examplePath
);
await
_flutterBuildApk
(
examplePath
);
...
...
@@ -756,6 +766,7 @@ Future<void> _runHostOnlyDeviceLabTests() async {
if
(
Platform
.
isMacOS
)
()
=>
_runDevicelabTest
(
'flutter_create_offline_test_mac'
),
if
(
Platform
.
isLinux
)
()
=>
_runDevicelabTest
(
'flutter_create_offline_test_linux'
),
if
(
Platform
.
isWindows
)
()
=>
_runDevicelabTest
(
'flutter_create_offline_test_windows'
),
()
=>
_runDevicelabTest
(
'gradle_fast_start_test'
,
environment:
gradleEnvironment
),
// TODO(ianh): Fails on macOS looking for "dexdump", https://github.com/flutter/flutter/issues/42494
if
(!
Platform
.
isMacOS
)
()
=>
_runDevicelabTest
(
'gradle_jetifier_test'
,
environment:
gradleEnvironment
),
()
=>
_runDevicelabTest
(
'gradle_non_android_plugin_test'
,
environment:
gradleEnvironment
),
...
...
dev/devicelab/bin/tasks/gradle_fast_start_test.dart
0 → 100644
View file @
2a113165
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
Future
<
void
>
main
()
async
{
await
task
(()
async
{
try
{
await
runPluginProjectTest
((
FlutterPluginProject
pluginProject
)
async
{
section
(
'APK content for task assembleDebug with --fast-start'
);
await
pluginProject
.
runGradleTask
(
'assembleDebug'
,
options:
<
String
>[
'-Pfast-start=true'
]);
final
Iterable
<
String
>
apkFiles
=
await
getFilesInApk
(
pluginProject
.
debugApkPath
);
checkCollectionContains
<
String
>(<
String
>[
...
debugAssets
,
...
baseApkFiles
,
'lib/x86/libflutter.so'
,
'lib/x86_64/libflutter.so'
,
'lib/armeabi-v7a/libflutter.so'
,
'lib/arm64-v8a/libflutter.so'
,
],
apkFiles
);
checkCollectionDoesNotContain
<
String
>(<
String
>[
...
flutterAssets
,
],
apkFiles
);
});
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
return
taskResult
;
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
});
}
examples/splash/lib/main.dart
0 → 100644
View file @
2a113165
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
void
main
(
)
{
runApp
(
const
DecoratedBox
(
decoration:
BoxDecoration
(
color:
Colors
.
white
),
child:
Center
(
child:
FlutterLogo
(
size:
48
),
),
),
);
}
examples/splash/pubspec.yaml
0 → 100644
View file @
2a113165
name
:
splash
environment
:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk
:
"
>=2.0.0-dev.68.0
<3.0.0"
dependencies
:
flutter
:
sdk
:
flutter
collection
:
1.14.11
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta
:
1.1.8
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data
:
1.1.6
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math
:
2.0.8
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies
:
flutter_test
:
sdk
:
flutter
archive
:
2.0.11
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args
:
1.5.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async
:
2.4.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector
:
1.0.5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
charcode
:
1.1.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert
:
2.1.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto
:
2.1.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
image
:
2.1.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher
:
0.12.6
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path
:
1.6.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pedantic
:
1.8.0+1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
petitparser
:
2.4.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
quiver
:
2.0.5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span
:
1.5.5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stack_trace
:
1.9.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_channel
:
2.0.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner
:
1.0.5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph
:
1.1.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_api
:
0.2.11
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xml
:
3.5.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: f789
examples/splash/test/splash_test.dart
0 → 100644
View file @
2a113165
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:splash/main.dart'
as
entrypoint
;
void
main
(
)
{
testWidgets
(
'Displays flutter logo'
,
(
WidgetTester
tester
)
async
{
entrypoint
.
main
();
expect
(
find
.
byType
(
FlutterLogo
),
findsOneWidget
);
});
}
packages/flutter_tools/gradle/flutter.gradle
View file @
2a113165
...
...
@@ -472,6 +472,15 @@ class FlutterPlugin implements Plugin<Project> {
return
false
}
/// Whether to build the debug app in "fast-start" mode.
private
Boolean
isFastStart
()
{
if
(
project
.
hasProperty
(
"fast-start"
))
{
return
project
.
property
(
"fast-start"
).
toBoolean
()
}
return
false
}
private
static
Boolean
shouldShrinkResources
(
Project
project
)
{
if
(
project
.
hasProperty
(
"shrink"
))
{
return
project
.
property
(
"shrink"
).
toBoolean
()
...
...
@@ -610,6 +619,7 @@ class FlutterPlugin implements Plugin<Project> {
localEngineSrcPath
this
.
localEngineSrcPath
targetPath
target
verbose
isVerbose
()
fastStart
isFastStart
()
fileSystemRoots
fileSystemRootsValue
fileSystemScheme
fileSystemSchemeValue
trackWidgetCreation
trackWidgetCreationValue
...
...
@@ -729,6 +739,8 @@ abstract class BaseFlutterTask extends DefaultTask {
String
localEngine
String
localEngineSrcPath
@Input
Boolean
fastStart
@Input
String
targetPath
@Optional
Boolean
verbose
...
...
@@ -769,9 +781,13 @@ abstract class BaseFlutterTask extends DefaultTask {
// cache.
String
[]
ruleNames
;
if
(
buildMode
==
"debug"
)
{
ruleNames
=
[
"debug_android_application"
]
if
(
fastStart
)
{
ruleNames
=
[
"faststart_android_application"
]
}
else
{
ruleNames
=
[
"debug_android_application"
]
}
}
else
{
ruleNames
=
targetPlatformValues
.
collect
{
"android_aot_bundle_${buildMode}_$it"
}
ruleNames
=
targetPlatformValues
.
collect
{
"android_aot_bundle_${buildMode}_$it"
}
}
project
.
exec
{
executable
flutterExecutable
.
absolutePath
...
...
@@ -788,7 +804,11 @@ abstract class BaseFlutterTask extends DefaultTask {
args
"assemble"
args
"--depfile"
,
"${intermediateDir}/flutter_build.d"
args
"--output"
,
"${intermediateDir}"
args
"-dTargetFile=${targetPath}"
if
(!
fastStart
||
buildMode
!=
"debug"
)
{
args
"-dTargetFile=${targetPath}"
}
else
{
args
"-dTargetFile=${Paths.get(flutterRoot.absolutePath, "
examples
", "
splash
", "
lib
", "
main
.
dart
")}"
}
args
"-dTargetPlatform=android"
args
"-dBuildMode=${buildMode}"
if
(
extraFrontEndOptions
!=
null
)
{
...
...
packages/flutter_tools/lib/src/android/android_device.dart
View file @
2a113165
...
...
@@ -527,6 +527,7 @@ class AndroidDevice extends Device {
androidBuildInfo:
AndroidBuildInfo
(
debuggingOptions
.
buildInfo
,
targetArchs:
<
AndroidArch
>[
androidArch
],
fastStart:
debuggingOptions
.
fastStart
),
);
// Package has been built, so we can get the updated application ID and
...
...
@@ -643,6 +644,9 @@ class AndroidDevice extends Device {
@override
bool
get
supportsHotRestart
=>
true
;
@override
bool
get
supportsFastStart
=>
true
;
@override
Future
<
bool
>
stopApp
(
AndroidApk
app
)
{
final
List
<
String
>
command
=
adbCommandForDevice
(<
String
>[
'shell'
,
'am'
,
'force-stop'
,
app
.
id
]);
...
...
packages/flutter_tools/lib/src/android/gradle.dart
View file @
2a113165
...
...
@@ -331,6 +331,9 @@ Future<void> buildGradleApp({
// Don't use settings.gradle from the current project since it includes the plugins as subprojects.
command
.
add
(
'--settings-file=settings_aar.gradle'
);
}
if
(
androidBuildInfo
.
fastStart
)
{
command
.
add
(
'-Pfast-start=true'
);
}
command
.
add
(
assembleTask
);
GradleHandledError
detectedGradleError
;
...
...
packages/flutter_tools/lib/src/build_info.dart
View file @
2a113165
...
...
@@ -103,6 +103,7 @@ class AndroidBuildInfo {
],
this
.
splitPerAbi
=
false
,
this
.
shrink
=
false
,
this
.
fastStart
=
false
,
});
// The build info containing the mode and flavor.
...
...
@@ -120,6 +121,9 @@ class AndroidBuildInfo {
/// The target platforms for the build.
final
Iterable
<
AndroidArch
>
targetArchs
;
/// Whether to bootstrap an empty application.
final
bool
fastStart
;
}
/// A summary of the compilation strategy used for Dart.
...
...
packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
View file @
2a113165
...
...
@@ -423,7 +423,7 @@ class _ExperimentalResidentWebRunner extends ResidentWebRunner {
@override
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
AfterRestart
=
false
,
bool
pause
=
false
,
String
reason
,
bool
benchmarkMode
=
false
,
})
async
{
...
...
@@ -692,7 +692,7 @@ class _DwdsResidentWebRunner extends ResidentWebRunner {
@override
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
AfterRestart
=
false
,
bool
pause
=
false
,
String
reason
,
bool
benchmarkMode
=
false
,
})
async
{
...
...
packages/flutter_tools/lib/src/build_system/targets/android.dart
View file @
2a113165
...
...
@@ -31,10 +31,13 @@ abstract class AndroidAssetBundle extends Target {
List
<
Source
>
get
outputs
=>
const
<
Source
>[];
@override
List
<
String
>
get
depfiles
=>
const
<
String
>[
'flutter_assets.d'
,
List
<
String
>
get
depfiles
=>
<
String
>[
if
(
_copyAssets
)
'flutter_assets.d'
,
];
bool
get
_copyAssets
=>
true
;
@override
Future
<
void
>
build
(
Environment
environment
)
async
{
if
(
environment
.
defines
[
kBuildMode
]
==
null
)
{
...
...
@@ -56,8 +59,10 @@ abstract class AndroidAssetBundle extends Target {
fs
.
file
(
isolateSnapshotData
)
.
copySync
(
outputDirectory
.
childFile
(
'isolate_snapshot_data'
).
path
);
}
final
Depfile
assetDepfile
=
await
copyAssets
(
environment
,
outputDirectory
);
assetDepfile
.
writeToFile
(
environment
.
buildDir
.
childFile
(
'flutter_assets.d'
));
if
(
_copyAssets
)
{
final
Depfile
assetDepfile
=
await
copyAssets
(
environment
,
outputDirectory
);
assetDepfile
.
writeToFile
(
environment
.
buildDir
.
childFile
(
'flutter_assets.d'
));
}
}
@override
...
...
@@ -90,6 +95,17 @@ class DebugAndroidApplication extends AndroidAssetBundle {
];
}
/// A minimal android application that does not include assets.
class
FastStartAndroidApplication
extends
DebugAndroidApplication
{
const
FastStartAndroidApplication
();
@override
String
get
name
=>
'faststart_android_application'
;
@override
bool
get
_copyAssets
=>
false
;
}
/// An implementation of [AndroidAssetBundle] that only includes assets.
class
AotAndroidAssetBundle
extends
AndroidAssetBundle
{
const
AotAndroidAssetBundle
();
...
...
packages/flutter_tools/lib/src/commands/assemble.dart
View file @
2a113165
...
...
@@ -37,6 +37,7 @@ const List<Target> _kDefaultTargets = <Target>[
DebugBundleLinuxAssets
(),
WebReleaseBundle
(),
DebugAndroidApplication
(),
FastStartAndroidApplication
(),
ProfileAndroidApplication
(),
ReleaseAndroidApplication
(),
// These are one-off rules for bundle and aot compat
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
2a113165
...
...
@@ -577,7 +577,7 @@ class AppDomain extends Domain {
}
_inProgressHotReload
=
app
.
_runInZone
<
OperationResult
>(
this
,
()
{
return
app
.
restart
(
fullRestart:
fullRestart
,
pause
AfterRestart
:
pauseAfterRestart
,
reason:
restartReason
);
return
app
.
restart
(
fullRestart:
fullRestart
,
pause:
pauseAfterRestart
,
reason:
restartReason
);
});
return
_inProgressHotReload
.
whenComplete
(()
{
_inProgressHotReload
=
null
;
...
...
@@ -922,8 +922,8 @@ class AppInstance {
_AppRunLogger
_logger
;
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
AfterRestart
=
false
,
String
reason
})
{
return
runner
.
restart
(
fullRestart:
fullRestart
,
pause
AfterRestart:
pauseAfterRestart
,
reason:
reason
);
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
=
false
,
String
reason
})
{
return
runner
.
restart
(
fullRestart:
fullRestart
,
pause
:
pause
,
reason:
reason
);
}
Future
<
void
>
stop
()
=>
runner
.
exit
();
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
2a113165
...
...
@@ -187,6 +187,14 @@ class RunCommand extends RunCommandBase {
hide:
true
,
help:
'Whether to automatically invoke webOnlyInitializePlatform.'
,
)
..
addFlag
(
'fast-start'
,
negatable:
true
,
defaultsTo:
false
,
hide:
true
,
help:
'Whether to quickly bootstrap applications with a minimal app. '
'Currently this is only supported on Android devices. This option '
'cannot be paired with --use-application-binary.'
)
..
addOption
(
FlutterOptions
.
kExtraFrontEndOptions
,
hide:
true
)
..
addOption
(
FlutterOptions
.
kExtraGenSnapshotOptions
,
hide:
true
)
..
addMultiOption
(
FlutterOptions
.
kEnableExperiment
,
...
...
@@ -284,6 +292,9 @@ class RunCommand extends RunCommandBase {
if
(!
runningWithPrebuiltApplication
)
{
await
super
.
validateCommand
();
}
if
(
boolArg
(
'fast-start'
)
&&
runningWithPrebuiltApplication
)
{
throwToolExit
(
'--fast-start is not supported with --use-application-binary'
);
}
if
(
deviceManager
.
hasSpecifiedAllDevices
&&
runningWithPrebuiltApplication
)
{
throwToolExit
(
'Using -d all with --use-application-binary is not supported'
);
}
...
...
@@ -318,6 +329,9 @@ class RunCommand extends RunCommandBase {
hostname:
featureFlags
.
isWebEnabled
?
stringArg
(
'web-hostname'
)
:
''
,
port:
featureFlags
.
isWebEnabled
?
stringArg
(
'web-port'
)
:
''
,
vmserviceOutFile:
stringArg
(
'vmservice-out-file'
),
// Allow forcing fast-start to off to prevent doing more work on devices that
// don't support it.
fastStart:
boolArg
(
'fast-start'
)
&&
devices
.
every
((
Device
device
)
=>
device
.
supportsFastStart
),
);
}
}
...
...
@@ -385,6 +399,12 @@ class RunCommand extends RunCommandBase {
}
for
(
Device
device
in
devices
)
{
if
(!
device
.
supportsFastStart
&&
boolArg
(
'fast-start'
))
{
printStatus
(
'Using --fast-start option with device
${device.name}
, but this device '
'does not support it. Overriding the setting to false.'
);
}
if
(
await
device
.
isLocalEmulator
)
{
if
(
await
device
.
supportsHardwareRendering
)
{
final
bool
enableSoftwareRendering
=
boolArg
(
'enable-software-rendering'
)
==
true
;
...
...
packages/flutter_tools/lib/src/device.dart
View file @
2a113165
...
...
@@ -420,6 +420,9 @@ abstract class Device {
/// application.
bool
get
supportsScreenshot
=>
false
;
/// Whether the device supports the '--fast-start' development mode.
bool
get
supportsFastStart
=>
false
;
/// Stop an app package on the current device.
Future
<
bool
>
stopApp
(
covariant
ApplicationPackage
app
);
...
...
@@ -534,6 +537,7 @@ class DebuggingOptions {
this
.
hostname
,
this
.
port
,
this
.
vmserviceOutFile
,
this
.
fastStart
=
false
,
})
:
debuggingEnabled
=
true
;
DebuggingOptions
.
disabled
(
this
.
buildInfo
,
{
this
.
initializePlatform
=
true
,
this
.
port
,
this
.
hostname
,
this
.
cacheSkSL
=
false
,
})
...
...
@@ -550,7 +554,8 @@ class DebuggingOptions {
verboseSystemLogs
=
false
,
hostVmServicePort
=
null
,
deviceVmServicePort
=
null
,
vmserviceOutFile
=
null
;
vmserviceOutFile
=
null
,
fastStart
=
false
;
final
bool
debuggingEnabled
;
...
...
@@ -574,6 +579,7 @@ class DebuggingOptions {
final
String
hostname
;
/// A file where the vmservice URL should be written after the application is started.
final
String
vmserviceOutFile
;
final
bool
fastStart
;
bool
get
hasObservatoryPort
=>
hostVmServicePort
!=
null
;
}
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
2a113165
...
...
@@ -712,7 +712,7 @@ abstract class ResidentRunner {
bool
get
supportsRestart
=>
false
;
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
AfterRestart
=
false
,
String
reason
})
{
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pause
=
false
,
String
reason
})
{
final
String
mode
=
isRunningProfile
?
'profile'
:
isRunningRelease
?
'release'
:
'this'
;
throw
'
${fullRestart ? 'Restart' : 'Reload'}
is not supported in
$mode
mode'
;
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
2a113165
...
...
@@ -103,7 +103,7 @@ class HotRunner extends ResidentRunner {
bool
pause
=
false
,
})
async
{
// TODO(cbernaschina): check that isolateId is the id of the UI isolate.
final
OperationResult
result
=
await
restart
(
pause
AfterRestart
:
pause
);
final
OperationResult
result
=
await
restart
(
pause:
pause
);
if
(!
result
.
isOk
)
{
throw
rpc
.
RpcException
(
rpc_error_code
.
INTERNAL_ERROR
,
...
...
@@ -114,7 +114,7 @@ class HotRunner extends ResidentRunner {
Future
<
void
>
_restartService
({
bool
pause
=
false
})
async
{
final
OperationResult
result
=
await
restart
(
fullRestart:
true
,
pause
AfterRestart
:
pause
);
await
restart
(
fullRestart:
true
,
pause:
pause
);
if
(!
result
.
isOk
)
{
throw
rpc
.
RpcException
(
rpc_error_code
.
INTERNAL_ERROR
,
...
...
@@ -211,6 +211,15 @@ class HotRunner extends ResidentRunner {
}
}
if
(
debuggingOptions
.
fastStart
)
{
await
restart
(
fullRestart:
true
,
benchmarkMode:
!
debuggingOptions
.
startPaused
,
reason:
'restart'
,
silent:
true
,
);
}
appStartedCompleter
?.
complete
();
if
(
benchmarkMode
)
{
...
...
@@ -356,12 +365,10 @@ class HotRunner extends ResidentRunner {
Uri
packagesUri
,
Uri
assetsDirectoryUri
,
)
{
final
List
<
Future
<
void
>>
futures
=
<
Future
<
void
>>[
for
(
FlutterView
view
in
device
.
views
)
view
.
runFromSource
(
entryUri
,
packagesUri
,
assetsDirectoryUri
),
];
final
Completer
<
void
>
completer
=
Completer
<
void
>();
Future
.
wait
(
futures
).
whenComplete
(()
{
completer
.
complete
(
null
);
});
return
completer
.
future
;
return
Future
.
wait
(<
Future
<
void
>>[
for
(
FlutterView
view
in
device
.
views
)
view
.
runFromSource
(
entryUri
,
packagesUri
,
assetsDirectoryUri
),
]);
}
Future
<
void
>
_launchFromDevFS
(
String
mainScript
)
async
{
...
...
@@ -458,9 +465,11 @@ class HotRunner extends ResidentRunner {
for
(
FlutterDevice
device
in
flutterDevices
)
{
for
(
FlutterView
view
in
device
.
views
)
{
isolateNotifications
.
add
(
view
.
owner
.
vm
.
vmService
.
onIsolateEvent
.
then
((
Stream
<
ServiceEvent
>
serviceEvents
)
async
{
view
.
owner
.
vm
.
vmService
.
onIsolateEvent
.
then
((
Stream
<
ServiceEvent
>
serviceEvents
)
async
{
await
for
(
ServiceEvent
serviceEvent
in
serviceEvents
)
{
if
(
serviceEvent
.
owner
.
name
.
contains
(
'_spawn'
)
&&
serviceEvent
.
kind
==
ServiceEvent
.
kIsolateExit
)
{
if
(
serviceEvent
.
owner
.
name
.
contains
(
'_spawn'
)
&&
serviceEvent
.
kind
==
ServiceEvent
.
kIsolateExit
)
{
return
;
}
}
...
...
@@ -521,9 +530,10 @@ class HotRunner extends ResidentRunner {
@override
Future
<
OperationResult
>
restart
({
bool
fullRestart
=
false
,
bool
pauseAfterRestart
=
false
,
String
reason
,
bool
benchmarkMode
=
false
,
bool
silent
=
false
,
bool
pause
=
false
,
})
async
{
String
targetPlatform
;
String
sdkName
;
...
...
@@ -550,8 +560,11 @@ class HotRunner extends ResidentRunner {
emulator:
emulator
,
reason:
reason
,
benchmarkMode:
benchmarkMode
,
silent:
silent
,
);
printStatus
(
'Restarted application in
${getElapsedAsMilliseconds(timer.elapsed)}
.'
);
if
(!
silent
)
{
printStatus
(
'Restarted application in
${getElapsedAsMilliseconds(timer.elapsed)}
.'
);
}
return
result
;
}
final
OperationResult
result
=
await
_hotReloadHelper
(
...
...
@@ -559,11 +572,13 @@ class HotRunner extends ResidentRunner {
sdkName:
sdkName
,
emulator:
emulator
,
reason:
reason
,
pause
AfterRestart:
pauseAfterRestart
,
pause
:
pause
,
);
if
(
result
.
isOk
)
{
final
String
elapsed
=
getElapsedAsMilliseconds
(
timer
.
elapsed
);
printStatus
(
'
${result.message}
in
$elapsed
.'
);
if
(!
silent
)
{
printStatus
(
'
${result.message}
in
$elapsed
.'
);
}
}
return
result
;
}
...
...
@@ -574,15 +589,19 @@ class HotRunner extends ResidentRunner {
bool
emulator
,
String
reason
,
bool
benchmarkMode
,
bool
silent
,
})
async
{
if
(!
canHotRestart
)
{
return
OperationResult
(
1
,
'hotRestart not supported'
);
}
final
Status
status
=
logger
.
startProgress
(
'Performing hot restart...'
,
timeout:
timeoutConfiguration
.
fastOperation
,
progressId:
'hot.restart'
,
);
Status
status
;
if
(!
silent
)
{
status
=
logger
.
startProgress
(
'Performing hot restart...'
,
timeout:
timeoutConfiguration
.
fastOperation
,
progressId:
'hot.restart'
,
);
}
OperationResult
result
;
String
restartEvent
=
'restart'
;
try
{
...
...
@@ -610,7 +629,7 @@ class HotRunner extends ResidentRunner {
emulator:
emulator
,
fullRestart:
true
,
reason:
reason
).
send
();
status
.
cancel
();
status
?
.
cancel
();
}
return
result
;
}
...
...
@@ -620,7 +639,7 @@ class HotRunner extends ResidentRunner {
String
sdkName
,
bool
emulator
,
String
reason
,
bool
pause
AfterRestart
=
false
,
bool
pause
,
})
async
{
final
bool
reloadOnTopOfSnapshot
=
_runningFromSnapshot
;
final
String
progressPrefix
=
reloadOnTopOfSnapshot
?
'Initializing'
:
'Performing'
;
...
...
@@ -635,8 +654,8 @@ class HotRunner extends ResidentRunner {
targetPlatform:
targetPlatform
,
sdkName:
sdkName
,
emulator:
emulator
,
pause:
pauseAfterRestart
,
reason:
reason
,
pause:
pause
,
onSlow:
(
String
message
)
{
status
?.
cancel
();
status
=
logger
.
startProgress
(
...
...
packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
View file @
2a113165
...
...
@@ -10,11 +10,14 @@ import 'package:args/command_runner.dart';
import
'package:flutter_tools/src/application_package.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/context.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/run.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/features.dart'
;
import
'package:flutter_tools/src/globals.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:flutter_tools/src/resident_runner.dart'
;
import
'package:flutter_tools/src/runner/flutter_command.dart'
;
...
...
@@ -53,6 +56,71 @@ void main() {
}
});
testUsingContext
(
'does not support "--use-application-binary" and "--fast-start"'
,
()
async
{
fs
.
file
(
fs
.
path
.
join
(
'lib'
,
'main.dart'
)).
createSync
(
recursive:
true
);
fs
.
file
(
'pubspec.yaml'
).
createSync
();
fs
.
file
(
'.packages'
).
createSync
();
final
RunCommand
command
=
RunCommand
();
applyMocksToCommand
(
command
);
try
{
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'run'
,
'--use-application-binary=app/bar/faz'
,
'--fast-start'
,
'--no-pub'
,
'--show-test-device'
,
]);
fail
(
'Expect exception'
);
}
catch
(
e
)
{
expect
(
e
.
toString
(),
contains
(
'--fast-start is not supported with --use-application-binary'
));
}
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
MemoryFileSystem
(),
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
});
testUsingContext
(
'Forces fast start off for devices that do not support it'
,
()
async
{
final
MockDevice
mockDevice
=
MockDevice
(
TargetPlatform
.
android_arm
);
when
(
mockDevice
.
name
).
thenReturn
(
'mockdevice'
);
when
(
mockDevice
.
supportsFastStart
).
thenReturn
(
false
);
when
(
mockDevice
.
supportsHotReload
).
thenReturn
(
true
);
when
(
mockDevice
.
isLocalEmulator
).
thenAnswer
((
Invocation
invocation
)
async
=>
false
);
when
(
deviceManager
.
hasSpecifiedAllDevices
).
thenReturn
(
false
);
when
(
deviceManager
.
findTargetDevices
(
any
)).
thenAnswer
((
Invocation
invocation
)
{
return
Future
<
List
<
Device
>>.
value
(<
Device
>[
mockDevice
]);
});
when
(
deviceManager
.
getDevices
()).
thenAnswer
((
Invocation
invocation
)
{
return
Stream
<
Device
>.
value
(
mockDevice
);
});
fs
.
file
(
fs
.
path
.
join
(
'lib'
,
'main.dart'
)).
createSync
(
recursive:
true
);
fs
.
file
(
'pubspec.yaml'
).
createSync
();
fs
.
file
(
'.packages'
).
createSync
();
final
RunCommand
command
=
RunCommand
();
applyMocksToCommand
(
command
);
try
{
await
createTestCommandRunner
(
command
).
run
(<
String
>[
'run'
,
'--fast-start'
,
'--no-pub'
,
]);
fail
(
'Expect exception'
);
}
catch
(
e
)
{
expect
(
e
,
isInstanceOf
<
ToolExit
>());
}
final
BufferLogger
bufferLogger
=
logger
as
BufferLogger
;
expect
(
bufferLogger
.
statusText
,
contains
(
'Using --fast-start option with device mockdevice, but this device '
'does not support it. Overriding the setting to false.'
));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
MemoryFileSystem
(),
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
DeviceManager:
()
=>
MockDeviceManager
(),
});
group
(
'cache'
,
()
{
MemoryFileSystem
fs
;
MockCache
mockCache
;
...
...
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
2a113165
...
...
@@ -154,6 +154,41 @@ void main() {
expect
(
onAppStart
.
isCompleted
,
true
);
}));
test
(
'ResidentRunner can attach to device successfully with --fast-start'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockDevice
.
supportsHotRestart
).
thenReturn
(
true
);
when
(
mockDevice
.
sdkNameAndVersion
).
thenAnswer
((
Invocation
invocation
)
async
{
return
'Example'
;
});
when
(
mockDevice
.
targetPlatform
).
thenAnswer
((
Invocation
invocation
)
async
{
return
TargetPlatform
.
android_arm
;
});
when
(
mockDevice
.
isLocalEmulator
).
thenAnswer
((
Invocation
invocation
)
async
{
return
false
;
});
residentRunner
=
HotRunner
(
<
FlutterDevice
>[
mockFlutterDevice
,
],
stayResident:
false
,
debuggingOptions:
DebuggingOptions
.
enabled
(
BuildInfo
.
debug
,
fastStart:
true
,
startPaused:
true
),
);
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
;
expect
(
await
result
,
0
);
verify
(
mockFlutterDevice
.
initLogReader
()).
called
(
1
);
expect
(
onConnectionInfo
.
isCompleted
,
true
);
expect
((
await
connectionInfo
).
baseUri
,
'foo://bar'
);
expect
(
onAppStart
.
isCompleted
,
true
);
}));
test
(
'ResidentRunner can handle an RPC exception from hot reload'
,
()
=>
testbed
.
run
(()
async
{
when
(
mockDevice
.
sdkNameAndVersion
).
thenAnswer
((
Invocation
invocation
)
async
{
return
'Example'
;
...
...
packages/flutter_tools/test/integration.shard/test_driver.dart
View file @
2a113165
...
...
@@ -497,7 +497,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
// fast.
unawaited
(
_process
.
exitCode
.
then
((
_
)
{
if
(!
prematureExitGuard
.
isCompleted
)
{
prematureExitGuard
.
completeError
(
'Process existed prematurely:
${args.join(' ')}
'
);
prematureExitGuard
.
completeError
(
'Process existed prematurely:
${args.join(' ')}
:
$_errorBuffer
'
);
}
}));
...
...
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