diff --git a/packages/.analysis_options b/.analysis_options similarity index 100% rename from packages/.analysis_options rename to .analysis_options diff --git a/bin/cache/engine.version b/bin/cache/engine.version index bf129913617..662dd630b6c 100644 --- a/bin/cache/engine.version +++ b/bin/cache/engine.version @@ -1 +1 @@ -d85ead8ec2556739924282e2b3f77ff077a45820 +86837edd4ecbe5d28f16a770dff40a239f5b40b7 diff --git a/examples/material_gallery/.analysis_options b/examples/material_gallery/.analysis_options deleted file mode 100644 index a9b94d74906..00000000000 --- a/examples/material_gallery/.analysis_options +++ /dev/null @@ -1,3 +0,0 @@ -analyzer: - exclude: - - 'ios/.generated/**' diff --git a/examples/material_gallery/lib/demo/fitness_demo.dart b/examples/material_gallery/lib/demo/fitness_demo.dart index 01707985c23..45cc3bac1fb 100644 --- a/examples/material_gallery/lib/demo/fitness_demo.dart +++ b/examples/material_gallery/lib/demo/fitness_demo.dart @@ -7,7 +7,6 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_sprites/flutter_sprites.dart'; -import 'package:vector_math/vector_math_64.dart' as vec; ImageMap _images; SpriteSheet _sprites; @@ -581,7 +580,7 @@ class _FireworksNode extends NodeWithSize { speedVar: 50.0, startSize: 1.0, startSizeVar: 0.5, - gravity: new vec.Vector2(0.0, 30.0), + gravity: const Offset(0.0, 30.0), colorSequence: new ColorSequence.fromStartAndEndColor(startColor, endColor) ); system.position = new Point(randomDouble() * 1024.0, randomDouble() * 1024.0); diff --git a/examples/stocks/.analysis_options b/examples/stocks/.analysis_options new file mode 100644 index 00000000000..f9e8f30d8fe --- /dev/null +++ b/examples/stocks/.analysis_options @@ -0,0 +1,3 @@ +analyzer: + exclude: + - 'lib/i18n/stock_messages_*.dart' diff --git a/packages/flutter/lib/src/material/drop_down.dart b/packages/flutter/lib/src/material/drop_down.dart index a727b97aacf..376eb34f66a 100644 --- a/packages/flutter/lib/src/material/drop_down.dart +++ b/packages/flutter/lib/src/material/drop_down.dart @@ -28,7 +28,6 @@ class _DropDownMenuPainter extends CustomPainter { _DropDownMenuPainter({ Color color, int elevation, - this.buttonRect, this.selectedIndex, Animation resize }) : color = color, @@ -43,7 +42,6 @@ class _DropDownMenuPainter extends CustomPainter { final Color color; final int elevation; - final Rect buttonRect; final int selectedIndex; final Animation resize; @@ -52,12 +50,12 @@ class _DropDownMenuPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final Tween top = new Tween( - begin: (selectedIndex * buttonRect.height + _kMenuVerticalPadding.top).clamp(0.0, size.height - buttonRect.height), + begin: (selectedIndex * _kMenuItemHeight + _kMenuVerticalPadding.top).clamp(0.0, size.height - _kMenuItemHeight), end: 0.0 ); final Tween bottom = new Tween( - begin: (top.begin + buttonRect.height).clamp(buttonRect.height, size.height), + begin: (top.begin + _kMenuItemHeight).clamp(_kMenuItemHeight, size.height), end: size.height ); @@ -68,7 +66,6 @@ class _DropDownMenuPainter extends CustomPainter { bool shouldRepaint(_DropDownMenuPainter oldPainter) { return oldPainter.color != color || oldPainter.elevation != elevation - || oldPainter.buttonRect != buttonRect || oldPainter.selectedIndex != selectedIndex || oldPainter.resize != resize; } @@ -130,7 +127,6 @@ class _DropDownMenu extends StatusTransitionWidget { painter: new _DropDownMenuPainter( color: Theme.of(context).canvasColor, elevation: route.elevation, - buttonRect: route.buttonRect, selectedIndex: route.selectedIndex, resize: new CurvedAnimation( parent: route.animation, @@ -140,8 +136,9 @@ class _DropDownMenu extends StatusTransitionWidget { ), child: new Material( type: MaterialType.transparency, - child: new Block( + child: new ScrollableList( padding: _kMenuVerticalPadding, + itemExtent: _kMenuItemHeight, children: children ) ) @@ -162,10 +159,11 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate { // the view height. This ensures a tappable area outside of the simple menu // with which to dismiss the menu. // -- https://www.google.com/design/spec/components/menus.html#menus-simple-menus - final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * buttonRect.height); + final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * _kMenuItemHeight); + final double width = buttonRect.width; return new BoxConstraints( - minWidth: buttonRect.width, - maxWidth: buttonRect.width, + minWidth: width, + maxWidth: width, minHeight: 0.0, maxHeight: maxHeight ); @@ -173,14 +171,15 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate { @override Offset getPositionForChild(Size size, Size childSize) { - double top = buttonRect.top - selectedIndex * buttonRect.height - _kMenuVerticalPadding.top; - double topPreferredLimit = buttonRect.height; + final double buttonTop = buttonRect.top; + double top = buttonTop - selectedIndex * _kMenuItemHeight - _kMenuVerticalPadding.top; + double topPreferredLimit = _kMenuItemHeight; if (top < topPreferredLimit) - top = math.min(buttonRect.top, topPreferredLimit); + top = math.min(buttonTop, topPreferredLimit); double bottom = top + childSize.height; - double bottomPreferredLimit = size.height - buttonRect.height; + double bottomPreferredLimit = size.height - _kMenuItemHeight; if (bottom > bottomPreferredLimit) { - bottom = math.max(buttonRect.bottom, bottomPreferredLimit); + bottom = math.max(buttonTop + _kMenuItemHeight, bottomPreferredLimit); top = bottom - childSize.height; } assert(top >= 0.0); @@ -277,7 +276,7 @@ class DropDownMenuItem extends StatelessWidget { Widget build(BuildContext context) { return new Container( height: _kMenuItemHeight, - padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: _kTopMargin), + padding: const EdgeInsets.symmetric(horizontal: 8.0), child: new DefaultTextStyle( style: Theme.of(context).textTheme.subhead, child: new Baseline( @@ -363,7 +362,7 @@ class DropDownButton extends StatefulWidget { } class _DropDownButtonState extends State> { - final GlobalKey indexedStackKey = new GlobalKey(debugLabel: 'DropDownButton.IndexedStack'); + final GlobalKey _itemKey = new GlobalKey(debugLabel: 'DropDownButton item key'); @override void initState() { @@ -390,13 +389,13 @@ class _DropDownButtonState extends State> { } void _handleTap() { - final RenderBox renderBox = indexedStackKey.currentContext.findRenderObject(); - final Rect buttonRect = renderBox.localToGlobal(Point.origin) & renderBox.size; + final RenderBox itemBox = _itemKey.currentContext.findRenderObject(); + final Rect itemRect = itemBox.localToGlobal(Point.origin) & itemBox.size; final Completer<_DropDownRouteResult> completer = new Completer<_DropDownRouteResult>(); Navigator.push(context, new _DropDownRoute( completer: completer, items: config.items, - buttonRect: _kMenuHorizontalPadding.inflateRect(buttonRect), + buttonRect: _kMenuHorizontalPadding.inflateRect(itemRect), selectedIndex: _selectedIndex, elevation: config.elevation )); @@ -412,27 +411,27 @@ class _DropDownButtonState extends State> { Widget build(BuildContext context) { assert(debugCheckHasMaterial(context)); Widget result = new Row( + mainAxisAlignment: MainAxisAlignment.collapse, children: [ + // We use an IndexedStack to make sure we have enough width to show any + // possible item as the selected item without changing size. new IndexedStack( children: config.items, - key: indexedStackKey, + key: _itemKey, index: _selectedIndex, alignment: FractionalOffset.topCenter ), - new Container( - child: new Icon(icon: Icons.arrow_drop_down, size: 36.0), - padding: const EdgeInsets.only(top: _kTopMargin) - ) - ], - mainAxisAlignment: MainAxisAlignment.collapse + new Icon(icon: Icons.arrow_drop_down, size: 36.0) + ] ); if (DropDownButtonHideUnderline.at(context)) { result = new Padding( - padding: const EdgeInsets.only(bottom: _kBottomBorderHeight), + padding: const EdgeInsets.only(top: _kTopMargin, bottom: _kBottomBorderHeight), child: result ); } else { result = new Container( + padding: const EdgeInsets.only(top: _kTopMargin), decoration: const BoxDecoration(border: _kDropDownUnderline), child: result ); diff --git a/packages/flutter/lib/src/widgets/performance_overlay.dart b/packages/flutter/lib/src/widgets/performance_overlay.dart index 0205071471f..d4cdb215403 100644 --- a/packages/flutter/lib/src/widgets/performance_overlay.dart +++ b/packages/flutter/lib/src/widgets/performance_overlay.dart @@ -7,6 +7,18 @@ import 'package:flutter/rendering.dart'; import 'framework.dart'; /// Displays performance statistics. +/// +/// The overlay show two time series. The first shows how much time was required +/// on this thread to produce each frame. The second shows how much time was +/// required on the GPU thread to produce each frame. Ideally, both these values +/// would be less than the total frame budget for the hardware on which the app +/// is running. For example, if the hardware has a screen that updates at 60 Hz, +/// each thread should ideally spend less than 16 ms producing each frame. This +/// ideal condition is indicated by a green vertical line for each thread. +/// +/// The simplest way to show the performance overlay is to set +/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay] +/// to `true`. class PerformanceOverlay extends LeafRenderObjectWidget { // TODO(abarth): We should have a page on the web site with a screenshot and // an explanation of all the various readouts. diff --git a/packages/flutter/test/material/drop_down_test.dart b/packages/flutter/test/material/drop_down_test.dart index 3555940c379..f48d6a7ce63 100644 --- a/packages/flutter/test/material/drop_down_test.dart +++ b/packages/flutter/test/material/drop_down_test.dart @@ -38,6 +38,14 @@ void main() { tester.pump(); tester.pump(const Duration(seconds: 1)); // finish the menu animation + // We should have two copies of item 5, one in the menu and one in the + // button itself. + expect(find.text('5').evaluate().length, 2); + + // We should only have one copy of item 19, which is in the button itself. + // The copy in the menu shouldn't be in the tree because it's off-screen. + expect(find.text('19').evaluate().length, 1); + tester.tap(find.byConfig(button)); // Ideally this would be 4 because the menu would be overscrolled to the diff --git a/packages/flutter_sprites/lib/src/particle_system.dart b/packages/flutter_sprites/lib/src/particle_system.dart index 7f6c435d811..7f7609f9939 100644 --- a/packages/flutter_sprites/lib/src/particle_system.dart +++ b/packages/flutter_sprites/lib/src/particle_system.dart @@ -41,6 +41,49 @@ class _ParticleAccelerations { /// number of particles can never exceed the [maxParticles] limit. class ParticleSystem extends Node { + ParticleSystem(this.texture, + {this.life: 1.5, + this.lifeVar: 1.0, + this.posVar: Point.origin, + this.startSize: 2.5, + this.startSizeVar: 0.5, + this.endSize: 0.0, + this.endSizeVar: 0.0, + this.startRotation: 0.0, + this.startRotationVar: 0.0, + this.endRotation: 0.0, + this.endRotationVar: 0.0, + this.rotateToMovement : false, + this.direction: 0.0, + this.directionVar: 360.0, + this.speed: 100.0, + this.speedVar: 50.0, + this.radialAcceleration: 0.0, + this.radialAccelerationVar: 0.0, + this.tangentialAcceleration: 0.0, + this.tangentialAccelerationVar: 0.0, + this.maxParticles: 100, + this.emissionRate: 50.0, + this.colorSequence, + this.alphaVar: 0, + this.redVar: 0, + this.greenVar: 0, + this.blueVar: 0, + this.transferMode: TransferMode.plus, + this.numParticlesToEmit: 0, + this.autoRemoveOnFinish: true, + Offset gravity + }) { + this.gravity = gravity; + _particles = new List<_Particle>(); + _emitCounter = 0.0; + // _elapsedTime = 0.0; + if (_gravity == null) + _gravity = new Vector2.zero(); + if (colorSequence == null) + colorSequence = new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff)); + } + /// The texture used to draw each individual sprite. Texture texture; @@ -108,7 +151,21 @@ class ParticleSystem extends Node { double tangentialAccelerationVar; /// The gravity vector of the particle system. - Vector2 gravity; + Offset get gravity { + if (_gravity == null) + return null; + + return new Offset(_gravity.x, _gravity.y); + } + + Vector2 _gravity; + + void set gravity(Offset gravity) { + if (gravity == null) + _gravity = null; + else + _gravity = new Vector2(gravity.dx, gravity.dy); + } /// The maximum number of particles the system can display at a single time. int maxParticles; @@ -157,45 +214,6 @@ class ParticleSystem extends Node { ..filterQuality = FilterQuality.low ..isAntiAlias = false; - ParticleSystem(this.texture, - {this.life: 1.5, - this.lifeVar: 1.0, - this.posVar: Point.origin, - this.startSize: 2.5, - this.startSizeVar: 0.5, - this.endSize: 0.0, - this.endSizeVar: 0.0, - this.startRotation: 0.0, - this.startRotationVar: 0.0, - this.endRotation: 0.0, - this.endRotationVar: 0.0, - this.rotateToMovement : false, - this.direction: 0.0, - this.directionVar: 360.0, - this.speed: 100.0, - this.speedVar: 50.0, - this.radialAcceleration: 0.0, - this.radialAccelerationVar: 0.0, - this.tangentialAcceleration: 0.0, - this.tangentialAccelerationVar: 0.0, - this.gravity, - this.maxParticles: 100, - this.emissionRate: 50.0, - this.colorSequence, - this.alphaVar: 0, - this.redVar: 0, - this.greenVar: 0, - this.blueVar: 0, - this.transferMode: TransferMode.plus, - this.numParticlesToEmit: 0, - this.autoRemoveOnFinish: true}) { - _particles = new List<_Particle>(); - _emitCounter = 0.0; - // _elapsedTime = 0.0; - if (gravity == null) gravity = new Vector2.zero(); - if (colorSequence == null) colorSequence = new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff)); - } - @override void update(double dt) { // TODO: Fix this (it's a temp fix for low framerates) @@ -249,11 +267,11 @@ class ParticleSystem extends Node { tangential.scale(particle.accelerations.tangentialAccel); // (gravity + radial + tangential) * dt - Vector2 accel = (gravity + radial + tangential).scale(dt); + final Vector2 accel = (_gravity + radial + tangential).scale(dt); particle.dir += accel; - } else if (gravity[0] != 0.0 || gravity[1] != 0) { + } else if (_gravity[0] != 0.0 || _gravity[1] != 0) { // gravity - Vector2 accel = new Vector2.copy(gravity).scale(dt); + final Vector2 accel = new Vector2.copy(_gravity).scale(dt); particle.dir += accel; } @@ -362,7 +380,8 @@ class ParticleSystem extends Node { @override void paint(Canvas canvas) { - if (opacity == 0.0) return; + if (opacity == 0.0) + return; List transforms = []; List rects = []; diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index 98b6664d416..0d9cddfbe69 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -102,7 +102,7 @@ Future main(List args) async { flutterUsage.sendException(error, chain); - if (Platform.environment.containsKey('FLUTTER_DEV')) { + if (Platform.environment.containsKey('FLUTTER_DEV') || isRunningOnBot) { // If we're working on the tools themselves, just print the stack trace. stderr.writeln('$error'); stderr.writeln(chain.terse.toString()); diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index b5e37ebde13..0712fdec431 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -49,23 +49,49 @@ class AndroidDevice extends Device { final String modelID; final String deviceCodeName; + Map _properties; bool _isLocalEmulator; + TargetPlatform _platform; + + String _getProperty(String name) { + if (_properties == null) { + String getpropOutput = runCheckedSync(adbCommandForDevice(['shell', 'getprop'])); + RegExp propertyExp = new RegExp(r'\[(.*?)\]: \[(.*?)\]'); + _properties = {}; + for (Match m in propertyExp.allMatches(getpropOutput)) { + _properties[m.group(1)] = m.group(2); + } + } + return _properties[name]; + } @override bool get isLocalEmulator { if (_isLocalEmulator == null) { + String characteristics = _getProperty('ro.build.characteristics'); + _isLocalEmulator = characteristics != null && characteristics.contains('emulator'); + } + return _isLocalEmulator; + } + + @override + TargetPlatform get platform { + if (_platform == null) { // http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...) - try { - String value = runCheckedSync(adbCommandForDevice( - ['shell', 'getprop', 'ro.product.cpu.abi'] - )); - _isLocalEmulator = value.startsWith('x86'); - } catch (error) { - _isLocalEmulator = false; + switch (_getProperty('ro.product.cpu.abi')) { + case 'x86_64': + _platform = TargetPlatform.android_x64; + break; + case 'x86': + _platform = TargetPlatform.android_x86; + break; + default: + _platform = TargetPlatform.android_arm; + break; } } - return _isLocalEmulator; + return _platform; } _AdbLogReader _logReader; @@ -123,9 +149,7 @@ class AndroidDevice extends Device { runCheckedSync([androidSdk.adbPath, 'start-server']); // Sample output: '22' - String sdkVersion = runCheckedSync( - adbCommandForDevice(['shell', 'getprop', 'ro.build.version.sdk']) - ).trimRight(); + String sdkVersion = _getProperty('ro.build.version.sdk'); int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null); if (sdkVersionParsed == null) { @@ -333,9 +357,6 @@ class AndroidDevice extends Device { return runCommandAndStreamOutput(command).then((int exitCode) => exitCode == 0); } - @override - TargetPlatform get platform => isLocalEmulator ? TargetPlatform.android_x64 : TargetPlatform.android_arm; - @override void clearLogs() { runSync(adbCommandForDevice(['logcat', '-c'])); diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart index 07a9318a98c..f4154eb9700 100644 --- a/packages/flutter_tools/lib/src/application_package.dart +++ b/packages/flutter_tools/lib/src/application_package.dart @@ -103,6 +103,7 @@ ApplicationPackage getApplicationPackageForPlatform(TargetPlatform platform) { switch (platform) { case TargetPlatform.android_arm: case TargetPlatform.android_x64: + case TargetPlatform.android_x86: return new AndroidApk.fromCurrentDirectory(); case TargetPlatform.ios: return new IOSApp.fromCurrentDirectory(); @@ -122,6 +123,7 @@ class ApplicationPackageStore { switch (platform) { case TargetPlatform.android_arm: case TargetPlatform.android_x64: + case TargetPlatform.android_x86: android ??= new AndroidApk.fromCurrentDirectory(); return android; case TargetPlatform.ios: diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart index 8b1ba05dcf0..a550f9cbbf4 100644 --- a/packages/flutter_tools/lib/src/base/utils.dart +++ b/packages/flutter_tools/lib/src/base/utils.dart @@ -8,6 +8,13 @@ import 'dart:io'; import 'package:crypto/crypto.dart'; import 'package:path/path.dart' as path; +bool get isRunningOnBot { + // https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables + return + Platform.environment['TRAVIS'] == 'true' || + Platform.environment['CONTINUOUS_INTEGRATION'] == 'true'; +} + String hex(List bytes) { StringBuffer result = new StringBuffer(); for (int part in bytes) diff --git a/packages/flutter_tools/lib/src/build_configuration.dart b/packages/flutter_tools/lib/src/build_configuration.dart index a70e6916765..e4e992c4373 100644 --- a/packages/flutter_tools/lib/src/build_configuration.dart +++ b/packages/flutter_tools/lib/src/build_configuration.dart @@ -41,6 +41,7 @@ String getNameForHostPlatform(HostPlatform platform) { enum TargetPlatform { android_arm, android_x64, + android_x86, ios, darwin_x64, linux_x64 diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index 892657baa88..ebb7369051f 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart @@ -192,7 +192,8 @@ class FlutterEngine { 'android-arm', 'android-arm-profile', 'android-arm-release', - 'android-x64' + 'android-x64', + 'android-x86', ]; if (Platform.isMacOS) diff --git a/packages/flutter_tools/lib/src/commands/analyze.dart b/packages/flutter_tools/lib/src/commands/analyze.dart index 88288b840eb..cd8f72f3be7 100644 --- a/packages/flutter_tools/lib/src/commands/analyze.dart +++ b/packages/flutter_tools/lib/src/commands/analyze.dart @@ -34,15 +34,8 @@ class AnalyzeCommand extends FlutterCommand { argParser.addFlag('watch', help: 'Run analysis continuously, watching the filesystem for changes.', negatable: false); argParser.addOption('dart-sdk', help: 'The path to the Dart SDK.', hide: true); - // Options to enable a benchmarking mode. - argParser.addFlag('benchmark', - negatable: false, - hide: true - ); - argParser.addOption('benchmark-expected', - hide: true, - help: 'The time (in seconds) that the benchmark is expected to run.' - ); + // Hidden option to enable a benchmarking mode. + argParser.addFlag('benchmark', negatable: false, hide: true); usesPubOption(); } @@ -393,19 +386,12 @@ class AnalyzeCommand extends FlutterCommand { void _writeBenchmark(Stopwatch stopwatch, int errorCount) { final String benchmarkOut = 'analysis_benchmark.json'; - String expectedTime = argResults['benchmark-expected']; - Map data = { 'time': (stopwatch.elapsedMilliseconds / 1000.0), 'issues': errorCount }; - - if (expectedTime != null) - data['expected'] = expectedTime; - JsonEncoder encoder = new JsonEncoder.withIndent(' '); new File(benchmarkOut).writeAsStringSync(encoder.convert(data) + '\n'); - printStatus('Analysis benchmark written to $benchmarkOut.'); } } diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 6004bff412d..0029062785b 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -261,6 +261,21 @@ class BuildApkCommand extends FlutterCommand { } } +// Return the directory name within the APK that is used for native code libraries +// on the given platform. +String getAbiDirectory(TargetPlatform platform) { + switch (platform) { + case TargetPlatform.android_arm: + return 'armeabi-v7a'; + case TargetPlatform.android_x64: + return 'x86_64'; + case TargetPlatform.android_x86: + return 'x86'; + default: + throw new Exception('Unsupported platform.'); + } +} + Future<_ApkComponents> _findApkComponents( TargetPlatform platform, BuildMode buildMode, @@ -274,7 +289,7 @@ Future<_ApkComponents> _findApkComponents( components.extraFiles = extraFiles != null ? extraFiles : {}; if (tools.isLocalEngine) { - String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64'; + String abiDir = getAbiDirectory(platform); String enginePath = tools.engineSrcPath; String buildDir = tools.getEngineArtifactsDirectory(platform, buildMode).path; @@ -348,7 +363,7 @@ int _buildApk( _AssetBuilder artifactBuilder = new _AssetBuilder(tempDir, 'artifacts'); artifactBuilder.add(classesDex, 'classes.dex'); - String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64'; + String abiDir = getAbiDirectory(platform); artifactBuilder.add(components.libSkyShell, 'lib/$abiDir/libsky_shell.so'); for (String relativePath in components.extraFiles.keys) diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 562342c25c5..70c1b610594 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -10,7 +10,7 @@ import '../base/process.dart'; import '../dart/pub.dart'; import '../globals.dart'; import '../runner/flutter_command.dart'; -import '../runner/version.dart'; +import '../version.dart'; class UpgradeCommand extends FlutterCommand { @override diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 2d9d5f77723..9dbebed3ee9 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -57,7 +57,7 @@ class DeviceManager { devices = devices.where((Device device) { return (device.id.toLowerCase().startsWith(deviceId) || device.name.toLowerCase().startsWith(deviceId)); - }); + }).toList(); return devices.length == 1 ? devices.first : null; } diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 7a718f0d129..86ac9411628 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -12,7 +12,7 @@ import 'base/context.dart'; import 'base/os.dart'; import 'globals.dart'; import 'ios/ios_workflow.dart'; -import 'runner/version.dart'; +import 'version.dart'; const Map _osNames = const { 'macos': 'Mac OS', diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 382cc4ef9c8..03a34f1ba03 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -18,7 +18,7 @@ import '../build_configuration.dart'; import '../globals.dart'; import '../package_map.dart'; import '../toolchain.dart'; -import 'version.dart'; +import '../version.dart'; const String kFlutterRootEnvironmentVariableName = 'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo) const String kFlutterEngineEnvironmentVariableName = 'FLUTTER_ENGINE'; // should point to //engine/src/ (root of flutter/engine repo) diff --git a/packages/flutter_tools/lib/src/toolchain.dart b/packages/flutter_tools/lib/src/toolchain.dart index 7c876560ba9..3c3dd9749b6 100644 --- a/packages/flutter_tools/lib/src/toolchain.dart +++ b/packages/flutter_tools/lib/src/toolchain.dart @@ -144,10 +144,9 @@ class ToolConfiguration { switch (platform) { case TargetPlatform.android_arm: - type = 'android'; - break; case TargetPlatform.android_x64: - type = 'android_sim'; + case TargetPlatform.android_x86: + type = 'android'; break; // TODO(devoncarew): We will need an ios vs ios_x86 target (for ios vs. ios_sim). @@ -166,6 +165,18 @@ class ToolConfiguration { if (isAotBuildMode(mode)) buildOutputPath += '_Deploy'; + // Add a suffix for the target architecture. + switch (platform) { + case TargetPlatform.android_x64: + buildOutputPath += '_x64'; + break; + case TargetPlatform.android_x86: + buildOutputPath += '_x86'; + break; + default: + break; + } + return new Directory(path.join(engineSrcPath, buildOutputPath)); } else { String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : ''; diff --git a/packages/flutter_tools/lib/src/usage.dart b/packages/flutter_tools/lib/src/usage.dart index 388adb3027a..440ce5e1f78 100644 --- a/packages/flutter_tools/lib/src/usage.dart +++ b/packages/flutter_tools/lib/src/usage.dart @@ -8,8 +8,9 @@ import 'package:usage/src/usage_impl_io.dart'; import 'package:usage/usage.dart'; import 'base/context.dart'; +import 'base/utils.dart'; import 'globals.dart'; -import 'runner/version.dart'; +import 'version.dart'; // TODO(devoncarew): We'll need to do some work on the user agent in order to // correctly track usage by operating system (dart-lang/usage/issues/70). @@ -22,7 +23,19 @@ class Usage { Usage() { String version = FlutterVersion.getVersionString(whitelistBranchName: true); _analytics = new AnalyticsIO(_kFlutterUA, 'flutter', version); - _analytics.analyticsOpt = AnalyticsOpt.optOut; + + bool runningOnCI = false; + + // Many CI systems don't do a full git checkout. + if (version.startsWith('unknown/')) + runningOnCI = true; + + // Check for common CI systems. + if (isRunningOnBot) + runningOnCI = true; + + // If we think we're running on a CI system, default to not sending analytics. + _analytics.analyticsOpt = runningOnCI ? AnalyticsOpt.optIn : AnalyticsOpt.optOut; } /// Returns [Usage] active in the current app context. @@ -82,10 +95,14 @@ class Usage { final String versionString = FlutterVersion.getVersionString(whitelistBranchName: true); + String welcomeString = 'Welcome to Flutter! - Flutter version $versionString - https://flutter.io'; + welcomeString = welcomeString.padLeft((welcomeString.length + 100) ~/ 2); + welcomeString = welcomeString.padRight(100); + printStatus(''); printStatus(''' ╔════════════════════════════════════════════════════════════════════════════════════════════════════╗ - ║ Welcome to Flutter! - Flutter version $versionString - https://flutter.io ║ + ║$welcomeString║ ║ ║ ║ The Flutter tool anonymously reports feature usage statistics and basic crash reports to Google in ║ ║ order to help Google contribute improvements to Flutter over time. See Google's privacy policy: ║ diff --git a/packages/flutter_tools/lib/src/runner/version.dart b/packages/flutter_tools/lib/src/version.dart similarity index 95% rename from packages/flutter_tools/lib/src/runner/version.dart rename to packages/flutter_tools/lib/src/version.dart index 8e400c55272..5b402a4a66d 100644 --- a/packages/flutter_tools/lib/src/runner/version.dart +++ b/packages/flutter_tools/lib/src/version.dart @@ -4,8 +4,8 @@ import 'dart:io'; -import '../artifacts.dart'; -import '../base/process.dart'; +import 'artifacts.dart'; +import 'base/process.dart'; final Set kKnownBranchNames = new Set.from([ 'master', @@ -64,7 +64,7 @@ class FlutterVersion { return new FlutterVersion(flutterRoot != null ? flutterRoot : ArtifactStore.flutterRoot); } - /// Return a short string for the version (`a76bc8e22b/alpha`). + /// Return a short string for the version (`alpha/a76bc8e22b`). static String getVersionString({ bool whitelistBranchName: false }) { final String cwd = ArtifactStore.flutterRoot; @@ -80,7 +80,7 @@ class FlutterVersion { branch = 'dev'; } - return '$commit/$branch'; + return '$branch/$commit'; } } diff --git a/travis/setup.sh b/travis/setup.sh index 213102825dd..cad886fc872 100755 --- a/travis/setup.sh +++ b/travis/setup.sh @@ -1,10 +1,8 @@ #!/bin/bash set -ex -# Download dependencies flutter -./bin/flutter --version - -# Disable analytics on the bots (to avoid skewing analytics data). +# disable analytics on the bots and download Flutter dependencies ./bin/flutter config --no-analytics +# run pub get in all the repo packages ./bin/flutter update-packages