Unverified Commit f098de1f authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Enable Proguard by default on release mode (#39986)

parent 362cde43
......@@ -132,16 +132,6 @@ class FlutterPlugin implements Plugin<Project> {
}
}
// Add custom build types
project.android.buildTypes {
profile {
initWith debug
if (it.hasProperty('matchingFallbacks')) {
matchingFallbacks = ['debug', 'release']
}
}
}
String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
if (flutterRootPath == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable.")
......@@ -154,6 +144,30 @@ class FlutterPlugin implements Plugin<Project> {
String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();
// Add custom build types.
project.android.buildTypes {
profile {
initWith debug
if (it.hasProperty("matchingFallbacks")) {
matchingFallbacks = ["debug", "release"]
}
}
}
if (useProguard(project)) {
String flutterProguardRules = Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools",
"gradle", "flutter_proguard_rules.pro")
project.android.buildTypes {
release {
minifyEnabled true
useProguard true
// Fallback to `android/app/proguard-rules.pro`.
// This way, custom Proguard rules can be configured as needed.
proguardFiles project.android.getDefaultProguardFile("proguard-android.txt"), flutterProguardRules, "proguard-rules.pro"
}
}
}
if (useLocalEngine(project)) {
String engineOutPath = project.property('localEngineOut')
File engineOut = project.file(engineOutPath)
......@@ -375,6 +389,14 @@ class FlutterPlugin implements Plugin<Project> {
return false
}
private static Boolean useProguard(Project project) {
if (project.hasProperty('proguard')) {
return project.property('proguard').toBoolean()
}
return false
}
private static Boolean buildPluginAsAar() {
return System.getProperty('build-plugins-as-aars') == 'true'
}
......
# Prevents `Fragment and FragmentActivity not found`.
# TODO(blasten): Remove once we bring the Maven dependencies.
-dontwarn io.flutter.embedding.**
# Build the ephemeral app in a module project.
# Prevents: Warning: library class <plugin-package> depends on program class io.flutter.plugin.**
# This is due to plugins (libraries) depending on the embedding (the program jar)
-dontwarn io.flutter.plugin.**
# The android.** package is provided by the OS at runtime.
-dontwarn android.**
......@@ -92,6 +92,7 @@ class AndroidBuildInfo {
AndroidArch.arm64_v8a,
],
this.splitPerAbi = false,
this.proguard = false,
});
// The build info containing the mode and flavor.
......@@ -104,6 +105,9 @@ class AndroidBuildInfo {
/// will be produced.
final bool splitPerAbi;
/// Whether to enable Proguard on release mode.
final bool proguard;
/// The target platforms for the build.
final Iterable<AndroidArch> targetArchs;
}
......
......@@ -25,9 +25,15 @@ class BuildApkCommand extends BuildSubCommand {
argParser
..addFlag('split-per-abi',
negatable: false,
help: 'Whether to split the APKs per ABIs.'
help: 'Whether to split the APKs per ABIs. '
'To learn more, see: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split',
)
..addFlag('proguard',
negatable: true,
defaultsTo: true,
help: 'Whether to enable Proguard on release mode. '
'To learn more, see: https://flutter.dev/docs/deployment/android#enabling-proguard',
)
..addMultiOption('target-platform',
splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'],
......@@ -79,7 +85,8 @@ class BuildApkCommand extends BuildSubCommand {
final BuildInfo buildInfo = getBuildInfo();
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(buildInfo,
splitPerAbi: argResults['split-per-abi'],
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName)
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
proguard: argResults['proguard'],
);
if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
......
......@@ -22,6 +22,12 @@ class BuildAppBundleCommand extends BuildSubCommand {
argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
..addFlag('proguard',
negatable: true,
defaultsTo: true,
help: 'Whether to enable Proguard on release mode. '
'To learn more, see: https://flutter.dev/docs/deployment/android#enabling-proguard',
)
..addMultiOption('target-platform',
splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'],
......@@ -63,7 +69,8 @@ class BuildAppBundleCommand extends BuildSubCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(),
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName)
targetArchs: argResults['target-platform'].map<AndroidArch>(getAndroidArchForName),
proguard: argResults['proguard'],
);
await androidBuilder.buildAab(
project: FlutterProject.current(),
......
......@@ -7,6 +7,7 @@ import 'dart:async';
import 'android/android_sdk.dart';
import 'android/android_studio.dart';
import 'android/android_workflow.dart';
import 'android/gradle.dart';
import 'application_package.dart';
import 'artifacts.dart';
import 'asset.dart';
......@@ -89,6 +90,7 @@ Future<T> runInContext<T>(
FuchsiaSdk: () => FuchsiaSdk(),
FuchsiaWorkflow: () => FuchsiaWorkflow(),
GenSnapshot: () => const GenSnapshot(),
GradleUtils: () => GradleUtils(),
HotRunnerConfig: () => HotRunnerConfig(),
IMobileDevice: () => IMobileDevice(),
IOSDeploy: () => const IOSDeploy(),
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io' hide File;
import 'package:args/command_runner.dart';
......@@ -17,21 +16,7 @@ import 'package:process/process.dart';
import '../src/common.dart';
import '../src/context.dart';
Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr = '' }) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stdout),
]);
final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stderr),
]);
final Process process = MockProcess();
when(process.stdout).thenAnswer((_) => stdoutStream);
when(process.stderr).thenAnswer((_) => stderrStream);
when(process.exitCode).thenAnswer((_) => Future<int>.value(exitCode));
return process;
}
import '../src/mocks.dart';
void main() {
group('channel', () {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
......@@ -17,21 +15,7 @@ import 'package:process/process.dart';
import '../../src/common.dart';
import '../../src/context.dart';
Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr = '' }) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stdout),
]);
final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stderr),
]);
final Process process = MockProcess();
when(process.stdout).thenAnswer((_) => stdoutStream);
when(process.stderr).thenAnswer((_) => stderrStream);
when(process.exitCode).thenAnswer((_) => Future<int>.value(exitCode));
return process;
}
import '../../src/mocks.dart';
void main() {
group('UpgradeCommandRunner', () {
......
......@@ -116,6 +116,8 @@ Future<String> createProject(Directory temp, { List<String> arguments }) async {
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', ...arguments, projectPath]);
// Created `.packages` since it's not created when the flag `--no-pub` is passed.
fs.file(fs.path.join(projectPath, '.packages')).createSync();
return projectPath;
}
......
......@@ -221,6 +221,24 @@ ProcessFactory flakyProcessFactory({
};
}
/// Creates a mock process that returns with the given [exitCode], [stdout] and [stderr].
Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr = '' }) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stdout),
]);
final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(<List<int>>[
utf8.encode(stderr),
]);
final Process process = MockBasicProcess();
when(process.stdout).thenAnswer((_) => stdoutStream);
when(process.stderr).thenAnswer((_) => stderrStream);
when(process.exitCode).thenAnswer((_) => Future<int>.value(exitCode));
return process;
}
class MockBasicProcess extends Mock implements Process {}
/// A process that exits successfully with no output and ignores all input.
class MockProcess extends Mock implements Process {
MockProcess({
......
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