[flutter_tools] Move homeDirPath to FileSystemUtils (#49909)

diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart
index c2a27e8..a23fc9a 100644
--- a/packages/flutter_tools/lib/src/android/android_sdk.dart
+++ b/packages/flutter_tools/lib/src/android/android_sdk.dart
@@ -307,16 +307,31 @@
       } else if (globals.platform.environment.containsKey(kAndroidSdkRoot)) {
         androidHomeDir = globals.platform.environment[kAndroidSdkRoot];
       } else if (globals.platform.isLinux) {
-        if (homeDirPath != null) {
-          androidHomeDir = globals.fs.path.join(homeDirPath, 'Android', 'Sdk');
+        if (globals.fsUtils.homeDirPath != null) {
+          androidHomeDir = globals.fs.path.join(
+            globals.fsUtils.homeDirPath,
+            'Android',
+            'Sdk',
+          );
         }
       } else if (globals.platform.isMacOS) {
-        if (homeDirPath != null) {
-          androidHomeDir = globals.fs.path.join(homeDirPath, 'Library', 'Android', 'sdk');
+        if (globals.fsUtils.homeDirPath != null) {
+          androidHomeDir = globals.fs.path.join(
+            globals.fsUtils.homeDirPath,
+            'Library',
+            'Android',
+            'sdk',
+          );
         }
       } else if (globals.platform.isWindows) {
-        if (homeDirPath != null) {
-          androidHomeDir = globals.fs.path.join(homeDirPath, 'AppData', 'Local', 'Android', 'sdk');
+        if (globals.fsUtils.homeDirPath != null) {
+          androidHomeDir = globals.fs.path.join(
+            globals.fsUtils.homeDirPath,
+            'AppData',
+            'Local',
+            'Android',
+            'sdk',
+          );
         }
       }
 
diff --git a/packages/flutter_tools/lib/src/android/android_studio.dart b/packages/flutter_tools/lib/src/android/android_studio.dart
index 65cb3e9..44d822d 100644
--- a/packages/flutter_tools/lib/src/android/android_studio.dart
+++ b/packages/flutter_tools/lib/src/android/android_studio.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import '../base/common.dart';
 import '../base/context.dart';
 import '../base/file_system.dart';
 import '../base/process.dart';
@@ -67,8 +66,13 @@
       }
     }
     final String presetPluginsPath = pathsSelectorValue == null
-        ? null
-        : globals.fs.path.join(homeDirPath, 'Library', 'Application Support', pathsSelectorValue);
+      ? null
+      : globals.fs.path.join(
+        globals.fsUtils.homeDirPath,
+        'Library',
+        'Application Support',
+        pathsSelectorValue,
+      );
     return AndroidStudio(studioPath, version: version, presetPluginsPath: presetPluginsPath);
   }
 
@@ -123,15 +127,18 @@
     final int minor = version?.minor;
     if (globals.platform.isMacOS) {
       return globals.fs.path.join(
-          homeDirPath,
-          'Library',
-          'Application Support',
-          'AndroidStudio$major.$minor');
+        globals.fsUtils.homeDirPath,
+        'Library',
+        'Application Support',
+        'AndroidStudio$major.$minor',
+      );
     } else {
-      return globals.fs.path.join(homeDirPath,
-          '.$studioAppName$major.$minor',
-          'config',
-          'plugins');
+      return globals.fs.path.join(
+        globals.fsUtils.homeDirPath,
+        '.$studioAppName$major.$minor',
+        'config',
+        'plugins',
+      );
     }
   }
 
@@ -198,7 +205,10 @@
     }
 
     _checkForStudio('/Applications');
