Add a --no-http flag to start command
This flag builds a local FLX file and pushes that to the device instead of
using an HTTP server.
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 09a2061..f705622 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -66,16 +66,15 @@
ApplicationPackageStore({ this.android, this.iOS, this.iOSSimulator });
- ApplicationPackage getPackageForPlatform(BuildPlatform platform) {
+ ApplicationPackage getPackageForPlatform(TargetPlatform platform) {
switch (platform) {
- case BuildPlatform.android:
+ case TargetPlatform.android:
return android;
- case BuildPlatform.iOS:
+ case TargetPlatform.iOS:
return iOS;
- case BuildPlatform.iOSSimulator:
+ case TargetPlatform.iOSSimulator:
return iOSSimulator;
- case BuildPlatform.mac:
- case BuildPlatform.linux:
+ case TargetPlatform.linux:
return null;
}
}
@@ -86,31 +85,32 @@
IOSApp iOSSimulator;
for (BuildConfiguration config in configs) {
- switch (config.platform) {
- case BuildPlatform.android:
+ switch (config.targetPlatform) {
+ case TargetPlatform.android:
assert(android == null);
- String localPath = config.type == BuildType.prebuilt ?
- await ArtifactStore.getPath(Artifact.flutterShell) :
- path.join(config.buildDir, 'apks', AndroidApk._defaultName);
- android = new AndroidApk(localPath: localPath);
+ if (config.type != BuildType.prebuilt) {
+ String localPath = path.join(config.buildDir, 'apks', AndroidApk._defaultName);
+ android = new AndroidApk(localPath: localPath);
+ } else {
+ Artifact artifact = ArtifactStore.getArtifact(
+ type: ArtifactType.shell, targetPlatform: TargetPlatform.android);
+ android = new AndroidApk(localPath: await ArtifactStore.getPath(artifact));
+ }
break;
- case BuildPlatform.iOS:
+ case TargetPlatform.iOS:
assert(iOS == null);
assert(config.type != BuildType.prebuilt);
iOS = new IOSApp(localPath: path.join(config.buildDir, IOSApp._defaultName));
break;
- case BuildPlatform.iOSSimulator:
+ case TargetPlatform.iOSSimulator:
assert(iOSSimulator == null);
assert(config.type != BuildType.prebuilt);
iOSSimulator = new IOSApp(localPath: path.join(config.buildDir, IOSApp._defaultName));
break;
- case BuildPlatform.mac:
- case BuildPlatform.linux:
- // TODO(abarth): Support mac and linux targets.
- assert(false);
+ case TargetPlatform.linux:
break;
}
}
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index 9bd6a06..5e39e47 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -10,15 +10,147 @@
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
+import 'build_configuration.dart';
+
final Logger _logging = new Logger('sky_tools.artifacts');
-enum Artifact {
- flutterCompiler,
- flutterShell,
- skyViewerMojo,
+const String _kShellCategory = 'shell';
+const String _kViewerCategory = 'viewer';
+
+String _getNameForHostPlatform(HostPlatform platform) {
+ switch (platform) {
+ case HostPlatform.linux:
+ return 'linux-x64';
+ case HostPlatform.mac:
+ return 'darwin-x64';
+ }
+}
+
+String _getNameForTargetPlatform(TargetPlatform platform) {
+ switch (platform) {
+ case TargetPlatform.android:
+ return 'android-arm';
+ case TargetPlatform.iOS:
+ return 'ios-arm';
+ case TargetPlatform.iOSSimulator:
+ return 'ios-x64';
+ case TargetPlatform.linux:
+ return 'linux-x64';
+ }
+}
+
+// Keep in sync with https://github.com/flutter/engine/blob/master/sky/tools/big_red_button.py#L50
+String _getCloudStorageBaseUrl({String category, String platform, String revision}) {
+ if (platform == 'darwin-x64') {
+ // In the fullness of time, we'll have a consistent URL pattern for all of
+ // our artifacts, but, for the time being, darwin artifacts are stored in a
+ // different cloud storage bucket.
+ return 'https://storage.googleapis.com/mojo_infra/flutter/${platform}/${revision}/';
+ }
+ return 'https://storage.googleapis.com/mojo/sky/${category}/${platform}/${revision}/';
+}
+
+enum ArtifactType {
+ snapshot,
+ shell,
+ viewer,
+}
+
+class Artifact {
+ const Artifact._({
+ this.name,
+ this.fileName,
+ this.category,
+ this.type,
+ this.hostPlatform,
+ this.targetPlatform
+ });
+
+ final String name;
+ final String fileName;
+ final String category; // TODO(abarth): Remove categories.
+ final ArtifactType type;
+ final HostPlatform hostPlatform;
+ final TargetPlatform targetPlatform;
+
+ String get platform {
+ if (targetPlatform != null)
+ return _getNameForTargetPlatform(targetPlatform);
+ if (hostPlatform != null)
+ return _getNameForHostPlatform(hostPlatform);
+ assert(false);
+ return null;
+ }
+
+ String getUrl(String revision) {
+ return _getCloudStorageBaseUrl(category: category, platform: platform, revision: revision) + fileName;
+ }
+
+ // Whether the artifact needs to be marked as executable on disk.
+ bool get executable => type == ArtifactType.snapshot;
}
class ArtifactStore {
+ static const List<Artifact> knownArtifacts = const <Artifact>[
+ const Artifact._(
+ name: 'Sky Shell',
+ fileName: 'SkyShell.apk',
+ category: _kShellCategory,
+ type: ArtifactType.shell,
+ targetPlatform: TargetPlatform.android
+ ),
+ const Artifact._(
+ name: 'Sky Snapshot',
+ fileName: 'sky_snapshot',
+ category: _kShellCategory,
+ type: ArtifactType.snapshot,
+ hostPlatform: HostPlatform.linux
+ ),
+ const Artifact._(
+ name: 'Sky Snapshot',
+ fileName: 'sky_snapshot',
+ category: _kShellCategory,
+ type: ArtifactType.snapshot,
+ hostPlatform: HostPlatform.mac
+ ),
+ const Artifact._(
+ name: 'Sky Viewer',
+ fileName: 'sky_viewer.mojo',
+ category: _kViewerCategory,
+ type: ArtifactType.viewer,
+ targetPlatform: TargetPlatform.android
+ ),
+ const Artifact._(
+ name: 'Sky Viewer',
+ fileName: 'sky_viewer.mojo',
+ category: _kViewerCategory,
+ type: ArtifactType.viewer,
+ targetPlatform: TargetPlatform.linux
+ ),
+ ];
+
+ static Artifact getArtifact({
+ ArtifactType type,
+ HostPlatform hostPlatform,
+ TargetPlatform targetPlatform
+ }) {
+ for (Artifact artifact in ArtifactStore.knownArtifacts) {
+ if (type != null &&
+ type != artifact.type)
+ continue;
+ if (hostPlatform != null &&
+ artifact.hostPlatform != null &&
+ hostPlatform != artifact.hostPlatform)
+ continue;
+ if (targetPlatform != null &&
+ artifact.targetPlatform != null &&
+ targetPlatform != artifact.targetPlatform)
+ continue;
+ return artifact;
+ }
+ return null;
+ }
+
static String packageRoot;
static String _engineRevision;
@@ -31,102 +163,68 @@
return _engineRevision;
}
- // Keep in sync with https://github.com/flutter/engine/blob/master/sky/tools/big_red_button.py#L50
- static String googleStorageUrl(String category, String platform) {
- return 'https://storage.googleapis.com/mojo/sky/${category}/${platform}/${engineRevision}/';
+ static String getCloudStorageBaseUrl(String category, String platform) {
+ return _getCloudStorageBaseUrl(category: category, platform: platform, revision: engineRevision);
}
static Future _downloadFile(String url, File file) async {
- print('Downloading $url to ${file.path}.');
+ _logging.info('Downloading $url to ${file.path}.');
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
- _logging.fine('Received response');
- if (response.statusCode != 200) throw new Exception(response.reasonPhrase);
+ _logging.fine('Received response statusCode=${response.statusCode}');
+ if (response.statusCode != 200)
+ throw new Exception(response.reasonPhrase);
IOSink sink = file.openWrite();
await sink.addStream(response);
await sink.close();
_logging.fine('Wrote file');
}
- static Future<Directory> _cacheDir() async {
+ static Directory _getBaseCacheDir() {
Directory cacheDir = new Directory(path.join(packageRoot, 'sky_tools', 'cache'));
- if (!await cacheDir.exists()) {
- await cacheDir.create(recursive: true);
- }
+ if (!cacheDir.existsSync())
+ cacheDir.createSync(recursive: true);
return cacheDir;
}
- static Future<Directory> _engineSpecificCacheDir() async {
- Directory cacheDir = await _cacheDir();
+ static Directory _getCacheDirForArtifact(Artifact artifact) {
+ Directory baseDir = _getBaseCacheDir();
// For now, all downloaded artifacts are release mode host binaries so use
// a path that mirrors a local release build.
// TODO(jamesr): Add support for more configurations.
String config = 'Release';
- Directory engineSpecificDir = new Directory(path.join(cacheDir.path, 'sky_engine', engineRevision, config));
-
- if (!await engineSpecificDir.exists()) {
- await engineSpecificDir.create(recursive: true);
- }
- return engineSpecificDir;
- }
-
- // Whether the artifact needs to be marked as executable on disk.
- static bool _needsToBeExecutable(Artifact artifact) {
- return artifact == Artifact.flutterCompiler;
+ Directory artifactSpecificDir = new Directory(path.join(
+ baseDir.path, 'sky_engine', engineRevision, config, artifact.platform));
+ if (!artifactSpecificDir.existsSync())
+ artifactSpecificDir.createSync(recursive: true);
+ return artifactSpecificDir;
}
static Future<String> getPath(Artifact artifact) async {
- Directory cacheDir = await _engineSpecificCacheDir();
-
- String category;
- String platform;
- String name;
-
- switch (artifact) {
- case Artifact.flutterCompiler:
- category = 'shell';
- name = 'sky_snapshot';
- break;
- case Artifact.flutterShell:
- category = 'shell';
- platform = 'android-arm';
- name = 'SkyShell.apk';
- break;
- case Artifact.skyViewerMojo:
- category = 'viewer';
- name = 'sky_viewer.mojo';
- break;
- }
-
- File cachedFile = new File(path.join(cacheDir.path, name));
- if (!await cachedFile.exists()) {
- _logging.info('Downloading ${name} from the cloud, one moment please...');
- if (platform == null) {
- if (!Platform.isLinux)
- throw new Exception('Platform unsupported.');
- platform = 'linux-x64';
- }
- String url = googleStorageUrl(category, platform) + name;
- await _downloadFile(url, cachedFile);
- if (_needsToBeExecutable(artifact)) {
- ProcessResult result = await Process.run('chmod', ['u+x', cachedFile.path]);
- if (result.exitCode != 0) throw new Exception(result.stderr);
+ Directory cacheDir = _getCacheDirForArtifact(artifact);
+ File cachedFile = new File(path.join(cacheDir.path, artifact.fileName));
+ if (!cachedFile.existsSync()) {
+ print('Downloading ${artifact.name} from the cloud, one moment please...');
+ await _downloadFile(artifact.getUrl(engineRevision), cachedFile);
+ if (artifact.executable) {
+ // TODO(abarth): We should factor this out into a separate function that
+ // can have a platform-specific implementation.
+ ProcessResult result = Process.runSync('chmod', ['u+x', cachedFile.path]);
+ if (result.exitCode != 0)
+ throw new Exception(result.stderr);
}
}
return cachedFile.path;
}
- static Future clear() async {
- Directory cacheDir = await _cacheDir();
+ static void clear() {
+ Directory cacheDir = _getBaseCacheDir();
_logging.fine('Clearing cache directory ${cacheDir.path}');
- await cacheDir.delete(recursive: true);
+ cacheDir.deleteSync(recursive: true);
}
- static Future populate() async {
- for (Artifact artifact in Artifact.values) {
- _logging.fine('Populating cache with $artifact');
- await getPath(artifact);
- }
+ static Future populate() {
+ return Future.wait(knownArtifacts.map((artifact) => getPath(artifact)));
}
}
diff --git a/packages/flutter_tools/lib/src/build_configuration.dart b/packages/flutter_tools/lib/src/build_configuration.dart
index 0db0299e..5fc0356 100644
--- a/packages/flutter_tools/lib/src/build_configuration.dart
+++ b/packages/flutter_tools/lib/src/build_configuration.dart
@@ -2,29 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:io';
+
+import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
+final Logger _logging = new Logger('sky_tools.build_configuration');
+
enum BuildType {
prebuilt,
release,
debug,
}
-enum BuildPlatform {
- android,
- iOS,
- iOSSimulator,
+enum HostPlatform {
mac,
linux,
}
+enum TargetPlatform {
+ android,
+ iOS,
+ iOSSimulator,
+ linux,
+}
+
+HostPlatform getCurrentHostPlatform() {
+ if (Platform.isMacOS)
+ return HostPlatform.mac;
+ if (Platform.isLinux)
+ return HostPlatform.linux;
+ _logging.warning('Unsupported host platform, defaulting to Linux');
+ return HostPlatform.linux;
+}
+
class BuildConfiguration {
- BuildConfiguration.prebuilt({ this.platform })
+ BuildConfiguration.prebuilt({ this.hostPlatform, this.targetPlatform })
: type = BuildType.prebuilt, buildDir = null;
BuildConfiguration.local({
this.type,
- this.platform,
+ this.hostPlatform,
+ this.targetPlatform,
String enginePath,
String buildPath
}) : buildDir = path.normalize(path.join(enginePath, buildPath)) {
@@ -32,6 +51,7 @@
}
final BuildType type;
- final BuildPlatform platform;
+ final HostPlatform hostPlatform;
+ final TargetPlatform targetPlatform;
final String buildDir;
}
diff --git a/packages/flutter_tools/lib/src/commands/flutter_command_runner.dart b/packages/flutter_tools/lib/src/commands/flutter_command_runner.dart
index b12c257..8f0b389 100644
--- a/packages/flutter_tools/lib/src/commands/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/commands/flutter_command_runner.dart
@@ -27,8 +27,10 @@
negatable: false,
help: 'Very noisy logging, including the output of all '
'shell commands executed.');
+ argParser.addOption('package-root',
+ help: 'Path to your packages directory.', defaultsTo: 'packages');
- argParser.addSeparator('Global build selection options:');
+ argParser.addSeparator('Local build selection options:');
argParser.addFlag('debug',
negatable: false,
help:
@@ -48,42 +50,40 @@
'Automatically detect your engine src directory from an overridden Flutter package.'
'Useful if you are building Flutter locally and are using a dependency_override for'
'the Flutter package that points to your engine src directory.');
- argParser.addOption('engine-src-path',
+ argParser.addOption('engine-src-path', hide: true,
help:
'Path to your engine src directory, if you are building Flutter locally. '
'Ignored if neither debug nor release is set. Not normally required.');
- argParser.addOption('android-debug-build-path',
+ argParser.addOption('android-debug-build-path', hide: true,
help:
'Path to your Android Debug out directory, if you are building Flutter locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/android_Debug/');
- argParser.addOption('android-release-build-path',
+ argParser.addOption('android-release-build-path', hide: true,
help:
'Path to your Android Release out directory, if you are building Flutter locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/android_Release/');
- argParser.addOption('ios-debug-build-path',
+ argParser.addOption('ios-debug-build-path', hide: true,
help:
'Path to your iOS Debug out directory, if you are building Flutter locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/ios_Debug/');
- argParser.addOption('ios-release-build-path',
+ argParser.addOption('ios-release-build-path', hide: true,
help:
'Path to your iOS Release out directory, if you are building Flutter locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/ios_Release/');
- argParser.addOption('ios-sim-debug-build-path',
+ argParser.addOption('ios-sim-debug-build-path', hide: true,
help:
'Path to your iOS Simulator Debug out directory, if you are building Sky locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/ios_sim_Debug/');
- argParser.addOption('ios-sim-release-build-path',
+ argParser.addOption('ios-sim-release-build-path', hide: true,
help:
'Path to your iOS Simulator Release out directory, if you are building Sky locally. '
'This path is relative to engine-src-path. Not normally required.',
defaultsTo: 'out/ios_sim_Release/');
- argParser.addOption('package-root',
- help: 'Path to your packages directory.', defaultsTo: 'packages');
}
List<BuildConfiguration> get buildConfigurations {
@@ -124,6 +124,7 @@
String enginePath = globalResults['engine-src-path'];
bool isDebug = globalResults['debug'];
bool isRelease = globalResults['release'];
+ HostPlatform hostPlatform = getCurrentHostPlatform();
if (enginePath == null && globalResults['local-build']) {
Directory flutterDir = new Directory(path.join(globalResults['package-root'], 'flutter'));
@@ -141,7 +142,8 @@
List<BuildConfiguration> configs = <BuildConfiguration>[];
if (enginePath == null) {
- configs.add(new BuildConfiguration.prebuilt(platform: BuildPlatform.android));
+ configs.add(new BuildConfiguration.prebuilt(
+ hostPlatform: hostPlatform, targetPlatform: TargetPlatform.android));
} else {
if (!FileSystemEntity.isDirectorySync(enginePath))
_logging.warning('$enginePath is not a valid directory');
@@ -152,7 +154,8 @@
if (isDebug) {
configs.add(new BuildConfiguration.local(
type: BuildType.debug,
- platform: BuildPlatform.android,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.android,
enginePath: enginePath,
buildPath: globalResults['android-debug-build-path']
));
@@ -160,14 +163,16 @@
if (Platform.isMacOS) {
configs.add(new BuildConfiguration.local(
type: BuildType.debug,
- platform: BuildPlatform.iOS,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.iOS,
enginePath: enginePath,
buildPath: globalResults['ios-debug-build-path']
));
configs.add(new BuildConfiguration.local(
type: BuildType.debug,
- platform: BuildPlatform.iOSSimulator,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.iOSSimulator,
enginePath: enginePath,
buildPath: globalResults['ios-sim-debug-build-path']
));
@@ -177,7 +182,8 @@
if (isRelease) {
configs.add(new BuildConfiguration.local(
type: BuildType.release,
- platform: BuildPlatform.android,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.android,
enginePath: enginePath,
buildPath: globalResults['android-release-build-path']
));
@@ -185,14 +191,16 @@
if (Platform.isMacOS) {
configs.add(new BuildConfiguration.local(
type: BuildType.release,
- platform: BuildPlatform.iOS,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.iOS,
enginePath: enginePath,
buildPath: globalResults['ios-release-build-path']
));
configs.add(new BuildConfiguration.local(
type: BuildType.release,
- platform: BuildPlatform.iOSSimulator,
+ hostPlatform: hostPlatform,
+ targetPlatform: TargetPlatform.iOSSimulator,
enginePath: enginePath,
buildPath: globalResults['ios-sim-release-build-path']
));
diff --git a/packages/flutter_tools/lib/src/commands/run_mojo.dart b/packages/flutter_tools/lib/src/commands/run_mojo.dart
index bbab6ac..5853204 100644
--- a/packages/flutter_tools/lib/src/commands/run_mojo.dart
+++ b/packages/flutter_tools/lib/src/commands/run_mojo.dart
@@ -9,6 +9,7 @@
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
+import '../build_configuration.dart';
import '../artifacts.dart';
import '../process.dart';
@@ -40,7 +41,7 @@
}
Future<int> _runAndroid(String devtoolsPath, _MojoConfig mojoConfig, String appPath, List<String> additionalArgs) {
- String skyViewerUrl = ArtifactStore.googleStorageUrl('viewer', 'android-arm');
+ String skyViewerUrl = ArtifactStore.getCloudStorageBaseUrl('viewer', 'android-arm');
String command = _makePathAbsolute(devtoolsPath);
String appName = path.basename(appPath);
String appDir = path.dirname(appPath);
@@ -65,7 +66,8 @@
}
Future<int> _runLinux(String mojoPath, _MojoConfig mojoConfig, String appPath, List<String> additionalArgs) async {
- String viewerPath = _makePathAbsolute(await ArtifactStore.getPath(Artifact.skyViewerMojo));
+ Artifact artifact = ArtifactStore.getArtifact(type: ArtifactType.viewer, targetPlatform: TargetPlatform.linux);
+ String viewerPath = _makePathAbsolute(await ArtifactStore.getPath(artifact));
String mojoBuildType = mojoConfig == _MojoConfig.Debug ? 'Debug' : 'Release';
String mojoShellPath = _makePathAbsolute(path.join(mojoPath, 'out', mojoBuildType, 'mojo_shell'));
List<String> cmd = [
diff --git a/packages/flutter_tools/lib/src/commands/start.dart b/packages/flutter_tools/lib/src/commands/start.dart
index 33f9f46..2fb4701 100644
--- a/packages/flutter_tools/lib/src/commands/start.dart
+++ b/packages/flutter_tools/lib/src/commands/start.dart
@@ -3,17 +3,21 @@
// found in the LICENSE file.
import 'dart:async';
+import 'dart:io';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
import '../application_package.dart';
import '../device.dart';
+import 'build.dart';
import 'flutter_command.dart';
import 'install.dart';
import 'stop.dart';
final Logger _logging = new Logger('sky_tools.start');
+const String _localBundlePath = 'app.flx';
+const bool _kUseServer = true;
class StartCommand extends FlutterCommand {
final String name = 'start';
@@ -31,13 +35,20 @@
defaultsTo: '.',
abbr: 't',
help: 'Target app path or filename to start.');
+ argParser.addFlag('http',
+ negatable: true,
+ defaultsTo: true,
+ help: 'Use a local HTTP server to serve your app to your device.');
argParser.addFlag('boot',
help: 'Boot the iOS Simulator if it isn\'t already running.');
}
@override
Future<int> runInProject() async {
- await downloadApplicationPackagesAndConnectToDevices();
+ await Future.wait([
+ downloadToolchain(),
+ downloadApplicationPackagesAndConnectToDevices(),
+ ]);
bool poke = argResults['poke'];
if (!poke) {
@@ -59,8 +70,19 @@
continue;
if (device is AndroidDevice) {
String target = path.absolute(argResults['target']);
- if (await device.startServer(target, poke, argResults['checked'], package))
- startedSomething = true;
+ if (argResults['http']) {
+ if (await device.startServer(target, poke, argResults['checked'], package))
+ startedSomething = true;
+ } else {
+ String mainPath = target;
+ if (FileSystemEntity.isDirectorySync(target))
+ mainPath = path.join(target, 'lib', 'main.dart');
+ BuildCommand builder = new BuildCommand();
+ builder.inheritFromParent(this);
+ await builder.build(outputPath: _localBundlePath, mainPath: mainPath);
+ if (device.startBundle(package, _localBundlePath, poke, argResults['checked']))
+ startedSomething = true;
+ }
} else {
if (await device.startApp(package))
startedSomething = true;
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart
index 75c994e..fa13654 100644
--- a/packages/flutter_tools/lib/src/device.dart
+++ b/packages/flutter_tools/lib/src/device.dart
@@ -66,7 +66,7 @@
/// Check if the current version of the given app is already installed
bool isAppInstalled(ApplicationPackage app);
- BuildPlatform get platform;
+ TargetPlatform get platform;
Future<int> logs({bool clear: false});
@@ -271,7 +271,7 @@
}
@override
- BuildPlatform get platform => BuildPlatform.iOS;
+ TargetPlatform get platform => TargetPlatform.iOS;
/// Note that clear is not supported on iOS at this time.
Future<int> logs({bool clear: false}) async {
@@ -487,7 +487,7 @@
}
@override
- BuildPlatform get platform => BuildPlatform.iOSSimulator;
+ TargetPlatform get platform => TargetPlatform.iOSSimulator;
Future<int> logs({bool clear: false}) async {
if (!isConnected()) {
@@ -695,6 +695,10 @@
return '${_getDeviceDataPath(app)}/${app.name}.sha1';
}
+ String _getDeviceBundlePath(ApplicationPackage app) {
+ return '${_getDeviceDataPath(app)}/dev.flx';
+ }
+
String _getDeviceApkSha1(ApplicationPackage app) {
return runCheckedSync([adbPath, 'shell', 'cat', _getDeviceSha1Path(app)]);
}
@@ -750,12 +754,45 @@
return true;
}
+ void _forwardObservatoryPort() {
+ // Set up port forwarding for observatory.
+ String observatoryPortString = 'tcp:$_observatoryPort';
+ runCheckedSync(
+ [adbPath, 'forward', observatoryPortString, observatoryPortString]);
+ }
+
+ bool startBundle(AndroidApk apk, String bundlePath, bool poke, bool checked) {
+ if (!FileSystemEntity.isFileSync(bundlePath)) {
+ _logging.severe('Cannot find $bundlePath');
+ return false;
+ }
+
+ if (!poke)
+ _forwardObservatoryPort();
+
+ String deviceTmpPath = '/data/local/tmp/dev.flx';
+ String deviceBundlePath = _getDeviceBundlePath(apk);
+ runCheckedSync([adbPath, 'push', bundlePath, deviceTmpPath]);
+ runCheckedSync([adbPath, 'shell', 'mv', deviceTmpPath, deviceBundlePath]);
+ List<String> cmd = [
+ adbPath,
+ 'shell', 'am', 'start',
+ '-a', 'android.intent.action.RUN',
+ '-d', deviceBundlePath,
+ ];
+ if (checked)
+ cmd.addAll(['--ez', 'enable-checked-mode', 'true']);
+ cmd.add(apk.launchActivity);
+ runCheckedSync(cmd);
+ return true;
+ }
+
Future<bool> startServer(
String target, bool poke, bool checked, AndroidApk apk) async {
String serverRoot = '';
String mainDart = '';
String missingMessage = '';
- if (await FileSystemEntity.isDirectory(target)) {
+ if (FileSystemEntity.isDirectorySync(target)) {
serverRoot = target;
mainDart = path.join(serverRoot, 'lib', 'main.dart');
missingMessage = 'Missing lib/main.dart in project: $serverRoot';
@@ -765,16 +802,13 @@
missingMessage = '$mainDart does not exist.';
}
- if (!await FileSystemEntity.isFile(mainDart)) {
+ if (!FileSystemEntity.isFileSync(mainDart)) {
_logging.severe(missingMessage);
return false;
}
if (!poke) {
- // Set up port forwarding for observatory.
- String observatoryPortString = 'tcp:$_observatoryPort';
- runCheckedSync(
- [adbPath, 'forward', observatoryPortString, observatoryPortString]);
+ _forwardObservatoryPort();
// Actually start the server.
Process server = await Process.start(
@@ -794,28 +828,20 @@
String relativeDartMain = _convertToURL(path.relative(mainDart, from: serverRoot));
String url = 'http://localhost:$_serverPort/$relativeDartMain';
- if (poke) {
+ if (poke)
url += '?rand=${new Random().nextDouble()}';
- }
// Actually launch the app on Android.
List<String> cmd = [
adbPath,
- 'shell',
- 'am',
- 'start',
- '-a',
- 'android.intent.action.VIEW',
- '-d',
- url,
+ 'shell', 'am', 'start',
+ '-a', 'android.intent.action.VIEW',
+ '-d', url,
];
- if (checked) {
+ if (checked)
cmd.addAll(['--ez', 'enable-checked-mode', 'true']);
- }
cmd.add(apk.launchActivity);
-
runCheckedSync(cmd);
-
return true;
}
@@ -880,7 +906,7 @@
}
@override
- BuildPlatform get platform => BuildPlatform.android;
+ TargetPlatform get platform => TargetPlatform.android;
void clearLogs() {
runSync([adbPath, 'logcat', '-c']);
@@ -985,24 +1011,20 @@
IOSSimulator iOSSimulator;
for (BuildConfiguration config in configs) {
- switch (config.platform) {
- case BuildPlatform.android:
+ switch (config.targetPlatform) {
+ case TargetPlatform.android:
assert(android == null);
android = new AndroidDevice();
break;
- case BuildPlatform.iOS:
+ case TargetPlatform.iOS:
assert(iOS == null);
iOS = new IOSDevice();
break;
- case BuildPlatform.iOSSimulator:
+ case TargetPlatform.iOSSimulator:
assert(iOSSimulator == null);
iOSSimulator = new IOSSimulator();
break;
-
- case BuildPlatform.mac:
- case BuildPlatform.linux:
- // TODO(abarth): Support mac and linux targets.
- assert(false);
+ case TargetPlatform.linux:
break;
}
}
diff --git a/packages/flutter_tools/lib/src/toolchain.dart b/packages/flutter_tools/lib/src/toolchain.dart
index 655e6b6..34301ec 100644
--- a/packages/flutter_tools/lib/src/toolchain.dart
+++ b/packages/flutter_tools/lib/src/toolchain.dart
@@ -11,16 +11,16 @@
import 'process.dart';
class Compiler {
- Compiler(this._compilerPath);
+ Compiler(this._path);
- String _compilerPath;
+ String _path;
Future<int> compile({
String mainPath,
String snapshotPath
}) {
return runCommandAndStreamOutput([
- _compilerPath,
+ _path,
mainPath,
'--package-root=${ArtifactStore.packageRoot}',
'--snapshot=$snapshotPath'
@@ -28,18 +28,22 @@
}
}
+Future<String> _getCompilerPath(BuildConfiguration config) async {
+ if (config.type != BuildType.prebuilt)
+ return path.join(config.buildDir, 'clang_x64', 'sky_snapshot');
+ Artifact artifact = ArtifactStore.getArtifact(
+ type: ArtifactType.snapshot, hostPlatform: config.hostPlatform);
+ return await ArtifactStore.getPath(artifact);
+}
+
class Toolchain {
Toolchain({ this.compiler });
final Compiler compiler;
static Future<Toolchain> forConfigs(List<BuildConfiguration> configs) async {
- // TODO(abarth): Add a notion of "host platform" to the build configs.
- BuildConfiguration config = configs.first;
- String compilerPath = config.type == BuildType.prebuilt ?
- await ArtifactStore.getPath(Artifact.flutterCompiler) :
- path.join(config.buildDir, 'clang_x64', 'sky_snapshot');
-
+ // TODO(abarth): Shouldn't we consider all the configs?
+ String compilerPath = await _getCompilerPath(configs.first);
return new Toolchain(compiler: new Compiler(compilerPath));
}
}