Register Service Extension for Events (#1330)

diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md
index 0caf7ad..dde53b6 100644
--- a/dwds/CHANGELOG.md
+++ b/dwds/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 - Add global functions to the injected client for `dart.developer.postEvent`
   and `dart.developer.registerExtension`.
+- Register new service extension `ext.dwds.emitEvent` so clients can emit
+  events. This is intended to be used for analytics.
 
 ## 11.0.2
 
diff --git a/dwds/lib/src/dwds_vm_client.dart b/dwds/lib/src/dwds_vm_client.dart
index 4a27d8d..6e93fc6 100644
--- a/dwds/lib/src/dwds_vm_client.dart
+++ b/dwds/lib/src/dwds_vm_client.dart
@@ -11,6 +11,7 @@
 import 'package:vm_service/vm_service.dart';
 import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
 
+import 'events.dart';
 import 'services/chrome_proxy_service.dart' show ChromeProxyService;
 import 'services/debug_service.dart';
 
@@ -153,6 +154,13 @@
     });
     await client.registerService('ext.dwds.screenshot', 'DWDS');
 
+    client.registerServiceCallback('ext.dwds.emitEvent', (event) async {
+      emitEvent(DwdsEvent(
+          event['type'] as String, event['payload'] as Map<String, dynamic>));
+      return {'result': Success().toJson()};
+    });
+    await client.registerService('ext.dwds.emitEvent', 'DWDS');
+
     client.registerServiceCallback('_yieldControlToDDS', (request) async {
       final ddsUri = request['uri'] as String;
       if (ddsUri == null) {
diff --git a/dwds/test/events_test.dart b/dwds/test/events_test.dart
index c47fe07..ddca843 100644
--- a/dwds/test/events_test.dart
+++ b/dwds/test/events_test.dart
@@ -63,6 +63,20 @@
       bootstrap = isolate.rootLib;
     });
 
+    test('can emit event through service extension', () async {
+      expect(
+          context.testServer.dwds.events,
+          emits(predicate((DwdsEvent event) =>
+              event.type == 'foo-event' && event.payload['data'] == 1234)));
+
+      var response = await context.debugConnection.vmService
+          .callServiceExtension('ext.dwds.emitEvent', args: {
+        'type': 'foo-event',
+        'payload': {'data': 1234},
+      });
+      expect(response.type, 'Success');
+    });
+
     test('emits EVALUATE events on evaluation success', () async {
       var expression = "helloString('world')";
       expect(