Unverified Commit 96afa500 authored by Andrew Kolos's avatar Andrew Kolos Committed by GitHub

[tools] allow explicitly specifying the JDK to use via a new config setting (#128264)

Closes https://github.com/flutter/flutter/issues/106416.

This PR adds a new `flutter config` setting named `jdk-dir`. When set, the tool will use the JDK found at this location for all Java-dependent tool operations such as building Android apps via gradle and running Android SDK tools.
parent b675e978
......@@ -8,7 +8,6 @@ import 'package:process/process.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
......@@ -18,7 +17,6 @@ import '../convert.dart';
import '../doctor_validator.dart';
import '../features.dart';
import 'android_sdk.dart';
import 'android_studio.dart';
import 'java.dart';
const int kAndroidSdkMinVersion = 29;
......@@ -226,29 +224,23 @@ class AndroidLicenseValidator extends DoctorValidator {
required Java? java,
required AndroidSdk? androidSdk,
required Platform platform,
required FileSystem fileSystem,
required ProcessManager processManager,
required Logger logger,
required AndroidStudio? androidStudio,
required Stdio stdio,
required UserMessages userMessages,
}) : _java = java,
_androidSdk = androidSdk,
_platform = platform,
_fileSystem = fileSystem,
_processManager = processManager,
_logger = logger,
_androidStudio = androidStudio,
_stdio = stdio,
_userMessages = userMessages,
super('Android license subvalidator');
final Java? _java;
final AndroidSdk? _androidSdk;
final AndroidStudio? _androidStudio;
final Stdio _stdio;
final Platform _platform;
final FileSystem _fileSystem;
final ProcessManager _processManager;
final Logger _logger;
final UserMessages _userMessages;
......@@ -287,13 +279,8 @@ class AndroidLicenseValidator extends DoctorValidator {
}
Future<bool> _checkJavaVersionNoOutput() async {
final String? javaBinary = Java.find(
logger: _logger,
androidStudio: _androidStudio,
fileSystem: _fileSystem,
platform: _platform,
processManager: _processManager,
)?.binaryPath;
final String? javaBinary = _java?.binaryPath;
if (javaBinary == null) {
return false;
}
......
......@@ -4,6 +4,7 @@
import 'package:process/process.dart';
import '../base/config.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
......@@ -52,6 +53,7 @@ class Java {
///
/// Returns null if no java binary could be found.
static Java? find({
required Config config,
required AndroidStudio? androidStudio,
required Logger logger,
required FileSystem fileSystem,
......@@ -65,6 +67,7 @@ class Java {
processManager: processManager
);
final String? home = _findJavaHome(
config: config,
logger: logger,
androidStudio: androidStudio,
platform: platform
......@@ -181,10 +184,16 @@ class Java {
}
String? _findJavaHome({
required Config config,
required Logger logger,
required AndroidStudio? androidStudio,
required Platform platform,
}) {
final Object? configured = config.getValue('jdk-dir');
if (configured != null) {
return configured as String;
}
final String? androidStudioJavaPath = androidStudio?.javaPath;
if (androidStudioJavaPath != null) {
return androidStudioJavaPath;
......
......@@ -4,6 +4,7 @@
import '../../src/android/android_sdk.dart';
import '../../src/android/android_studio.dart';
import '../android/java.dart';
import '../base/common.dart';
import '../convert.dart';
import '../features.dart';
......@@ -19,7 +20,12 @@ class ConfigCommand extends FlutterCommand {
negatable: false,
help: 'Clear the saved development certificate choice used to sign apps for iOS device deployment.');
argParser.addOption('android-sdk', help: 'The Android SDK directory.');
argParser.addOption('android-studio-dir', help: 'The Android Studio install directory. If unset, flutter will search for valid installs at well-known locations.');
argParser.addOption('android-studio-dir', help: 'The Android Studio installation directory. If unset, flutter will search for valid installations at well-known locations.');
argParser.addOption('jdk-dir', help: 'The Java Development Kit (JDK) installation directory. '
'If unset, flutter will search for one in the following order:\n'
' 1) the JDK bundled with the latest installation of Android Studio,\n'
' 2) the JDK found at the directory found in the JAVA_HOME environment variable, and\n'
" 3) the directory containing the java binary found in the user's path.");
argParser.addOption('build-dir', help: 'The relative path to override a projects build directory.',
valueHelp: 'out/');
argParser.addFlag('machine',
......@@ -101,7 +107,7 @@ class ConfigCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final List<String> rest = argResults?.rest ?? <String>[];
final List<String> rest = argResults!.rest;
if (rest.isNotEmpty) {
throwToolExit(exitCode: 2,
'error: flutter config: Too many arguments.\n'
......@@ -126,7 +132,7 @@ class ConfigCommand extends FlutterCommand {
return FlutterCommandResult.success();
}
if (argResults?.wasParsed('analytics') ?? false) {
if (argResults!.wasParsed('analytics')) {
final bool value = boolArg('analytics');
// The tool sends the analytics event *before* toggling the flag
// intentionally to be sure that opt-out events are sent correctly.
......@@ -146,19 +152,23 @@ class ConfigCommand extends FlutterCommand {
await globals.analytics.setTelemetry(value);
}
if (argResults?.wasParsed('android-sdk') ?? false) {
if (argResults!.wasParsed('android-sdk')) {
_updateConfig('android-sdk', stringArg('android-sdk')!);
}
if (argResults?.wasParsed('android-studio-dir') ?? false) {
if (argResults!.wasParsed('android-studio-dir')) {
_updateConfig('android-studio-dir', stringArg('android-studio-dir')!);
}
if (argResults?.wasParsed('clear-ios-signing-cert') ?? false) {
if (argResults!.wasParsed('jdk-dir')) {
_updateConfig('jdk-dir', stringArg('jdk-dir')!);
}
if (argResults!.wasParsed('clear-ios-signing-cert')) {
_updateConfig('ios-signing-cert', '');
}
if (argResults?.wasParsed('build-dir') ?? false) {
if (argResults!.wasParsed('build-dir')) {
final String buildDir = stringArg('build-dir')!;
if (globals.fs.path.isAbsolute(buildDir)) {
throwToolExit('build-dir should be a relative path');
......@@ -171,7 +181,7 @@ class ConfigCommand extends FlutterCommand {
if (configSetting == null) {
continue;
}
if (argResults?.wasParsed(configSetting) ?? false) {
if (argResults!.wasParsed(configSetting)) {
final bool keyValue = boolArg(configSetting);
globals.config.setValue(configSetting, keyValue);
globals.printStatus('Setting "$configSetting" value to "$keyValue".');
......@@ -203,6 +213,10 @@ class ConfigCommand extends FlutterCommand {
if (results['android-sdk'] == null && androidSdk != null) {
results['android-sdk'] = androidSdk.directory.path;
}
final Java? java = globals.java;
if (results['jdk-dir'] == null && java != null) {
results['jdk-dir'] = java.javaHome;
}
globals.printStatus(const JsonEncoder.withIndent(' ').convert(results));
}
......
......@@ -102,11 +102,9 @@ Future<T> runInContext<T>(
platform: globals.platform,
userMessages: globals.userMessages,
processManager: globals.processManager,
androidStudio: globals.androidStudio,
java: globals.java,
androidSdk: globals.androidSdk,
logger: globals.logger,
fileSystem: globals.fs,
stdio: globals.stdio,
),
AndroidSdk: AndroidSdk.locateAndroidSdk,
......@@ -255,6 +253,7 @@ Future<T> runInContext<T>(
platform: globals.platform,
),
Java: () => Java.find(
config: globals.config,
androidStudio: globals.androidStudio,
logger: globals.logger,
fileSystem: globals.fs,
......
......@@ -7,6 +7,7 @@ import 'dart:convert';
import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/android/java.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
......@@ -18,9 +19,11 @@ import 'package:test/fake.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/test_flutter_command_runner.dart';
void main() {
late Java fakeJava;
late FakeAndroidStudio fakeAndroidStudio;
late FakeAndroidSdk fakeAndroidSdk;
late FakeFlutterVersion fakeFlutterVersion;
......@@ -31,6 +34,7 @@ void main() {
});
setUp(() {
fakeJava = FakeJava();
fakeAndroidStudio = FakeAndroidStudio();
fakeAndroidSdk = FakeAndroidSdk();
fakeFlutterVersion = FakeFlutterVersion();
......@@ -65,16 +69,15 @@ void main() {
final dynamic jsonObject = json.decode(testLogger.statusText);
expect(jsonObject, const TypeMatcher<Map<String, dynamic>>());
if (jsonObject is Map<String, dynamic>) {
expect(jsonObject.containsKey('android-studio-dir'), true);
expect(jsonObject['android-studio-dir'], isNotNull);
expect(jsonObject.containsKey('android-sdk'), true);
expect(jsonObject['android-sdk'], isNotNull);
expect(jsonObject['android-studio-dir'], fakeAndroidStudio.directory);
expect(jsonObject['android-sdk'], fakeAndroidSdk.directory.path);
expect(jsonObject['jdk-dir'], fakeJava.javaHome);
}
verifyNoAnalytics();
}, overrides: <Type, Generator>{
AndroidStudio: () => fakeAndroidStudio,
AndroidSdk: () => fakeAndroidSdk,
Java: () => fakeJava,
Usage: () => testUsage,
});
......@@ -289,7 +292,10 @@ void main() {
class FakeAndroidStudio extends Fake implements AndroidStudio, Comparable<AndroidStudio> {
@override
String get directory => 'path/to/android/stdio';
String get directory => 'path/to/android/studio';
@override
String? get javaPath => 'path/to/android/studio/jbr';
}
class FakeAndroidSdk extends Fake implements AndroidSdk {
......
......@@ -5,10 +5,8 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/android/java.dart';
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:test/fake.dart';
......@@ -345,99 +343,6 @@ void main() {
Platform: () => FakePlatform(operatingSystem: 'windows'),
Config: () => config,
});
group('findJavaBinary', () {
testUsingContext('returns the path of the JDK bundled with Android Studio, if it exists', () {
final String androidStudioBundledJdkHome = globals.androidStudio!.javaPath!;
final String expectedJavaBinaryPath = globals.fs.path.join(androidStudioBundledJdkHome, 'bin', 'java');
final String? foundJavaBinaryPath = Java.find(
logger: globals.logger,
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
platform: globals.platform,
processManager: globals.processManager,
)?.binaryPath;
expect(foundJavaBinaryPath, expectedJavaBinaryPath);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
Platform: () => FakePlatform(),
Config: () => Config,
AndroidStudio: () => FakeAndroidStudioWithJdk(),
});
testUsingContext('returns the current value of JAVA_HOME if it is set and the JDK bundled with Android Studio could not be found', () {
final String expectedJavaBinaryPath = globals.fs.path.join('java-home-path', 'bin', 'java');
final String? foundJavaBinaryPath = Java.find(
logger: globals.logger,
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
platform: globals.platform,
processManager: globals.processManager,
)?.binaryPath;
expect(foundJavaBinaryPath, expectedJavaBinaryPath);
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.empty(),
Platform: () => FakePlatform(environment: <String, String>{
Java.javaHomeEnvironmentVariable: 'java-home-path',
}),
Config: () => Config,
AndroidStudio: () => FakeAndroidStudioWithoutJdk(),
});
testUsingContext('returns the java binary found on PATH if no other can be found', () {
final String? foundJavaBinaryPath = Java.find(
logger: globals.logger,
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
platform: globals.platform,
processManager: globals.processManager,
)?.binaryPath;
expect(foundJavaBinaryPath, 'java');
}, overrides: <Type, Generator>{
Logger: () => BufferLogger.test(),
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>['which', 'java'],
stdout: 'java',
),
]),
Platform: () => FakePlatform(),
Config: () => Config,
AndroidStudio: () => FakeAndroidStudioWithoutJdk(),
});
testUsingContext('returns null if no java binary could be found', () {
final String? foundJavaBinaryPath = Java.find(
logger: globals.logger,
androidStudio: globals.androidStudio,
fileSystem: globals.fs,
platform: globals.platform,
processManager: globals.processManager,
)?.binaryPath;
expect(foundJavaBinaryPath, null);
}, overrides: <Type, Generator>{
Logger: () => BufferLogger.test(),
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>['which', 'java'],
exitCode: 1,
),
]),
Platform: () => FakePlatform(),
Config: () => Config,
AndroidStudio: () => FakeAndroidStudioWithoutJdk(),
});
});
});
}
......
......@@ -4,7 +4,6 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/android/java.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -125,13 +124,11 @@ void main() {
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted licenseStatus = await licenseValidator.licensesAccepted;
......@@ -144,13 +141,11 @@ void main() {
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted licenseStatus = await licenseValidator.licensesAccepted;
......@@ -168,13 +163,11 @@ void main() {
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
......@@ -197,13 +190,11 @@ All SDK package licenses accepted.
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
......@@ -226,13 +217,11 @@ All SDK package licenses accepted.
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: java,
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted licenseStatus = await licenseValidator.licensesAccepted;
......@@ -256,13 +245,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
......@@ -286,13 +273,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
......@@ -312,13 +297,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
expect(await licenseValidator.runLicenseManager(), isTrue);
......@@ -331,13 +314,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
expect(licenseValidator.runLicenseManager(), throwsToolExit());
......@@ -360,13 +341,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: logger,
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
await licenseValidator.runLicenseManager();
......@@ -381,13 +360,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: BufferLogger.test(),
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
expect(licenseValidator.runLicenseManager(), throwsToolExit());
......@@ -408,13 +385,11 @@ Review licenses that have not been accepted (y/N)?
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
java: FakeJava(),
androidSdk: sdk,
fileSystem: fileSystem,
processManager: processManager,
platform: FakePlatform(environment: <String, String>{'HOME': '/home/me'}),
stdio: stdio,
logger: logger,
userMessages: UserMessages(),
androidStudio: FakeAndroidStudio(),
);
await expectLater(
......@@ -651,11 +626,6 @@ class FakeAndroidSdkVersion extends Fake implements AndroidSdkVersion {
String get platformName => '';
}
class FakeAndroidStudio extends Fake implements AndroidStudio {
@override
String get javaPath => 'java';
}
class ThrowingStdin<T> extends Fake implements IOSink {
ThrowingStdin(this.exception);
......
......@@ -5,6 +5,7 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/android/java.dart';
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
......@@ -20,12 +21,14 @@ import '../../src/fakes.dart';
void main() {
late Config config;
late Logger logger;
late FileSystem fs;
late Platform platform;
late FakeProcessManager processManager;
setUp(() {
config = Config.test();
logger = BufferLogger.test();
fs = MemoryFileSystem.test();
platform = FakePlatform(environment: <String, String>{
......@@ -54,6 +57,7 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
'''
));
final Java java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
......@@ -74,6 +78,7 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
final String expectedJavaBinaryPath = fs.path.join(javaHome, 'bin', 'java');
final Java java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
......@@ -99,6 +104,7 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
);
final Java java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
......@@ -119,6 +125,7 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
),
);
final Java? java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
......@@ -127,6 +134,53 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
);
expect(java, isNull);
});
testWithoutContext('finds and prefers JDK found at config item "jdk-dir" if it is set', () {
const String configuredJdkPath = '/jdk';
config.setValue('jdk-dir', configuredJdkPath);
processManager.addCommand(
const FakeCommand(
command: <String>['which', 'java'],
stdout: '/fake/which/java/path',
),
);
final _FakeAndroidStudioWithJdk androidStudio = _FakeAndroidStudioWithJdk();
final FakePlatform platformWithJavaHome = FakePlatform(
environment: <String, String>{
'JAVA_HOME': '/old/jdk'
},
);
Java? java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
platform: platformWithJavaHome,
processManager: processManager,
);
expect(java, isNotNull);
expect(java!.javaHome, configuredJdkPath);
expect(java.binaryPath, fs.path.join(configuredJdkPath, 'bin', 'java'));
config.removeValue('jdk-dir');
java = Java.find(
config: config,
androidStudio: androidStudio,
logger: logger,
fileSystem: fs,
platform: platformWithJavaHome,
processManager: processManager,
);
expect(java, isNotNull);
assert(androidStudio.javaPath != configuredJdkPath);
expect(java!.javaHome, androidStudio.javaPath);
expect(java.binaryPath, fs.path.join(androidStudio.javaPath!, 'bin', 'java'));
});
});
group('getVersionString', () {
......
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