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> { ...@@ -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) String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
if (flutterRootPath == null) { 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.") 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> { ...@@ -154,6 +144,30 @@ class FlutterPlugin implements Plugin<Project> {
String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter" String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile(); 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)) { if (useLocalEngine(project)) {
String engineOutPath = project.property('localEngineOut') String engineOutPath = project.property('localEngineOut')
File engineOut = project.file(engineOutPath) File engineOut = project.file(engineOutPath)
...@@ -375,6 +389,14 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -375,6 +389,14 @@ class FlutterPlugin implements Plugin<Project> {
return false return false
} }
private static Boolean useProguard(Project project) {
if (project.hasProperty('proguard')) {
return project.property('proguard').toBoolean()
}
return false
}
private static Boolean buildPluginAsAar() { private static Boolean buildPluginAsAar() {
return System.getProperty('build-plugins-as-aars') == 'true' 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 { ...@@ -92,6 +92,7 @@ class AndroidBuildInfo {
AndroidArch.arm64_v8a, AndroidArch.arm64_v8a,
], ],
this.splitPerAbi = false, this.splitPerAbi = false,
this.proguard = false,
}); });
// The build info containing the mode and flavor. // The build info containing the mode and flavor.
...@@ -104,6 +105,9 @@ class AndroidBuildInfo { ...@@ -104,6 +105,9 @@ class AndroidBuildInfo {
/// will be produced. /// will be produced.
final bool splitPerAbi; final bool splitPerAbi;
/// Whether to enable Proguard on release mode.
final bool proguard;
/// The target platforms for the build. /// The target platforms for the build.
final Iterable<AndroidArch> targetArchs; final Iterable<AndroidArch> targetArchs;
} }
......
...@@ -25,9 +25,15 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -25,9 +25,15 @@ class BuildApkCommand extends BuildSubCommand {
argParser argParser
..addFlag('split-per-abi', ..addFlag('split-per-abi',
negatable: false, 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', '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', ..addMultiOption('target-platform',
splitCommas: true, splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'], defaultsTo: <String>['android-arm', 'android-arm64'],
...@@ -79,7 +85,8 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -79,7 +85,8 @@ class BuildApkCommand extends BuildSubCommand {
final BuildInfo buildInfo = getBuildInfo(); final BuildInfo buildInfo = getBuildInfo();
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(buildInfo, final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(buildInfo,
splitPerAbi: argResults['split-per-abi'], 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) { if (buildInfo.isRelease && !androidBuildInfo.splitPerAbi && androidBuildInfo.targetArchs.length > 1) {
......
...@@ -22,6 +22,12 @@ class BuildAppBundleCommand extends BuildSubCommand { ...@@ -22,6 +22,12 @@ class BuildAppBundleCommand extends BuildSubCommand {
argParser argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp) ..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', ..addMultiOption('target-platform',
splitCommas: true, splitCommas: true,
defaultsTo: <String>['android-arm', 'android-arm64'], defaultsTo: <String>['android-arm', 'android-arm64'],
...@@ -63,7 +69,8 @@ class BuildAppBundleCommand extends BuildSubCommand { ...@@ -63,7 +69,8 @@ class BuildAppBundleCommand extends BuildSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final AndroidBuildInfo androidBuildInfo = AndroidBuildInfo(getBuildInfo(), 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( await androidBuilder.buildAab(
project: FlutterProject.current(), project: FlutterProject.current(),
......
...@@ -7,6 +7,7 @@ import 'dart:async'; ...@@ -7,6 +7,7 @@ import 'dart:async';
import 'android/android_sdk.dart'; import 'android/android_sdk.dart';
import 'android/android_studio.dart'; import 'android/android_studio.dart';
import 'android/android_workflow.dart'; import 'android/android_workflow.dart';
import 'android/gradle.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'artifacts.dart'; import 'artifacts.dart';
import 'asset.dart'; import 'asset.dart';
...@@ -89,6 +90,7 @@ Future<T> runInContext<T>( ...@@ -89,6 +90,7 @@ Future<T> runInContext<T>(
FuchsiaSdk: () => FuchsiaSdk(), FuchsiaSdk: () => FuchsiaSdk(),
FuchsiaWorkflow: () => FuchsiaWorkflow(), FuchsiaWorkflow: () => FuchsiaWorkflow(),
GenSnapshot: () => const GenSnapshot(), GenSnapshot: () => const GenSnapshot(),
GradleUtils: () => GradleUtils(),
HotRunnerConfig: () => HotRunnerConfig(), HotRunnerConfig: () => HotRunnerConfig(),
IMobileDevice: () => IMobileDevice(), IMobileDevice: () => IMobileDevice(),
IOSDeploy: () => const IOSDeploy(), IOSDeploy: () => const IOSDeploy(),
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io' hide File; import 'dart:io' hide File;
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
...@@ -17,21 +16,7 @@ import 'package:process/process.dart'; ...@@ -17,21 +16,7 @@ import 'package:process/process.dart';
import '../src/common.dart'; import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
import '../src/mocks.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;
}
void main() { void main() {
group('channel', () { group('channel', () {
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:convert';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
...@@ -17,21 +15,7 @@ import 'package:process/process.dart'; ...@@ -17,21 +15,7 @@ import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/mocks.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;
}
void main() { void main() {
group('UpgradeCommandRunner', () { group('UpgradeCommandRunner', () {
......
...@@ -116,6 +116,8 @@ Future<String> createProject(Directory temp, { List<String> arguments }) async { ...@@ -116,6 +116,8 @@ Future<String> createProject(Directory temp, { List<String> arguments }) async {
final CreateCommand command = CreateCommand(); final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', ...arguments, projectPath]); 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; return projectPath;
} }
......
...@@ -221,6 +221,24 @@ ProcessFactory flakyProcessFactory({ ...@@ -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. /// A process that exits successfully with no output and ignores all input.
class MockProcess extends Mock implements Process { class MockProcess extends Mock implements Process {
MockProcess({ 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