Unverified Commit 958ab933 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Revert "[flutter_tools] reland migrate FlutterView to new vmservice (#55774)" (#55788)

This reverts commit a18e6361.
parent a18e6361
......@@ -620,12 +620,13 @@ class FuchsiaDevice extends Device {
// loopback (::1).
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$port');
final VMService vmService = await VMService.connect(uri);
final List<FlutterView> flutterViews = await vmService.getFlutterViews();
for (final FlutterView flutterView in flutterViews) {
await vmService.getVMOld();
await vmService.refreshViews();
for (final FlutterView flutterView in vmService.vm.views) {
if (flutterView.uiIsolate == null) {
continue;
}
final Uri address = vmService.httpAddress;
final Uri address = flutterView.owner.vmService.httpAddress;
if (flutterView.uiIsolate.name.contains(isolateName)) {
return address.port;
}
......@@ -716,12 +717,13 @@ class FuchsiaIsolateDiscoveryProtocol {
continue;
}
}
final List<FlutterView> flutterViews = await service.getFlutterViews();
for (final FlutterView flutterView in flutterViews) {
await service.getVMOld();
await service.refreshViews();
for (final FlutterView flutterView in service.vm.views) {
if (flutterView.uiIsolate == null) {
continue;
}
final Uri address = service.httpAddress;
final Uri address = flutterView.owner.vmService.httpAddress;
if (flutterView.uiIsolate.name.contains(_isolateName)) {
_foundUri.complete(_device.ipv6
? Uri.parse('http://[$_ipv6Loopback]:${address.port}/')
......
......@@ -233,25 +233,18 @@ class FlutterDevice {
if (vmService == null) {
return;
}
final List<FlutterView> updatedViews = await vmService.getFlutterViews();
_views
..clear()
..addAll(updatedViews);
await flutterDeprecatedVmService.vm.refreshViews(waitForViews: true);
}
final List<FlutterView> _views = <FlutterView>[];
List<FlutterView> get views {
if (vmService == null) {
if (vmService == null || flutterDeprecatedVmService.isClosed) {
return <FlutterView>[];
}
if (viewFilter != null) {
return <FlutterView>[
for (final FlutterView flutterView in views)
if (flutterView.uiIsolate.name.contains(viewFilter))
flutterView
];
}
return _views;
return (viewFilter != null
? flutterDeprecatedVmService.vm.allViewsWithName(viewFilter)
: flutterDeprecatedVmService.vm.views).toList();
}
Future<void> getVMs() => flutterDeprecatedVmService.getVMOld();
......@@ -261,32 +254,35 @@ class FlutterDevice {
await device.stopApp(package);
return;
}
await refreshViews();
if (views == null || views.isEmpty) {
final List<FlutterView> flutterViews = views;
if (flutterViews == null || flutterViews.isEmpty) {
return;
}
// If any of the flutter views are paused, we might not be able to
// cleanly exit since the service extension may not have been registered.
for (final FlutterView flutterView in views) {
final vm_service.Isolate isolate = await vmService
.getIsolateOrNull(flutterView.uiIsolate.id);
if (isolate == null) {
continue;
}
if (isPauseEvent(isolate.pauseEvent.kind)) {
await device.stopApp(package);
return;
if (flutterViews.any((FlutterView view) {
return view != null &&
view.uiIsolate != null &&
view.uiIsolate.pauseEvent != null &&
view.uiIsolate.pauseEvent.isPauseEvent;
}
)) {
await device.stopApp(package);
return;
}
for (final FlutterView view in views) {
final List<Future<void>> futures = <Future<void>>[];
for (final FlutterView view in flutterViews) {
if (view != null && view.uiIsolate != null) {
// If successful, there will be no response from flutterExit.
unawaited(vmService.flutterExit(
assert(!view.uiIsolate.pauseEvent.isPauseEvent);
futures.add(vmService.flutterExit(
isolateId: view.uiIsolate.id,
));
}
}
return vmService.onDone;
// The flutterExit message only returns if it fails, so just wait a few
// seconds then assume it worked.
// TODO(ianh): We should make this return once the VM service disconnects.
await Future.wait(futures).timeout(const Duration(seconds: 2), onTimeout: () => <void>[]);
}
Future<Uri> setupDevFS(
......
This diff is collapsed.
......@@ -53,9 +53,8 @@ class Tracing {
}
});
bool done = false;
final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
if (await vmService
for (final FlutterView view in vmService.vm.views) {
if (await view.uiIsolate.vmService
.flutterAlreadyPaintedFirstUsefulFrame(
isolateId: view.uiIsolate.id,
)) {
......
......@@ -7,7 +7,6 @@ import 'dart:async';
import 'package:file/memory.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
import 'package:quiver/testing/async.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
......@@ -35,22 +34,6 @@ import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/mocks.dart';
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
id: '1',
pauseEvent: vm_service.Event(
kind: vm_service.EventKind.kResume,
timestamp: 0
),
breakpoints: <vm_service.Breakpoint>[],
exceptionPauseMode: null,
libraries: <vm_service.LibraryRef>[],
livePorts: 0,
name: 'test',
number: '1',
pauseOnExit: false,
runnable: true,
startTime: 0,
);
void main() {
group('attach', () {
......@@ -508,7 +491,7 @@ void main() {
}, overrides: <Type, Generator>{
FileSystem: () => testFileSystem,
ProcessManager: () => FakeProcessManager.any(),
}, skip: const LocalPlatform().isWindows); // mDNS does not work on Windows.
});
group('forwarding to given port', () {
const int devicePort = 499;
......@@ -822,21 +805,11 @@ VMServiceConnector getFakeVmServiceFactory({
version: '',
);
});
when(vmService.getIsolate(any))
.thenAnswer((Invocation invocation) async {
return fakeUnpausedIsolate;
});
when(vmService.callMethod(kListViewsMethod))
.thenAnswer((_) async {
return vm_service.Response.parse(<String, Object>{
'views': <Object>[
<String, Object>{
'id': '1',
'isolate': fakeUnpausedIsolate.toJson()
}
]
});
});
when(vm.refreshViews(waitForViews: anyNamed('waitForViews')))
.thenAnswer((_) => Future<void>.value(null));
when(vm.views)
.thenReturn(<FlutterView>[FlutterViewMock()]);
when(vm.createDevFS(any))
.thenAnswer((_) => Future<Map<String, dynamic>>.value(<String, dynamic>{'uri': '/',}));
......@@ -886,6 +859,7 @@ class TestHotRunnerFactory extends HotRunnerFactory {
class VMMock extends Mock implements VM {}
class VMServiceMock extends Mock implements VMService {}
class FlutterViewMock extends Mock implements FlutterView {}
class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {}
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
......
......@@ -6,12 +6,6 @@ import 'dart:async';
import 'dart:convert';
import 'package:file/memory.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
......@@ -33,27 +27,14 @@ import 'package:flutter_tools/src/fuchsia/tiles_ctl.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
import '../../src/common.dart';
import '../../src/context.dart';
final vm_service.Isolate fakeIsolate = vm_service.Isolate(
id: '1',
pauseEvent: vm_service.Event(
kind: vm_service.EventKind.kResume,
timestamp: 0
),
breakpoints: <vm_service.Breakpoint>[],
exceptionPauseMode: null,
libraries: <vm_service.LibraryRef>[],
livePorts: 0,
name: 'wrong name',
number: '1',
pauseOnExit: false,
runnable: true,
startTime: 0,
);
void main() {
group('fuchsia device', () {
MemoryFileSystem memoryFileSystem;
......@@ -626,92 +607,71 @@ void main() {
});
group('FuchsiaIsolateDiscoveryProtocol', () {
group(FuchsiaIsolateDiscoveryProtocol, () {
MockPortForwarder portForwarder;
MockVMService vmService;
MockVM vm;
setUp(() {
portForwarder = MockPortForwarder();
vmService = MockVMService();
vm = MockVM();
when(vm.vmService).thenReturn(vmService);
when(vmService.vm).thenReturn(vm);
});
Future<Uri> findUri(List<FlutterView> views, String expectedIsolateName) async {
Future<Uri> findUri(List<MockFlutterView> views, String expectedIsolateName) async {
when(vm.views).thenReturn(views);
for (final MockFlutterView view in views) {
when(view.owner).thenReturn(vm);
}
final MockFuchsiaDevice fuchsiaDevice =
MockFuchsiaDevice('123', portForwarder, false);
MockFuchsiaDevice('123', portForwarder, false);
final FuchsiaIsolateDiscoveryProtocol discoveryProtocol =
FuchsiaIsolateDiscoveryProtocol(
FuchsiaIsolateDiscoveryProtocol(
fuchsiaDevice,
expectedIsolateName,
(Uri uri) async => vmService,
true, // only poll once.
);
when(fuchsiaDevice.servicePorts())
.thenAnswer((Invocation invocation) async => <int>[1]);
when(portForwarder.forward(1))
.thenAnswer((Invocation invocation) async => 2);
when(vmService.getVMOld())
.thenAnswer((Invocation invocation) => Future<void>.value(null));
when(vmService.refreshViews())
.thenAnswer((Invocation invocation) => Future<void>.value(null));
when(vmService.httpAddress).thenReturn(Uri.parse('example'));
when(vmService.callMethod(kListViewsMethod)).thenAnswer((Invocation invocation) async {
return vm_service.Response.parse(<String, Object>{
'views': <Object>[
for (FlutterView view in views)
view.toJson()
],
});
});
return await discoveryProtocol.uri;
}
testUsingContext('can find flutter view with matching isolate name', () async {
const String expectedIsolateName = 'foobar';
final Uri uri = await findUri(<FlutterView>[
// no ui isolate.
FlutterView(id: '1', uiIsolate: null),
// wrong name.
FlutterView(
id: '2',
uiIsolate: vm_service.Isolate.parse(<String, dynamic>{
...fakeIsolate.toJson(),
'name': 'Wrong name',
}),
),
// matching name.
FlutterView(
id: '3',
uiIsolate: vm_service.Isolate.parse(<String, dynamic>{
...fakeIsolate.toJson(),
'name': expectedIsolateName,
}),
),
final Uri uri = await findUri(<MockFlutterView>[
MockFlutterView(null), // no ui isolate.
MockFlutterView(MockIsolate('wrong name')), // wrong name.
MockFlutterView(MockIsolate(expectedIsolateName)), // matching name.
], expectedIsolateName);
expect(
uri.toString(), 'http://${InternetAddress.loopbackIPv4.address}:0/');
});
testUsingContext('can handle flutter view without matching isolate name', () async {
const String expectedIsolateName = 'foobar';
final Future<Uri> uri = findUri(<FlutterView>[
// no ui isolate.
FlutterView(id: '1', uiIsolate: null),
// wrong name.
FlutterView(id: '2', uiIsolate: vm_service.Isolate.parse(<String, Object>{
...fakeIsolate.toJson(),
'name': 'wrong name',
})),
final Future<Uri> uri = findUri(<MockFlutterView>[
MockFlutterView(null), // no ui isolate.
MockFlutterView(MockIsolate('wrong name')), // wrong name.
], expectedIsolateName);
expect(uri, throwsException);
});
testUsingContext('can handle non flutter view', () async {
const String expectedIsolateName = 'foobar';
final Future<Uri> uri = findUri(<FlutterView>[
FlutterView(id: '1', uiIsolate: null), // no ui isolate.
final Future<Uri> uri = findUri(<MockFlutterView>[
MockFlutterView(null), // no ui isolate.
], expectedIsolateName);
expect(uri, throwsException);
});
});
......@@ -1123,6 +1083,22 @@ class MockPortForwarder extends Mock implements DevicePortForwarder {}
class MockVMService extends Mock implements VMService {}
class MockVM extends Mock implements VM {}
class MockFlutterView extends Mock implements FlutterView {
MockFlutterView(this.uiIsolate);
@override
final Isolate uiIsolate;
}
class MockIsolate extends Mock implements Isolate {
MockIsolate(this.name);
@override
final String name;
}
class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice {
FuchsiaDeviceWithFakeDiscovery(String id, {String name}) : super(id, name: name);
......
......@@ -4,7 +4,6 @@
import 'dart:async';
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/build_info.dart';
......@@ -171,52 +170,6 @@ void main() {
});
testUsingContext('Does hot restarts when all devices support it', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
const FakeVmServiceRequest(
id: '2',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
FakeVmServiceRequest(
id: '3',
method: 'getVM',
args: null,
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
FakeVmServiceRequest(
id: '4',
method: 'getVM',
args: null,
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
const FakeVmServiceRequest(
id: '5',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
const FakeVmServiceRequest(
id: '6',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
]);
// Setup mocks
final MockDevice mockDevice = MockDevice();
final MockDevice mockHotDevice = MockDevice();
......@@ -226,12 +179,8 @@ void main() {
when(mockHotDevice.supportsHotRestart).thenReturn(true);
// Trigger a restart.
final List<FlutterDevice> devices = <FlutterDevice>[
FlutterDevice(mockDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)
..vmService = fakeVmServiceHost.vmService
..devFS = mockDevFs,
FlutterDevice(mockHotDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)
..vmService = fakeVmServiceHost.vmService
..devFS = mockDevFs,
FlutterDevice(mockDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)..devFS = mockDevFs,
FlutterDevice(mockHotDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)..devFS = mockDevFs,
];
final HotRunner hotRunner = HotRunner(devices);
final OperationResult result = await hotRunner.restart(fullRestart: true);
......@@ -262,39 +211,13 @@ void main() {
testUsingContext('hot restart supported', () async {
// Setup mocks
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
FakeVmServiceRequest(
id: '2',
method: 'getVM',
args: null,
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
const FakeVmServiceRequest(
id: '3',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
]);
final MockDevice mockDevice = MockDevice();
when(mockDevice.supportsHotReload).thenReturn(true);
when(mockDevice.supportsHotRestart).thenReturn(true);
when(mockDevice.targetPlatform).thenAnswer((Invocation _) async => TargetPlatform.tester);
// Trigger hot restart.
final List<FlutterDevice> devices = <FlutterDevice>[
FlutterDevice(mockDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)
..vmService = fakeVmServiceHost.vmService
..devFS = mockDevFs,
FlutterDevice(mockDevice, generator: residentCompiler, buildInfo: BuildInfo.debug)..devFS = mockDevFs,
];
final HotRunner hotRunner = HotRunner(devices);
final OperationResult result = await hotRunner.restart(fullRestart: true);
......
......@@ -91,6 +91,46 @@ final Map<String, Object> listViews = <String, dynamic>{
typedef ServiceCallback = Future<Map<String, dynamic>> Function(Map<String, Object>);
void main() {
testUsingContext('VMService can refreshViews', () async {
final MockVMService mockVmService = MockVMService();
final VMService vmService = VMService(
null,
null,
null,
null,
null,
null,
null,
mockVmService,
Completer<void>(),
const Stream<dynamic>.empty(),
);
verify(mockVmService.registerService('flutterVersion', 'Flutter Tools')).called(1);
when(mockVmService.callServiceExtension('getVM',
args: anyNamed('args'), // Empty
isolateId: null
)).thenAnswer((Invocation invocation) async {
return vm_service.Response.parse(vm);
});
await vmService.getVMOld();
when(mockVmService.callServiceExtension('_flutter.listViews',
args: anyNamed('args'),
isolateId: anyNamed('isolateId')
)).thenAnswer((Invocation invocation) async {
return vm_service.Response.parse(listViews);
});
await vmService.refreshViews(waitForViews: true);
expect(vmService.vm.name, 'vm');
expect(vmService.vm.views.single.id, '_flutterView/0x4a4c1f8');
}, overrides: <Type, Generator>{
Logger: () => BufferLogger.test()
});
testUsingContext('VmService registers reloadSources', () {
Future<void> reloadSources(String isolateId, { bool pause, bool force}) async {}
final MockVMService mockVMService = MockVMService();
......
......@@ -97,7 +97,6 @@ void main() {
_project.scheduledBreakpointUri,
_project.scheduledBreakpointLine,
);
await Future<void>.delayed(const Duration(seconds: 2));
await _flutter.hotReload(); // reload triggers code which eventually hits the breakpoint
isolate = await _flutter.waitForPause();
expect(isolate.pauseEvent.kind, equals(EventKind.kPauseBreakpoint));
......
......@@ -191,7 +191,7 @@ abstract class FlutterTestDriver {
// ceases to be the case, this code will need changing.
if (_flutterIsolateId == null) {
final VM vm = await _vmService.getVM();
_flutterIsolateId = vm.isolates.single.id;
_flutterIsolateId = vm.isolates.first.id;
}
return _flutterIsolateId;
}
......
......@@ -242,11 +242,6 @@ class FakeVmServiceHost {
.having((Map<String, Object> request) => request['id'], 'id', fakeRequest.id)
.having((Map<String, Object> request) => request['params'], 'args', fakeRequest.args)
);
if (fakeRequest.close) {
_vmService.dispose();
expect(_requests, isEmpty);
return;
}
if (fakeRequest.errorCode == null) {
_input.add(json.encode(<String, Object>{
'jsonrpc': '2.0',
......@@ -303,15 +298,11 @@ class FakeVmServiceRequest implements VmServiceExpectation {
@required this.args,
this.jsonResponse,
this.errorCode,
this.close = false,
});
final String method;
final String id;
/// When true, the vm service is automatically closed.
final bool close;
/// If non-null, the error code for a [vm_service.RPCError] in place of a
/// standard response.
final int errorCode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment