Initial sketch of install command and what devices look like.
diff --git a/packages/flutter_tools/lib/src/common.dart b/packages/flutter_tools/lib/src/common.dart
index 9fc6d19..c3e1ba1 100644
--- a/packages/flutter_tools/lib/src/common.dart
+++ b/packages/flutter_tools/lib/src/common.dart
@@ -14,6 +14,7 @@
ArgParser get parser;
+ /// @return 0 for no errors or warnings executing command, 1 for warnings, 2 for errors.
Future<int> processArgResults(ArgResults results);
void printUsage([String message]) {
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart
new file mode 100644
index 0000000..3167abb
--- /dev/null
+++ b/packages/flutter_tools/lib/src/device.dart
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library sky_tools.device;
+
+abstract class _Device {
+ final String id;
+ static Map<String, _Device> _deviceCache = {};
+
+ factory _Device(String className, [String id = null]) {
+ if (id == null) {
+ if (className == AndroidDevice.className) {
+ id = AndroidDevice.defaultDeviceID;
+ } else {
+ throw 'Attempted to create a Device of unknown type $className';
+ }
+ }
+
+ return _deviceCache.putIfAbsent(id, () {
+ if (className == AndroidDevice.className) {
+ final device = new AndroidDevice._(id);
+ _deviceCache[id] = device;
+ return device;
+ } else {
+ throw 'Attempted to create a Device of unknown type $className';
+ }
+ });
+ }
+
+ _Device._(this.id);
+
+ /// Install an app package on the current device
+ bool installApp(String path);
+
+ /// Check if the current device needs an installation
+ bool needsInstall();
+
+ /// Check if the device is currently connected
+ bool isConnected();
+}
+
+class AndroidDevice extends _Device {
+ static const String className = 'AndroidDevice';
+ static final String defaultDeviceID = 'default';
+
+ factory AndroidDevice([String id = null]) {
+ return new _Device(className, id);
+ }
+
+ AndroidDevice._(id) : super._(id);
+
+ @override
+ bool installApp(String path) {
+ return false;
+ }
+
+ @override
+ bool needsInstall() {
+ return true;
+ }
+
+ @override
+ bool isConnected() {
+ return true;
+ }
+}
diff --git a/packages/flutter_tools/lib/src/install.dart b/packages/flutter_tools/lib/src/install.dart
new file mode 100644
index 0000000..1a89dee
--- /dev/null
+++ b/packages/flutter_tools/lib/src/install.dart
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library sky_tools.install;
+
+import 'dart:async';
+
+import 'package:args/args.dart';
+
+import 'common.dart';
+import 'device.dart';
+
+class InstallCommandHandler extends CommandHandler {
+ InstallCommandHandler()
+ : super('install', 'Install your Sky app on attached devices.');
+
+ @override
+ ArgParser get parser {
+ ArgParser parser = new ArgParser();
+ parser.addFlag('help',
+ abbr: 'h', negatable: false, help: 'Display this help message.');
+ return parser;
+ }
+
+ @override
+ Future<int> processArgResults(ArgResults results) async {
+ if (results['help']) {
+ printUsage();
+ return 0;
+ }
+
+ bool installedSomewhere = false;
+
+ AndroidDevice android = new AndroidDevice();
+ if (android.isConnected()) {
+ installedSomewhere = installedSomewhere || android.installApp('');
+ }
+
+ if (installedSomewhere) {
+ return 0;
+ } else {
+ return 2;
+ }
+ }
+}