Merge branch 'master' into analysis_rework

This commit is contained in:
pq 2016-05-06 08:58:49 -07:00
commit 2df43d50d3
25 changed files with 226 additions and 130 deletions

View File

@ -1 +1 @@
d85ead8ec2556739924282e2b3f77ff077a45820 86837edd4ecbe5d28f16a770dff40a239f5b40b7

View File

@ -1,3 +0,0 @@
analyzer:
exclude:
- 'ios/.generated/**'

View File

@ -7,7 +7,6 @@ import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_sprites/flutter_sprites.dart'; import 'package:flutter_sprites/flutter_sprites.dart';
import 'package:vector_math/vector_math_64.dart' as vec;
ImageMap _images; ImageMap _images;
SpriteSheet _sprites; SpriteSheet _sprites;
@ -581,7 +580,7 @@ class _FireworksNode extends NodeWithSize {
speedVar: 50.0, speedVar: 50.0,
startSize: 1.0, startSize: 1.0,
startSizeVar: 0.5, startSizeVar: 0.5,
gravity: new vec.Vector2(0.0, 30.0), gravity: const Offset(0.0, 30.0),
colorSequence: new ColorSequence.fromStartAndEndColor(startColor, endColor) colorSequence: new ColorSequence.fromStartAndEndColor(startColor, endColor)
); );
system.position = new Point(randomDouble() * 1024.0, randomDouble() * 1024.0); system.position = new Point(randomDouble() * 1024.0, randomDouble() * 1024.0);

View File

@ -0,0 +1,3 @@
analyzer:
exclude:
- 'lib/i18n/stock_messages_*.dart'

View File

@ -28,7 +28,6 @@ class _DropDownMenuPainter extends CustomPainter {
_DropDownMenuPainter({ _DropDownMenuPainter({
Color color, Color color,
int elevation, int elevation,
this.buttonRect,
this.selectedIndex, this.selectedIndex,
Animation<double> resize Animation<double> resize
}) : color = color, }) : color = color,
@ -43,7 +42,6 @@ class _DropDownMenuPainter extends CustomPainter {
final Color color; final Color color;
final int elevation; final int elevation;
final Rect buttonRect;
final int selectedIndex; final int selectedIndex;
final Animation<double> resize; final Animation<double> resize;
@ -52,12 +50,12 @@ class _DropDownMenuPainter extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final Tween<double> top = new Tween<double>( final Tween<double> top = new Tween<double>(
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 end: 0.0
); );
final Tween<double> bottom = new Tween<double>( final Tween<double> bottom = new Tween<double>(
begin: (top.begin + buttonRect.height).clamp(buttonRect.height, size.height), begin: (top.begin + _kMenuItemHeight).clamp(_kMenuItemHeight, size.height),
end: size.height end: size.height
); );
@ -68,7 +66,6 @@ class _DropDownMenuPainter extends CustomPainter {
bool shouldRepaint(_DropDownMenuPainter oldPainter) { bool shouldRepaint(_DropDownMenuPainter oldPainter) {
return oldPainter.color != color return oldPainter.color != color
|| oldPainter.elevation != elevation || oldPainter.elevation != elevation
|| oldPainter.buttonRect != buttonRect
|| oldPainter.selectedIndex != selectedIndex || oldPainter.selectedIndex != selectedIndex
|| oldPainter.resize != resize; || oldPainter.resize != resize;
} }
@ -130,7 +127,6 @@ class _DropDownMenu<T> extends StatusTransitionWidget {
painter: new _DropDownMenuPainter( painter: new _DropDownMenuPainter(
color: Theme.of(context).canvasColor, color: Theme.of(context).canvasColor,
elevation: route.elevation, elevation: route.elevation,
buttonRect: route.buttonRect,
selectedIndex: route.selectedIndex, selectedIndex: route.selectedIndex,
resize: new CurvedAnimation( resize: new CurvedAnimation(
parent: route.animation, parent: route.animation,
@ -140,8 +136,9 @@ class _DropDownMenu<T> extends StatusTransitionWidget {
), ),
child: new Material( child: new Material(
type: MaterialType.transparency, type: MaterialType.transparency,
child: new Block( child: new ScrollableList(
padding: _kMenuVerticalPadding, padding: _kMenuVerticalPadding,
itemExtent: _kMenuItemHeight,
children: children children: children
) )
) )
@ -162,10 +159,11 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate {
// the view height. This ensures a tappable area outside of the simple menu // the view height. This ensures a tappable area outside of the simple menu
// with which to dismiss the menu. // with which to dismiss the menu.
// -- https://www.google.com/design/spec/components/menus.html#menus-simple-menus // -- 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( return new BoxConstraints(
minWidth: buttonRect.width, minWidth: width,
maxWidth: buttonRect.width, maxWidth: width,
minHeight: 0.0, minHeight: 0.0,
maxHeight: maxHeight maxHeight: maxHeight
); );
@ -173,14 +171,15 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate {
@override @override
Offset getPositionForChild(Size size, Size childSize) { Offset getPositionForChild(Size size, Size childSize) {
double top = buttonRect.top - selectedIndex * buttonRect.height - _kMenuVerticalPadding.top; final double buttonTop = buttonRect.top;
double topPreferredLimit = buttonRect.height; double top = buttonTop - selectedIndex * _kMenuItemHeight - _kMenuVerticalPadding.top;
double topPreferredLimit = _kMenuItemHeight;
if (top < topPreferredLimit) if (top < topPreferredLimit)
top = math.min(buttonRect.top, topPreferredLimit); top = math.min(buttonTop, topPreferredLimit);
double bottom = top + childSize.height; double bottom = top + childSize.height;
double bottomPreferredLimit = size.height - buttonRect.height; double bottomPreferredLimit = size.height - _kMenuItemHeight;
if (bottom > bottomPreferredLimit) { if (bottom > bottomPreferredLimit) {
bottom = math.max(buttonRect.bottom, bottomPreferredLimit); bottom = math.max(buttonTop + _kMenuItemHeight, bottomPreferredLimit);
top = bottom - childSize.height; top = bottom - childSize.height;
} }
assert(top >= 0.0); assert(top >= 0.0);
@ -277,7 +276,7 @@ class DropDownMenuItem<T> extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Container( return new Container(
height: _kMenuItemHeight, height: _kMenuItemHeight,
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: _kTopMargin), padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: Theme.of(context).textTheme.subhead, style: Theme.of(context).textTheme.subhead,
child: new Baseline( child: new Baseline(
@ -363,7 +362,7 @@ class DropDownButton<T> extends StatefulWidget {
} }
class _DropDownButtonState<T> extends State<DropDownButton<T>> { class _DropDownButtonState<T> extends State<DropDownButton<T>> {
final GlobalKey indexedStackKey = new GlobalKey(debugLabel: 'DropDownButton.IndexedStack'); final GlobalKey _itemKey = new GlobalKey(debugLabel: 'DropDownButton item key');
@override @override
void initState() { void initState() {
@ -390,13 +389,13 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
} }
void _handleTap() { void _handleTap() {
final RenderBox renderBox = indexedStackKey.currentContext.findRenderObject(); final RenderBox itemBox = _itemKey.currentContext.findRenderObject();
final Rect buttonRect = renderBox.localToGlobal(Point.origin) & renderBox.size; final Rect itemRect = itemBox.localToGlobal(Point.origin) & itemBox.size;
final Completer<_DropDownRouteResult<T>> completer = new Completer<_DropDownRouteResult<T>>(); final Completer<_DropDownRouteResult<T>> completer = new Completer<_DropDownRouteResult<T>>();
Navigator.push(context, new _DropDownRoute<T>( Navigator.push(context, new _DropDownRoute<T>(
completer: completer, completer: completer,
items: config.items, items: config.items,
buttonRect: _kMenuHorizontalPadding.inflateRect(buttonRect), buttonRect: _kMenuHorizontalPadding.inflateRect(itemRect),
selectedIndex: _selectedIndex, selectedIndex: _selectedIndex,
elevation: config.elevation elevation: config.elevation
)); ));
@ -412,27 +411,27 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context)); assert(debugCheckHasMaterial(context));
Widget result = new Row( Widget result = new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[ children: <Widget>[
// 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( new IndexedStack(
children: config.items, children: config.items,
key: indexedStackKey, key: _itemKey,
index: _selectedIndex, index: _selectedIndex,
alignment: FractionalOffset.topCenter alignment: FractionalOffset.topCenter
), ),
new Container( new Icon(icon: Icons.arrow_drop_down, size: 36.0)
child: new Icon(icon: Icons.arrow_drop_down, size: 36.0), ]
padding: const EdgeInsets.only(top: _kTopMargin)
)
],
mainAxisAlignment: MainAxisAlignment.collapse
); );
if (DropDownButtonHideUnderline.at(context)) { if (DropDownButtonHideUnderline.at(context)) {
result = new Padding( result = new Padding(
padding: const EdgeInsets.only(bottom: _kBottomBorderHeight), padding: const EdgeInsets.only(top: _kTopMargin, bottom: _kBottomBorderHeight),
child: result child: result
); );
} else { } else {
result = new Container( result = new Container(
padding: const EdgeInsets.only(top: _kTopMargin),
decoration: const BoxDecoration(border: _kDropDownUnderline), decoration: const BoxDecoration(border: _kDropDownUnderline),
child: result child: result
); );

View File

@ -7,6 +7,18 @@ import 'package:flutter/rendering.dart';
import 'framework.dart'; import 'framework.dart';
/// Displays performance statistics. /// 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 { class PerformanceOverlay extends LeafRenderObjectWidget {
// TODO(abarth): We should have a page on the web site with a screenshot and // TODO(abarth): We should have a page on the web site with a screenshot and
// an explanation of all the various readouts. // an explanation of all the various readouts.

View File

@ -38,6 +38,14 @@ void main() {
tester.pump(); tester.pump();
tester.pump(const Duration(seconds: 1)); // finish the menu animation 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)); tester.tap(find.byConfig(button));
// Ideally this would be 4 because the menu would be overscrolled to the // Ideally this would be 4 because the menu would be overscrolled to the

View File

@ -41,6 +41,49 @@ class _ParticleAccelerations {
/// number of particles can never exceed the [maxParticles] limit. /// number of particles can never exceed the [maxParticles] limit.
class ParticleSystem extends Node { 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. /// The texture used to draw each individual sprite.
Texture texture; Texture texture;
@ -108,7 +151,21 @@ class ParticleSystem extends Node {
double tangentialAccelerationVar; double tangentialAccelerationVar;
/// The gravity vector of the particle system. /// 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. /// The maximum number of particles the system can display at a single time.
int maxParticles; int maxParticles;
@ -157,45 +214,6 @@ class ParticleSystem extends Node {
..filterQuality = FilterQuality.low ..filterQuality = FilterQuality.low
..isAntiAlias = false; ..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 @override
void update(double dt) { void update(double dt) {
// TODO: Fix this (it's a temp fix for low framerates) // TODO: Fix this (it's a temp fix for low framerates)
@ -249,11 +267,11 @@ class ParticleSystem extends Node {
tangential.scale(particle.accelerations.tangentialAccel); tangential.scale(particle.accelerations.tangentialAccel);
// (gravity + radial + tangential) * dt // (gravity + radial + tangential) * dt
Vector2 accel = (gravity + radial + tangential).scale(dt); final Vector2 accel = (_gravity + radial + tangential).scale(dt);
particle.dir += accel; particle.dir += accel;
} else if (gravity[0] != 0.0 || gravity[1] != 0) { } else if (_gravity[0] != 0.0 || _gravity[1] != 0) {
// gravity // gravity
Vector2 accel = new Vector2.copy(gravity).scale(dt); final Vector2 accel = new Vector2.copy(_gravity).scale(dt);
particle.dir += accel; particle.dir += accel;
} }
@ -362,7 +380,8 @@ class ParticleSystem extends Node {
@override @override
void paint(Canvas canvas) { void paint(Canvas canvas) {
if (opacity == 0.0) return; if (opacity == 0.0)
return;
List<RSTransform> transforms = <RSTransform>[]; List<RSTransform> transforms = <RSTransform>[];
List<Rect> rects = <Rect>[]; List<Rect> rects = <Rect>[];

View File

@ -102,7 +102,7 @@ Future<Null> main(List<String> args) async {
flutterUsage.sendException(error, chain); 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. // If we're working on the tools themselves, just print the stack trace.
stderr.writeln('$error'); stderr.writeln('$error');
stderr.writeln(chain.terse.toString()); stderr.writeln(chain.terse.toString());

View File

@ -49,23 +49,49 @@ class AndroidDevice extends Device {
final String modelID; final String modelID;
final String deviceCodeName; final String deviceCodeName;
Map<String, String> _properties;
bool _isLocalEmulator; bool _isLocalEmulator;
TargetPlatform _platform;
String _getProperty(String name) {
if (_properties == null) {
String getpropOutput = runCheckedSync(adbCommandForDevice(<String>['shell', 'getprop']));
RegExp propertyExp = new RegExp(r'\[(.*?)\]: \[(.*?)\]');
_properties = <String, String>{};
for (Match m in propertyExp.allMatches(getpropOutput)) {
_properties[m.group(1)] = m.group(2);
}
}
return _properties[name];
}
@override @override
bool get isLocalEmulator { bool get isLocalEmulator {
if (_isLocalEmulator == null) { 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, ...) // http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...)
try { switch (_getProperty('ro.product.cpu.abi')) {
String value = runCheckedSync(adbCommandForDevice( case 'x86_64':
<String>['shell', 'getprop', 'ro.product.cpu.abi'] _platform = TargetPlatform.android_x64;
)); break;
_isLocalEmulator = value.startsWith('x86'); case 'x86':
} catch (error) { _platform = TargetPlatform.android_x86;
_isLocalEmulator = false; break;
default:
_platform = TargetPlatform.android_arm;
break;
} }
} }
return _isLocalEmulator; return _platform;
} }
_AdbLogReader _logReader; _AdbLogReader _logReader;
@ -123,9 +149,7 @@ class AndroidDevice extends Device {
runCheckedSync(<String>[androidSdk.adbPath, 'start-server']); runCheckedSync(<String>[androidSdk.adbPath, 'start-server']);
// Sample output: '22' // Sample output: '22'
String sdkVersion = runCheckedSync( String sdkVersion = _getProperty('ro.build.version.sdk');
adbCommandForDevice(<String>['shell', 'getprop', 'ro.build.version.sdk'])
).trimRight();
int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null); int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null);
if (sdkVersionParsed == null) { if (sdkVersionParsed == null) {
@ -333,9 +357,6 @@ class AndroidDevice extends Device {
return runCommandAndStreamOutput(command).then((int exitCode) => exitCode == 0); return runCommandAndStreamOutput(command).then((int exitCode) => exitCode == 0);
} }
@override
TargetPlatform get platform => isLocalEmulator ? TargetPlatform.android_x64 : TargetPlatform.android_arm;
@override @override
void clearLogs() { void clearLogs() {
runSync(adbCommandForDevice(<String>['logcat', '-c'])); runSync(adbCommandForDevice(<String>['logcat', '-c']));

View File

@ -103,6 +103,7 @@ ApplicationPackage getApplicationPackageForPlatform(TargetPlatform platform) {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
return new AndroidApk.fromCurrentDirectory(); return new AndroidApk.fromCurrentDirectory();
case TargetPlatform.ios: case TargetPlatform.ios:
return new IOSApp.fromCurrentDirectory(); return new IOSApp.fromCurrentDirectory();
@ -122,6 +123,7 @@ class ApplicationPackageStore {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
android ??= new AndroidApk.fromCurrentDirectory(); android ??= new AndroidApk.fromCurrentDirectory();
return android; return android;
case TargetPlatform.ios: case TargetPlatform.ios:

View File

@ -8,6 +8,13 @@ import 'dart:io';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:path/path.dart' as path; 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<int> bytes) { String hex(List<int> bytes) {
StringBuffer result = new StringBuffer(); StringBuffer result = new StringBuffer();
for (int part in bytes) for (int part in bytes)

View File

@ -41,6 +41,7 @@ String getNameForHostPlatform(HostPlatform platform) {
enum TargetPlatform { enum TargetPlatform {
android_arm, android_arm,
android_x64, android_x64,
android_x86,
ios, ios,
darwin_x64, darwin_x64,
linux_x64 linux_x64

View File

@ -192,7 +192,8 @@ class FlutterEngine {
'android-arm', 'android-arm',
'android-arm-profile', 'android-arm-profile',
'android-arm-release', 'android-arm-release',
'android-x64' 'android-x64',
'android-x86',
]; ];
if (Platform.isMacOS) if (Platform.isMacOS)

View File

@ -34,15 +34,8 @@ class AnalyzeCommand extends FlutterCommand {
argParser.addFlag('watch', help: 'Run analysis continuously, watching the filesystem for changes.', negatable: false); 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); argParser.addOption('dart-sdk', help: 'The path to the Dart SDK.', hide: true);
// Options to enable a benchmarking mode. // Hidden option to enable a benchmarking mode.
argParser.addFlag('benchmark', argParser.addFlag('benchmark', negatable: false, hide: true);
negatable: false,
hide: true
);
argParser.addOption('benchmark-expected',
hide: true,
help: 'The time (in seconds) that the benchmark is expected to run.'
);
usesPubOption(); usesPubOption();
} }
@ -393,19 +386,12 @@ class AnalyzeCommand extends FlutterCommand {
void _writeBenchmark(Stopwatch stopwatch, int errorCount) { void _writeBenchmark(Stopwatch stopwatch, int errorCount) {
final String benchmarkOut = 'analysis_benchmark.json'; final String benchmarkOut = 'analysis_benchmark.json';
String expectedTime = argResults['benchmark-expected'];
Map<String, dynamic> data = <String, dynamic>{ Map<String, dynamic> data = <String, dynamic>{
'time': (stopwatch.elapsedMilliseconds / 1000.0), 'time': (stopwatch.elapsedMilliseconds / 1000.0),
'issues': errorCount 'issues': errorCount
}; };
if (expectedTime != null)
data['expected'] = expectedTime;
JsonEncoder encoder = new JsonEncoder.withIndent(' '); JsonEncoder encoder = new JsonEncoder.withIndent(' ');
new File(benchmarkOut).writeAsStringSync(encoder.convert(data) + '\n'); new File(benchmarkOut).writeAsStringSync(encoder.convert(data) + '\n');
printStatus('Analysis benchmark written to $benchmarkOut.'); printStatus('Analysis benchmark written to $benchmarkOut.');
} }
} }

View File

@ -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( Future<_ApkComponents> _findApkComponents(
TargetPlatform platform, TargetPlatform platform,
BuildMode buildMode, BuildMode buildMode,
@ -274,7 +289,7 @@ Future<_ApkComponents> _findApkComponents(
components.extraFiles = extraFiles != null ? extraFiles : <String, File>{}; components.extraFiles = extraFiles != null ? extraFiles : <String, File>{};
if (tools.isLocalEngine) { if (tools.isLocalEngine) {
String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64'; String abiDir = getAbiDirectory(platform);
String enginePath = tools.engineSrcPath; String enginePath = tools.engineSrcPath;
String buildDir = tools.getEngineArtifactsDirectory(platform, buildMode).path; String buildDir = tools.getEngineArtifactsDirectory(platform, buildMode).path;
@ -348,7 +363,7 @@ int _buildApk(
_AssetBuilder artifactBuilder = new _AssetBuilder(tempDir, 'artifacts'); _AssetBuilder artifactBuilder = new _AssetBuilder(tempDir, 'artifacts');
artifactBuilder.add(classesDex, 'classes.dex'); 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'); artifactBuilder.add(components.libSkyShell, 'lib/$abiDir/libsky_shell.so');
for (String relativePath in components.extraFiles.keys) for (String relativePath in components.extraFiles.keys)

View File

@ -10,7 +10,7 @@ import '../base/process.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
import '../globals.dart'; import '../globals.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import '../runner/version.dart'; import '../version.dart';
class UpgradeCommand extends FlutterCommand { class UpgradeCommand extends FlutterCommand {
@override @override

View File

@ -57,7 +57,7 @@ class DeviceManager {
devices = devices.where((Device device) { devices = devices.where((Device device) {
return (device.id.toLowerCase().startsWith(deviceId) || return (device.id.toLowerCase().startsWith(deviceId) ||
device.name.toLowerCase().startsWith(deviceId)); device.name.toLowerCase().startsWith(deviceId));
}); }).toList();
return devices.length == 1 ? devices.first : null; return devices.length == 1 ? devices.first : null;
} }

View File

@ -12,7 +12,7 @@ import 'base/context.dart';
import 'base/os.dart'; import 'base/os.dart';
import 'globals.dart'; import 'globals.dart';
import 'ios/ios_workflow.dart'; import 'ios/ios_workflow.dart';
import 'runner/version.dart'; import 'version.dart';
const Map<String, String> _osNames = const <String, String>{ const Map<String, String> _osNames = const <String, String>{
'macos': 'Mac OS', 'macos': 'Mac OS',

View File

@ -18,7 +18,7 @@ import '../build_configuration.dart';
import '../globals.dart'; import '../globals.dart';
import '../package_map.dart'; import '../package_map.dart';
import '../toolchain.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 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) const String kFlutterEngineEnvironmentVariableName = 'FLUTTER_ENGINE'; // should point to //engine/src/ (root of flutter/engine repo)

View File

@ -144,10 +144,9 @@ class ToolConfiguration {
switch (platform) { switch (platform) {
case TargetPlatform.android_arm: case TargetPlatform.android_arm:
type = 'android';
break;
case TargetPlatform.android_x64: case TargetPlatform.android_x64:
type = 'android_sim'; case TargetPlatform.android_x86:
type = 'android';
break; break;
// TODO(devoncarew): We will need an ios vs ios_x86 target (for ios vs. ios_sim). // 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)) if (isAotBuildMode(mode))
buildOutputPath += '_Deploy'; 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)); return new Directory(path.join(engineSrcPath, buildOutputPath));
} else { } else {
String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : ''; String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : '';

View File

@ -8,8 +8,9 @@ import 'package:usage/src/usage_impl_io.dart';
import 'package:usage/usage.dart'; import 'package:usage/usage.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/utils.dart';
import 'globals.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 // 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). // correctly track usage by operating system (dart-lang/usage/issues/70).
@ -22,7 +23,19 @@ class Usage {
Usage() { Usage() {
String version = FlutterVersion.getVersionString(whitelistBranchName: true); String version = FlutterVersion.getVersionString(whitelistBranchName: true);
_analytics = new AnalyticsIO(_kFlutterUA, 'flutter', version); _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. /// Returns [Usage] active in the current app context.
@ -82,10 +95,14 @@ class Usage {
final String versionString = FlutterVersion.getVersionString(whitelistBranchName: true); 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('');
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 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: ║ order to help Google contribute improvements to Flutter over time. See Google's privacy policy: ║

View File

@ -4,8 +4,8 @@
import 'dart:io'; import 'dart:io';
import '../artifacts.dart'; import 'artifacts.dart';
import '../base/process.dart'; import 'base/process.dart';
final Set<String> kKnownBranchNames = new Set<String>.from(<String>[ final Set<String> kKnownBranchNames = new Set<String>.from(<String>[
'master', 'master',
@ -64,7 +64,7 @@ class FlutterVersion {
return new FlutterVersion(flutterRoot != null ? flutterRoot : ArtifactStore.flutterRoot); 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 }) { static String getVersionString({ bool whitelistBranchName: false }) {
final String cwd = ArtifactStore.flutterRoot; final String cwd = ArtifactStore.flutterRoot;
@ -80,7 +80,7 @@ class FlutterVersion {
branch = 'dev'; branch = 'dev';
} }
return '$commit/$branch'; return '$branch/$commit';
} }
} }

View File

@ -1,10 +1,8 @@
#!/bin/bash #!/bin/bash
set -ex set -ex
# Download dependencies flutter # disable analytics on the bots and download Flutter dependencies
./bin/flutter --version
# Disable analytics on the bots (to avoid skewing analytics data).
./bin/flutter config --no-analytics ./bin/flutter config --no-analytics
# run pub get in all the repo packages
./bin/flutter update-packages ./bin/flutter update-packages