screenshot method

Future<List<int>> screenshot ({Duration timeout })

Take a screenshot. The image will be returned as a PNG.

Implementation

Future<List<int>> screenshot({ Duration timeout }) async {
  timeout ??= _longTimeout(timeoutMultiplier);

  // HACK: this artificial delay here is to deal with a race between the
  //       driver script and the GPU thread. The issue is that driver API
  //       synchronizes with the framework based on transient callbacks, which
  //       are out of sync with the GPU thread. Here's the timeline of events
  //       in ASCII art:
  //
  //       -------------------------------------------------------------------
  //       Before this change:
  //       -------------------------------------------------------------------
  //       UI    : <-- build -->
  //       GPU   :               <-- rasterize -->
  //       Gap   :              | random |
  //       Driver:                        <-- screenshot -->
  //
  //       In the diagram above, the gap is the time between the last driver
  //       action taken, such as a `tap()`, and the subsequent call to
  //       `screenshot()`. The gap is random because it is determined by the
  //       unpredictable network communication between the driver process and
  //       the application. If this gap is too short, the screenshot is taken
  //       before the GPU thread is done rasterizing the frame, so the
  //       screenshot of the previous frame is taken, which is wrong.
  //
  //       -------------------------------------------------------------------
  //       After this change:
  //       -------------------------------------------------------------------
  //       UI    : <-- build -->
  //       GPU   :               <-- rasterize -->
  //       Gap   :              |    2 seconds or more   |
  //       Driver:                                        <-- screenshot -->
  //
  //       The two-second gap should be long enough for the GPU thread to
  //       finish rasterizing the frame, but not longer than necessary to keep
  //       driver tests as fast a possible.
  await Future<void>.delayed(const Duration(seconds: 2));

  final Map<String, dynamic> result = await _peer.sendRequest('_flutter.screenshot').timeout(timeout);
  return base64.decode(result['screenshot']);
}