service_extensions_test.dart 45.2 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7 8 9 10
// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=123"
@Tags(<String>['no-shuffle'])

11 12 13 14 15 16 17 18 19 20
import 'dart:async';
import 'dart:convert';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
21
import 'package:flutter_test/flutter_test.dart';
22 23

class TestServiceExtensionsBinding extends BindingBase
24 25
  with SchedulerBinding,
       ServicesBinding,
26
       GestureBinding,
27
       PaintingBinding,
28
       SemanticsBinding,
29
       RendererBinding,
30 31
       WidgetsBinding,
       TestDefaultBinaryMessengerBinding {
32 33 34

  final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};

35 36
  final Map<String, List<Map<String, dynamic>>> eventsDispatched = <String, List<Map<String, dynamic>>>{};

37
  @override
38
  @protected
39
  void registerServiceExtension({
40 41
    required String name,
    required ServiceExtensionCallback callback,
42 43 44 45 46
  }) {
    expect(extensions.containsKey(name), isFalse);
    extensions[name] = callback;
  }

47
  @override
48
  void postEvent(String eventKind, Map<String, dynamic> eventData) {
49 50 51 52 53 54 55 56 57 58 59 60
    getEventsDispatched(eventKind).add(eventData);
  }

  List<Map<String, dynamic>> getEventsDispatched(String eventKind) {
    return eventsDispatched.putIfAbsent(eventKind, () => <Map<String, dynamic>>[]);
  }

  Iterable<Map<String, dynamic>> getServiceExtensionStateChangedEvents(String extensionName) {
    return getEventsDispatched('Flutter.ServiceExtensionStateChanged')
      .where((Map<String, dynamic> event) => event['extension'] == extensionName);
  }

61
  Future<Map<String, dynamic>> testExtension(String name, Map<String, String> arguments) {
62
    expect(extensions.containsKey(name), isTrue);
63
    return extensions[name]!(arguments);
64 65 66
  }

  int reassembled = 0;
67
  bool pendingReassemble = false;
68
  @override
69
  Future<void> performReassemble() {
70
    reassembled += 1;
71
    pendingReassemble = true;
72
    return super.performReassemble();
73 74 75 76 77
  }

  bool frameScheduled = false;
  @override
  void scheduleFrame() {
78
    ensureFrameCallbacksRegistered();
79 80
    frameScheduled = true;
  }
81
  Future<void> doFrame() async {
82
    frameScheduled = false;
83
    binding.platformDispatcher.onBeginFrame?.call(Duration.zero);
84
    await flushMicrotasks();
85 86
    binding.platformDispatcher.onDrawFrame?.call();
    binding.platformDispatcher.onReportTimings?.call(<ui.FrameTiming>[]);
87 88
  }

89 90 91 92 93 94 95 96 97 98 99
  @override
  void scheduleForcedFrame() {
    expect(true, isFalse);
  }

  @override
  void scheduleWarmUpFrame() {
    expect(pendingReassemble, isTrue);
    pendingReassemble = false;
  }

100 101
  Future<void> flushMicrotasks() {
    final Completer<void> completer = Completer<void>();
102
    Timer.run(completer.complete);
103 104 105 106
    return completer.future;
  }
}

107
late TestServiceExtensionsBinding binding;
108

109
Future<Map<String, dynamic>> hasReassemble(Future<Map<String, dynamic>> pendingResult) async {
110 111 112 113 114 115
  bool completed = false;
  pendingResult.whenComplete(() { completed = true; });
  expect(binding.frameScheduled, isFalse);
  await binding.flushMicrotasks();
  expect(binding.frameScheduled, isTrue);
  expect(completed, isFalse);
116
  await binding.flushMicrotasks();
117
  await binding.doFrame();
118 119 120 121 122 123
  await binding.flushMicrotasks();
  expect(completed, isTrue);
  expect(binding.frameScheduled, isFalse);
  return pendingResult;
}

124
void main() {
125
  final List<String?> console = <String?>[];
126

127
  setUpAll(() async {
128
    binding = TestServiceExtensionsBinding()..scheduleFrame();
129
    expect(binding.frameScheduled, isTrue);
130 131 132 133 134

    // We need to test this service extension here because the result is true
    // after the first binding.doFrame() call.
    Map<String, dynamic> firstFrameResult;
    expect(binding.debugDidSendFirstFrameEvent, isFalse);
135
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, <String, String>{});
136
    expect(firstFrameResult, <String, String>{'enabled': 'false'});
137

138
    expect(binding.firstFrameRasterized, isFalse);
139
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, <String, String>{});
140 141
    expect(firstFrameResult, <String, String>{'enabled': 'false'});

142
    await binding.doFrame();
143 144

    expect(binding.debugDidSendFirstFrameEvent, isTrue);
145
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, <String, String>{});
146
    expect(firstFrameResult, <String, String>{'enabled': 'true'});
147

148
    expect(binding.firstFrameRasterized, isTrue);
149
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, <String, String>{});
150 151
    expect(firstFrameResult, <String, String>{'enabled': 'true'});

152 153 154
    expect(binding.frameScheduled, isFalse);

    expect(debugPrint, equals(debugPrintThrottled));
155
    debugPrint = (String? message, { int? wrapWidth }) {
156 157 158 159
      console.add(message);
    };
  });

160 161 162
  tearDownAll(() async {
    // See widget_inspector_test.dart for tests of the ext.flutter.inspector
    // service extensions included in this count.
163
    int widgetInspectorExtensionCount = 22;
164 165 166 167 168 169
    if (WidgetInspectorService.instance.isWidgetCreationTracked()) {
      // Some inspector extensions are only exposed if widget creation locations
      // are tracked.
      widgetInspectorExtensionCount += 2;
    }

170 171
    // The following service extensions are disabled in web:
    // 1. exit
172 173
    // 2. showPerformanceOverlay
    const int disabledExtensions = kIsWeb ? 2 : 0;
174 175 176 177 178

    // The expected number of registered service extensions in the Flutter
    // framework, excluding any that are for the widget inspector
    // (see widget_inspector_test.dart for tests of the ext.flutter.inspector
    // service extensions).
179
    const int serviceExtensionCount = 37;
180 181

    expect(binding.extensions.length, serviceExtensionCount + widgetInspectorExtensionCount - disabledExtensions);
182 183 184 185 186

    expect(console, isEmpty);
    debugPrint = debugPrintThrottled;
  });

187 188 189
  // The following list is alphabetical, one test per extension.

  test('Service extensions - debugAllowBanner', () async {
190
    Map<String, dynamic> result;
191 192 193

    expect(binding.frameScheduled, isFalse);
    expect(WidgetsApp.debugAllowBannerOverride, true);
194
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
195
    expect(result, <String, String>{'enabled': 'true'});
196
    expect(WidgetsApp.debugAllowBannerOverride, true);
197
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{'enabled': 'false'});
198
    expect(result, <String, String>{'enabled': 'false'});
199
    expect(WidgetsApp.debugAllowBannerOverride, false);
200
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
201
    expect(result, <String, String>{'enabled': 'false'});
202
    expect(WidgetsApp.debugAllowBannerOverride, false);
203
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{'enabled': 'true'});
204
    expect(result, <String, String>{'enabled': 'true'});
205
    expect(WidgetsApp.debugAllowBannerOverride, true);
206
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
207
    expect(result, <String, String>{'enabled': 'true'});
208 209 210 211 212
    expect(WidgetsApp.debugAllowBannerOverride, true);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDumpApp', () async {
213
    final Map<String, dynamic> result = await binding.testExtension(WidgetsServiceExtensions.debugDumpApp.name, <String, String>{});
214

215 216 217
    expect(result, <String, dynamic>{
      'data': matches('TestServiceExtensionsBinding - DEBUG MODE\n<no tree currently mounted>'),
    });
