gallery.dart 2.81 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2016 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.

import 'dart:async';
import 'dart:convert';
import 'dart:io';
8
import 'dart:math' as math;
9 10 11 12 13

import '../framework/adb.dart';
import '../framework/framework.dart';
import '../framework/utils.dart';

14 15
TaskFunction createGalleryTransitionTest() {
  return new GalleryTransitionTest();
16 17 18 19 20
}

class GalleryTransitionTest {

  Future<TaskResult> call() async {
21 22 23
    Device device = await devices.workingDevice;
    await device.unlock();
    String deviceId = device.deviceId;
24 25 26
    Directory galleryDirectory =
        dir('${flutterDirectory.path}/examples/flutter_gallery');
    await inDirectory(galleryDirectory, () async {
27
      await flutter('packages', options: <String>['get']);
28

29
      if (deviceOperatingSystem == DeviceOperatingSystem.ios) {
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
        // This causes an Xcode project to be created.
        await flutter('build', options: <String>['ios', '--profile']);
      }

      await flutter('drive', options: <String>[
        '--profile',
        '--trace-startup',
        '-t',
        'test_driver/transitions_perf.dart',
        '-d',
        deviceId,
      ]);
    });

    // Route paths contains slashes, which Firebase doesn't accept in keys, so we
    // remove them.
46
    Map<String, List<int>> original = JSON.decode(file(
47 48
            '${galleryDirectory.path}/build/transition_durations.timeline.json')
        .readAsStringSync());
49
    Map<String, List<int>> transitions = new Map<String, List<int>>.fromIterable(
50 51 52 53
        original.keys,
        key: (String key) => key.replaceAll('/', ''),
        value: (String key) => original[key]);

54 55 56 57
    Map<String, dynamic> summary = JSON.decode(file('${galleryDirectory.path}/build/transitions.timeline_summary.json').readAsStringSync());

    Map<String, dynamic> data = <String, dynamic>{
      'transitions': transitions,
58
      'missed_transition_count': _countMissedTransitions(transitions),
59 60 61 62
    };
    data.addAll(summary);

    return new TaskResult.success(data, benchmarkScoreKeys: <String>[
63
      'missed_transition_count',
64 65 66
      'average_frame_build_time_millis',
      'worst_frame_build_time_millis',
      'missed_frame_build_budget_count',
67 68 69
      'average_frame_rasterizer_time_millis',
      'worst_frame_rasterizer_time_millis',
      'missed_frame_rasterizer_budget_count',
70
    ]);
71 72
  }
}
73 74 75 76 77 78 79 80 81 82 83 84 85

int _countMissedTransitions(Map<String, List<int>> transitions) {
  const int _kTransitionBudget = 100000; // µs
  int count = 0;
  transitions.forEach((String demoName, List<int> durations) {
    int longestDuration = durations.reduce(math.max);
    if (longestDuration > _kTransitionBudget) {
      print('$demoName missed transition time budget ($longestDuration µs > $_kTransitionBudget µs)');
      count++;
    }
  });
  return count;
}