2019-11-27 23:04:02 +00:00
|
|
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
2018-04-18 10:37:59 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2021-01-27 23:17:53 +00:00
|
|
|
// @dart = 2.8
|
|
|
|
|
2021-01-27 21:07:07 +00:00
|
|
|
import 'package:file/file.dart';
|
2020-05-27 17:10:30 +00:00
|
|
|
import 'package:file/memory.dart';
|
2021-05-01 00:39:03 +00:00
|
|
|
import 'package:flutter_tools/src/android/android_sdk.dart';
|
2020-05-27 17:10:30 +00:00
|
|
|
import 'package:flutter_tools/src/android/android_workflow.dart';
|
|
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
2019-06-19 16:10:39 +00:00
|
|
|
import 'package:flutter_tools/src/device.dart';
|
2018-04-18 10:37:59 +00:00
|
|
|
import 'package:flutter_tools/src/emulator.dart';
|
2018-07-19 09:32:44 +00:00
|
|
|
import 'package:flutter_tools/src/ios/ios_emulators.dart';
|
2019-05-25 02:51:02 +00:00
|
|
|
import 'package:flutter_tools/src/macos/xcode.dart';
|
2021-05-01 00:39:03 +00:00
|
|
|
import 'package:test/fake.dart';
|
2018-04-18 10:37:59 +00:00
|
|
|
|
2019-07-13 18:51:44 +00:00
|
|
|
import '../src/common.dart';
|
|
|
|
import '../src/context.dart';
|
2021-02-26 19:13:32 +00:00
|
|
|
import '../src/fakes.dart';
|
2018-04-18 10:37:59 +00:00
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
const FakeEmulator emulator1 = FakeEmulator('Nexus_5', 'Nexus 5', 'Google');
|
|
|
|
const FakeEmulator emulator2 = FakeEmulator('Nexus_5X_API_27_x86', 'Nexus 5X', 'Google');
|
|
|
|
const FakeEmulator emulator3 = FakeEmulator('iOS Simulator', 'iOS Simulator', 'Apple');
|
|
|
|
const List<Emulator> emulators = <Emulator>[
|
|
|
|
emulator1,
|
|
|
|
emulator2,
|
|
|
|
emulator3,
|
|
|
|
];
|
|
|
|
|
|
|
|
// We have to send a command that fails in order to get the list of valid
|
2021-05-01 00:39:03 +00:00
|
|
|
// system images paths. This is an example of the output to use in the fake.
|
2020-05-27 17:10:30 +00:00
|
|
|
const String fakeCreateFailureOutput =
|
|
|
|
'Error: Package path (-k) not specified. Valid system image paths are:\n'
|
|
|
|
'system-images;android-27;google_apis;x86\n'
|
|
|
|
'system-images;android-P;google_apis;x86\n'
|
|
|
|
'system-images;android-27;google_apis_playstore;x86\n'
|
|
|
|
'null\n'; // Yep, these really end with null (on dantup's machine at least)
|
|
|
|
|
|
|
|
const FakeCommand kListEmulatorsCommand = FakeCommand(
|
|
|
|
command: <String>['avdmanager', 'create', 'avd', '-n', 'temp'],
|
|
|
|
stderr: fakeCreateFailureOutput,
|
|
|
|
exitCode: 1,
|
|
|
|
);
|
|
|
|
|
2018-04-18 10:37:59 +00:00
|
|
|
void main() {
|
2021-01-27 21:07:07 +00:00
|
|
|
FakeProcessManager fakeProcessManager;
|
2021-05-01 00:39:03 +00:00
|
|
|
FakeAndroidSdk sdk;
|
2021-01-27 21:07:07 +00:00
|
|
|
FileSystem fileSystem;
|
|
|
|
Xcode xcode;
|
2018-06-28 07:07:40 +00:00
|
|
|
|
|
|
|
setUp(() {
|
2021-01-27 21:07:07 +00:00
|
|
|
fileSystem = MemoryFileSystem.test();
|
2021-04-15 21:19:02 +00:00
|
|
|
fakeProcessManager = FakeProcessManager.empty();
|
2021-05-01 00:39:03 +00:00
|
|
|
sdk = FakeAndroidSdk();
|
2021-01-27 21:07:07 +00:00
|
|
|
xcode = Xcode.test(processManager: fakeProcessManager, fileSystem: fileSystem);
|
2018-06-28 07:07:40 +00:00
|
|
|
|
2021-05-01 00:39:03 +00:00
|
|
|
sdk
|
|
|
|
..avdManagerPath = 'avdmanager'
|
|
|
|
..emulatorPath = 'emulator'
|
|
|
|
..adbPath = 'adb';
|
2018-06-28 07:07:40 +00:00
|
|
|
});
|
|
|
|
|
2018-04-18 10:37:59 +00:00
|
|
|
group('EmulatorManager', () {
|
2020-05-27 17:10:30 +00:00
|
|
|
// iOS discovery uses context.
|
2018-04-18 10:37:59 +00:00
|
|
|
testUsingContext('getEmulators', () async {
|
|
|
|
// Test that EmulatorManager.getEmulators() doesn't throw.
|
2020-05-27 17:10:30 +00:00
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['emulator', '-list-avds'],
|
|
|
|
stdout: 'existing-avd-1',
|
|
|
|
),
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2021-03-06 02:38:15 +00:00
|
|
|
await expectLater(() async => emulatorManager.getAllAvailableEmulators(),
|
2020-05-27 17:10:30 +00:00
|
|
|
returnsNormally);
|
|
|
|
});
|
|
|
|
|
2020-10-05 15:57:04 +00:00
|
|
|
testUsingContext('getEmulators with no Android SDK', () async {
|
|
|
|
// Test that EmulatorManager.getEmulators() doesn't throw when there's no Android SDK.
|
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['emulator', '-list-avds'],
|
|
|
|
stdout: 'existing-avd-1',
|
|
|
|
),
|
|
|
|
]),
|
|
|
|
androidSdk: null,
|
|
|
|
androidWorkflow: AndroidWorkflow(
|
|
|
|
androidSdk: null,
|
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-10-05 15:57:04 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2021-03-06 02:38:15 +00:00
|
|
|
await expectLater(() async => emulatorManager.getAllAvailableEmulators(),
|
2020-10-05 15:57:04 +00:00
|
|
|
returnsNormally);
|
|
|
|
});
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
testWithoutContext('getEmulatorsById', () async {
|
|
|
|
final TestEmulatorManager testEmulatorManager = TestEmulatorManager(emulators);
|
|
|
|
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('Nexus_5'), <Emulator>[emulator1]);
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('Nexus_5X'), <Emulator>[emulator2]);
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('Nexus_5X_API_27_x86'), <Emulator>[emulator2]);
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('Nexus'), <Emulator>[emulator1, emulator2]);
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('iOS Simulator'), <Emulator>[emulator3]);
|
|
|
|
expect(await testEmulatorManager.getEmulatorsMatching('ios'), <Emulator>[emulator3]);
|
2018-04-18 10:37:59 +00:00
|
|
|
});
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
testUsingContext('create emulator with a missing avdmanager does not crash.', () async {
|
2021-05-01 00:39:03 +00:00
|
|
|
sdk.avdManagerPath = null;
|
2020-05-27 17:10:30 +00:00
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['emulator', '-list-avds'],
|
|
|
|
stdout: 'existing-avd-1',
|
|
|
|
),
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
final CreateEmulatorResult result = await emulatorManager.createEmulator();
|
|
|
|
|
|
|
|
expect(result.success, false);
|
|
|
|
expect(result.error, contains('avdmanager is missing from the Android SDK'));
|
2018-04-18 10:37:59 +00:00
|
|
|
});
|
2018-06-28 07:07:40 +00:00
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
// iOS discovery uses context.
|
2019-03-07 20:09:28 +00:00
|
|
|
testUsingContext('create emulator with an empty name does not fail', () async {
|
2020-05-27 17:10:30 +00:00
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['emulator', '-list-avds'],
|
|
|
|
stdout: 'existing-avd-1',
|
|
|
|
),
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['avdmanager', 'list', 'device', '-c'],
|
|
|
|
stdout: 'test\ntest2\npixel\npixel-xl\n',
|
|
|
|
),
|
|
|
|
kListEmulatorsCommand,
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>[
|
|
|
|
'avdmanager',
|
|
|
|
'create',
|
|
|
|
'avd',
|
|
|
|
'-n',
|
|
|
|
'flutter_emulator',
|
|
|
|
'-k',
|
|
|
|
'system-images;android-27;google_apis_playstore;x86',
|
|
|
|
'-d',
|
|
|
|
'pixel',
|
|
|
|
],
|
|
|
|
)
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
final CreateEmulatorResult result = await emulatorManager.createEmulator();
|
|
|
|
|
|
|
|
expect(result.success, true);
|
2018-06-28 07:07:40 +00:00
|
|
|
});
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
testWithoutContext('create emulator with a unique name does not throw', () async {
|
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['avdmanager', 'list', 'device', '-c'],
|
|
|
|
stdout: 'test\ntest2\npixel\npixel-xl\n',
|
|
|
|
),
|
|
|
|
kListEmulatorsCommand,
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>[
|
|
|
|
'avdmanager',
|
|
|
|
'create',
|
|
|
|
'avd',
|
|
|
|
// The specified name is given with the -n flag.
|
|
|
|
'-n',
|
|
|
|
'test',
|
|
|
|
'-k',
|
|
|
|
'system-images;android-27;google_apis_playstore;x86',
|
|
|
|
'-d',
|
|
|
|
'pixel',
|
|
|
|
],
|
|
|
|
)
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'test');
|
|
|
|
|
|
|
|
expect(result.success, true);
|
2018-06-28 07:07:40 +00:00
|
|
|
});
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
testWithoutContext('create emulator with an existing name errors', () async {
|
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['avdmanager', 'list', 'device', '-c'],
|
|
|
|
stdout: 'test\ntest2\npixel\npixel-xl\n',
|
|
|
|
),
|
|
|
|
kListEmulatorsCommand,
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>[
|
|
|
|
'avdmanager',
|
|
|
|
'create',
|
|
|
|
'avd',
|
|
|
|
'-n',
|
|
|
|
'existing-avd-1',
|
|
|
|
'-k',
|
|
|
|
'system-images;android-27;google_apis_playstore;x86',
|
|
|
|
'-d',
|
|
|
|
'pixel',
|
|
|
|
],
|
|
|
|
exitCode: 1,
|
|
|
|
stderr: "Error: Android Virtual Device 'existing-avd-1' already exists.\n"
|
|
|
|
'Use --force if you want to replace it.'
|
|
|
|
)
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'existing-avd-1');
|
|
|
|
|
|
|
|
expect(result.success, false);
|
2018-06-28 07:07:40 +00:00
|
|
|
});
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
// iOS discovery uses context.
|
2019-03-07 20:09:28 +00:00
|
|
|
testUsingContext('create emulator without a name but when default exists adds a suffix', () async {
|
2020-05-27 17:10:30 +00:00
|
|
|
final EmulatorManager emulatorManager = EmulatorManager(
|
|
|
|
fileSystem: MemoryFileSystem.test(),
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
processManager: FakeProcessManager.list(<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['emulator', '-list-avds'],
|
|
|
|
stdout: 'existing-avd-1\nflutter_emulator',
|
|
|
|
),
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['avdmanager', 'list', 'device', '-c'],
|
|
|
|
stdout: 'test\ntest2\npixel\npixel-xl\n',
|
|
|
|
),
|
|
|
|
kListEmulatorsCommand,
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>[
|
|
|
|
'avdmanager',
|
|
|
|
'create',
|
|
|
|
'avd',
|
|
|
|
// a "_2" suffix is added to disambiguate from the existing emulator.
|
|
|
|
'-n',
|
|
|
|
'flutter_emulator_2',
|
|
|
|
'-k',
|
|
|
|
'system-images;android-27;google_apis_playstore;x86',
|
|
|
|
'-d',
|
|
|
|
'pixel',
|
|
|
|
],
|
|
|
|
)
|
|
|
|
]),
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-05-27 17:10:30 +00:00
|
|
|
androidWorkflow: AndroidWorkflow(
|
2021-05-01 00:39:03 +00:00
|
|
|
androidSdk: sdk,
|
2020-07-16 16:51:59 +00:00
|
|
|
featureFlags: TestFeatureFlags(),
|
2021-02-12 22:25:30 +00:00
|
|
|
operatingSystemUtils: FakeOperatingSystemUtils(),
|
2020-05-27 17:10:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
final CreateEmulatorResult result = await emulatorManager.createEmulator();
|
|
|
|
|
|
|
|
expect(result.success, true);
|
|
|
|
expect(result.emulatorName, 'flutter_emulator_2');
|
2018-06-28 07:07:40 +00:00
|
|
|
});
|
2018-04-18 10:37:59 +00:00
|
|
|
});
|
2018-07-19 09:32:44 +00:00
|
|
|
|
|
|
|
group('ios_emulators', () {
|
|
|
|
testUsingContext('runs correct launch commands', () async {
|
2021-01-27 21:07:07 +00:00
|
|
|
fileSystem.directory('/fake/Xcode.app/Contents/Developer/Applications/Simulator.app').createSync(recursive: true);
|
|
|
|
fakeProcessManager.addCommands(
|
|
|
|
<FakeCommand>[
|
|
|
|
const FakeCommand(
|
|
|
|
command: <String>['/usr/bin/xcode-select', '--print-path'],
|
|
|
|
stdout: '/fake/Xcode.app/Contents/Developer',
|
|
|
|
),
|
|
|
|
const FakeCommand(command: <String>[
|
|
|
|
'open',
|
|
|
|
'-n',
|
|
|
|
'-a',
|
|
|
|
'/fake/Xcode.app/Contents/Developer/Applications/Simulator.app',
|
|
|
|
]),
|
|
|
|
const FakeCommand(command: <String>[
|
|
|
|
'open',
|
|
|
|
'-a',
|
|
|
|
'/fake/Xcode.app/Contents/Developer/Applications/Simulator.app',
|
|
|
|
])
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
2020-12-16 19:52:59 +00:00
|
|
|
const Emulator emulator = IOSEmulator('ios');
|
2018-07-19 09:32:44 +00:00
|
|
|
await emulator.launch();
|
2021-01-27 21:07:07 +00:00
|
|
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
2018-07-19 09:32:44 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-01-27 21:07:07 +00:00
|
|
|
ProcessManager: () => fakeProcessManager,
|
|
|
|
Xcode: () => xcode,
|
|
|
|
FileSystem: () => fileSystem,
|
2018-07-19 09:32:44 +00:00
|
|
|
});
|
|
|
|
});
|
2018-04-18 10:37:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class TestEmulatorManager extends EmulatorManager {
|
|
|
|
TestEmulatorManager(this.allEmulators);
|
|
|
|
|
2018-10-04 05:28:07 +00:00
|
|
|
final List<Emulator> allEmulators;
|
|
|
|
|
2018-04-18 10:37:59 +00:00
|
|
|
@override
|
2018-05-03 16:12:31 +00:00
|
|
|
Future<List<Emulator>> getAllAvailableEmulators() {
|
2018-09-12 06:29:29 +00:00
|
|
|
return Future<List<Emulator>>.value(allEmulators);
|
2018-04-18 10:37:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 17:10:30 +00:00
|
|
|
class FakeEmulator extends Emulator {
|
|
|
|
const FakeEmulator(String id, this.name, this.manufacturer)
|
2019-01-29 20:47:16 +00:00
|
|
|
: super(id, true);
|
2018-04-18 10:37:59 +00:00
|
|
|
|
|
|
|
@override
|
2018-04-18 12:43:22 +00:00
|
|
|
final String name;
|
2018-06-28 07:07:40 +00:00
|
|
|
|
2018-04-18 12:43:22 +00:00
|
|
|
@override
|
|
|
|
final String manufacturer;
|
2018-06-28 07:07:40 +00:00
|
|
|
|
2019-06-19 16:10:39 +00:00
|
|
|
@override
|
|
|
|
Category get category => Category.mobile;
|
|
|
|
|
|
|
|
@override
|
2020-12-16 19:52:59 +00:00
|
|
|
PlatformType get platformType => PlatformType.android;
|
2019-06-19 16:10:39 +00:00
|
|
|
|
2018-04-18 13:50:16 +00:00
|
|
|
@override
|
2018-06-14 06:59:50 +00:00
|
|
|
Future<void> launch() {
|
2018-09-12 06:29:29 +00:00
|
|
|
throw UnimplementedError('Not implemented in Mock');
|
2018-04-18 13:50:16 +00:00
|
|
|
}
|
2018-04-18 10:37:59 +00:00
|
|
|
}
|
2021-05-01 00:39:03 +00:00
|
|
|
|
|
|
|
class FakeAndroidSdk extends Fake implements AndroidSdk {
|
|
|
|
@override
|
|
|
|
String avdManagerPath;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String emulatorPath;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String adbPath;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String getAvdManagerPath() => avdManagerPath;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String getAvdPath() => 'avd';
|
|
|
|
|
|
|
|
@override
|
|
|
|
Map<String, String> get sdkManagerEnv => <String, String>{};
|
|
|
|
}
|