218 219 220
  });

  test('Service extensions - debugDumpRenderTree', () async {
221
    await binding.doFrame();
222
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpRenderTree.name, <String, String>{});
223 224 225

    expect(result, <String, dynamic>{
      'data': matches(
226
        r'^'
227
        r'RenderView#[0-9a-f]{5}\n'
228
        r'   debug mode enabled - [a-zA-Z]+\n'
229 230 231
        r'   window size: Size\(2400\.0, 1800\.0\) \(in physical pixels\)\n'
        r'   device pixel ratio: 3\.0 \(physical pixels per logical pixel\)\n'
        r'   configuration: Size\(800\.0, 600\.0\) at 3\.0x \(in logical pixels\)\n'
232
        r'$',
233
      ),
234
    });
235 236
  });

237 238
  test('Service extensions - debugDumpLayerTree', () async {
    await binding.doFrame();
239
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpLayerTree.name, <String, String>{});
240 241 242

    expect(result, <String, dynamic>{
      'data': matches(
243
        r'^'
244 245
        r'TransformLayer#[0-9a-f]{5}\n'
        r'   owner: RenderView#[0-9a-f]{5}\n'
246
        r'   creator: RenderView\n'
247
        r'   engine layer: (TransformEngineLayer|PersistedTransform)#[0-9a-f]{5}\n'
248
        r'   handles: 1\n'
249 250
        r'   offset: Offset\(0\.0, 0\.0\)\n'
        r'   transform:\n'
251 252
        r'     \[0] 3\.0,0\.0,0\.0,0\.0\n'
        r'     \[1] 0\.0,3\.0,0\.0,0\.0\n'
253 254
        r'     \[2] 0\.0,0\.0,1\.0,0\.0\n'
        r'     \[3] 0\.0,0\.0,0\.0,1\.0\n'
255
        r'$',
256
      ),
257
    });
258 259
  });

260
  test('Service extensions - debugDumpSemanticsTreeInTraversalOrder', () async {
261
    await binding.doFrame();
262
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInTraversalOrder.name, <String, String>{});
263 264

    expect(result, <String, String>{
265 266 267 268
      'data': 'Semantics not generated.\n'
        'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
        'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
        'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
269
    });
270 271 272 273
  });

  test('Service extensions - debugDumpSemanticsTreeInInverseHitTestOrder', () async {
    await binding.doFrame();
274
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInInverseHitTestOrder.name, <String, String>{});
275 276

    expect(result, <String, String>{
277 278 279 280
      'data': 'Semantics not generated.\n'
        'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
        'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
        'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
281
    });
282 283
  });

284
  test('Service extensions - debugPaint', () async {
285 286
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.debugPaint');
    Map<String, dynamic> extensionChangedEvent;
287 288
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
289 290 291 292
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugPaintSizeEnabled, false);
293
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
294
    expect(result, <String, String>{'enabled': 'false'});
295
    expect(debugPaintSizeEnabled, false);
296
    expect(extensionChangedEvents, isEmpty);
297
    expect(binding.frameScheduled, isFalse);
298
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{'enabled': 'true'});
299 300 301 302 303
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
304
    await binding.doFrame();
305 306 307 308
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
309
    expect(result, <String, String>{'enabled': 'true'});
310
    expect(debugPaintSizeEnabled, true);
311 312 313 314
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
    expect(extensionChangedEvent['value'], 'true');
315
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
316
    expect(result, <String, String>{'enabled': 'true'});
317
    expect(debugPaintSizeEnabled, true);
318
    expect(extensionChangedEvents.length, 1);
319
    expect(binding.frameScheduled, isFalse);
320
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{'enabled': 'false'});
321 322
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
323
    await binding.doFrame();
324 325
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
326
    expect(result, <String, String>{'enabled': 'false'});
327
    expect(debugPaintSizeEnabled, false);
328 329 330 331
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
    expect(extensionChangedEvent['value'], 'false');
332
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
333
    expect(result, <String, String>{'enabled': 'false'});
334
    expect(debugPaintSizeEnabled, false);
335
    expect(extensionChangedEvents.length, 2);
336 337 338
    expect(binding.frameScheduled, isFalse);
  });

339
  test('Service extensions - debugPaintBaselinesEnabled', () async {
340 341
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
342 343 344 345
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugPaintBaselinesEnabled, false);
346
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
347
    expect(result, <String, String>{'enabled': 'false'});
348 349
    expect(debugPaintBaselinesEnabled, false);
    expect(binding.frameScheduled, isFalse);
350
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{'enabled': 'true'});
351 352 353 354 355 356 357 358 359 360
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
361
    expect(result, <String, String>{'enabled': 'true'});
362
    expect(debugPaintBaselinesEnabled, true);
363
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
364
    expect(result, <String, String>{'enabled': 'true'});
365 366
    expect(debugPaintBaselinesEnabled, true);
    expect(binding.frameScheduled, isFalse);
367
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{'enabled': 'false'});
368 369 370 371 372
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
373
    expect(result, <String, String>{'enabled': 'false'});
374
    expect(debugPaintBaselinesEnabled, false);
375
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
376
    expect(result, <String, String>{'enabled': 'false'});
377 378 379 380
    expect(debugPaintBaselinesEnabled, false);
    expect(binding.frameScheduled, isFalse);
  });

381 382
  test('Service extensions - invertOversizedImages', () async {
    Map<String, dynamic> result;
383 384
    Future<Map<String, dynamic>> pendingResult;
    bool completed;
385 386 387

    expect(binding.frameScheduled, isFalse);
    expect(debugInvertOversizedImages, false);
388
    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
389 390
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);
391 392
    expect(binding.frameScheduled, isFalse);

393
    pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{'enabled': 'true'});
394 395 396 397 398 399 400 401 402 403
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
404 405
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugInvertOversizedImages, true);
406

407
    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
408 409
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugInvertOversizedImages, true);
410 411
    expect(binding.frameScheduled, isFalse);

412
    pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{'enabled': 'false'});
413 414 415 416 417
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
418 419
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);
420

421
    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
422 423 424 425 426
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);
    expect(binding.frameScheduled, isFalse);
  });

427 428 429 430 431 432
  test('Service extensions - profileWidgetBuilds', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabled, false);

433
    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
434
    expect(result, <String, String>{'enabled': 'false'});
435 436
    expect(debugProfileBuildsEnabled, false);

437
    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{'enabled': 'true'});
438
    expect(result, <String, String>{'enabled': 'true'});
439 440
    expect(debugProfileBuildsEnabled, true);

441
    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
442
    expect(result, <String, String>{'enabled': 'true'});
443 444
    expect(debugProfileBuildsEnabled, true);

445
    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{'enabled': 'false'});
446
    expect(result, <String, String>{'enabled': 'false'});
447 448
    expect(debugProfileBuildsEnabled, false);

449
    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
450
    expect(result, <String, String>{'enabled': 'false'});
451 452
    expect(debugProfileBuildsEnabled, false);

453 454 455 456 457 458 459 460 461
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileUserWidgetBuilds', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabledUserWidgets, false);

462
    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
463 464 465
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

466
    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{'enabled': 'true'});
467 468 469
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabledUserWidgets, true);

470
    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
471 472 473
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabledUserWidgets, true);

474
    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{'enabled': 'false'});
475 476 477
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

478
    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
479 480 481
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

482 483 484
    expect(binding.frameScheduled, isFalse);
  });

485 486 487 488 489 490
  test('Service extensions - profileRenderObjectPaints', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabled, false);

491
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
492 493 494
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

495
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{'enabled': 'true'});
496 497 498
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfilePaintsEnabled, true);

499
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
500 501 502
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfilePaintsEnabled, true);

503
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{'enabled': 'false'});
504 505 506
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

507
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
508 509 510 511 512 513 514 515 516 517 518 519
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileRenderObjectLayouts', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileLayoutsEnabled, false);

520
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
521 522 523
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

524
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{'enabled': 'true'});
525 526 527
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileLayoutsEnabled, true);

528
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
529 530 531
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileLayoutsEnabled, true);

532
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{'enabled': 'false'});
533 534 535
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

536
    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
537 538 539 540 541 542
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

    expect(binding.frameScheduled, isFalse);
  });

543
  test('Service extensions - evict', () async {
544
    Map<String, dynamic> result;
545 546 547
    bool completed;

    completed = false;
548
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
549
      expect(utf8.decode(message!.buffer.asUint8List()), 'test');
550
      completed = true;
551
      return ByteData(5); // 0x0000000000
552 553
    });
    bool data;
554 555 556 557
    data = await rootBundle.loadStructuredData<bool>('test', (String value) async {
      expect(value, '\x00\x00\x00\x00\x00');
      return true;
    });
558 559 560
    expect(data, isTrue);
    expect(completed, isTrue);
    completed = false;
561
    data = await rootBundle.loadStructuredData('test', (String value) async {
562
      throw Error();
563
    });
564 565
    expect(data, isTrue);
    expect(completed, isFalse);
566
    result = await binding.testExtension(ServicesServiceExtensions.evict.name, <String, String>{'value': 'test'});
567
    expect(result, <String, String>{'value': ''});
568
    expect(completed, isFalse);
569 570 571 572
    data = await rootBundle.loadStructuredData<bool>('test', (String value) async {
      expect(value, '\x00\x00\x00\x00\x00');
      return false;
    });
573 574
    expect(data, isFalse);
    expect(completed, isTrue);
575
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
576 577 578 579
  });

  test('Service extensions - exit', () async {
    // no test for _calling_ 'exit', because that should terminate the process!
580
    // Not expecting extension to be available for web platform.
581
    expect(binding.extensions.containsKey(FoundationServiceExtensions.exit.name), !isBrowser);
582 583
  });

584
  test('Service extensions - platformOverride', () async {
585 586
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.platformOverride');
    Map<String, dynamic> extensionChangedEvent;
587
    Map<String, dynamic> result;
588 589 590

    expect(binding.reassembled, 0);
    expect(defaultTargetPlatform, TargetPlatform.android);
591
    result = await binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{});
592 593
    expect(result, <String, String>{'value': 'android'});
    expect(defaultTargetPlatform, TargetPlatform.android);
594
    expect(extensionChangedEvents, isEmpty);
595
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'iOS'}));
596 597 598
    expect(result, <String, String>{'value': 'iOS'});
    expect(binding.reassembled, 1);
    expect(defaultTargetPlatform, TargetPlatform.iOS);
599 600 601 602
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'iOS');
603
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'macOS'}));
Dan Field's avatar
Dan Field committed
604 605 606 607 608 609 610
    expect(result, <String, String>{'value': 'macOS'});
    expect(binding.reassembled, 2);
    expect(defaultTargetPlatform, TargetPlatform.macOS);
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'macOS');
611
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'android'}));
612
    expect(result, <String, String>{'value': 'android'});
Dan Field's avatar
Dan Field committed
613
    expect(binding.reassembled, 3);
614
    expect(defaultTargetPlatform, TargetPlatform.android);
Dan Field's avatar
Dan Field committed
615
    expect(extensionChangedEvents.length, 3);
616 617 618
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
619
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'fuchsia'}));
620
    expect(result, <String, String>{'value': 'fuchsia'});
Dan Field's avatar
Dan Field committed
621
    expect(binding.reassembled, 4);
622
    expect(defaultTargetPlatform, TargetPlatform.fuchsia);
Dan Field's avatar
Dan Field committed
623
    expect(extensionChangedEvents.length, 4);
624 625 626
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'fuchsia');
627
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'default'}));
628
    expect(result, <String, String>{'value': 'android'});
Dan Field's avatar
Dan Field committed
629
    expect(binding.reassembled, 5);
630
    expect(defaultTargetPlatform, TargetPlatform.android);
Dan Field's avatar
Dan Field committed
631
    expect(extensionChangedEvents.length, 5);
632 633 634
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
635
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'iOS'}));
636
    expect(result, <String, String>{'value': 'iOS'});
Dan Field's avatar
Dan Field committed
637
    expect(binding.reassembled, 6);
638
    expect(defaultTargetPlatform, TargetPlatform.iOS);
Dan Field's avatar
Dan Field committed
639
    expect(extensionChangedEvents.length, 6);
640 641 642
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'iOS');
643
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'linux'}));
644 645 646 647 648 649 650
    expect(result, <String, String>{'value': 'linux'});
    expect(binding.reassembled, 7);
    expect(defaultTargetPlatform, TargetPlatform.linux);
    expect(extensionChangedEvents.length, 7);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'linux');
651
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'windows'}));
652 653 654 655 656 657 658
    expect(result, <String, String>{'value': 'windows'});
    expect(binding.reassembled, 8);
    expect(defaultTargetPlatform, TargetPlatform.windows);
    expect(extensionChangedEvents.length, 8);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'windows');
659
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'bogus'}));
660
    expect(result, <String, String>{'value': 'android'});
661
    expect(binding.reassembled, 9);
662
    expect(defaultTargetPlatform, TargetPlatform.android);
663
    expect(extensionChangedEvents.length, 9);
664 665 666
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
667 668 669
    binding.reassembled = 0;
  });

670
  test('Service extensions - repaintRainbow', () async {
671 672
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
673 674 675 676
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugRepaintRainbowEnabled, false);
677
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
678
    expect(result, <String, String>{'enabled': 'false'});
679 680
    expect(debugRepaintRainbowEnabled, false);
    expect(binding.frameScheduled, isFalse);
681
    pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{'enabled': 'true'});
682 683 684 685 686 687
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
688
    expect(result, <String, String>{'enabled': 'true'});
689
    expect(debugRepaintRainbowEnabled, true);
690
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
691
    expect(result, <String, String>{'enabled': 'true'});
692 693
    expect(debugRepaintRainbowEnabled, true);
    expect(binding.frameScheduled, isFalse);
694
    pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{'enabled': 'false'});
695 696 697 698 699
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(completed, false);
    expect(binding.frameScheduled, isTrue);
700
    await binding.doFrame();
701 702 703 704
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
705
    expect(result, <String, String>{'enabled': 'false'});
706
    expect(debugRepaintRainbowEnabled, false);
707
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
708
    expect(result, <String, String>{'enabled': 'false'});
709 710 711 712
    expect(debugRepaintRainbowEnabled, false);
    expect(binding.frameScheduled, isFalse);
  });

713 714 715 716 717 718 719
  test('Service extensions - debugDisableClipLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisableClipLayers, false);
720
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
721 722 723
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
    expect(binding.frameScheduled, isFalse);
724
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{'enabled': 'true'});
725 726 727 728 729 730 731 732 733 734 735 736
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableClipLayers, true);
737
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
738 739 740
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableClipLayers, true);
    expect(binding.frameScheduled, isFalse);
741
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{'enabled': 'false'});
742 743 744 745 746 747 748
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
749
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
750 751 752 753 754 755 756 757 758 759 760 761
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDisablePhysicalShapeLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisablePhysicalShapeLayers, false);
762
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
763 764 765
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
    expect(binding.frameScheduled, isFalse);
766
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{'enabled': 'true'});
767 768 769 770 771 772 773 774 775 776 777 778
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisablePhysicalShapeLayers, true);
779
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
780 781 782
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisablePhysicalShapeLayers, true);
    expect(binding.frameScheduled, isFalse);
783
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{'enabled': 'false'});
784 785 786 787 788 789 790
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
791
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
792 793 794 795 796 797 798 799 800 801 802 803
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDisableOpacityLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisableOpacityLayers, false);
804
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
805 806 807
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
    expect(binding.frameScheduled, isFalse);
808
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{'enabled': 'true'});
809 810 811 812 813 814 815 816 817 818 819 820
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableOpacityLayers, true);
821
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
822 823 824
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableOpacityLayers, true);
    expect(binding.frameScheduled, isFalse);
825
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{'enabled': 'false'});
826 827 828 829 830 831 832
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
833
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
834 835 836 837 838
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

839
  test('Service extensions - reassemble', () async {
840 841
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
842 843 844 845
    bool completed;

    completed = false;
    expect(binding.reassembled, 0);
846
    pendingResult = binding.testExtension(FoundationServiceExtensions.reassemble.name, <String, String>{});
847 848 849 850
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, false);
851
    await binding.flushMicrotasks();
852
    await binding.doFrame();
853 854 855 856 857 858 859 860 861
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{});
    expect(binding.reassembled, 1);
  });

  test('Service extensions - showPerformanceOverlay', () async {
862
    Map<String, dynamic> result;
863

864 865
    // The performance overlay service extension is disabled on the web.
    if (kIsWeb) {
866
      expect(binding.extensions.containsKey(WidgetsServiceExtensions.showPerformanceOverlay.name), isFalse);
867 868 869
      return;
    }

870 871
    expect(binding.frameScheduled, isFalse);
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
872
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
873
    expect(result, <String, String>{'enabled': 'false'});
874
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
875
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{'enabled': 'true'});
876
    expect(result, <String, String>{'enabled': 'true'});
877
    expect(WidgetsApp.showPerformanceOverlayOverride, true);
878
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
879
    expect(result, <String, String>{'enabled': 'true'});
880
    expect(WidgetsApp.showPerformanceOverlayOverride, true);
881
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{'enabled': 'false'});
882
    expect(result, <String, String>{'enabled': 'false'});
883
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
884
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
885
    expect(result, <String, String>{'enabled': 'false'});
886 887 888 889 890
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - timeDilation', () async {
891 892
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.timeDilation');
    Map<String, dynamic> extensionChangedEvent;
893
    Map<String, dynamic> result;
894 895 896

    expect(binding.frameScheduled, isFalse);
    expect(timeDilation, 1.0);
897 898
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
899
    expect(timeDilation, 1.0);
900
    expect(extensionChangedEvents, isEmpty);
901 902
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{SchedulerServiceExtensions.timeDilation.name: '100.0'});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 100.0.toString()});
903
    expect(timeDilation, 100.0);
904 905
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
906
    expect(extensionChangedEvent['extension'], 'ext.flutter.${SchedulerServiceExtensions.timeDilation.name}');
907
    expect(extensionChangedEvent['value'], 100.0.toString());
908 909
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 100.0.toString()});
910
    expect(timeDilation, 100.0);
911
    expect(extensionChangedEvents.length, 1);
912 913
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{SchedulerServiceExtensions.timeDilation.name: '1.0'});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
914
    expect(timeDilation, 1.0);
915 916
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
917
    expect(extensionChangedEvent['extension'], 'ext.flutter.${SchedulerServiceExtensions.timeDilation.name}');
918
    expect(extensionChangedEvent['value'], 1.0.toString());
919 920
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
921
    expect(timeDilation, 1.0);
922
    expect(extensionChangedEvents.length, 2);
923 924 925
    expect(binding.frameScheduled, isFalse);
  });

926
  test('Service extensions - brightnessOverride', () async {
927
    Map<String, dynamic> result;
928
    result = await binding.testExtension(FoundationServiceExtensions.brightnessOverride.name, <String, String>{});
929 930 931 932
    final String brightnessValue = result['value'] as String;

    expect(brightnessValue, 'Brightness.light');
  });
933 934 935

  test('Service extensions - activeDevToolsServerAddress', () async {
    Map<String, dynamic> result;
936
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{});
937 938
    String serverAddress = result['value'] as String;
    expect(serverAddress, '');
939
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{'value': 'http://127.0.0.1:9101'});
940 941
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:9101');
942
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{'value': 'http://127.0.0.1:9102'});
943 944 945
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:9102');
  });
946 947 948

  test('Service extensions - connectedVmServiceUri', () async {
    Map<String, dynamic> result;
949
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{});
950 951
    String serverAddress = result['value'] as String;
    expect(serverAddress, '');
952
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{'value': 'http://127.0.0.1:54669/kMUMseKAnog=/'});
953 954
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:54669/kMUMseKAnog=/');
955
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{'value': 'http://127.0.0.1:54000/kMUMseKAnog=/'});
956 957 958
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:54000/kMUMseKAnog=/');
  });
959
}