-    _checkForStudio(globals.fs.path.join(homeDirPath, 'Applications'));
+    _checkForStudio(globals.fs.path.join(
+      globals.fsUtils.homeDirPath,
+      'Applications',
+    ));
 
     final String configuredStudioDir = globals.config.getValue('android-studio-dir') as String;
     if (configuredStudioDir != null) {
@@ -235,14 +245,17 @@
 
     // Read all $HOME/.AndroidStudio*/system/.home files. There may be several
     // pointing to the same installation, so we grab only the latest one.
-    if (homeDirPath != null && globals.fs.directory(homeDirPath).existsSync()) {
-      for (final FileSystemEntity entity in globals.fs.directory(homeDirPath).listSync(followLinks: false)) {
-        if (entity is Directory && entity.basename.startsWith('.AndroidStudio')) {
-          final AndroidStudio studio = AndroidStudio.fromHomeDot(entity);
-          if (studio != null && !_hasStudioAt(studio.directory, newerThan: studio.version)) {
-            studios.removeWhere((AndroidStudio other) => other.directory == studio.directory);
-            studios.add(studio);
-          }
+    if (globals.fsUtils.homeDirPath != null &&
+        globals.fs.directory(globals.fsUtils.homeDirPath).existsSync()) {
+      final Directory homeDir = globals.fs.directory(globals.fsUtils.homeDirPath);
+      for (final Directory entity in homeDir.listSync(followLinks: false).whereType<Directory>()) {
+        if (!entity.basename.startsWith('.AndroidStudio')) {
+          continue;
+        }
+        final AndroidStudio studio = AndroidStudio.fromHomeDot(entity);
+        if (studio != null && !_hasStudioAt(studio.directory, newerThan: studio.version)) {
+          studios.removeWhere((AndroidStudio other) => other.directory == studio.directory);
+          studios.add(studio);
         }
       }
     }
@@ -262,7 +275,7 @@
 
       // Add /opt/android-studio and $HOME/android-studio, if they exist.
       _checkWellKnownPath('/opt/android-studio');
-      _checkWellKnownPath('$homeDirPath/android-studio');
+      _checkWellKnownPath('${globals.fsUtils.homeDirPath}/android-studio');
     }
     return studios;
   }
diff --git a/packages/flutter_tools/lib/src/base/common.dart b/packages/flutter_tools/lib/src/base/common.dart
index 965e46c..58e17ae 100644
--- a/packages/flutter_tools/lib/src/base/common.dart
+++ b/packages/flutter_tools/lib/src/base/common.dart
@@ -2,23 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import '../globals.dart' as globals;
-
 /// Whether the tool started from the daemon, as opposed to the command line.
 // TODO(jonahwilliams): remove once IDE updates have rolled.
 bool isRunningFromDaemon = false;
 
-/// Return the absolute path of the user's home directory
-String get homeDirPath {
-  String path = globals.platform.isWindows
-      ? globals.platform.environment['USERPROFILE']
-      : globals.platform.environment['HOME'];
-  if (path != null) {
-    path = globals.fs.path.absolute(path);
-  }
-  return path;
-}
-
 /// Throw a specialized exception for expected situations
 /// where the tool should exit with a clear message to the user
 /// and no stack trace unless the --verbose option is specified.
diff --git a/packages/flutter_tools/lib/src/base/file_system.dart b/packages/flutter_tools/lib/src/base/file_system.dart
index 7d418ff..e71900b 100644
--- a/packages/flutter_tools/lib/src/base/file_system.dart
+++ b/packages/flutter_tools/lib/src/base/file_system.dart
@@ -140,4 +140,15 @@
     final String envKey = _platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
     return _platform.environment[envKey] ?? '.';
   }
+
+  /// Return the absolute path of the user's home directory
+  String get homeDirPath {
+    String path = _platform.isWindows
+        ? _platform.environment['USERPROFILE']
+        : _platform.environment['HOME'];
+    if (path != null) {
+      path = _fileSystem.path.absolute(path);
+    }
+    return path;
+  }
 }
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index b50b770..e6e4017 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -8,7 +8,6 @@
 import 'android/android_workflow.dart';
 import 'artifacts.dart';
 import 'base/async_guard.dart';
-import 'base/common.dart';
 import 'base/context.dart';
 import 'base/file_system.dart';
 import 'base/logger.dart';
@@ -748,7 +747,7 @@
 
   static Iterable<DoctorValidator> get installed {
     final List<DoctorValidator> validators = <DoctorValidator>[];
-    if (homeDirPath == null) {
+    if (globals.fsUtils.homeDirPath == null) {
       return validators;
     }
 
@@ -767,25 +766,24 @@
       validators.add(validator);
     }
 
-    for (final FileSystemEntity dir in globals.fs.directory(homeDirPath).listSync()) {
-      if (dir is Directory) {
-        final String name = globals.fs.path.basename(dir.path);
-        IntelliJValidator._idToTitle.forEach((String id, String title) {
-          if (name.startsWith('.$id')) {
-            final String version = name.substring(id.length + 1);
-            String installPath;
-            try {
-              installPath = globals.fs.file(globals.fs.path.join(dir.path, 'system', '.home')).readAsStringSync();
-            } catch (e) {
-              // ignored
-            }
-            if (installPath != null && globals.fs.isDirectorySync(installPath)) {
-              final String pluginsPath = globals.fs.path.join(dir.path, 'config', 'plugins');
-              addValidator(title, version, installPath, pluginsPath);
-            }
+    final Directory homeDir = globals.fs.directory(globals.fsUtils.homeDirPath);
+    for (final Directory dir in homeDir.listSync().whereType<Directory>()) {
+      final String name = globals.fs.path.basename(dir.path);
+      IntelliJValidator._idToTitle.forEach((String id, String title) {
+        if (name.startsWith('.$id')) {
+          final String version = name.substring(id.length + 1);
+          String installPath;
+          try {
+            installPath = globals.fs.file(globals.fs.path.join(dir.path, 'system', '.home')).readAsStringSync();
+          } catch (e) {
+            // ignored
           }
-        });
-      }
+          if (installPath != null && globals.fs.isDirectorySync(installPath)) {
+            final String pluginsPath = globals.fs.path.join(dir.path, 'config', 'plugins');
+            addValidator(title, version, installPath, pluginsPath);
+          }
+        }
+      });
     }
     return validators;
   }
@@ -804,7 +802,10 @@
 
   static Iterable<DoctorValidator> get installed {
     final List<DoctorValidator> validators = <DoctorValidator>[];
-    final List<String> installPaths = <String>['/Applications', globals.fs.path.join(homeDirPath, 'Applications')];
+    final List<String> installPaths = <String>[
+      '/Applications',
+      globals.fs.path.join(globals.fsUtils.homeDirPath, 'Applications'),
+    ];
 
     void checkForIntelliJ(Directory dir) {
       final String name = globals.fs.path.basename(dir.path);
@@ -861,7 +862,12 @@
     final List<String> split = version.split('.');
     final String major = split[0];
     final String minor = split[1];
-    return globals.fs.path.join(homeDirPath, 'Library', 'Application Support', '$id$major.$minor');
+    return globals.fs.path.join(
+      globals.fsUtils.homeDirPath,
+      'Library',
+      'Application Support',
+      '$id$major.$minor',
+    );
   }
 }
 
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 6fd9094..8d691c6 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -471,8 +471,15 @@
 
   String get logFilePath {
     return globals.platform.environment.containsKey('IOS_SIMULATOR_LOG_FILE_PATH')
-        ? globals.platform.environment['IOS_SIMULATOR_LOG_FILE_PATH'].replaceAll('%{id}', id)
-        : globals.fs.path.join(homeDirPath, 'Library', 'Logs', 'CoreSimulator', id, 'system.log');
+      ? globals.platform.environment['IOS_SIMULATOR_LOG_FILE_PATH'].replaceAll('%{id}', id)
+      : globals.fs.path.join(
+          globals.fsUtils.homeDirPath,
+          'Library',
+          'Logs',
+          'CoreSimulator',
+          id,
+          'system.log',
+        );
   }
 
   @override
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart
index e0ba702..7257afa 100644
--- a/packages/flutter_tools/lib/src/macos/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -129,7 +129,7 @@
       return true;
     }
     final String cocoapodsReposDir = globals.platform.environment['CP_REPOS_DIR']
-      ?? globals.fs.path.join(homeDirPath, '.cocoapods', 'repos');
+      ?? globals.fs.path.join(globals.fsUtils.homeDirPath, '.cocoapods', 'repos');
     return globals.fs.isDirectory(globals.fs.path.join(cocoapodsReposDir, 'master'));
   }
 
diff --git a/packages/flutter_tools/lib/src/vscode/vscode.dart b/packages/flutter_tools/lib/src/vscode/vscode.dart
index b110046..a1c9fd6 100644
--- a/packages/flutter_tools/lib/src/vscode/vscode.dart
+++ b/packages/flutter_tools/lib/src/vscode/vscode.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import '../base/common.dart';
 import '../base/file_system.dart';
 import '../base/utils.dart';
 import '../base/version.dart';
@@ -116,7 +115,12 @@
         '.vscode',
       ),
       _VsCodeInstallLocation(
-        globals.fs.path.join(homeDirPath, 'Applications', 'Visual Studio Code.app', 'Contents'),
+        globals.fs.path.join(
+          globals.fsUtils.homeDirPath,
+          'Applications',
+          'Visual Studio Code.app',
+          'Contents',
+        ),
         '.vscode',
       ),
       _VsCodeInstallLocation(
@@ -125,7 +129,12 @@
         isInsiders: true,
       ),
       _VsCodeInstallLocation(
-        globals.fs.path.join(homeDirPath, 'Applications', 'Visual Studio Code - Insiders.app', 'Contents'),
+        globals.fs.path.join(
+          globals.fsUtils.homeDirPath,
+          'Applications',
+          'Visual Studio Code - Insiders.app',
+          'Contents',
+        ),
         '.vscode-insiders',
         isInsiders: true,
       ),
