TraceProcessor RPC: Add API version to handle version mismatch

This CL adds a notion of API version to the TraceProcessor
RPC protocol. This is to deal with cases where we introduce
a new TP feature (a new table, a new operator) that the UI
depends on.
Today the UI breaks in unexpected ways when the user is using
a version of trace_processor_shell --http that is too old.
This change makes it more explicit, telling the user what to do.

Preview: https://imgur.com/a/Jvap5K2
Bug: 159142289
Change-Id: Ic2d68f94c7eb7bd5b95eabd842dae71fe61222d4
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index f2358ac..23625b3 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -356,6 +356,7 @@
       ":lib",
       "../../gn:default_deps",
       "../../gn:protobuf_full",
+      "../../protos/perfetto/trace_processor:zero",
       "../../src/profiling:deobfuscator",
       "../../src/profiling/symbolizer",
       "../../src/profiling/symbolizer:symbolize_database",
diff --git a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor
index 476c0b9..e3e9b24 100644
--- a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor
+++ b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor
Binary files differ
diff --git a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1 b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1
index 1b19c08..6e01bd0 100644
--- a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1
+++ b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1
@@ -2,5 +2,5 @@
 // SHA1(tools/gen_binary_descriptors)
 // 9fc6d77de57ec76a80b76aa282f4c7cf5ce55eec
 // SHA1(protos/perfetto/trace_processor/trace_processor.proto)
-// f0ba693bdd1111c81e9240c966e16babd489bb03
+// b4135d9bc2551939bfdaa4d03423cf34a8fbcffb
   
\ No newline at end of file
diff --git a/src/trace_processor/rpc/httpd.cc b/src/trace_processor/rpc/httpd.cc
index da690fc..2cdf80f 100644
--- a/src/trace_processor/rpc/httpd.cc
+++ b/src/trace_processor/rpc/httpd.cc
@@ -401,12 +401,9 @@
   }
 
   if (req.uri == "/status") {
-    protozero::HeapBuffered<protos::pbzero::StatusResult> res;
-    res->set_loaded_trace_name(
-        trace_processor_rpc_.GetCurrentTraceName().c_str());
-    std::vector<uint8_t> buf = res.SerializeAsArray();
-    return HttpReply(client->sock.get(), "200 OK", headers, buf.data(),
-                     buf.size());
+    auto status = trace_processor_rpc_.GetStatus();
+    return HttpReply(client->sock.get(), "200 OK", headers, status.data(),
+                     status.size());
   }
 
   if (req.uri == "/compute_metric") {
diff --git a/src/trace_processor/rpc/rpc.cc b/src/trace_processor/rpc/rpc.cc
index 17df0be..a58cd7c 100644
--- a/src/trace_processor/rpc/rpc.cc
+++ b/src/trace_processor/rpc/rpc.cc
@@ -23,6 +23,7 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/base/version.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/protozero/scattered_stream_writer.h"
 #include "perfetto/trace_processor/trace_processor.h"
@@ -241,6 +242,13 @@
       resp.Send(rpc_response_fn_);
       break;
     }
+    case RpcProto::TPM_GET_STATUS: {
+      Response resp(tx_seq_id_++, req_type);
+      std::vector<uint8_t> status = GetStatus();
+      resp->set_status()->AppendRawProtoBytes(status.data(), status.size());
+      resp.Send(rpc_response_fn_);
+      break;
+    }
     default: {
       // This can legitimately happen if the client is newer. We reply with a
       // generic "unkown request" response, so the client can do feature
@@ -453,10 +461,6 @@
   PERFETTO_DLOG("[RPC] RawQuery > %d rows (err: %d)", rows, !status.ok());
 }
 
-std::string Rpc::GetCurrentTraceName() {
-  return trace_processor_->GetCurrentTraceName();
-}
-
 void Rpc::RestoreInitialTables() {
   trace_processor_->RestoreInitialTables();
 }
@@ -534,5 +538,13 @@
   }
 }
 
+std::vector<uint8_t> Rpc::GetStatus() {
+  protozero::HeapBuffered<protos::pbzero::StatusResult> status;
+  status->set_loaded_trace_name(trace_processor_->GetCurrentTraceName());
+  status->set_human_readable_version(base::GetVersionString());
+  status->set_api_version(protos::pbzero::TRACE_PROCESSOR_CURRENT_API_VERSION);
+  return status.SerializeAsArray();
+}
+
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/rpc/rpc.h b/src/trace_processor/rpc/rpc.h
index 9006154..8501b56 100644
--- a/src/trace_processor/rpc/rpc.h
+++ b/src/trace_processor/rpc/rpc.h
@@ -106,6 +106,7 @@
   std::vector<uint8_t> ComputeMetric(const uint8_t* data, size_t len);
   void EnableMetatrace();
   std::vector<uint8_t> DisableAndReadMetatrace();
+  std::vector<uint8_t> GetStatus();
 
   // Creates a new RPC session by deleting all tables and views that have been
   // created (by the UI or user) after the trace was loaded; built-in
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 9db56c4..6925948 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -45,6 +45,8 @@
 #include "src/trace_processor/util/proto_to_json.h"
 #include "src/trace_processor/util/status_macros.h"
 
+#include "protos/perfetto/trace_processor/trace_processor.pbzero.h"
+
 #if PERFETTO_BUILDFLAG(PERFETTO_TP_HTTPD)
 #include "src/trace_processor/rpc/httpd.h"
 #endif
@@ -756,6 +758,8 @@
 
     if (option == 'v') {
       printf("%s\n", base::GetVersionString());
+      printf("Trace Processor RPC API version: %d\n",
+             protos::pbzero::TRACE_PROCESSOR_CURRENT_API_VERSION);
       exit(0);
     }