Commit 2df43d50 authored by pq's avatar pq

Merge branch 'master' into analysis_rework

parents eb215c14 bd564a02
d85ead8ec2556739924282e2b3f77ff077a45820
86837edd4ecbe5d28f16a770dff40a239f5b40b7
......@@ -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);
......
analyzer:
exclude:
- 'ios/.generated/**'
- 'lib/i18n/stock_messages_*.dart'
......@@ -28,7 +28,6 @@ class _DropDownMenuPainter extends CustomPainter {
_DropDownMenuPainter({
Color color,
int elevation,
this.buttonRect,
this.selectedIndex,
Animation<double> 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<double> resize;
......@@ -52,12 +50,12 @@ class _DropDownMenuPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
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
);
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
);
......@@ -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<T> 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<T> 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<T> 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<T> extends StatefulWidget {
}
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
void initState() {
......@@ -390,13 +389,13 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
}
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<T>> completer = new Completer<_DropDownRouteResult<T>>();
Navigator.push(context, new _DropDownRoute<T>(
completer: completer,
items: config.items,
buttonRect: _kMenuHorizontalPadding.inflateRect(buttonRect),
buttonRect: _kMenuHorizontalPadding.inflateRect(itemRect),
selectedIndex: _selectedIndex,
elevation: config.elevation
));
......@@ -412,27 +411,27 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
Widget result = new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
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(
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
);
......
......@@ -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.
......
......@@ -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
......
......@@ -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<RSTransform> transforms = <RSTransform>[];
List<Rect> rects = <Rect>[];
......
......@@ -102,7 +102,7 @@ Future<Null> main(List<String> 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());
......
......@@ -49,23 +49,49 @@ class AndroidDevice extends Device {
final String modelID;
final String deviceCodeName;
Map<String, String> _properties;
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
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(
<String>['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(<String>[androidSdk.adbPath, 'start-server']);
// Sample output: '22'
String sdkVersion = runCheckedSync(
adbCommandForDevice(<String>['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(<String>['logcat', '-c']));
......
......@@ -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:
......
......@@ -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<int> bytes) {
StringBuffer result = new StringBuffer();
for (int part in bytes)
......
......@@ -41,6 +41,7 @@ String getNameForHostPlatform(HostPlatform platform) {
enum TargetPlatform {
android_arm,
android_x64,
android_x86,
ios,
darwin_x64,
linux_x64
......
......@@ -192,7 +192,8 @@ class FlutterEngine {
'android-arm',
'android-arm-profile',
'android-arm-release',
'android-x64'
'android-x64',
'android-x86',
];
if (Platform.isMacOS)
......
......@@ -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<String, dynamic> data = <String, dynamic>{
'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.');
}
}
......
......@@ -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 : <String, File>{};
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)
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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<String, String> _osNames = const <String, String>{
'macos': 'Mac OS',
......
......@@ -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)
......
......@@ -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)}' : '';
......
......@@ -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:
......
......@@ -4,8 +4,8 @@
import 'dart:io';
import '../artifacts.dart';
import '../base/process.dart';
import 'artifacts.dart';
import 'base/process.dart';
final Set<String> kKnownBranchNames = new Set<String>.from(<String>[
'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';
}
}
......
#!/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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment