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
5a5eb2d9
Unverified
Commit
5a5eb2d9
authored
Apr 15, 2021
by
Jonah Williams
Committed by
GitHub
Apr 15, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] connect devtools deeplink URLs for web target platform / debug mode (#80389)
parent
2a8dba4a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
152 additions
and
40 deletions
+152
-40
resident_web_runner.dart
...s/flutter_tools/lib/src/isolated/resident_web_runner.dart
+14
-0
resident_devtools_handler.dart
...ages/flutter_tools/lib/src/resident_devtools_handler.dart
+28
-23
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+2
-1
integration_test_device.dart
...s/flutter_tools/lib/src/test/integration_test_device.dart
+5
-2
vmservice.dart
packages/flutter_tools/lib/src/vmservice.dart
+30
-14
resident_devtools_handler_test.dart
...ls/test/general.shard/resident_devtools_handler_test.dart
+73
-0
No files found.
packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
View file @
5a5eb2d9
...
...
@@ -35,6 +35,7 @@ import '../platform_plugins.dart';
import
'../plugins.dart'
;
import
'../project.dart'
;
import
'../reporting/reporting.dart'
;
import
'../resident_devtools_handler.dart'
;
import
'../resident_runner.dart'
;
import
'../run_hot.dart'
;
import
'../vmservice.dart'
;
...
...
@@ -99,6 +100,7 @@ class ResidentWebRunner extends ResidentRunner {
@required
Usage
usage
,
@required
UrlTunneller
urlTunneller
,
@required
FeatureFlags
featureFlags
,
ResidentDevtoolsHandlerFactory
devtoolsHandler
=
createDefaultHandler
,
})
:
_fileSystem
=
fileSystem
,
_logger
=
logger
,
_systemClock
=
systemClock
,
...
...
@@ -112,6 +114,7 @@ class ResidentWebRunner extends ResidentRunner {
ipv6:
ipv6
,
stayResident:
stayResident
,
machine:
machine
,
devtoolsHandler:
devtoolsHandler
,
);
final
FileSystem
_fileSystem
;
...
...
@@ -193,6 +196,7 @@ class ResidentWebRunner extends ResidentRunner {
if
(
_exited
)
{
return
;
}
await
residentDevtoolsHandler
.
shutdown
();
await
_stdOutSub
?.
cancel
();
await
_stdErrSub
?.
cancel
();
await
_extensionEventSub
?.
cancel
();
...
...
@@ -228,6 +232,8 @@ class ResidentWebRunner extends ResidentRunner {
_logger
.
printStatus
(
message
);
const
String
quitMessage
=
'To quit, press "q".'
;
_logger
.
printStatus
(
'For a more detailed help message, press "h".
$quitMessage
'
);
_logger
.
printStatus
(
''
);
printDebuggerList
();
}
@override
...
...
@@ -632,6 +638,7 @@ class ResidentWebRunner extends ResidentRunner {
final
Duration
elapsed
=
_systemClock
.
now
().
difference
(
start
);
final
String
elapsedMS
=
getElapsedAsMilliseconds
(
elapsed
);
_logger
.
printStatus
(
'Restarted application in
$elapsedMS
.'
);
unawaited
(
residentDevtoolsHandler
.
hotRestart
(
flutterDevices
));
// Don't track restart times for dart2js builds or web-server devices.
if
(
debuggingOptions
.
buildInfo
.
isDebug
&&
deviceIsDebuggable
)
{
...
...
@@ -844,6 +851,13 @@ class ResidentWebRunner extends ResidentRunner {
}
});
}
if
(
enableDevTools
)
{
// The method below is guaranteed never to return a failing future.
unawaited
(
residentDevtoolsHandler
.
serveAndAnnounceDevTools
(
devToolsServerAddress:
debuggingOptions
.
devToolsServerAddress
,
flutterDevices:
flutterDevices
,
));
}
}
if
(
websocketUri
!=
null
)
{
if
(
debuggingOptions
.
vmserviceOutFile
!=
null
)
{
...
...
packages/flutter_tools/lib/src/resident_devtools_handler.dart
View file @
5a5eb2d9
...
...
@@ -9,6 +9,7 @@ import 'dart:async';
import
'package:meta/meta.dart'
;
import
'base/logger.dart'
;
import
'build_info.dart'
;
import
'resident_runner.dart'
;
import
'vmservice.dart'
;
...
...
@@ -41,7 +42,7 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
bool
_served
=
false
;
@override
DevToolsServerAddress
get
activeDevToolsServer
=>
_devToolsLauncher
?.
activeDevToolsServer
;
DevToolsServerAddress
get
activeDevToolsServer
=>
_devToolsLauncher
?.
activeDevToolsServer
;
// This must be guaranteed not to return a Future that fails.
@override
...
...
@@ -59,7 +60,6 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
await
_devToolsLauncher
.
serve
();
}
await
_devToolsLauncher
.
ready
;
if
(
_residentRunner
.
reportedDebuggers
)
{
// Since the DevTools only just became available, we haven't had a chance to
// report their URLs yet. Do so now.
...
...
@@ -74,16 +74,15 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
);
}
Future
<
void
>
_maybeCallDevToolsUriServiceExtension
(
List
<
FlutterDevice
>
flutterDevices
,
)
async
{
if
(
_devToolsLauncher
?.
activeDevToolsServer
==
null
)
{
return
;
}
Future
<
void
>
_maybeCallDevToolsUriServiceExtension
(
List
<
FlutterDevice
>
flutterDevices
,
)
async
{
if
(
_devToolsLauncher
?.
activeDevToolsServer
==
null
)
{
return
;
}
await
Future
.
wait
(<
Future
<
void
>>[
for
(
final
FlutterDevice
device
in
flutterDevices
)
if
(
device
.
vmService
!=
null
)
_callDevToolsUriExtension
(
device
),
if
(
device
.
vmService
!=
null
)
_callDevToolsUriExtension
(
device
),
]);
}
...
...
@@ -108,8 +107,7 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
Future
<
List
<
FlutterDevice
>>
_devicesWithExtensions
(
List
<
FlutterDevice
>
flutterDevices
)
async
{
final
List
<
FlutterDevice
>
devices
=
await
Future
.
wait
(<
Future
<
FlutterDevice
>>[
for
(
final
FlutterDevice
device
in
flutterDevices
)
_waitForExtensionsForDevice
(
device
)
for
(
final
FlutterDevice
device
in
flutterDevices
)
_waitForExtensionsForDevice
(
device
)
]);
return
devices
.
where
((
FlutterDevice
device
)
=>
device
!=
null
).
toList
();
}
...
...
@@ -118,7 +116,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
Future
<
FlutterDevice
>
_waitForExtensionsForDevice
(
FlutterDevice
flutterDevice
)
async
{
const
String
extension
=
'ext.flutter.connectedVmServiceUri'
;
try
{
await
flutterDevice
.
vmService
?.
findExtensionIsolate
(
extension
);
await
flutterDevice
.
vmService
?.
findExtensionIsolate
(
extension
,
webIsolate:
flutterDevice
.
targetPlatform
==
TargetPlatform
.
web_javascript
,
);
return
flutterDevice
;
}
on
VmServiceDisappearedException
{
_logger
.
printTrace
(
...
...
@@ -133,8 +134,7 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
Future
<
void
>
_callConnectedVmServiceUriExtension
(
List
<
FlutterDevice
>
flutterDevices
)
async
{
await
Future
.
wait
(<
Future
<
void
>>[
for
(
final
FlutterDevice
device
in
flutterDevices
)
if
(
device
.
vmService
!=
null
)
_callConnectedVmServiceExtension
(
device
),
if
(
device
.
vmService
!=
null
)
_callConnectedVmServiceExtension
(
device
),
]);
}
...
...
@@ -160,21 +160,26 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
}
}
Future
<
void
>
_invokeRpcOnFirstView
(
String
method
,
{
Future
<
void
>
_invokeRpcOnFirstView
(
String
method
,
{
@required
FlutterDevice
device
,
@required
Map
<
String
,
dynamic
>
params
,
})
async
{
if
(
device
.
targetPlatform
==
TargetPlatform
.
web_javascript
)
{
return
device
.
vmService
.
callMethodWrapper
(
method
,
args:
params
,
);
}
final
List
<
FlutterView
>
views
=
await
device
.
vmService
.
getFlutterViews
();
if
(
views
.
isEmpty
)
{
return
;
}
await
device
.
vmService
.
invokeFlutterExtensionRpcRaw
(
method
,
args:
params
,
isolateId:
views
.
first
.
uiIsolate
.
id
);
await
device
.
vmService
.
invokeFlutterExtensionRpcRaw
(
method
,
args:
params
,
isolateId:
views
.
first
.
uiIsolate
.
id
,
);
}
@override
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
5a5eb2d9
...
...
@@ -48,7 +48,7 @@ class FlutterDevice {
this
.
fileSystemRoots
,
this
.
fileSystemScheme
,
TargetModel
targetModel
=
TargetModel
.
flutter
,
TargetPlatform
targetPlatform
,
this
.
targetPlatform
,
ResidentCompiler
generator
,
this
.
userIdentifier
,
})
:
assert
(
buildInfo
.
trackWidgetCreation
!=
null
),
...
...
@@ -196,6 +196,7 @@ class FlutterDevice {
final
ResidentCompiler
generator
;
final
BuildInfo
buildInfo
;
final
String
userIdentifier
;
final
TargetPlatform
targetPlatform
;
DevFSWriter
devFSWriter
;
Stream
<
Uri
>
observatoryUris
;
...
...
packages/flutter_tools/lib/src/test/integration_test_device.dart
View file @
5a5eb2d9
...
...
@@ -41,7 +41,7 @@ class IntegrationTestTestDevice implements TestDevice {
/// Starts the device.
///
/// [entrypointPath] must be a path to an uncompiled source file.
/// [entrypointPath] must be a path to an un
-
compiled source file.
@override
Future
<
StreamChannel
<
String
>>
start
(
String
entrypointPath
)
async
{
final
TargetPlatform
targetPlatform
=
await
device
.
targetPlatform
;
...
...
@@ -76,7 +76,10 @@ class IntegrationTestTestDevice implements TestDevice {
);
globals
.
printTrace
(
'test
$id
: Finding the correct isolate with the integration test service extension'
);
final
vm_service
.
IsolateRef
isolateRef
=
await
vmService
.
findExtensionIsolate
(
kIntegrationTestMethod
);
final
vm_service
.
IsolateRef
isolateRef
=
await
vmService
.
findExtensionIsolate
(
kIntegrationTestMethod
,
webIsolate:
targetPlatform
==
TargetPlatform
.
web_javascript
,
);
await
vmService
.
service
.
streamListen
(
vm_service
.
EventStreams
.
kExtension
);
final
Stream
<
String
>
remoteMessages
=
vmService
.
service
.
onExtensionEvent
...
...
packages/flutter_tools/lib/src/vmservice.dart
View file @
5a5eb2d9
...
...
@@ -829,9 +829,12 @@ class FlutterVmService {
/// Looks at the list of loaded extensions for first Flutter view, as well as
/// the stream of added extensions to avoid races.
///
/// If [webIsolate] is true, this uses the VM Service isolate list instead of
/// the `_flutter.listViews` method, which is not implemented by DWDS.
///
/// Throws a [VmServiceDisappearedException] should the VM Service disappear
/// while making calls to it.
Future
<
vm_service
.
IsolateRef
>
findExtensionIsolate
(
String
extensionName
)
async
{
Future
<
vm_service
.
IsolateRef
>
findExtensionIsolate
(
String
extensionName
,
{
bool
webIsolate
=
false
}
)
async
{
try
{
await
service
.
streamListen
(
vm_service
.
EventStreams
.
kIsolate
);
}
on
vm_service
.
RPCError
{
...
...
@@ -849,20 +852,11 @@ class FlutterVmService {
});
try
{
final
List
<
FlutterView
>
flutterViews
=
await
getFlutterViews
();
if
(
flutterViews
.
isEmpty
)
{
throw
VmServiceDisappearedException
();
}
for
(
final
FlutterView
flutterView
in
flutterViews
)
{
final
vm_service
.
IsolateRef
isolateRef
=
flutterView
.
uiIsolate
;
if
(
isolateRef
==
null
)
{
continue
;
}
final
vm_service
.
Isolate
isolate
=
await
service
.
getIsolate
(
isolateRef
.
id
);
final
List
<
vm_service
.
IsolateRef
>
refs
=
await
_getIsolateRefs
(
webIsolate
);
for
(
final
vm_service
.
IsolateRef
ref
in
refs
)
{
final
vm_service
.
Isolate
isolate
=
await
service
.
getIsolate
(
ref
.
id
);
if
(
isolate
.
extensionRPCs
.
contains
(
extensionName
))
{
return
isolateR
ef
;
return
r
ef
;
}
}
return
await
extensionAdded
.
future
;
...
...
@@ -876,6 +870,28 @@ class FlutterVmService {
}
}
Future
<
List
<
vm_service
.
IsolateRef
>>
_getIsolateRefs
(
bool
webIsolate
)
async
{
if
(
webIsolate
)
{
final
List
<
vm_service
.
IsolateRef
>
refs
=
(
await
service
.
getVM
()).
isolates
;
if
(
refs
.
isEmpty
)
{
throw
VmServiceDisappearedException
();
}
return
refs
;
}
final
List
<
FlutterView
>
flutterViews
=
await
getFlutterViews
();
if
(
flutterViews
.
isEmpty
)
{
throw
VmServiceDisappearedException
();
}
final
List
<
vm_service
.
IsolateRef
>
refs
=
<
vm_service
.
IsolateRef
>[];
for
(
final
FlutterView
flutterView
in
flutterViews
)
{
if
(
flutterView
.
uiIsolate
!=
null
)
{
refs
.
add
(
flutterView
.
uiIsolate
);
}
}
return
refs
;
}
/// Attempt to retrieve the isolate with id [isolateId], or `null` if it has
/// been collected.
Future
<
vm_service
.
Isolate
>
getIsolateOrNull
(
String
isolateId
)
{
...
...
packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart
View file @
5a5eb2d9
...
...
@@ -5,6 +5,7 @@
// @dart = 2.8
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/devtools_launcher.dart'
;
import
'package:flutter_tools/src/vmservice.dart'
;
...
...
@@ -45,6 +46,21 @@ final vm_service.Isolate isolate = vm_service.Isolate(
extensionRPCs:
<
String
>[
'ext.flutter.connectedVmServiceUri'
],
);
final
vm_service
.
VM
fakeVM
=
vm_service
.
VM
(
isolates:
<
vm_service
.
IsolateRef
>[
isolate
],
pid:
1
,
hostCPU:
''
,
isolateGroups:
<
vm_service
.
IsolateGroupRef
>[],
targetCPU:
''
,
startTime:
0
,
name:
'dart'
,
architectureBits:
64
,
operatingSystem:
''
,
version:
''
,
systemIsolateGroups:
<
vm_service
.
IsolateGroupRef
>[],
systemIsolates:
<
vm_service
.
IsolateRef
>[],
);
final
FakeVmServiceRequest
listViews
=
FakeVmServiceRequest
(
method:
kListViewsMethod
,
jsonResponse:
<
String
,
Object
>{
...
...
@@ -175,6 +191,60 @@ void main() {
);
});
testWithoutContext
(
'serveAndAnnounceDevTools with web device'
,
()
async
{
final
ResidentDevtoolsHandler
handler
=
FlutterResidentDevtoolsHandler
(
FakeDevtoolsLauncher
()..
activeDevToolsServer
=
DevToolsServerAddress
(
'localhost'
,
8080
),
FakeResidentRunner
(),
BufferLogger
.
test
(),
);
final
FakeVmServiceHost
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
const
FakeVmServiceRequest
(
method:
'streamListen'
,
args:
<
String
,
Object
>{
'streamId'
:
'Isolate'
,
}
),
FakeVmServiceRequest
(
method:
'getVM'
,
jsonResponse:
fakeVM
.
toJson
(),
args:
<
String
,
Object
>{},
),
FakeVmServiceRequest
(
method:
'getIsolate'
,
jsonResponse:
isolate
.
toJson
(),
args:
<
String
,
Object
>{
'isolateId'
:
'1'
,
},
),
const
FakeVmServiceRequest
(
method:
'streamCancel'
,
args:
<
String
,
Object
>{
'streamId'
:
'Isolate'
,
},
),
const
FakeVmServiceRequest
(
method:
'ext.flutter.activeDevToolsServerAddress'
,
args:
<
String
,
Object
>{
'value'
:
'http://localhost:8080'
,
},
),
const
FakeVmServiceRequest
(
method:
'ext.flutter.connectedVmServiceUri'
,
args:
<
String
,
Object
>{
'value'
:
'http://localhost:1234'
,
},
),
],
httpAddress:
Uri
.
parse
(
'http://localhost:1234'
));
final
FakeFlutterDevice
device
=
FakeFlutterDevice
()
..
vmService
=
fakeVmServiceHost
.
vmService
..
targetPlatform
=
TargetPlatform
.
web_javascript
;
await
handler
.
serveAndAnnounceDevTools
(
flutterDevices:
<
FlutterDevice
>[
device
],
);
});
testWithoutContext
(
'serveAndAnnounceDevTools with skips calling service extensions when VM service disappears'
,
()
async
{
final
ResidentDevtoolsHandler
handler
=
FlutterResidentDevtoolsHandler
(
FakeDevtoolsLauncher
()..
activeDevToolsServer
=
DevToolsServerAddress
(
'localhost'
,
8080
),
...
...
@@ -313,6 +383,9 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override
FlutterVmService
vmService
;
@override
TargetPlatform
targetPlatform
=
TargetPlatform
.
android_arm
;
}
class
FakeDevice
extends
Fake
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