blob: d29f01cca272cbd0b8ccd06ba85cb198fd880da0 [file] [log] [blame]
// Copyright 2013 The Flutter 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:typed_data';
/// A screenshot from the Android emulator.
class Screenshot {
Screenshot(this.filename, this.fileContent, this.pixelCount);
/// The name of the screenshot.
final String filename;
/// The binary content of the screenshot.
final Uint8List fileContent;
/// The number of pixels in the screenshot.
final int pixelCount;
}
/// Takes the input stream and transforms it into [Screenshot]s.
class ScreenshotBlobTransformer extends StreamTransformerBase<Uint8List, Screenshot> {
const ScreenshotBlobTransformer();
@override
Stream<Screenshot> bind(Stream<Uint8List> stream) async* {
final BytesBuilder pending = BytesBuilder();
await for (final Uint8List blob in stream) {
pending.add(blob);
if (pending.length < 12) {
continue;
}
// See ScreenshotUtil#writeFile in ScreenshotUtil.java for producer side.
final Uint8List bytes = pending.toBytes();
final ByteData byteData = bytes.buffer.asByteData();
int off = 0;
final int fnameLen = byteData.getInt32(off);
off += 4;
final int fcontentLen = byteData.getInt32(off);
off += 4;
final int pixelCount = byteData.getInt32(off);
off += 4;
assert(fnameLen > 0);
assert(fcontentLen > 0);
assert(pixelCount > 0);
if (pending.length < off + fnameLen) {
continue;
}
final String filename = utf8.decode(bytes.buffer.asUint8List(off, fnameLen));
off += fnameLen;
if (pending.length < off + fcontentLen) {
continue;
}
final Uint8List fileContent = bytes.buffer.asUint8List(off, fcontentLen);
off += fcontentLen;
pending.clear();
pending.add(bytes.buffer.asUint8List(off));
yield Screenshot('$filename.png', fileContent, pixelCount);
}
}
}