[ VM / Service ] Add getVMTimelineMicros RPC to the service protocol

Allows for clients outside of the process to retrieve the current clock used by
the timeline.

Change-Id: I8fc3f06d537b00cd961bffe29100e9005da7b4e1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107445
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index a5f9a4f..de073bf 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(20));
+    expect(result['minor'], equals(21));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart
new file mode 100644
index 0000000..e8fa8e6
--- /dev/null
+++ b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = <VMTest>[
+  (VM vm) async {
+    var result = await vm.invokeRpcNoUpgrade('getVMTimelineMicros', {});
+    expect(result['type'], equals('Timestamp'));
+    expect(result['timestamp'], isPositive);
+  },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index a5f12e0..b39fa23 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3628,6 +3628,17 @@
 #endif
 }
 
+static const MethodParameter* get_vm_timeline_micros_params[] = {
+    NO_ISOLATE_PARAMETER, NULL,
+};
+
+static bool GetVMTimelineMicros(Thread* thread, JSONStream* js) {
+  JSONObject obj(js);
+  obj.AddProperty("type", "Timestamp");
+  obj.AddPropertyTimeMicros("timestamp", OS::GetCurrentMonotonicMicros());
+  return true;
+}
+
 static const MethodParameter* clear_vm_timeline_params[] = {
     NO_ISOLATE_PARAMETER, NULL,
 };
@@ -4976,6 +4987,8 @@
     get_vm_timeline_params },
   { "getVMTimelineFlags", GetVMTimelineFlags,
     get_vm_timeline_flags_params },
+  { "getVMTimelineMicros", GetVMTimelineMicros,
+    get_vm_timeline_micros_params },
   { "invoke", Invoke, invoke_params },
   { "kill", Kill, kill_params },
   { "pause", Pause,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 15d30ff..835282f 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 20
+#define SERVICE_PROTOCOL_MINOR_VERSION 21
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 89e580b..2dfda77 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.20
+# Dart VM Service Protocol 3.21
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.20_ of the Dart VM Service Protocol. This
+This document describes of _version 3.21_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
   - [getVM](#getvm)
   - [getVMTimeline](#getvmtimeline)
   - [getVMTimelineFlags](#getvmtimelineflags)
+  - [getVMTimelineMicros](#getvmtimelinemicros)
   - [invoke](#invoke)
   - [pause](#pause)
   - [kill](#kill)
@@ -107,6 +108,7 @@
   - [Timeline](#timeline)
   - [TimelineEvent](#timelineevent)
   - [TimelineFlags](#timelineflags)
+  - [Timestamp](#timestamp)
   - [TypeArguments](#typearguments)
   - [UresolvedSourceLocation](#unresolvedsourcelocation)
   - [Version](#version)
@@ -490,7 +492,7 @@
 
 ### clearVMTimeline
 
-``` 
+```
 Success clearVMTimeline()
 ```
 
@@ -816,7 +818,8 @@
 
 The _timeOriginMicros_ parameter is the beginning of the time range used to filter
 timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
 
 The _timeExtentMicros_ parameter specifies how large the time range used to filter
 timeline events should be.
@@ -840,6 +843,17 @@
 
 See [TimelineFlags](#timelineflags).
 
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
 ### pause
 
 ```
@@ -2898,7 +2912,7 @@
 class TimelineFlags extends Response {
   // The name of the recorder currently in use. Recorder types include, but are
   // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
-  // Set to "null" if no recorder is currently set. 
+  // Set to "null" if no recorder is currently set.
   string recorderName;
 
   // The list of all available timeline streams.
@@ -2909,6 +2923,15 @@
 }
 ```
 
+### Timestamp
+
+```
+class Timestamp extends Response {
+  // A timestamp in microseconds since epoch.
+  int timestamp;
+}
+```
+
 ### TypeArguments
 
 ```
@@ -3057,5 +3080,6 @@
 3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
 3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
 3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index ccf44c1..04fd1e9 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.21-dev
+# Dart VM Service Protocol 3.22-dev
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.21-dev_ of the Dart VM Service Protocol. This
+This document describes of _version 3.22-dev_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
   - [getVM](#getvm)
   - [getVMTimeline](#getvmtimeline)
   - [getVMTimelineFlags](#getvmtimelineflags)
+  - [getVMTimelineMicros](#getvmtimelinemicros)
   - [invoke](#invoke)
   - [pause](#pause)
   - [kill](#kill)
@@ -107,6 +108,7 @@
   - [Timeline](#timeline)
   - [TimelineEvent](#timelineevent)
   - [TimelineFlags](#timelineflags)
+  - [Timestamp](#timestamp)
   - [TypeArguments](#typearguments)
   - [UresolvedSourceLocation](#unresolvedsourcelocation)
   - [Version](#version)
@@ -490,7 +492,7 @@
 
 ### clearVMTimeline
 
-``` 
+```
 Success clearVMTimeline()
 ```
 
@@ -816,7 +818,8 @@
 
 The _timeOriginMicros_ parameter is the beginning of the time range used to filter
 timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
 
 The _timeExtentMicros_ parameter specifies how large the time range used to filter
 timeline events should be.
@@ -840,6 +843,17 @@
 
 See [TimelineFlags](#timelineflags).
 
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
 ### pause
 
 ```
@@ -2898,7 +2912,7 @@
 class TimelineFlags extends Response {
   // The name of the recorder currently in use. Recorder types include, but are
   // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
-  // Set to "null" if no recorder is currently set. 
+  // Set to "null" if no recorder is currently set.
   string recorderName;
 
   // The list of all available timeline streams.
@@ -2909,6 +2923,15 @@
 }
 ```
 
+### Timestamp
+
+```
+class Timestamp extends Response {
+  // A timestamp in microseconds since epoch.
+  int timestamp;
+}
+```
+
 ### TypeArguments
 
 ```
@@ -3057,5 +3080,6 @@
 3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
 3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
 3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss