screenshot method
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']);
}