Skip to content

Commit

Permalink
Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmanuel Garcia committed Oct 31, 2019
1 parent a1584cc commit f67a150
Show file tree
Hide file tree
Showing 12 changed files with 471 additions and 315 deletions.
46 changes: 15 additions & 31 deletions packages/flutter_tools/lib/src/android/android_builder.dart
Expand Up @@ -15,10 +15,14 @@ import 'android_sdk.dart';
import 'gradle.dart';

/// The builder in the current context.
AndroidBuilder get androidBuilder => context.get<AndroidBuilder>() ?? _AndroidBuilderImpl();
AndroidBuilder get androidBuilder {
return context.get<AndroidBuilder>() ?? const _AndroidBuilderImpl();
}

/// Provides the methods to build Android artifacts.
// TODO(egarciad): https://github.com/flutter/flutter/issues/43863
abstract class AndroidBuilder {
const AndroidBuilder();
/// Builds an AAR artifact.
Future<void> buildAar({
@required FlutterProject project,
Expand All @@ -44,7 +48,7 @@ abstract class AndroidBuilder {

/// Default implementation of [AarBuilder].
class _AndroidBuilderImpl extends AndroidBuilder {
_AndroidBuilderImpl();
const _AndroidBuilderImpl();

/// Builds the AAR and POM files for the current Flutter module or plugin.
@override
Expand All @@ -55,11 +59,17 @@ class _AndroidBuilderImpl extends AndroidBuilder {
@required String outputDir,
}) async {
try {
Directory outputDirectory =
fs.directory(outputDir ?? project.android.buildDirectory);
if (project.isModule) {
// Module projects artifacts are located in `build/host`.
outputDirectory = outputDirectory.childDirectory('host');
}
await buildGradleAar(
project: project,
androidBuildInfo: androidBuildInfo,
target: target,
outputDir: fs.directory(outputDir ?? project.android.buildDirectory),
outputDir: outputDirectory,
);
} finally {
androidSdk.reinitialize();
Expand All @@ -79,7 +89,7 @@ class _AndroidBuilderImpl extends AndroidBuilder {
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: false,
gradleErrors: gradleErrors,
localGradleErrors: gradleErrors,
);
} finally {
androidSdk.reinitialize();
Expand All @@ -99,36 +109,10 @@ class _AndroidBuilderImpl extends AndroidBuilder {
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: true,
gradleErrors: gradleErrors,
localGradleErrors: gradleErrors,
);
} finally {
androidSdk.reinitialize();
}
}
}

/// A fake implementation of [AndroidBuilder].
@visibleForTesting
class FakeAndroidBuilder implements AndroidBuilder {
@override
Future<void> buildAar({
@required FlutterProject project,
@required AndroidBuildInfo androidBuildInfo,
@required String target,
@required String outputDir,
}) async {}

@override
Future<void> buildApk({
@required FlutterProject project,
@required AndroidBuildInfo androidBuildInfo,
@required String target,
}) async {}

@override
Future<void> buildAab({
@required FlutterProject project,
@required AndroidBuildInfo androidBuildInfo,
@required String target,
}) async {}
}
134 changes: 75 additions & 59 deletions packages/flutter_tools/lib/src/android/gradle.dart
Expand Up @@ -147,7 +147,7 @@ Future<void> checkGradleDependencies() async {
],
throwOnError: true,
workingDirectory: flutterProject.android.hostAppGradleRoot.path,
environment: gradleEnv,
environment: gradleEnvironment,
);
androidSdk.reinitialize();
progress.stop();
Expand Down Expand Up @@ -191,12 +191,10 @@ void createSettingsAarGradle(Directory androidDirectory) {
}
if (!exactMatch) {
status.cancel();
printError('*******************************************************************************************');
printError('Flutter tried to create the file `$newSettingsRelativeFile`, but failed.');
printStatus('$warningMark Flutter tried to create the file `$newSettingsRelativeFile`, but failed.');
// Print how to manually update the file.
printError(fs.file(fs.path.join(flutterRoot, 'packages','flutter_tools',
printStatus(fs.file(fs.path.join(flutterRoot, 'packages','flutter_tools',
'gradle', 'manual_migration_settings.gradle.md')).readAsStringSync());
printError('*******************************************************************************************');
throwToolExit('Please create the file and run this command again.');
}
// Copy the new file.
Expand All @@ -215,13 +213,13 @@ void createSettingsAarGradle(Directory androidDirectory) {
/// * The plugins are built as AARs if [shouldBuildPluginAsAar] is `true`. This isn't set by default
/// because it makes the build slower proportional to the number of plugins.
/// * [retries] is the max number of build retries in case one of the [GradleHandledError] handler
/// returns [GradleBuildStatus.RETRY] or [GradleBuildStatus.RETRY_WITH_AAR_PLUGINS].
/// returns [GradleBuildStatus.retry] or [GradleBuildStatus.retryWithAarPlugins].
Future<void> buildGradleApp({
@required FlutterProject project,
@required AndroidBuildInfo androidBuildInfo,
@required String target,
@required bool isBuildingBundle,
@required List<GradleHandledError> gradleErrors,
@required List<GradleHandledError> localGradleErrors,
bool shouldBuildPluginAsAar = false,
int retries = 1,
}) async {
Expand Down Expand Up @@ -333,20 +331,24 @@ Future<void> buildGradleApp({
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: gradleEnv,
environment: gradleEnvironment,
mapFunction: (String line) {
// This message was removed from 1P plugins,
// This message was removed from first-party plugins,
// but older plugin versions still display this message.
if (androidXPluginWarningRegex.hasMatch(line)) {
// Don't pipe.
return null;
}
if (detectedGradleError == null) {
for (final GradleHandledError gradleError in gradleErrors) {
if (gradleError.test(line)) {
detectedGradleErrorLine = line;
detectedGradleError = gradleError;
}
if (detectedGradleError != null) {
// Pipe stdout/sterr from Gradle.
return line;
}
for (final GradleHandledError gradleError in localGradleErrors) {
if (gradleError.test(line)) {
detectedGradleErrorLine = line;
detectedGradleError = gradleError;
// The first error match wins.
break;
}
}
// Pipe stdout/sterr from Gradle.
Expand All @@ -357,54 +359,62 @@ Future<void> buildGradleApp({
status.stop();
}

if (exitCode != 0 && detectedGradleError == null) {
BuildEvent('unknown-failure').send();
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
);
}
flutterUsage.sendTiming('build', 'gradle', sw.elapsed);

if (exitCode != 0 && detectedGradleError != null) {
final GradleBuildStatus status = await detectedGradleError.handler(
line: detectedGradleErrorLine,
project: project,
usesAndroidX: usesAndroidX,
shouldBuildPluginAsAar: shouldBuildPluginAsAar,
);
if (status == GradleBuildStatus.RETRY && retries >= 1) {
await buildGradleApp(
if (exitCode != 0) {
if (detectedGradleError == null) {
BuildEvent('gradle--unkown-failure').send();
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
);
} else {
final GradleBuildStatus status = await detectedGradleError.handler(
line: detectedGradleErrorLine,
project: project,
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: isBuildingBundle,
gradleErrors: gradleErrors,
usesAndroidX: usesAndroidX,
shouldBuildPluginAsAar: shouldBuildPluginAsAar,
retries: retries - 1,
);
return;
}
if (status == GradleBuildStatus.RETRY_WITH_AAR_PLUGINS &&
retries >= 1) {
await buildGradleApp(
project: project,
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: isBuildingBundle,
gradleErrors: gradleErrors,
shouldBuildPluginAsAar: true,
retries: retries - 1,

if (retries >= 1) {
final String successEventLabel = 'gradle--${detectedGradleError.eventLabel}-success';
switch (status) {
case GradleBuildStatus.retry:
await buildGradleApp(
project: project,
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: isBuildingBundle,
localGradleErrors: localGradleErrors,
shouldBuildPluginAsAar: shouldBuildPluginAsAar,
retries: retries - 1,
);
BuildEvent(successEventLabel).send();
return;
case GradleBuildStatus.retryWithAarPlugins:
await buildGradleApp(
project: project,
androidBuildInfo: androidBuildInfo,
target: target,
isBuildingBundle: isBuildingBundle,
localGradleErrors: localGradleErrors,
shouldBuildPluginAsAar: true,
retries: retries - 1,
);
BuildEvent(successEventLabel).send();
return;
case GradleBuildStatus.exit:
// noop.
}
}
BuildEvent('gradle--${detectedGradleError.eventLabel}-failure').send();
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
);
return;
}
throwToolExit(
'Gradle task $assembleTask failed with exit code $exitCode',
exitCode: exitCode,
);
}

flutterUsage.sendTiming('build', 'gradle', Duration(milliseconds: sw.elapsedMilliseconds));

if (isBuildingBundle) {
final File bundleFile = findBundleFile(project, buildInfo);
if (bundleFile == null) {
Expand Down Expand Up @@ -475,7 +485,13 @@ Future<void> buildGradleAar({
);

final String flutterRoot = fs.path.absolute(Cache.flutterRoot);
final String initScript = fs.path.join(flutterRoot, 'packages','flutter_tools', 'gradle', 'aar_init_script.gradle');
final String initScript = fs.path.join(
flutterRoot,
'packages',
'flutter_tools',
'gradle',
'aar_init_script.gradle',
);
final List<String> command = <String>[
gradleUtils.getExecutable(project),
'-I=$initScript',
Expand Down Expand Up @@ -507,7 +523,7 @@ Future<void> buildGradleAar({
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: gradleEnv,
environment: gradleEnvironment,
);
} finally {
status.stop();
Expand Down Expand Up @@ -549,11 +565,11 @@ String _calculateSha(File file) {
final Stopwatch sw = Stopwatch()..start();
final List<int> bytes = file.readAsBytesSync();
printTrace('calculateSha: reading file took ${sw.elapsedMilliseconds}us');
flutterUsage.sendTiming('build', 'apk-sha-read', Duration(milliseconds: sw.elapsedMilliseconds));
flutterUsage.sendTiming('build', 'apk-sha-read', sw.elapsed);
sw.reset();
final String sha = _hex(sha1.convert(bytes).bytes);
printTrace('calculateSha: computing sha took ${sw.elapsedMilliseconds}us');
flutterUsage.sendTiming('build', 'apk-sha-calc', Duration(milliseconds: sw.elapsedMilliseconds));
flutterUsage.sendTiming('build', 'apk-sha-calc', sw.elapsed);
return sha;
}

Expand Down

0 comments on commit f67a150

Please sign in to comment.