22// Use of this source code is governed by a BSD-style license that can be
33// found in the LICENSE file.
44
5- import 'package:meta/meta.dart' ;
6-
75import '../base/common.dart' ;
86import '../base/file_system.dart' ;
9- import '../base/os.dart' ;
10- import '../base/platform.dart' ;
117import '../base/process.dart' ;
128import '../base/version.dart' ;
139import '../convert.dart' ;
1410import '../globals.dart' as globals;
15- import 'android_studio .dart' ;
11+ import 'java .dart' ;
1612
1713// ANDROID_HOME is deprecated.
1814// See https://developer.android.com/studio/command-line/variables.html#envar
@@ -36,16 +32,18 @@ final RegExp _sdkVersionRe = RegExp(r'^ro.build.version.sdk=([0-9]+)$');
3632// $ANDROID_SDK_ROOT/platforms/android-23/android.jar
3733// $ANDROID_SDK_ROOT/platforms/android-N/android.jar
3834class AndroidSdk {
39- AndroidSdk (this .directory) {
35+ AndroidSdk (this .directory, {
36+ Java ? java,
37+ }): _java = java {
4038 reinitialize ();
4139 }
4240
4341 static const String javaHomeEnvironmentVariable = 'JAVA_HOME' ;
44- static const String _javaExecutable = 'java' ;
45-
4642 /// The Android SDK root directory.
4743 final Directory directory;
4844
45+ final Java ? _java;
46+
4947 List <AndroidSdkVersion > _sdkVersions = < AndroidSdkVersion > [];
5048 AndroidSdkVersion ? _latestVersion;
5149
@@ -411,162 +409,6 @@ class AndroidSdk {
411409 return null ;
412410 }
413411
414- /// Returns the version of java in the format \d(.\d)+(.\d)+
415- /// Returns null if version not found.
416- String ? getJavaVersion ({
417- required AndroidStudio ? androidStudio,
418- required FileSystem fileSystem,
419- required OperatingSystemUtils operatingSystemUtils,
420- required Platform platform,
421- required ProcessUtils processUtils,
422- }) {
423- final String ? javaBinary = findJavaBinary (
424- androidStudio: androidStudio,
425- fileSystem: fileSystem,
426- operatingSystemUtils: operatingSystemUtils,
427- platform: platform,
428- );
429- if (javaBinary == null ) {
430- globals.printTrace ('Could not find java binary to get version.' );
431- return null ;
432- }
433- final RunResult result = processUtils.runSync (
434- < String > [javaBinary, '--version' ],
435- environment: sdkManagerEnv,
436- );
437- if (result.exitCode != 0 ) {
438- globals.printTrace (
439- 'java --version failed: exitCode: ${result .exitCode } stdout: ${result .stdout } stderr: ${result .stderr }' );
440- return null ;
441- }
442- return parseJavaVersion (result.stdout);
443- }
444-
445- /// Extracts JDK version from the output of java --version.
446- @visibleForTesting
447- static String ? parseJavaVersion (String rawVersionOutput) {
448- // The contents that matter come in the format '11.0.18' or '1.8.0_202'.
449- final RegExp jdkVersionRegex = RegExp (r'\d+\.\d+(\.\d+(?:_\d+)?)?' );
450- final Iterable <RegExpMatch > matches =
451- jdkVersionRegex.allMatches (rawVersionOutput);
452- if (matches.isEmpty) {
453- globals.logger.printWarning (_formatJavaVersionWarning (rawVersionOutput));
454- return null ;
455- }
456- final String ? versionString = matches.first.group (0 );
457- if (versionString == null || versionString.split ('_' ).isEmpty) {
458- globals.logger.printWarning (_formatJavaVersionWarning (rawVersionOutput));
459- return null ;
460- }
461- // Trim away _d+ from versions 1.8 and below.
462- return versionString.split ('_' ).first;
463- }
464-
465- /// A value that would be appropriate to use as JAVA_HOME.
466- ///
467- /// This method considers jdk in the following order:
468- /// * the JDK bundled with Android Studio, if one is found;
469- /// * the JAVA_HOME in the ambient environment, if set;
470- String ? get javaHome {
471- return findJavaHome (
472- androidStudio: globals.androidStudio,
473- fileSystem: globals.fs,
474- operatingSystemUtils: globals.os,
475- platform: globals.platform,
476- );
477- }
478-
479-
480- static String ? findJavaHome ({
481- required AndroidStudio ? androidStudio,
482- required FileSystem fileSystem,
483- required OperatingSystemUtils operatingSystemUtils,
484- required Platform platform,
485- }) {
486- if (androidStudio? .javaPath != null ) {
487- globals.printTrace ("Using Android Studio's java." );
488- return androidStudio! .javaPath! ;
489- }
490-
491- final String ? javaHomeEnv = platform.environment[javaHomeEnvironmentVariable];
492- if (javaHomeEnv != null ) {
493- globals.printTrace ('Using JAVA_HOME from environment valuables.' );
494- return javaHomeEnv;
495- }
496- return null ;
497- }
498-
499- /// Finds the java binary that is used for all operations across the tool.
500- ///
501- /// This comes from [findJavaHome] if that method returns non-null;
502- /// otherwise, it gets from searching PATH.
503- // TODO(andrewkolos): To prevent confusion when debugging Android-related
504- // issues (see https://github.com/flutter/flutter/issues/122609 for an example),
505- // this logic should be consistently followed by any Java-dependent operation
506- // across the the tool (building Android apps, interacting with the Android SDK, etc.).
507- // Currently, this consistency is fragile since the logic used for building
508- // Android apps exists independently of this method.
509- // See https://github.com/flutter/flutter/issues/124252.
510- static String ? findJavaBinary ({
511- required AndroidStudio ? androidStudio,
512- required FileSystem fileSystem,
513- required OperatingSystemUtils operatingSystemUtils,
514- required Platform platform,
515- }) {
516- final String ? javaHome = findJavaHome (
517- androidStudio: androidStudio,
518- fileSystem: fileSystem,
519- operatingSystemUtils: operatingSystemUtils,
520- platform: platform,
521- );
522-
523- if (javaHome != null ) {
524- return fileSystem.path.join (javaHome, 'bin' , 'java' );
525- }
526-
527- // Fallback to PATH based lookup.
528- final String ? pathJava = operatingSystemUtils.which (_javaExecutable)? .path;
529- if (pathJava != null ) {
530- globals.printTrace ('Using java from PATH.' );
531- } else {
532- globals.printTrace ('Could not find java path.' );
533- }
534- return pathJava;
535- }
536-
537- // Returns a user visible String that says the tool failed to parse
538- // the version of java along with the output.
539- static String _formatJavaVersionWarning (String javaVersionRaw) {
540- return 'Could not parse java version from: \n '
541- '$javaVersionRaw \n '
542- 'If there is a version please look for an existing bug '
543- 'https://github.com/flutter/flutter/issues/'
544- ' and if one does not exist file a new issue.' ;
545- }
546-
547- Map <String , String >? _sdkManagerEnv;
548-
549- /// Returns an environment with the Java folder added to PATH for use in calling
550- /// Java-based Android SDK commands such as sdkmanager and avdmanager.
551- Map <String , String > get sdkManagerEnv {
552- if (_sdkManagerEnv == null ) {
553- // If we can locate Java, then add it to the path used to run the Android SDK manager.
554- _sdkManagerEnv = < String , String > {};
555- final String ? javaBinary = findJavaBinary (
556- androidStudio: globals.androidStudio,
557- fileSystem: globals.fs,
558- operatingSystemUtils: globals.os,
559- platform: globals.platform,
560- );
561- if (javaBinary != null && globals.platform.environment['PATH' ] != null ) {
562- _sdkManagerEnv! ['PATH' ] = globals.fs.path.dirname (javaBinary) +
563- globals.os.pathVarSeparator +
564- globals.platform.environment['PATH' ]! ;
565- }
566- }
567- return _sdkManagerEnv! ;
568- }
569-
570412 /// Returns the version of the Android SDK manager tool or null if not found.
571413 String ? get sdkManagerVersion {
572414 if (sdkManagerPath == null || ! globals.processManager.canRun (sdkManagerPath)) {
@@ -577,7 +419,7 @@ class AndroidSdk {
577419 }
578420 final RunResult result = globals.processUtils.runSync (
579421 < String > [sdkManagerPath! , '--version' ],
580- environment: sdkManagerEnv ,
422+ environment: _java ? .environment ,
581423 );
582424 if (result.exitCode != 0 ) {
583425 globals.printTrace ('sdkmanager --version failed: exitCode: ${result .exitCode } stdout: ${result .stdout } stderr: ${result .stderr }' );
0 commit comments