@@ -154,31 +163,39 @@
 
     if (localAppData != null) {
       searchLocations.add(_VsCodeInstallLocation(
-          globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code'),
-          '.vscode'));
+        globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code'),
+        '.vscode',
+      ));
     }
     searchLocations.add(_VsCodeInstallLocation(
-        globals.fs.path.join(progFiles86, 'Microsoft VS Code'), '.vscode',
-        edition: '32-bit edition'));
+      globals.fs.path.join(progFiles86, 'Microsoft VS Code'),
+      '.vscode',
+      edition: '32-bit edition',
+    ));
     searchLocations.add(_VsCodeInstallLocation(
-        globals.fs.path.join(progFiles, 'Microsoft VS Code'), '.vscode',
-        edition: '64-bit edition'));
+      globals.fs.path.join(progFiles, 'Microsoft VS Code'),
+      '.vscode',
+      edition: '64-bit edition',
+    ));
     if (localAppData != null) {
       searchLocations.add(_VsCodeInstallLocation(
-          globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code Insiders'),
-          '.vscode-insiders',
-          isInsiders: true));
+        globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code Insiders'),
+        '.vscode-insiders',
+        isInsiders: true,
+      ));
     }
     searchLocations.add(_VsCodeInstallLocation(
-        globals.fs.path.join(progFiles86, 'Microsoft VS Code Insiders'),
-        '.vscode-insiders',
-        edition: '32-bit edition',
-        isInsiders: true));
+      globals.fs.path.join(progFiles86, 'Microsoft VS Code Insiders'),
+      '.vscode-insiders',
+      edition: '32-bit edition',
+      isInsiders: true,
+    ));
     searchLocations.add(_VsCodeInstallLocation(
-        globals.fs.path.join(progFiles, 'Microsoft VS Code Insiders'),
-        '.vscode-insiders',
-        edition: '64-bit edition',
-        isInsiders: true));
+      globals.fs.path.join(progFiles, 'Microsoft VS Code Insiders'),
+      '.vscode-insiders',
+      edition: '64-bit edition',
+      isInsiders: true,
+    ));
 
     return _findInstalled(searchLocations);
   }
@@ -192,7 +209,11 @@
   static List<VsCode> _installedLinux() {
     return _findInstalled(<_VsCodeInstallLocation>[
       const _VsCodeInstallLocation('/usr/share/code', '.vscode'),
-      const _VsCodeInstallLocation('/usr/share/code-insiders', '.vscode-insiders', isInsiders: true),
+      const _VsCodeInstallLocation(
+        '/usr/share/code-insiders',
+        '.vscode-insiders',
+        isInsiders: true,
+      ),
     ]);
   }
 
@@ -206,9 +227,16 @@
 
     for (final _VsCodeInstallLocation searchLocation in searchLocations) {
       if (globals.fs.isDirectorySync(searchLocation.installPath)) {
-        final String extensionDirectory =
-            globals.fs.path.join(homeDirPath, searchLocation.extensionsFolder, 'extensions');
-        results.add(VsCode.fromDirectory(searchLocation.installPath, extensionDirectory, edition: searchLocation.edition));
+        final String extensionDirectory = globals.fs.path.join(
+          globals.fsUtils.homeDirPath,
+          searchLocation.extensionsFolder,
+          'extensions',
+        );
+        results.add(VsCode.fromDirectory(
+          searchLocation.installPath,
+          extensionDirectory,
+          edition: searchLocation.edition,
+        ));
       }
     }
 
@@ -235,8 +263,13 @@
 }
 
 class _VsCodeInstallLocation {
-  const _VsCodeInstallLocation(this.installPath, this.extensionsFolder, { this.edition, bool isInsiders })
-    : isInsiders = isInsiders ?? false;
+  const _VsCodeInstallLocation(
+    this.installPath,
+    this.extensionsFolder, {
+    this.edition,
+    bool isInsiders
+  }) : isInsiders = isInsiders ?? false;
+
   final String installPath;
   final String extensionsFolder;
   final String edition;