Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 2 additions & 44 deletions packages/flutter_tools/lib/src/android/android_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

import '../base/common.dart';
import '../base/file_system.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../convert.dart';
import '../globals.dart' as globals;
import 'android_studio.dart';
import 'java.dart' as java;

// ANDROID_HOME is deprecated.
// See https://developer.android.com/studio/command-line/variables.html#envar
Expand Down Expand Up @@ -38,9 +36,6 @@ class AndroidSdk {
reinitialize();
}

static const String _javaHomeEnvironmentVariable = 'JAVA_HOME';
static const String _javaExecutable = 'java';

/// The Android SDK root directory.
final Directory directory;

Expand Down Expand Up @@ -409,51 +404,14 @@ class AndroidSdk {
return null;
}

/// First try Java bundled with Android Studio, then sniff JAVA_HOME, then fallback to PATH.
static String? findJavaBinary({
required AndroidStudio? androidStudio,
required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils,
required Platform platform,
}) {
if (androidStudio?.javaPath != null) {
return fileSystem.path.join(androidStudio!.javaPath!, 'bin', 'java');
}

final String? javaHomeEnv = platform.environment[_javaHomeEnvironmentVariable];
if (javaHomeEnv != null) {
// Trust JAVA_HOME.
return fileSystem.path.join(javaHomeEnv, 'bin', 'java');
}

// MacOS specific logic to avoid popping up a dialog window.
// See: http://stackoverflow.com/questions/14292698/how-do-i-check-if-the-java-jdk-is-installed-on-mac.
if (platform.isMacOS) {
try {
final String javaHomeOutput = globals.processUtils.runSync(
<String>['/usr/libexec/java_home', '-v', '1.8'],
throwOnError: true,
hideStdout: true,
).stdout.trim();
if (javaHomeOutput.isNotEmpty) {
final String javaHome = javaHomeOutput.split('\n').last.trim();
return fileSystem.path.join(javaHome, 'bin', 'java');
}
} on Exception { /* ignore */ }
}

// Fallback to PATH based lookup.
return operatingSystemUtils.which(_javaExecutable)?.path;
}

