From 57fd50f84e013146ecfe40a3c77f8b0499bf59da Mon Sep 17 00:00:00 2001 From: crasowas <110958409+crasowas@users.noreply.github.com> Date: Sat, 4 Feb 2023 10:04:04 +0800 Subject: [PATCH] Fix unable to find bundled Java version (#119244) --- AUTHORS | 3 +- .../lib/src/android/android_studio.dart | 21 ++- .../android/android_studio_test.dart | 164 ++++++++++++++++++ 3 files changed, 182 insertions(+), 6 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1911504ef8..15682b932c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -100,4 +100,5 @@ Jingyi Chen Junhua Lin <1075209054@qq.com> Tomasz Gucio Jason C.H -Hubert Jóźwiak \ No newline at end of file +Hubert Jóźwiak +Eli Albert \ No newline at end of file diff --git a/packages/flutter_tools/lib/src/android/android_studio.dart b/packages/flutter_tools/lib/src/android/android_studio.dart index 191e6afda2..1409191ae9 100644 --- a/packages/flutter_tools/lib/src/android/android_studio.dart +++ b/packages/flutter_tools/lib/src/android/android_studio.dart @@ -441,11 +441,22 @@ class AndroidStudio implements Comparable { return; } - final String javaPath = globals.platform.isMacOS ? - version != null && version.major < 2020 ? - globals.fs.path.join(directory, 'jre', 'jdk', 'Contents', 'Home') : - globals.fs.path.join(directory, 'jre', 'Contents', 'Home') : - globals.fs.path.join(directory, 'jre'); + final String javaPath; + if (globals.platform.isMacOS) { + if (version != null && version.major < 2020) { + javaPath = globals.fs.path.join(directory, 'jre', 'jdk', 'Contents', 'Home'); + } else if (version != null && version.major == 2022) { + javaPath = globals.fs.path.join(directory, 'jbr', 'Contents', 'Home'); + } else { + javaPath = globals.fs.path.join(directory, 'jre', 'Contents', 'Home'); + } + } else { + if (version != null && version.major == 2022) { + javaPath = globals.fs.path.join(directory, 'jbr'); + } else { + javaPath = globals.fs.path.join(directory, 'jre'); + } + } final String javaExecutable = globals.fs.path.join(javaPath, 'bin', 'java'); if (!globals.processManager.canRun(javaExecutable)) { _validationMessages.add('Unable to find bundled Java version.'); diff --git a/packages/flutter_tools/test/general.shard/android/android_studio_test.dart b/packages/flutter_tools/test/general.shard/android/android_studio_test.dart index 598eebe66d..2ed87f6f00 100644 --- a/packages/flutter_tools/test/general.shard/android/android_studio_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_studio_test.dart @@ -56,6 +56,19 @@ const Map macStudioInfoPlist2020_3 = { }, }; +const Map macStudioInfoPlist2022_1 = { + 'CFBundleGetInfoString': 'Android Studio 2022.1, build AI-221.6008.13.2211.9477386. Copyright JetBrains s.r.o., (c) 2000-2023', + 'CFBundleShortVersionString': '2022.1', + 'CFBundleVersion': 'AI-221.6008.13.2211.9477386', + 'JVMOptions': { + 'Properties': { + 'idea.vendor.name' : 'Google', + 'idea.paths.selector': 'AndroidStudio2022.1', + 'idea.platform.prefix': 'AndroidStudio', + }, + }, +}; + const Map macStudioInfoPlistEAP = { 'CFBundleGetInfoString': 'Android Studio EAP AI-212.5712.43.2112.8233820, build AI-212.5712.43.2112.8233820. Copyright JetBrains s.r.o., (c) 2000-2022', 'CFBundleShortVersionString': 'EAP AI-212.5712.43.2112.8233820', @@ -486,6 +499,84 @@ void main() { Platform: () => platform, PlistParser: () => plistUtils, }); + + testUsingContext('Can find Android Studio 2020.3 bundled Java version on Mac', () { + final String studioInApplicationPlistFolder = globals.fs.path.join( + '/', + 'Application', + 'Android Studio.app', + 'Contents', + ); + globals.fs.directory(studioInApplicationPlistFolder).createSync(recursive: true); + + final String plistFilePath = globals.fs.path.join(studioInApplicationPlistFolder, 'Info.plist'); + plistUtils.fileContents[plistFilePath] = macStudioInfoPlist2020_3; + processManager.addCommand(FakeCommand( + command: [ + globals.fs.path.join(studioInApplicationPlistFolder, 'jre', 'Contents', 'Home', 'bin', 'java'), + '-version', + ], + stderr: '123', + ) + ); + final AndroidStudio studio = AndroidStudio.fromMacOSBundle( + globals.fs.directory(studioInApplicationPlistFolder).parent.path, + )!; + + expect(studio.javaPath, equals(globals.fs.path.join( + studioInApplicationPlistFolder, + 'jre', + 'Contents', + 'Home', + ))); + }, overrides: { + FileSystem: () => fileSystem, + FileSystemUtils: () => fsUtils, + ProcessManager: () => processManager, + // Custom home paths are not supported on macOS nor Windows yet, + // so we force the platform to fake Linux here. + Platform: () => platform, + PlistParser: () => plistUtils, + }); + + testUsingContext('Can find Android Studio 2022.1 bundled Java version on Mac', () { + final String studioInApplicationPlistFolder = globals.fs.path.join( + '/', + 'Application', + 'Android Studio.app', + 'Contents', + ); + globals.fs.directory(studioInApplicationPlistFolder).createSync(recursive: true); + + final String plistFilePath = globals.fs.path.join(studioInApplicationPlistFolder, 'Info.plist'); + plistUtils.fileContents[plistFilePath] = macStudioInfoPlist2022_1; + processManager.addCommand(FakeCommand( + command: [ + globals.fs.path.join(studioInApplicationPlistFolder, 'jbr', 'Contents', 'Home', 'bin', 'java'), + '-version', + ], + stderr: '123', + ) + ); + final AndroidStudio studio = AndroidStudio.fromMacOSBundle( + globals.fs.directory(studioInApplicationPlistFolder).parent.path, + )!; + + expect(studio.javaPath, equals(globals.fs.path.join( + studioInApplicationPlistFolder, + 'jbr', + 'Contents', + 'Home', + ))); + }, overrides: { + FileSystem: () => fileSystem, + FileSystemUtils: () => fsUtils, + ProcessManager: () => processManager, + // Custom home paths are not supported on macOS nor Windows yet, + // so we force the platform to fake Linux here. + Platform: () => platform, + PlistParser: () => plistUtils, + }); }); late FileSystem windowsFileSystem; @@ -596,6 +687,38 @@ void main() { ProcessManager: () => FakeProcessManager.any(), }); + testUsingContext('Can find Android Studio 2020.3 bundled Java version on Windows', () { + windowsFileSystem.file(r'C:\Users\Dash\AppData\Local\Google\AndroidStudio2020.3\.home') + ..createSync(recursive: true) + ..writeAsStringSync(r'C:\Program Files\AndroidStudio'); + windowsFileSystem.directory(r'C:\Program Files\AndroidStudio') + .createSync(recursive: true); + + final AndroidStudio studio = AndroidStudio.allInstalled().single; + + expect(studio.javaPath, equals(r'C:\Program Files\AndroidStudio\jre')); + }, overrides: { + Platform: () => windowsPlatform, + FileSystem: () => windowsFileSystem, + ProcessManager: () => FakeProcessManager.any(), + }); + + testUsingContext('Can find Android Studio 2022.1 bundled Java version on Windows', () { + windowsFileSystem.file(r'C:\Users\Dash\AppData\Local\Google\AndroidStudio2022.1\.home') + ..createSync(recursive: true) + ..writeAsStringSync(r'C:\Program Files\AndroidStudio'); + windowsFileSystem.directory(r'C:\Program Files\AndroidStudio') + .createSync(recursive: true); + + final AndroidStudio studio = AndroidStudio.allInstalled().single; + + expect(studio.javaPath, equals(r'C:\Program Files\AndroidStudio\jbr')); + }, overrides: { + Platform: () => windowsPlatform, + FileSystem: () => windowsFileSystem, + ProcessManager: () => FakeProcessManager.any(), + }); + group('Installation detection on Linux', () { late FileSystemUtils fsUtils; @@ -686,6 +809,47 @@ void main() { Platform: () => linuxPlatform, ProcessManager: () => FakeProcessManager.any(), }); + + testUsingContext('Can find Android Studio 2020.3 bundled Java version on Linux', () { + const String studioHomeFilePath = '$homeLinux/.cache/Google/AndroidStudio2020.3/.home'; + const String studioInstallPath = '$homeLinux/AndroidStudio'; + + globals.fs.file(studioHomeFilePath) + ..createSync(recursive: true) + ..writeAsStringSync(studioInstallPath); + + globals.fs.directory(studioInstallPath).createSync(); + + final AndroidStudio studio = AndroidStudio.allInstalled().single; + + expect(studio.javaPath, equals('$studioInstallPath/jre')); + }, overrides: { + FileSystem: () => fileSystem, + FileSystemUtils: () => fsUtils, + Platform: () => linuxPlatform, + ProcessManager: () => FakeProcessManager.any(), + }); + + testUsingContext('Can find Android Studio 2022.1 bundled Java version on Linux', () { + const String studioHomeFilePath = + '$homeLinux/.cache/Google/AndroidStudio2022.1/.home'; + const String studioInstallPath = '$homeLinux/AndroidStudio'; + + globals.fs.file(studioHomeFilePath) + ..createSync(recursive: true) + ..writeAsStringSync(studioInstallPath); + + globals.fs.directory(studioInstallPath).createSync(); + + final AndroidStudio studio = AndroidStudio.allInstalled().single; + + expect(studio.javaPath, equals('$studioInstallPath/jbr')); + }, overrides: { + FileSystem: () => fileSystem, + FileSystemUtils: () => fsUtils, + Platform: () => linuxPlatform, + ProcessManager: () => FakeProcessManager.any(), + }); }); }