Unverified Commit 4954a46f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] shrink API surface of Android SDK (#63867)

Attempt to simplify the Android SDK interface ahead of refactoring it. The locateAndroidSdk static method is called at startup to locate the android SDK, returning null if it cannot be found. These helper methods attempted to first look up the AndroidSDK if it was already null - which could only cover the case where someone installed the Android SDK while flutter was running (possibly through an IDE)
parent 6f781314
......@@ -56,7 +56,7 @@ class AndroidEmulators extends EmulatorDiscovery {
/// Return the list of available emulator AVDs.
Future<List<AndroidEmulator>> _getEmulatorAvds() async {
final String emulatorPath = getEmulatorPath(_androidSdk);
final String emulatorPath = _androidSdk.emulatorPath;
if (emulatorPath == null) {
return <AndroidEmulator>[];
}
......@@ -81,7 +81,7 @@ class AndroidEmulators extends EmulatorDiscovery {
AndroidEmulator _loadEmulatorInfo(String id) {
id = id.trim();
final String avdPath = getAvdPath();
final String avdPath = _androidSdk.getAvdPath();
final AndroidEmulator androidEmulatorWithoutProperties = AndroidEmulator(
id,
processManager: _processManager,
......@@ -150,7 +150,7 @@ class AndroidEmulator extends Emulator {
@override
Future<void> launch() async {
final Process process = await _processUtils.start(
<String>[getEmulatorPath(_androidSdk), '-avd', id],
<String>[_androidSdk.emulatorPath, '-avd', id],
);
// Record output from the emulator process.
......
......@@ -19,20 +19,6 @@ import 'android_studio.dart';
const String kAndroidHome = 'ANDROID_HOME';
const String kAndroidSdkRoot = 'ANDROID_SDK_ROOT';
// Android SDK layout:
// $ANDROID_SDK_ROOT/platform-tools/adb
// $ANDROID_SDK_ROOT/build-tools/19.1.0/aapt, dx, zipalign
// $ANDROID_SDK_ROOT/build-tools/22.0.1/aapt
// $ANDROID_SDK_ROOT/build-tools/23.0.2/aapt
// $ANDROID_SDK_ROOT/build-tools/24.0.0-preview/aapt
// $ANDROID_SDK_ROOT/build-tools/25.0.2/apksigner
// $ANDROID_SDK_ROOT/platforms/android-22/android.jar
// $ANDROID_SDK_ROOT/platforms/android-23/android.jar
// $ANDROID_SDK_ROOT/platforms/android-N/android.jar
final RegExp _numberedAndroidPlatformRe = RegExp(r'^android-([0-9]+)$');
final RegExp _sdkVersionRe = RegExp(r'^ro.build.version.sdk=([0-9]+)$');
......@@ -43,66 +29,29 @@ const int minimumAndroidSdkVersion = 25;
/// This should be used over accessing androidSdk.adbPath directly because it
/// will work for those users who have Android Platform Tools installed but
/// not the full SDK.
String getAdbPath([ AndroidSdk existingSdk ]) {
String getAdbPath(AndroidSdk existingSdk) {
if (existingSdk?.adbPath != null) {
return existingSdk.adbPath;
}
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
if (sdk?.latestVersion == null) {
if (existingSdk?.latestVersion == null) {
return globals.os.which('adb')?.path;
} else {
return sdk?.adbPath;
}
return existingSdk?.adbPath;
}
/// Locate 'emulator'. Prefer to use one from an Android SDK, if we can locate that.
/// This should be used over accessing androidSdk.emulatorPath directly because it
/// will work for those users who have Android Tools installed but
/// not the full SDK.
String getEmulatorPath([ AndroidSdk existingSdk ]) {
return existingSdk?.emulatorPath ??
AndroidSdk.locateAndroidSdk()?.emulatorPath;
}
/// Locate the path for storing AVD emulator images. Returns null if none found.
String getAvdPath() {
final List<String> searchPaths = <String>[
globals.platform.environment['ANDROID_AVD_HOME'],
if (globals.platform.environment['HOME'] != null)
globals.fs.path.join(globals.platform.environment['HOME'], '.android', 'avd'),
];
if (globals.platform.isWindows) {
final String homeDrive = globals.platform.environment['HOMEDRIVE'];
final String homePath = globals.platform.environment['HOMEPATH'];
if (homeDrive != null && homePath != null) {
// Can't use path.join for HOMEDRIVE/HOMEPATH
// https://github.com/dart-lang/path/issues/37
final String home = homeDrive + homePath;
searchPaths.add(globals.fs.path.join(home, '.android', 'avd'));
}
}
// Android SDK layout:
return searchPaths.where((String p) => p != null).firstWhere(
(String p) => globals.fs.directory(p).existsSync(),
orElse: () => null,
);
}
// $ANDROID_SDK_ROOT/platform-tools/adb
/// Locate 'avdmanager'. Prefer to use one from an Android SDK, if we can locate that.
/// This should be used over accessing androidSdk.avdManagerPath directly because it
/// will work for those users who have Android Tools installed but
/// not the full SDK.
String getAvdManagerPath([ AndroidSdk existingSdk ]) {
return existingSdk?.avdManagerPath ??
AndroidSdk.locateAndroidSdk()?.avdManagerPath;
}
// $ANDROID_SDK_ROOT/build-tools/19.1.0/aapt, dx, zipalign
// $ANDROID_SDK_ROOT/build-tools/22.0.1/aapt
// $ANDROID_SDK_ROOT/build-tools/23.0.2/aapt
// $ANDROID_SDK_ROOT/build-tools/24.0.0-preview/aapt
// $ANDROID_SDK_ROOT/build-tools/25.0.2/apksigner
// $ANDROID_SDK_ROOT/platforms/android-22/android.jar
// $ANDROID_SDK_ROOT/platforms/android-23/android.jar
// $ANDROID_SDK_ROOT/platforms/android-N/android.jar
class AndroidSdk {
AndroidSdk(this.directory) {
reinitialize();
......@@ -240,6 +189,32 @@ class AndroidSdk {
String get avdManagerPath => getAvdManagerPath();
/// Locate the path for storing AVD emulator images. Returns null if none found.
String getAvdPath() {
final List<String> searchPaths = <String>[
globals.platform.environment['ANDROID_AVD_HOME'],
if (globals.platform.environment['HOME'] != null)
globals.fs.path.join(globals.platform.environment['HOME'], '.android', 'avd'),
];
if (globals.platform.isWindows) {
final String homeDrive = globals.platform.environment['HOMEDRIVE'];
final String homePath = globals.platform.environment['HOMEPATH'];
if (homeDrive != null && homePath != null) {
// Can't use path.join for HOMEDRIVE/HOMEPATH
// https://github.com/dart-lang/path/issues/37
final String home = homeDrive + homePath;
searchPaths.add(globals.fs.path.join(home, '.android', 'avd'));
}
}
return searchPaths.where((String p) => p != null).firstWhere(
(String p) => globals.fs.directory(p).existsSync(),
orElse: () => null,
);
}
Directory get _platformsDir => globals.fs.directory(globals.fs.path.join(directory, 'platforms'));
Iterable<Directory> get _platforms {
......
......@@ -64,7 +64,7 @@ class AndroidWorkflow implements Workflow {
bool get canLaunchDevices => _androidSdk != null && _androidSdk.validateSdkWellFormed().isEmpty;
@override
bool get canListEmulators => getEmulatorPath(_androidSdk) != null;
bool get canListEmulators => _androidSdk.emulatorPath != null;
}
class AndroidValidator extends DoctorValidator {
......
......@@ -140,7 +140,7 @@ class EmulatorManager {
.trim();
}
final RunResult runResult = await _processUtils.run(<String>[
getAvdManagerPath(_androidSdk),
_androidSdk?.avdManagerPath,
'create',
'avd',
'-n', name,
......@@ -163,7 +163,7 @@ class EmulatorManager {
Future<String> _getPreferredAvailableDevice() async {
final List<String> args = <String>[
getAvdManagerPath(_androidSdk),
_androidSdk?.avdManagerPath,
'list',
'device',
'-c',
......@@ -191,7 +191,7 @@ class EmulatorManager {
// It seems that to get the available list of images, we need to send a
// request to create without the image and it'll provide us a list :-(
final List<String> args = <String>[
getAvdManagerPath(_androidSdk),
_androidSdk?.avdManagerPath,
'create',
'avd',
'-n', 'temp',
......
......@@ -4,8 +4,6 @@
import 'dart:async';
import 'package:flutter_tools/src/android/android_sdk.dart'
show getEmulatorPath;
import 'package:flutter_tools/src/android/android_emulator.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/logger.dart';
......@@ -144,8 +142,6 @@ void main() {
logger: BufferLogger.test(),
);
expect(getEmulatorPath(mockSdk), mockSdk.emulatorPath);
final Completer<void> completer = Completer<void>();
FakeAsync().run((FakeAsync time) {
unawaited(emulator.launch().whenComplete(completer.complete));
......
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