Commit f29dd4f9 authored by Devon Carew's avatar Devon Carew Committed by GitHub

improve progress display when running apps; speed up startup (#9475)

* improve progress display when running apps; speed up startup

* review comments
parent 35803c22
......@@ -222,7 +222,7 @@ class AndroidDevice extends Device {
}
@override
bool installApp(ApplicationPackage app) {
Future<bool> installApp(ApplicationPackage app) async {
final AndroidApk apk = app;
if (!fs.isFileSync(apk.apkPath)) {
printError('"${apk.apkPath}" does not exist.');
......@@ -233,16 +233,18 @@ class AndroidDevice extends Device {
return false;
final Status status = logger.startProgress('Installing ${apk.apkPath}...', expectSlowOperation: true);
final String installOut = runCheckedSync(adbCommandForDevice(<String>['install', '-r', apk.apkPath]));
final RunResult installResult = await runCheckedAsync(adbCommandForDevice(<String>['install', '-r', apk.apkPath]));
status.stop();
final RegExp failureExp = new RegExp(r'^Failure.*$', multiLine: true);
final String failure = failureExp.stringMatch(installOut);
final String failure = failureExp.stringMatch(installResult.stdout);
if (failure != null) {
printError('Package install error: $failure');
return false;
}
runCheckedSync(adbCommandForDevice(<String>['shell', 'echo', '-n', _getSourceSha1(app), '>', _getDeviceSha1Path(app)]));
await runCheckedAsync(adbCommandForDevice(<String>[
'shell', 'echo', '-n', _getSourceSha1(app), '>', _getDeviceSha1Path(app)
]));
return true;
}
......@@ -262,7 +264,7 @@ class AndroidDevice extends Device {
return true;
}
bool _installLatestApp(ApplicationPackage package) {
Future<bool> _installLatestApp(ApplicationPackage package) async {
final bool wasInstalled = isAppInstalled(package);
if (wasInstalled) {
if (isLatestBuildInstalled(package)) {
......@@ -271,7 +273,7 @@ class AndroidDevice extends Device {
}
}
printTrace('Installing APK.');
if (!installApp(package)) {
if (!await installApp(package)) {
printTrace('Warning: Failed to install APK.');
if (wasInstalled) {
printStatus('Uninstalling old version...');
......@@ -279,7 +281,7 @@ class AndroidDevice extends Device {
printError('Error: Uninstalling old version failed.');
return false;
}
if (!installApp(package)) {
if (!await installApp(package)) {
printError('Error: Failed to install APK again.');
return false;
}
......@@ -325,7 +327,7 @@ class AndroidDevice extends Device {
printTrace("Stopping app '${package.name}' on $name.");
await stopApp(package);
if (!_installLatestApp(package))
if (!await _installLatestApp(package))
return new LaunchResult.failed();
final bool traceStartup = platformArgs['trace-startup'] ?? false;
......
......@@ -23,6 +23,8 @@ const String gradleManifestPath = 'android/app/src/main/AndroidManifest.xml';
const String gradleAppOutV1 = 'android/app/build/outputs/apk/app-debug.apk';
const String gradleAppOutDirV1 = 'android/app/build/outputs/apk';
String _cachedGradleAppOutDirV2;
enum FlutterPluginVersion {
none,
v1,
......@@ -54,7 +56,7 @@ FlutterPluginVersion get flutterPluginVersion {
return FlutterPluginVersion.none;
}
String get gradleAppOut {
String getGradleAppOut() {
switch (flutterPluginVersion) {
case FlutterPluginVersion.none:
// Fall through. Pretend we're v1, and just go with it.
......@@ -63,12 +65,18 @@ String get gradleAppOut {
case FlutterPluginVersion.managed:
// Fall through. The managed plugin matches plugin v2 for now.
case FlutterPluginVersion.v2:
return '$gradleAppOutDirV2/app.apk';
return '${getGradleAppOutDirV2()}/app.apk';
}
return null;
}
String get gradleAppOutDirV2 {
String getGradleAppOutDirV2() {
_cachedGradleAppOutDirV2 ??= _calculateGradleAppOutDirV2();
return _cachedGradleAppOutDirV2;
}
// Note: this call takes about a second to complete.
String _calculateGradleAppOutDirV2() {
final String gradle = ensureGradle();
ensureLocalProperties();
try {
......@@ -224,7 +232,7 @@ Future<Null> buildGradleProjectV2(String gradle, String buildModeName, String ta
if (exitcode != 0)
throwToolExit('Gradle build failed: $exitcode', exitCode: exitcode);
final String buildDirectory = gradleAppOutDirV2;
final String buildDirectory = getGradleAppOutDirV2();
final String apkFilename = 'app-$buildModeName.apk';
final File apkFile = fs.file('$buildDirectory/$apkFilename');
// Copy the APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
......
......@@ -83,16 +83,16 @@ class AndroidApk extends ApplicationPackage {
String apkPath;
if (isProjectUsingGradle()) {
if (fs.file(gradleAppOut).existsSync()) {
if (fs.file(getGradleAppOut()).existsSync()) {
// Grab information from the .apk. The gradle build script might alter
// the application Id, so we need to look at what was actually built.
return new AndroidApk.fromApk(gradleAppOut);
return new AndroidApk.fromApk(getGradleAppOut());
}
// The .apk hasn't been built yet, so we work with what we have. The run
// command will grab a new AndroidApk after building, to get the updated
// IDs.
manifestPath = gradleManifestPath;
apkPath = gradleAppOut;
apkPath = getGradleAppOut();
} else {
manifestPath = fs.path.join('android', 'AndroidManifest.xml');
apkPath = fs.path.join(getAndroidBuildDirectory(), 'app.apk');
......
......@@ -37,12 +37,12 @@ class InstallCommand extends FlutterCommand {
printStatus('Installing $package to $device...');
if (!installApp(device, package))
if (!await installApp(device, package))
throwToolExit('Install failed');
}
}
bool installApp(Device device, ApplicationPackage package, { bool uninstall: true }) {
Future<bool> installApp(Device device, ApplicationPackage package, { bool uninstall: true }) async {
if (package == null)
return false;
......
......@@ -150,7 +150,7 @@ abstract class Device {
bool isLatestBuildInstalled(ApplicationPackage app);
/// Install an app package on the current device
bool installApp(ApplicationPackage app);
Future<bool> installApp(ApplicationPackage app);
/// Uninstall an app package from the current device
bool uninstallApp(ApplicationPackage app);
......
......@@ -49,7 +49,7 @@ class FuchsiaDevice extends Device {
bool isLatestBuildInstalled(ApplicationPackage app) => false;
@override
bool installApp(ApplicationPackage app) => false;
Future<bool> installApp(ApplicationPackage app) => new Future<bool>.value(false);
@override
bool uninstallApp(ApplicationPackage app) => false;
......
......@@ -155,7 +155,7 @@ class IOSDevice extends Device {
bool isLatestBuildInstalled(ApplicationPackage app) => false;
@override
bool installApp(ApplicationPackage app) {
Future<bool> installApp(ApplicationPackage app) async {
final IOSApp iosApp = app;
final Directory bundle = fs.directory(iosApp.deviceBundlePath);
if (!bundle.existsSync()) {
......@@ -197,8 +197,7 @@ class IOSDevice extends Device {
bool applicationNeedsRebuild: false,
}) async {
if (!prebuiltApplication) {
// TODO(chinmaygarde): Use checked, mainPath, route.
// TODO(devoncarew): Handle startPaused, debugPort.
// TODO(chinmaygarde): Use mainPath, route.
printTrace('Building ${app.name} for $id');
// Step 1: Build the precompiled/DBC application if necessary.
......@@ -210,7 +209,7 @@ class IOSDevice extends Device {
return new LaunchResult.failed();
}
} else {
if (!installApp(app))
if (!await installApp(app))
return new LaunchResult.failed();
}
......
......@@ -343,7 +343,7 @@ class IOSSimulator extends Device {
bool isLatestBuildInstalled(ApplicationPackage app) => false;
@override
bool installApp(ApplicationPackage app) {
Future<bool> installApp(ApplicationPackage app) async {
try {
final IOSApp iosApp = app;
SimControl.instance.install(id, iosApp.simulatorBundlePath);
......@@ -435,7 +435,7 @@ class IOSSimulator extends Device {
return new LaunchResult.failed();
}
} else {
if (!installApp(app))
if (!await installApp(app))
return new LaunchResult.failed();
}
......
......@@ -53,6 +53,14 @@ class ColdRunner extends ResidentRunner {
}
}
final String modeName = getModeName(debuggingOptions.buildMode);
if (mainPath == null) {
assert(prebuiltMode);
printStatus('Launching ${package.displayName} on ${device.name} in $modeName mode...');
} else {
printStatus('Launching ${getDisplayPath(mainPath)} on ${device.name} in $modeName mode...');
}
package = getApplicationPackageForPlatform(device.targetPlatform, applicationBinary: applicationBinary);
if (package == null) {
......@@ -72,14 +80,6 @@ class ColdRunner extends ResidentRunner {
await startEchoingDeviceLog(package);
final String modeName = getModeName(debuggingOptions.buildMode);
if (mainPath == null) {
assert(prebuiltMode);
printStatus('Launching ${package.displayName} on ${device.name} in $modeName mode...');
} else {
printStatus('Launching ${getDisplayPath(mainPath)} on ${device.name} in $modeName mode...');
}
_result = await device.startApp(
package,
debuggingOptions.buildMode,
......
......@@ -174,6 +174,9 @@ class HotRunner extends ResidentRunner {
return 1;
}
final String modeName = getModeName(debuggingOptions.buildMode);
printStatus('Launching ${getDisplayPath(mainPath)} on ${device.name} in $modeName mode...');
package = getApplicationPackageForPlatform(device.targetPlatform, applicationBinary: applicationBinary);
if (package == null) {
......@@ -195,9 +198,6 @@ class HotRunner extends ResidentRunner {
await startEchoingDeviceLog(package);
final String modeName = getModeName(debuggingOptions.buildMode);
printStatus('Launching ${getDisplayPath(mainPath)} on ${device.name} in $modeName mode...');
// Start the application.
final Future<LaunchResult> futureResult = device.startApp(
package,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment