Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
b6262e7c
Unverified
Commit
b6262e7c
authored
Apr 15, 2020
by
Jonah Williams
Committed by
GitHub
Apr 15, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] remove runFromSource, move runInView to vm_service extension (#54700)
parent
846e8fe8
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
176 additions
and
52 deletions
+176
-52
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+10
-8
vmservice.dart
packages/flutter_tools/lib/src/vmservice.dart
+31
-43
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+16
-1
vmservice_test.dart
...ages/flutter_tools/test/general.shard/vmservice_test.dart
+119
-0
No files found.
packages/flutter_tools/lib/src/run_hot.dart
View file @
b6262e7c
...
...
@@ -457,14 +457,18 @@ class HotRunner extends ResidentRunner {
Future
<
void
>
_launchInView
(
FlutterDevice
device
,
Uri
entryUri
,
Uri
packagesUri
,
Uri
assetsDirectoryUri
,
)
{
return
Future
.
wait
(<
Future
<
void
>>[
Uri
main
,
Uri
assetsDirectory
,
)
async
{
await
Future
.
wait
(<
Future
<
void
>>[
for
(
final
FlutterView
view
in
device
.
views
)
view
.
runFromSource
(
entryUri
,
assetsDirectoryUri
),
device
.
vmService
.
runInView
(
viewId:
view
.
id
,
main:
main
,
assetsDirectory:
assetsDirectory
,
),
]);
await
device
.
refreshViews
();
}
Future
<
void
>
_launchFromDevFS
(
String
mainScript
)
async
{
...
...
@@ -473,12 +477,10 @@ class HotRunner extends ResidentRunner {
for
(
final
FlutterDevice
device
in
flutterDevices
)
{
final
Uri
deviceEntryUri
=
device
.
devFS
.
baseUri
.
resolveUri
(
globals
.
fs
.
path
.
toUri
(
entryUri
));
final
Uri
devicePackagesUri
=
device
.
devFS
.
baseUri
.
resolve
(
'.packages'
);
final
Uri
deviceAssetsDirectoryUri
=
device
.
devFS
.
baseUri
.
resolveUri
(
globals
.
fs
.
path
.
toUri
(
getAssetBuildDirectory
()));
futures
.
add
(
_launchInView
(
device
,
deviceEntryUri
,
devicePackagesUri
,
deviceAssetsDirectoryUri
));
}
await
Future
.
wait
(
futures
);
...
...
packages/flutter_tools/lib/src/vmservice.dart
View file @
b6262e7c
...
...
@@ -20,6 +20,7 @@ import 'version.dart';
const
String
kGetSkSLsMethod
=
'_flutter.getSkSLs'
;
const
String
kSetAssetBundlePathMethod
=
'_flutter.setAssetBundlePath'
;
const
String
kFlushUIThreadTasksMethod
=
'_flutter.flushUIThreadTasks'
;
const
String
kRunInViewMethod
=
'_flutter.runInView'
;
/// Override `WebSocketConnector` in [context] to use a different constructor
/// for [WebSocket]s (used by tests).
...
...
@@ -1091,19 +1092,6 @@ class VM extends ServiceObjectOwner {
return
invokeRpcRaw
(
'_deleteDevFS'
,
params:
<
String
,
dynamic
>{
'fsName'
:
fsName
});
}
Future
<
ServiceMap
>
runInView
(
String
viewId
,
Uri
main
,
Uri
assetsDirectory
,
)
{
return
invokeRpc
<
ServiceMap
>(
'_flutter.runInView'
,
params:
<
String
,
dynamic
>{
'viewId'
:
viewId
,
'mainScript'
:
main
.
toString
(),
'assetDirectory'
:
assetsDirectory
.
toString
(),
});
}
Future
<
Map
<
String
,
dynamic
>>
clearVMTimeline
()
{
return
invokeRpcRaw
(
'clearVMTimeline'
);
}
...
...
@@ -1541,36 +1529,6 @@ class FlutterView extends ServiceObject {
_uiIsolate
=
map
[
'isolate'
]
as
Isolate
;
}
// TODO(johnmccutchan): Report errors when running failed.
Future
<
void
>
runFromSource
(
Uri
entryUri
,
Uri
assetsDirectoryUri
,
)
async
{
final
String
viewId
=
id
;
// When this completer completes the isolate is running.
final
Completer
<
void
>
completer
=
Completer
<
void
>();
try
{
await
owner
.
vm
.
vmService
.
streamListen
(
'Isolate'
);
}
on
vm_service
.
RPCError
{
// Do nothing, since the tool is already subscribed.
}
final
StreamSubscription
<
vm_service
.
Event
>
subscription
=
owner
.
vm
.
vmService
.
onIsolateEvent
.
listen
((
vm_service
.
Event
event
)
{
if
(
event
.
kind
==
ServiceEvent
.
kIsolateRunnable
)
{
globals
.
printTrace
(
'Isolate is runnable.'
);
if
(!
completer
.
isCompleted
)
{
completer
.
complete
();
}
}
});
await
owner
.
vm
.
runInView
(
viewId
,
entryUri
,
assetsDirectoryUri
);
await
completer
.
future
;
await
owner
.
vm
.
refreshViews
(
waitForViews:
true
);
await
subscription
.
cancel
();
}
bool
get
hasIsolate
=>
_uiIsolate
!=
null
;
@override
...
...
@@ -1579,6 +1537,7 @@ class FlutterView extends ServiceObject {
/// Flutter specific VM Service functionality.
extension
FlutterVmService
on
vm_service
.
VmService
{
/// Set the asset directory for the an attached Flutter view.
Future
<
void
>
setAssetDirectory
({
@required
Uri
assetsDirectory
,
...
...
@@ -1623,4 +1582,33 @@ extension FlutterVmService on vm_service.VmService {
},
);
}
/// Launch the Dart isolate with entrypoint [main] in the Flutter engine [viewId]
/// with [assetsDirectory] as the devFS.
///
/// This method is used by the tool to hot restart an already running Flutter
/// engine.
Future
<
void
>
runInView
({
@required
String
viewId
,
@required
Uri
main
,
@required
Uri
assetsDirectory
,
})
async
{
try
{
await
streamListen
(
'Isolate'
);
}
on
vm_service
.
RPCError
{
// Do nothing, since the tool is already subscribed.
}
final
Future
<
void
>
onRunnable
=
onIsolateEvent
.
firstWhere
((
vm_service
.
Event
event
)
{
return
event
.
kind
==
vm_service
.
EventKind
.
kIsolateRunnable
;
});
await
callMethod
(
kRunInViewMethod
,
args:
<
String
,
Object
>{
'viewId'
:
viewId
,
'mainScript'
:
main
.
toString
(),
'assetDirectory'
:
assetsDirectory
.
toString
(),
},
);
await
onRunnable
;
}
}
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
b6262e7c
...
...
@@ -88,6 +88,8 @@ void main() {
invalidatedSourcesCount:
0
,
);
});
// TODO(jonahwilliams): replace mock with FakeVmServiceHost once all methods
// are moved to real vm service.
when
(
mockFlutterDevice
.
devFS
).
thenReturn
(
mockDevFS
);
when
(
mockFlutterDevice
.
views
).
thenReturn
(<
FlutterView
>[
mockFlutterView
,
...
...
@@ -97,7 +99,20 @@ void main() {
final
MockVM
mockVM
=
MockVM
();
when
(
mockVMService
.
vm
).
thenReturn
(
mockVM
);
when
(
mockVM
.
isolates
).
thenReturn
(<
Isolate
>[
mockIsolate
]);
when
(
mockFlutterView
.
runFromSource
(
any
,
any
)).
thenAnswer
((
Invocation
invocation
)
async
{});
when
(
mockVMService
.
streamListen
(
'Isolate'
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
vm_service
.
Success
();
});
when
(
mockVMService
.
onIsolateEvent
).
thenAnswer
((
Invocation
invocation
)
{
return
Stream
<
vm_service
.
Event
>.
fromIterable
(<
vm_service
.
Event
>[
vm_service
.
Event
(
kind:
vm_service
.
EventKind
.
kIsolateRunnable
,
timestamp:
0
),
]);
});
when
(
mockVMService
.
callMethod
(
kRunInViewMethod
,
args:
anyNamed
(
'args'
),
)).
thenAnswer
((
Invocation
invocation
)
async
{
return
vm_service
.
Success
();
});
when
(
mockFlutterDevice
.
stopEchoingDeviceLog
()).
thenAnswer
((
Invocation
invocation
)
async
{
});
when
(
mockFlutterDevice
.
observatoryUris
).
thenAnswer
((
_
)
=>
Stream
<
Uri
>.
value
(
testUri
));
when
(
mockFlutterDevice
.
connect
(
...
...
packages/flutter_tools/test/general.shard/vmservice_test.dart
View file @
b6262e7c
...
...
@@ -6,6 +6,7 @@ import 'dart:async';
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:meta/meta.dart'
;
import
'package:vm_service/vm_service.dart'
as
vm_service
;
import
'package:mockito/mockito.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
...
...
@@ -280,6 +281,124 @@ void main() {
]))
]));
});
testWithoutContext
(
'runInView forwards arguments correctly'
,
()
async
{
final
FakeVmServiceHost
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
const
FakeVmServiceRequest
(
method:
'streamListen'
,
id:
'1'
,
params:
<
String
,
Object
>{
'streamId'
:
'Isolate'
}),
const
FakeVmServiceRequest
(
method:
kRunInViewMethod
,
id:
'2'
,
params:
<
String
,
Object
>{
'viewId'
:
'1234'
,
'mainScript'
:
'main.dart'
,
'assetDirectory'
:
'flutter_assets/'
,
}),
FakeVmServiceStreamResponse
(
streamId:
'Isolate'
,
event:
vm_service
.
Event
(
kind:
vm_service
.
EventKind
.
kIsolateRunnable
,
timestamp:
1
,
)
),
]
);
await
fakeVmServiceHost
.
vmService
.
runInView
(
viewId:
'1234'
,
main:
Uri
.
file
(
'main.dart'
),
assetsDirectory:
Uri
.
file
(
'flutter_assets/'
),
);
expect
(
fakeVmServiceHost
.
hasRemainingExpectations
,
false
);
});
}
class
FakeVmServiceHost
{
FakeVmServiceHost
({
@required
List
<
VmServiceExpectation
>
requests
,
})
:
_requests
=
requests
{
_vmService
=
vm_service
.
VmService
(
_input
.
stream
,
_output
.
add
,
);
_applyStreamListen
();
_output
.
stream
.
listen
((
String
data
)
{
final
Map
<
String
,
Object
>
request
=
json
.
decode
(
data
)
as
Map
<
String
,
Object
>;
if
(
_requests
.
isEmpty
)
{
throw
Exception
(
'Unexpected request:
$request
'
);
}
final
FakeVmServiceRequest
fakeRequest
=
_requests
.
removeAt
(
0
)
as
FakeVmServiceRequest
;
expect
(
fakeRequest
,
isA
<
FakeVmServiceRequest
>()
.
having
((
FakeVmServiceRequest
request
)
=>
request
.
method
,
'method'
,
request
[
'method'
])
.
having
((
FakeVmServiceRequest
request
)
=>
request
.
id
,
'id'
,
request
[
'id'
])
.
having
((
FakeVmServiceRequest
request
)
=>
request
.
params
,
'params'
,
request
[
'params'
])
);
_input
.
add
(
json
.
encode
(<
String
,
Object
>{
'jsonrpc'
:
'2.0'
,
'id'
:
fakeRequest
.
id
,
'result'
:
fakeRequest
.
jsonResponse
??
<
String
,
Object
>{
'type'
:
'Success'
},
}));
_applyStreamListen
();
});
}
final
List
<
VmServiceExpectation
>
_requests
;
final
StreamController
<
String
>
_input
=
StreamController
<
String
>();
final
StreamController
<
String
>
_output
=
StreamController
<
String
>();
vm_service
.
VmService
get
vmService
=>
_vmService
;
vm_service
.
VmService
_vmService
;
bool
get
hasRemainingExpectations
=>
_requests
.
isNotEmpty
;
// remove FakeStreamResponse objects from _requests until it is empty
// or until we hit a FakeRequest
void
_applyStreamListen
()
{
while
(
_requests
.
isNotEmpty
&&
!
_requests
.
first
.
isRequest
)
{
final
FakeVmServiceStreamResponse
response
=
_requests
.
removeAt
(
0
)
as
FakeVmServiceStreamResponse
;
_input
.
add
(
json
.
encode
(<
String
,
Object
>{
'jsonrpc'
:
'2.0'
,
'method'
:
'streamNotify'
,
'params'
:
<
String
,
Object
>{
'streamId'
:
response
.
streamId
,
'event'
:
response
.
event
.
toJson
(),
},
}));
}
}
}
abstract
class
VmServiceExpectation
{
bool
get
isRequest
;
}
class
FakeVmServiceRequest
implements
VmServiceExpectation
{
const
FakeVmServiceRequest
({
@required
this
.
method
,
@required
this
.
id
,
@required
this
.
params
,
this
.
jsonResponse
,
});
final
String
method
;
final
String
id
;
final
Map
<
String
,
Object
>
params
;
final
Map
<
String
,
Object
>
jsonResponse
;
@override
bool
get
isRequest
=>
true
;
}
class
FakeVmServiceStreamResponse
implements
VmServiceExpectation
{
const
FakeVmServiceStreamResponse
({
@required
this
.
event
,
@required
this
.
streamId
,
});
final
vm_service
.
Event
event
;
final
String
streamId
;
@override
bool
get
isRequest
=>
false
;
}
class
MockDevice
extends
Mock
implements
Device
{}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment