GD Cert tests: log grpc communication in verbose mode

Bug: 145007149
Tag: #gd-refactor
Test: gd/cert/run --verbose
Change-Id: I0e81f5bf1b2d2320ac5569cc9e3ca13d2762e0da
diff --git a/system/gd/cert/gd_device.py b/system/gd/cert/gd_device.py
index 47e7922..6ebd503 100644
--- a/system/gd/cert/gd_device.py
+++ b/system/gd/cert/gd_device.py
@@ -38,6 +38,7 @@
 from google.protobuf import empty_pb2 as empty_proto
 
 from cert.async_subprocess_logger import AsyncSubprocessLogger
+from cert.logging_client_interceptor import LoggingClientInterceptor
 from cert.os_utils import get_gd_root
 from cert.os_utils import read_crash_snippet_and_log_tail
 from cert.os_utils import is_subprocess_alive
@@ -217,6 +218,9 @@
         self.grpc_root_server_channel = grpc.insecure_channel("localhost:%d" % self.grpc_root_server_port)
         self.grpc_channel = grpc.insecure_channel("localhost:%d" % self.grpc_port)
 
+        if self.verbose_mode:
+            self.grpc_channel = grpc.intercept_channel(self.grpc_channel, LoggingClientInterceptor(self.label))
+
         # Establish services from facades
         self.rootservice = facade_rootservice_pb2_grpc.RootFacadeStub(self.grpc_root_server_channel)
         self.hal = hal_facade_pb2_grpc.HciHalFacadeStub(self.grpc_channel)
diff --git a/system/gd/cert/logging_client_interceptor.py b/system/gd/cert/logging_client_interceptor.py
new file mode 100644
index 0000000..4fbd6d3
--- /dev/null
+++ b/system/gd/cert/logging_client_interceptor.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2020 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+import logging
+
+import grpc
+
+from google.protobuf import text_format
+
+
+def pretty_print(request):
+    return '{} {}'.format(type(request).__name__, text_format.MessageToString(request, as_one_line=True))
+
+
+class LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor):
+
+    def __init__(self, name):
+        self.name = name
+
+    def _intercept_call(self, continuation, client_call_details, request_or_iterator):
+        return continuation(client_call_details, request_or_iterator)
+
+    def intercept_unary_unary(self, continuation, client_call_details, request):
+        print('[host ▶▶▶▶▶ ' + self.name + '] ' + client_call_details.method + ' ' + pretty_print(request))
+        return self._intercept_call(continuation, client_call_details, request)