@@ -6,6 +6,7 @@ import 'dart:async';
6
6
import 'dart:convert' ;
7
7
import 'dart:io' ;
8
8
9
+ import 'package:pedantic/pedantic.dart' ;
9
10
import 'package:pub_semver/pub_semver.dart' as semver;
10
11
import 'package:vm_service_lib/vm_service_lib.dart' ;
11
12
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' ;
@@ -49,21 +50,25 @@ class ChromeProxyService implements VmServiceInterface {
49
50
ChromeProxyService ._(
50
51
this ._vm, this ._tab, this .tabConnection, this ._assetHandler);
51
52
52
- static Future <ChromeProxyService > create (ChromeConnection chromeConnection,
53
- Future <String > Function (String ) assetHandler, String appId) async {
53
+ static Future <ChromeProxyService > create (
54
+ ChromeConnection chromeConnection,
55
+ Future <String > Function (String ) assetHandler,
56
+ String appInstanceId) async {
54
57
ChromeTab appTab;
55
58
for (var tab in await chromeConnection.getTabs ()) {
56
59
if (tab.url.startsWith ('chrome-extensions:' )) continue ;
57
60
var tabConnection = await tab.connect ();
58
- var result = await tabConnection.runtime. sendCommand ( 'Runtime.evaluate' ,
59
- params : { 'expression' : r'window.$dartAppId;' , 'awaitPromise' : true } );
60
- if (result.result[ 'result' ][ ' value' ] == appId ) {
61
+ var result = await tabConnection.runtime
62
+ . evaluate ( r'window["$dartAppInstanceId"];' );
63
+ if (result.value == appInstanceId ) {
61
64
appTab = tab;
62
65
break ;
63
66
}
67
+ unawaited (tabConnection.close ());
64
68
}
65
69
if (appTab == null ) {
66
- throw StateError ('Could not connect to application with appId: $appId ' );
70
+ throw StateError ('Could not connect to application with appInstanceId: '
71
+ '$appInstanceId ' );
67
72
}
68
73
var tabConnection = await appTab.connect ();
69
74
await tabConnection.debugger.enable ();
@@ -142,6 +147,7 @@ class ChromeProxyService implements VmServiceInterface {
142
147
// Listen for `registerExtension` and `postEvent` calls.
143
148
_consoleSubscription = tabConnection.runtime.onConsoleAPICalled
144
149
.listen ((ConsoleAPIEvent event) {
150
+ if (_isolate == null ) return ;
145
151
if (event.type != 'debug' ) return ;
146
152
var firstArgValue = event.args[0 ].value as String ;
147
153
switch (firstArgValue) {
@@ -152,7 +158,8 @@ class ChromeProxyService implements VmServiceInterface {
152
158
'Isolate' ,
153
159
Event ()
154
160
..kind = EventKind .kServiceExtensionAdded
155
- ..extensionRPC = service);
161
+ ..extensionRPC = service
162
+ ..isolate = isolateRef);
156
163
break ;
157
164
case 'dart.developer.postEvent' :
158
165
_streamNotify (
@@ -161,7 +168,8 @@ class ChromeProxyService implements VmServiceInterface {
161
168
..kind = EventKind .kExtension
162
169
..extensionKind = event.args[1 ].value as String
163
170
..extensionData = ExtensionData .parse (
164
- jsonDecode (event.args[2 ].value as String ) as Map ));
171
+ jsonDecode (event.args[2 ].value as String ) as Map )
172
+ ..isolate = isolateRef);
165
173
break ;
166
174
case 'dart.developer.inspect' :
167
175
// All inspected objects should be real objects.
@@ -178,7 +186,8 @@ class ChromeProxyService implements VmServiceInterface {
178
186
Event ()
179
187
..kind = EventKind .kInspect
180
188
..inspectee = inspectee
181
- ..timestamp = event.timestamp.toInt ());
189
+ ..timestamp = event.timestamp.toInt ()
190
+ ..isolate = isolateRef);
182
191
break ;
183
192
default :
184
193
break ;
@@ -198,12 +207,25 @@ class ChromeProxyService implements VmServiceInterface {
198
207
Event ()
199
208
..kind = EventKind .kIsolateRunnable
200
209
..isolate = isolateRef);
210
+
211
+ // TODO: We shouldn't need to fire these events since they exist on the
212
+ // isolate, but devtools doesn't recognize extensions after a page refresh
213
+ // otherwise.
214
+ for (var extensionRpc in isolate.extensionRPCs) {
215
+ _streamNotify (
216
+ 'Isolate' ,
217
+ Event ()
218
+ ..kind = EventKind .kServiceExtensionAdded
219
+ ..extensionRPC = extensionRpc
220
+ ..isolate = isolateRef);
221
+ }
201
222
}
202
223
203
224
/// Should be called when there is a hot restart or full page refresh.
204
225
///
205
226
/// Clears out [_isolate] and all related cached information.
206
227
void destroyIsolate () {
228
+ if (_isolate == null ) return ;
207
229
_streamNotify (
208
230
'Isolate' ,
209
231
Event ()
@@ -354,7 +376,7 @@ require("dart_sdk").developer.invokeExtension(
354
376
/// Sync version of [getIsolate] for internal use, also has stronger typing
355
377
/// than the public one which has to be dynamic.
356
378
Isolate _getIsolate (String isolateId) {
357
- if (_isolate.id == isolateId) return _isolate;
379
+ if (_isolate? .id == isolateId) return _isolate;
358
380
throw ArgumentError .value (
359
381
isolateId, 'isolateId' , 'Unrecognized isolate id' );
360
382
}
@@ -439,7 +461,7 @@ require("dart_sdk").developer.invokeExtension(
439
461
}
440
462
441
463
Future <Library > _getLibrary (String isolateId, String objectId) async {
442
- if (isolateId != _isolate.id) return null ;
464
+ if (isolateId != _isolate? .id) return null ;
443
465
var libraryRef = _libraryRefs[objectId];
444
466
if (libraryRef == null ) return null ;
445
467
var library = _libraries[objectId];
@@ -670,6 +692,7 @@ require("dart_sdk").developer.invokeExtension(
670
692
}, onListen: () {
671
693
chromeConsoleSubscription =
672
694
tabConnection.runtime.onConsoleAPICalled.listen ((e) {
695
+ if (_isolate == null ) return ;
673
696
if (! filter (e)) return ;
674
697
var args = e.params['args' ] as List ;
675
698
var item = args[0 ] as Map ;
@@ -683,6 +706,7 @@ require("dart_sdk").developer.invokeExtension(
683
706
if (includeExceptions) {
684
707
exceptionsSubscription =
685
708
tabConnection.runtime.onExceptionThrown.listen ((e) {
709
+ if (_isolate == null ) return ;
686
710
controller.add (Event ()
687
711
..kind = EventKind .kWriteEvent
688
712
..isolate = toIsolateRef (_isolate)
@@ -703,6 +727,7 @@ require("dart_sdk").developer.invokeExtension(
703
727
StreamSubscription resumeSubscription;
704
728
return StreamController <Event >.broadcast (onListen: () {
705
729
pauseSubscription = tabConnection.debugger.onPaused.listen ((e) {
730
+ if (_isolate == null ) return ;
706
731
var event = Event ()..isolate = toIsolateRef (_isolate);
707
732
var params = e.params;
708
733
var breakpoints = params['hitBreakpoints' ] as List ;
@@ -717,6 +742,7 @@ require("dart_sdk").developer.invokeExtension(
717
742
_streamNotify ('Debug' , event);
718
743
});
719
744
resumeSubscription = tabConnection.debugger.onResumed.listen ((e) {
745
+ if (_isolate == null ) return ;
720
746
_streamNotify (
721
747
'Debug' ,
722
748
Event ()
0 commit comments