_callback_io.dart 3.65 KB
Newer Older
1 2 3 4
// Copyright 2014 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.

5
import 'dart:io' show Platform;
6 7 8 9 10
import 'dart:ui';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

11
import 'common.dart';
12
import 'src/channel.dart';
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

/// The dart:io implementation of [CallbackManager].
///
/// See also:
///
///  * `_callback_web.dart`, which has the dart:html implementation
CallbackManager get callbackManager => _singletonCallbackManager;

/// IOCallbackManager singleton.
final IOCallbackManager _singletonCallbackManager = IOCallbackManager();

/// Manages communication between `integration_tests` and the `driver_tests`.
///
/// This is the dart:io implementation.
class IOCallbackManager implements CallbackManager {
  @override
  Future<Map<String, dynamic>> callback(
      Map<String, String> params, IntegrationTestResults testRunner) async {
31
    final String command = params['command']!;
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    Map<String, String> response;
    switch (command) {
      case 'request_data':
        final bool allTestsPassed = await testRunner.allTestsPassed.future;
        response = <String, String>{
          'message': allTestsPassed
              ? Response.allTestsPassed(data: testRunner.reportData).toJson()
              : Response.someTestsFailed(
                  testRunner.failureMethodsDetails,
                  data: testRunner.reportData,
                ).toJson(),
        };
      case 'get_health':
        response = <String, String>{'status': 'ok'};
      default:
        throw UnimplementedError('$command is not implemented');
    }
    return <String, dynamic>{
      'isError': false,
      'response': response,
    };
  }

  @override
  void cleanup() {
    // no-op.
    // Add any IO platform specific Completer/Future cleanups to here if any
    // comes up in the future. For example: `WebCallbackManager.cleanup`.
  }

62 63
  // [convertFlutterSurfaceToImage] has been called and [takeScreenshot] is ready to capture the surface (Android only).
  bool _isSurfaceRendered = false;
64 65 66

  @override
  Future<void> convertFlutterSurfaceToImage() async {
67 68 69 70 71
    if (!Platform.isAndroid) {
      // No-op on other platforms.
      return;
    }
    assert(!_isSurfaceRendered, 'Surface already converted to an image');
72 73 74
    await integrationTestChannel.invokeMethod<void>(
      'convertFlutterSurfaceToImage',
    );
75
    _isSurfaceRendered = true;
76 77

    addTearDown(() async {
78
      assert(_isSurfaceRendered, 'Surface is not an image');
79 80 81
      await integrationTestChannel.invokeMethod<void>(
        'revertFlutterImage',
      );
82
      _isSurfaceRendered = false;
83 84 85
    });
  }

86
  @override
87 88
  Future<Map<String, dynamic>> takeScreenshot(String screenshot, [Map<String, Object?>? args]) async {
    assert(args == null, '[args] handling has not been implemented for this platform');
89
    if (Platform.isAndroid && !_isSurfaceRendered) {
90 91 92 93 94
      throw StateError('Call convertFlutterSurfaceToImage() before taking a screenshot');
    }
    integrationTestChannel.setMethodCallHandler(_onMethodChannelCall);
    final List<int>? rawBytes = await integrationTestChannel.invokeMethod<List<int>>(
      'captureScreenshot',
95
      <String, dynamic>{'name': screenshot},
96 97 98 99 100 101 102 103 104 105 106 107 108
    );
    if (rawBytes == null) {
      throw StateError('Expected a list of bytes, but instead captureScreenshot returned null');
    }
    return <String, dynamic>{
      'screenshotName': screenshot,
      'bytes': rawBytes,
    };
  }

  Future<dynamic> _onMethodChannelCall(MethodCall call) async {
    switch (call.method) {
      case 'scheduleFrame':
109
        PlatformDispatcher.instance.scheduleFrame();
110 111
    }
    return null;
112 113
  }
}