Map<String, String>? _sdkManagerEnv;
/// Returns an environment with the Java folder added to PATH for use in calling
/// Java-based Android SDK commands such as sdkmanager and avdmanager.
Map<String, String> get sdkManagerEnv {
if (_sdkManagerEnv == null) {
// If we can locate Java, then add it to the path used to run the Android SDK manager.
_sdkManagerEnv = <String, String>{};
final String? javaBinary = findJavaBinary(
final String? javaBinary = java.findJavaBinary(
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
operatingSystemUtils: globals.os,
Expand Down
10 changes: 5 additions & 5 deletions packages/flutter_tools/lib/src/android/android_studio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import 'android_studio_validator.dart';
final RegExp _dotHomeStudioVersionMatcher =
RegExp(r'^\.?(AndroidStudio[^\d]*)([\d.]+)');

String? get javaPath => globals.androidStudio?.javaPath;

class AndroidStudio implements Comparable<AndroidStudio> {
AndroidStudio(
this.directory, {
Expand Down Expand Up @@ -141,11 +139,13 @@ class AndroidStudio implements Comparable<AndroidStudio> {
final String? configured;
final String? presetPluginsPath;

String? _javaPath;
String? _javaHomePath;
bool _isValid = false;
final List<String> _validationMessages = <String>[];

String? get javaPath => _javaPath;
/// The path of the home directory of the JDK bundled with this instance
/// of Android Studio.
String? get javaHomePath => _javaHomePath;

bool get isValid => _isValid;

Expand Down Expand Up @@ -471,7 +471,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
final List<String> versionLines = result.stderr.split('\n');
final String javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0];
_validationMessages.add('Java version $javaVersion');
_javaPath = javaPath;
_javaHomePath = javaPath;
_isValid = true;
} else {
_validationMessages.add('Unable to determine bundled Java version.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import '../doctor_validator.dart';
import '../features.dart';
import 'android_sdk.dart';
import 'android_studio.dart';
import 'java.dart' as java;

const int kAndroidSdkMinVersion = 29;
final Version kAndroidJavaMinVersion = Version(1, 8, 0);
Expand Down Expand Up @@ -240,7 +241,7 @@ class AndroidValidator extends DoctorValidator {

_task = 'Finding Java binary';
// Now check for the JDK.
final String? javaBinary = AndroidSdk.findJavaBinary(
final String? javaBinary = java.findJavaBinary(
androidStudio: _androidStudio,
fileSystem: _fileSystem,
operatingSystemUtils: _operatingSystemUtils,
Expand Down Expand Up @@ -330,7 +331,7 @@ class AndroidLicenseValidator extends DoctorValidator {
}

Future<bool> _checkJavaVersionNoOutput() async {
final String? javaBinary = AndroidSdk.findJavaBinary(
final String? javaBinary = java.findJavaBinary(
androidStudio: _androidStudio,
fileSystem: _fileSystem,
operatingSystemUtils: _operatingSystemUtils,
Expand Down
12 changes: 7 additions & 5 deletions packages/flutter_tools/lib/src/android/gradle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import '../flutter_manifest.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import 'android_builder.dart';
import 'android_studio.dart';
import 'gradle_errors.dart';
import 'gradle_utils.dart';
import 'migrations/top_level_gradle_build_file_migration.dart';
Expand Down Expand Up @@ -124,11 +123,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
required Usage usage,
required GradleUtils gradleUtils,
required Platform platform,
required String? javaSdkHome,
}) : _logger = logger,
_fileSystem = fileSystem,
_artifacts = artifacts,
_usage = usage,
_gradleUtils = gradleUtils,
_javaSdkHome = javaSdkHome,
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform),
_processUtils = ProcessUtils(logger: logger, processManager: processManager);

Expand All @@ -139,6 +140,7 @@ class AndroidGradleBuilder implements AndroidBuilder {
final Usage _usage;
final GradleUtils _gradleUtils;
final FileSystemUtils _fileSystemUtils;
final String? _javaSdkHome;

/// Builds the AAR and POM files for the current Flutter module or plugin.
@override
Expand Down Expand Up @@ -402,8 +404,8 @@ class AndroidGradleBuilder implements AndroidBuilder {
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: <String, String>{
if (javaPath != null)
'JAVA_HOME': javaPath!,
if (_javaSdkHome != null)
'JAVA_HOME': _javaSdkHome!,
},
mapFunction: consumeLog,
);
Expand Down Expand Up @@ -671,8 +673,8 @@ class AndroidGradleBuilder implements AndroidBuilder {
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: <String, String>{
if (javaPath != null)
'JAVA_HOME': javaPath!,
if (_javaSdkHome != null)
'JAVA_HOME': _javaSdkHome!,
},
);
} finally {
Expand Down
13 changes: 10 additions & 3 deletions packages/flutter_tools/lib/src/android/gradle_errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import '../base/terminal.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../reporting/reporting.dart';
import 'android_studio.dart';
import 'gradle_utils.dart';
import 'java.dart' as java;
import 'multidex.dart';

typedef GradleErrorTest = bool Function(String);
Expand Down Expand Up @@ -367,6 +367,13 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
required bool usesAndroidX,
required bool multidexEnabled,
}) async {
final String? javaHome = java.findJavaHome(
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
operatingSystemUtils: globals.os,
platform: globals.platform,
);

final RunResult tasksRunResult = await globals.processUtils.run(
<String>[
globals.gradleUtils!.getExecutable(project),
Expand All @@ -377,8 +384,8 @@ final GradleHandledError flavorUndefinedHandler = GradleHandledError(
throwOnError: true,
workingDirectory: project.android.hostAppGradleRoot.path,
environment: <String, String>{
if (javaPath != null)
'JAVA_HOME': javaPath!,
if (javaHome != null)
'JAVA_HOME': javaHome,
},
);
// Extract build types and product flavors.
Expand Down
57 changes: 57 additions & 0 deletions packages/flutter_tools/lib/src/android/java.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 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 '../base/file_system.dart';
import '../base/os.dart';
import '../base/platform.dart';
import 'android_studio.dart';

const String _javaHomeEnvironmentVariable = 'JAVA_HOME';
const String _javaExecutable = 'java';

/// Attempts to find the home directory of the local Java installation used
/// by the flutter tool.
///
/// First tries Java bundled with Android Studio, then sniffs JAVA_HOME, then falls back to PATH.
String? findJavaHome({
required AndroidStudio? androidStudio,
required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils,
required Platform platform,
}) {
if (androidStudio?.javaHomePath != null) {
return androidStudio!.javaHomePath;
}

final String? javaHomeEnv = platform.environment[_javaHomeEnvironmentVariable];

if (javaHomeEnv != null) {
// Trust JAVA_HOME.
return javaHomeEnv;
}

// Fallback to PATH based lookup.
final String? binaryPath = operatingSystemUtils.which(_javaExecutable)?.path;
return binaryPath == null ? null : fileSystem.file(binaryPath).parent.parent.path;
}

/// Attempts to find the java binary of the local Java installation used by
/// the flutter tool.
///
/// See [findJavaHome].
String? findJavaBinary({
required AndroidStudio? androidStudio,
required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils,
required Platform platform,
}) {
final String? javaHome = findJavaHome(
androidStudio: androidStudio,
fileSystem: fileSystem,
operatingSystemUtils: operatingSystemUtils,
platform: platform
);

return javaHome == null ? null : fileSystem.path.join(javaHome, 'bin', 'java');
}
7 changes: 7 additions & 0 deletions packages/flutter_tools/lib/src/context_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'android/android_studio.dart';
import 'android/android_workflow.dart';
import 'android/gradle.dart';
import 'android/gradle_utils.dart';
import 'android/java.dart';
import 'application_package.dart';
import 'artifacts.dart';
import 'asset.dart';
Expand Down Expand Up @@ -87,6 +88,12 @@ Future<T> runInContext<T>(
overrides: overrides,
fallbacks: <Type, Generator>{
AndroidBuilder: () => AndroidGradleBuilder(
javaSdkHome: findJavaHome(
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
operatingSystemUtils: globals.os,
platform: globals.platform
),
logger: globals.logger,
processManager: globals.processManager,
fileSystem: globals.fs,
Expand Down
70 changes: 0 additions & 70 deletions packages/flutter_tools/lib/src/flutter_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ import 'dart:async';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';

import 'android/android_studio.dart';
import 'base/common.dart';
import 'base/error_handling_io.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/os.dart' show OperatingSystemUtils;
import 'base/platform.dart';
import 'base/process.dart';
import 'cache.dart';
import 'dart/package_map.dart';
import 'dart/pub.dart';
import 'globals.dart' as globals;
import 'project.dart';

/// An implementation of the [Cache] which provides all of Flutter's default artifacts.
Expand Down Expand Up @@ -350,73 +347,6 @@ class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
List<String> getLicenseDirs() { return <String>[]; }
}

/// A cached artifact containing the Maven dependencies used to build Android projects.
///
/// This is a no-op if the android SDK is not available.
class AndroidMavenArtifacts extends ArtifactSet {
AndroidMavenArtifacts(this.cache, {
required Platform platform,
}) : _platform = platform,
super(DevelopmentArtifact.androidMaven);

final Platform _platform;
final Cache cache;

@override
Future<void> update(
ArtifactUpdater artifactUpdater,
Logger logger,
FileSystem fileSystem,
OperatingSystemUtils operatingSystemUtils,
{bool offline = false}
) async {
if (globals.androidSdk == null) {
return;
}
final Directory tempDir = cache.getRoot().createTempSync('flutter_gradle_wrapper.');
globals.gradleUtils?.injectGradleWrapperIfNeeded(tempDir);

final Status status = logger.startProgress('Downloading Android Maven dependencies...');
final File gradle = tempDir.childFile(
_platform.isWindows ? 'gradlew.bat' : 'gradlew',
);
try {
final String gradleExecutable = gradle.absolute.path;
final String flutterSdk = globals.fsUtils.escapePath(Cache.flutterRoot!);
final RunResult processResult = await globals.processUtils.run(
<String>[
gradleExecutable,
'-b', globals.fs.path.join(flutterSdk, 'packages', 'flutter_tools', 'gradle', 'resolve_dependencies.gradle'),
'--project-cache-dir', tempDir.path,
'resolveDependencies',
],
environment: <String, String>{
if (javaPath != null)
'JAVA_HOME': javaPath!,
},
);
if (processResult.exitCode != 0) {
logger.printError('Failed to download the Android dependencies');
}
} finally {
status.stop();
tempDir.deleteSync(recursive: true);
globals.androidSdk?.reinitialize();
}
}

@override
Future<bool> isUpToDate(FileSystem fileSystem) async {
// The dependencies are downloaded and cached by Gradle.
// The tool doesn't know if the dependencies are already cached at this point.
// Therefore, call Gradle to figure this out.
return false;
}

@override
String get name => 'android-maven-artifacts';
}

/// Artifacts used for internal builds. The flutter tool builds Android projects
/// using the artifacts cached by [AndroidMavenArtifacts].
class AndroidInternalBuildArtifacts extends EngineCachedArtifact {
Expand Down
Loading