Adds vmservices for getting iOS build options (#121736)

Adds vmservices for getting iOS build options
This commit is contained in:
chunhtai 2023-03-06 14:37:55 -08:00 committed by GitHub
parent 33ffdd704f
commit 026adb8cc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 198 additions and 87 deletions

View file

@ -560,18 +560,13 @@ class ResidentWebRunner extends ResidentRunner {
// thrown if we're not already subscribed.
}
await setUpVmService(
(String isolateId, {
bool? force,
bool? pause,
}) async {
reloadSources: (String isolateId, {bool? force, bool? pause}) async {
await restart(pause: pause);
},
null,
null,
device!.device,
null,
printStructuredErrorLog,
_vmService.service,
device: device!.device,
flutterProject: flutterProject,
printStructuredErrorLogMethod: printStructuredErrorLog,
vmService: _vmService.service,
);

View file

@ -329,6 +329,7 @@ class FlutterDevice {
restart: restart,
compileExpression: compileExpression,
getSkSLMethod: getSkSLMethod,
flutterProject: FlutterProject.current(),
printStructuredErrorLogMethod: printStructuredErrorLogMethod,
device: device,
logger: globals.logger,

View file

@ -14,8 +14,13 @@ import 'base/logger.dart';
import 'base/utils.dart';
import 'convert.dart';
import 'device.dart';
import 'ios/xcodeproj.dart';
import 'project.dart';
import 'version.dart';
const String kResultType = 'type';
const String kResultTypeSuccess = 'Success';
const String kGetSkSLsMethod = '_flutter.getSkSLs';
const String kSetAssetBundlePathMethod = '_flutter.setAssetBundlePath';
const String kFlushUIThreadTasksMethod = '_flutter.flushUIThreadTasks';
@ -165,6 +170,7 @@ typedef VMServiceConnector = Future<FlutterVmService> Function(Uri httpUri, {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device? device,
@ -175,15 +181,16 @@ typedef VMServiceConnector = Future<FlutterVmService> Function(Uri httpUri, {
/// callbacks.
///
/// All parameters besides [vmService] may be null.
Future<vm_service.VmService> setUpVmService(
Future<vm_service.VmService> setUpVmService({
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
Device? device,
GetSkSLMethod? skSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
vm_service.VmService vmService
) async {
required vm_service.VmService vmService,
}) async {
// Each service registration requires a request to the attached VM service. Since the
// order of these requests does not matter, store each future in a list and await
// all at the end of this method.
@ -198,7 +205,7 @@ Future<vm_service.VmService> setUpVmService(
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
},
};
});
@ -211,7 +218,7 @@ Future<vm_service.VmService> setUpVmService(
await restart(pause: pause);
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
},
};
});
@ -225,7 +232,7 @@ Future<vm_service.VmService> setUpVmService(
versionJson['engineRevisionShort'] = version.engineRevisionShort;
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
...versionJson,
},
};
@ -246,7 +253,7 @@ Future<vm_service.VmService> setUpVmService(
expression, definitions, typeDefinitions, libraryUri, klass,
isStatic);
return <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
'result': <String, String>{'kernelBytes': kernelBytesBase64},
};
});
@ -257,7 +264,7 @@ Future<vm_service.VmService> setUpVmService(
final MemoryInfo result = await device.queryMemoryInfo();
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
...result.toJson(),
},
};
@ -270,19 +277,44 @@ Future<vm_service.VmService> setUpVmService(
if (filename == null) {
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
},
};
}
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
kResultType: kResultTypeSuccess,
'filename': filename,
},
};
});
registrationRequests.add(vmService.registerService('flutterGetSkSL', 'Flutter Tools'));
}
if (flutterProject != null) {
vmService.registerServiceCallback('flutterGetIOSBuildOptions', (Map<String, Object?> params) async {
final XcodeProjectInfo? info = await flutterProject.ios.projectInfo();
if (info == null) {
return <String, Object>{
'result': <String, Object>{
kResultType: kResultTypeSuccess,
},
};
}
return <String, Object>{
'result': <String, Object>{
kResultType: kResultTypeSuccess,
'targets': info.targets,
'schemes': info.schemes,
'buildConfigurations': info.buildConfigurations,
},
};
});
registrationRequests.add(
vmService.registerService('flutterGetIOSBuildOptions', 'Flutter Tools'),
);
}
if (printStructuredErrorLogMethod != null) {
vmService.onExtensionEvent.listen(printStructuredErrorLogMethod);
registrationRequests.add(vmService
@ -319,15 +351,16 @@ Future<vm_service.VmService> setUpVmService(
/// See: https://github.com/dart-lang/sdk/commit/df8bf384eb815cf38450cb50a0f4b62230fba217
Future<FlutterVmService> connectToVmService(
Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,
required Logger logger,
}) async {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,
required Logger logger,
}) async {
final VMServiceConnector connector = context.get<VMServiceConnector>() ?? _connect;
return connector(httpUri,
reloadSources: reloadSources,
@ -336,6 +369,7 @@ Future<FlutterVmService> connectToVmService(
compression: compression,
device: device,
getSkSLMethod: getSkSLMethod,
flutterProject: flutterProject,
printStructuredErrorLogMethod: printStructuredErrorLogMethod,
logger: logger,
);
@ -362,6 +396,7 @@ Future<FlutterVmService> _connect(
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,
@ -373,13 +408,14 @@ Future<FlutterVmService> _connect(
);
final vm_service.VmService service = await setUpVmService(
reloadSources,
restart,
compileExpression,
device,
getSkSLMethod,
printStructuredErrorLogMethod,
delegateService,
reloadSources: reloadSources,
restart: restart,
compileExpression: compileExpression,
device: device,
skSLMethod: getSkSLMethod,
flutterProject: flutterProject,
printStructuredErrorLogMethod: printStructuredErrorLogMethod,
vmService: delegateService,
);
// This call is to ensure we are able to establish a connection instead of

View file

@ -11,6 +11,7 @@ import 'package:flutter_tools/src/build_system/targets/shader_compiler.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/run_cold.dart';
import 'package:flutter_tools/src/tracing.dart';
@ -213,6 +214,7 @@ class TestFlutterDevice extends FlutterDevice {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
bool enableDds = true,
bool cacheStartupProfile = false,

View file

@ -15,6 +15,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/drive/drive_service.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:flutter_tools/src/vmservice.dart';
@ -443,6 +444,7 @@ FlutterDriverService setUpDriverService({
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,

View file

@ -16,6 +16,7 @@ import 'package:flutter_tools/src/build_system/targets/shader_compiler.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_devtools_handler.dart';
import 'package:flutter_tools/src/resident_runner.dart';
@ -678,6 +679,7 @@ class TestFlutterDevice extends FlutterDevice {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
bool disableServiceAuthCodes = false,
bool enableDds = true,

View file

@ -8,6 +8,7 @@ import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/test/integration_test_device.dart';
import 'package:flutter_tools/src/test/test_device.dart';
import 'package:flutter_tools/src/vmservice.dart';
@ -135,6 +136,7 @@ void main() {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -154,6 +156,7 @@ void main() {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -184,6 +187,7 @@ void main() {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -213,6 +217,7 @@ void main() {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -230,6 +235,7 @@ void main() {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,

View file

@ -27,6 +27,7 @@ import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_devtools_handler.dart';
import 'package:flutter_tools/src/resident_runner.dart';
@ -2147,6 +2148,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -2181,6 +2183,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -2214,6 +2217,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -2248,6 +2252,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
@ -2289,6 +2294,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,
@ -2344,6 +2350,7 @@ flutter:
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device? device,
@ -2576,6 +2583,7 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
int? hostVmServicePort,
int? ddsPort,
@ -2629,6 +2637,7 @@ class FakeDelegateFlutterDevice extends FlutterDevice {
bool ipv6 = false,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
int? hostVmServicePort,
int? ddsPort,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,

View file

@ -74,6 +74,10 @@ const List<VmServiceExpectation> kAttachIsolateExpectations =
'service': 'flutterMemoryInfo',
'alias': 'Flutter Tools',
}),
FakeVmServiceRequest(method: 'registerService', args: <String, Object>{
'service': 'flutterGetIOSBuildOptions',
'alias': 'Flutter Tools',
}),
FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{
@ -1637,6 +1641,7 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
int? hostVmServicePort,
int? ddsPort,

View file

@ -9,6 +9,8 @@ import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
@ -64,13 +66,8 @@ void main() {
final MockVMService mockVMService = MockVMService();
await setUpVmService(
reloadSources,
null,
null,
null,
null,
null,
mockVMService,
reloadSources: reloadSources,
vmService: mockVMService,
);
expect(mockVMService.services, containsPair('reloadSources', 'Flutter Tools'));
@ -81,28 +78,31 @@ void main() {
final MockVMService mockVMService = MockVMService();
await setUpVmService(
null,
null,
null,
mockDevice,
null,
null,
mockVMService,
device: mockDevice,
vmService: mockVMService,
);
expect(mockVMService.services, containsPair('flutterMemoryInfo', 'Flutter Tools'));
});
testWithoutContext('VmService registers flutterGetIOSBuildOptions service', () async {
final MockVMService mockVMService = MockVMService();
final FlutterProject mockedVMService = MockFlutterProject(
mockedIos: MockIosProject(),
);
await setUpVmService(
flutterProject: mockedVMService,
vmService: mockVMService,
);
expect(mockVMService.services, containsPair('flutterGetIOSBuildOptions', 'Flutter Tools'));
});
testWithoutContext('VM Service registers flutterGetSkSL service', () async {
final MockVMService mockVMService = MockVMService();
await setUpVmService(
null,
null,
null,
null,
() async => 'hello',
null,
mockVMService,
skSLMethod: () async => 'hello',
vmService: mockVMService,
);
expect(mockVMService.services, containsPair('flutterGetSkSL', 'Flutter Tools'));
@ -113,13 +113,8 @@ void main() {
..errorOnRegisterService = true;
await expectLater(() async => setUpVmService(
null,
null,
null,
null,
() async => 'hello',
null,
mockVMService,
skSLMethod: () async => 'hello',
vmService: mockVMService,
), throwsToolExit());
});
@ -128,26 +123,17 @@ void main() {
..errorOnRegisterService = true;
await expectLater(() async => setUpVmService(
null,
null,
null,
null,
() async => 'hello',
(vm_service.Event event) { },
mockVMService,
skSLMethod: () async => 'hello',
printStructuredErrorLogMethod: (vm_service.Event event) { },
vmService: mockVMService,
), throwsToolExit());
});
testWithoutContext('VM Service registers flutterPrintStructuredErrorLogMethod', () async {
final MockVMService mockVMService = MockVMService();
await setUpVmService(
null,
null,
null,
null,
null,
(vm_service.Event event) async => 'hello',
mockVMService,
printStructuredErrorLogMethod: (vm_service.Event event) async => 'hello',
vmService: mockVMService,
);
expect(mockVMService.listenedStreams, contains(vm_service.EventStreams.kExtension));
});
@ -155,13 +141,7 @@ void main() {
testWithoutContext('VM Service returns correct FlutterVersion', () async {
final MockVMService mockVMService = MockVMService();
await setUpVmService(
null,
null,
null,
null,
null,
null,
mockVMService,
vmService: mockVMService,
);
expect(mockVMService.services, containsPair('flutterVersion', 'Flutter Tools'));
@ -299,6 +279,50 @@ void main() {
]));
});
testWithoutContext('VmService forward flutterGetIOSBuildOptions request and response correctly', () async {
final MockVMService vmService = MockVMService();
final XcodeProjectInfo expectedProjectInfo = XcodeProjectInfo(
<String>['target1', 'target2'],
<String>['config1', 'config2'],
<String>['scheme1', 'scheme2'],
MockLogger(),
);
final FlutterProject mockedVMService = MockFlutterProject(
mockedIos: MockIosProject(mockedInfo: expectedProjectInfo),
);
await setUpVmService(
flutterProject: mockedVMService,
vmService: vmService
);
final vm_service.ServiceCallback cb = vmService.serviceCallBacks['flutterGetIOSBuildOptions']!;
final Map<String, dynamic> response = await cb(<String, dynamic>{});
final Map<String, dynamic> result = response['result']! as Map<String, dynamic>;
expect(result[kResultType], kResultTypeSuccess);
expect(result['targets'], expectedProjectInfo.targets);
expect(result['buildConfigurations'], expectedProjectInfo.buildConfigurations);
expect(result['schemes'], expectedProjectInfo.schemes);
});
testWithoutContext('VmService forward flutterGetIOSBuildOptions request and response correctly when no iOS project', () async {
final MockVMService vmService = MockVMService();
final FlutterProject mockedVMService = MockFlutterProject(
mockedIos: MockIosProject(),
);
await setUpVmService(
flutterProject: mockedVMService,
vmService: vmService
);
final vm_service.ServiceCallback cb = vmService.serviceCallBacks['flutterGetIOSBuildOptions']!;
final Map<String, dynamic> response = await cb(<String, dynamic>{});
final Map<String, dynamic> result = response['result']! as Map<String, dynamic>;
expect(result[kResultType], kResultTypeSuccess);
expect(result['targets'], isNull);
expect(result['buildConfigurations'], isNull);
expect(result['schemes'], isNull);
});
testWithoutContext('runInView forwards arguments correctly', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
@ -846,13 +870,36 @@ void main() {
});
}
class MockFlutterProject extends Fake implements FlutterProject {
MockFlutterProject({
required IosProject mockedIos
}) : ios = mockedIos;
@override
final IosProject ios;
}
class MockIosProject extends Fake implements IosProject {
MockIosProject({this.mockedInfo});
final XcodeProjectInfo? mockedInfo;
@override
Future<XcodeProjectInfo?> projectInfo() async => mockedInfo;
}
class MockLogger extends Fake implements Logger { }
class MockVMService extends Fake implements vm_service.VmService {
final Map<String, String> services = <String, String>{};
final Map<String, vm_service.ServiceCallback> serviceCallBacks = <String, vm_service.ServiceCallback>{};
final Set<String> listenedStreams = <String>{};
bool errorOnRegisterService = false;
@override
void registerServiceCallback(String service, vm_service.ServiceCallback cb) {}
void registerServiceCallback(String service, vm_service.ServiceCallback cb) {
serviceCallBacks[service] = cb;
}
@override
Future<vm_service.Success> registerService(String service, String alias) async {

View file

@ -55,7 +55,13 @@ void main() {
testWithoutContext('flutterMemoryInfo can be called', () async {
final Response response =
await vmService.callServiceExtension('s0.flutterMemoryInfo');
await vmService.callServiceExtension('s0.flutterMemoryInfo');
expect(response.type, 'Success');
});
testWithoutContext('flutterGetIOSBuildOptions can be called', () async {
final Response response =
await vmService.callServiceExtension('s0.flutterGetIOSBuildOptions');
expect(response.type, 'Success');
});