Add mechanism to collect fuzzer run data.

Right now only collect the number of times each api function was touched
by the fuzzer. That info is printed to screen at the end of the fuzzer
run.

Bug: 62191577
Test: SANITIZE_TARGET="address coverage" make vts -j64 && vts-tradefed
run commandAndExit vts --skip-all-system-status-check --primary-abi-only
--skip-preconditions -l VERBOSE --module VtsHalLightV2_0IfaceFuzzer
Merged-In: Idf98f3dfbd107d23095ae252fc7dba18a411704d
Change-Id: Idf98f3dfbd107d23095ae252fc7dba18a411704d

(cherry picked from commit f657d67ac863a62ebb4a4561d0e61b06d0c83b88)
diff --git a/iface_fuzzer/Android.bp b/iface_fuzzer/Android.bp
index 17bd091..c4c59a8 100644
--- a/iface_fuzzer/Android.bp
+++ b/iface_fuzzer/Android.bp
@@ -21,6 +21,7 @@
         "ProtoFuzzerMutator.cpp",
         "ProtoFuzzerMutateFns.cpp",
         "ProtoFuzzerRunner.cpp",
+        "ProtoFuzzerStats.cpp",
     ],
     include_dirs: [
         "test/vts/drivers/hal/common/include",
diff --git a/iface_fuzzer/ProtoFuzzerMain.cpp b/iface_fuzzer/ProtoFuzzerMain.cpp
index f1b2c3a..7fa208d 100644
--- a/iface_fuzzer/ProtoFuzzerMain.cpp
+++ b/iface_fuzzer/ProtoFuzzerMain.cpp
@@ -79,6 +79,8 @@
   for (const auto &iface_desc : runner->GetOpenedIfaces()) {
     cerr << iface_desc.first << endl;
   }
+  cerr << endl;
+  cerr << runner->GetStats().StatsString();
 }
 
 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
diff --git a/iface_fuzzer/ProtoFuzzerMutator.cpp b/iface_fuzzer/ProtoFuzzerMutator.cpp
index 3e6cdc4..b2baa77 100644
--- a/iface_fuzzer/ProtoFuzzerMutator.cpp
+++ b/iface_fuzzer/ProtoFuzzerMutator.cpp
@@ -17,9 +17,9 @@
 #include "ProtoFuzzerMutator.h"
 #include <iostream>
 
-using std::endl;
 using std::cerr;
 using std::cout;
+using std::endl;
 using std::make_unique;
 using std::unordered_map;
 using namespace std::placeholders;
diff --git a/iface_fuzzer/ProtoFuzzerRunner.cpp b/iface_fuzzer/ProtoFuzzerRunner.cpp
index 7c9ea84..ec9dee1 100644
--- a/iface_fuzzer/ProtoFuzzerRunner.cpp
+++ b/iface_fuzzer/ProtoFuzzerRunner.cpp
@@ -25,11 +25,11 @@
 
 using android::vintf::HalManifest;
 
-using std::cout;
 using std::cerr;
+using std::cout;
 using std::string;
-using std::vector;
 using std::unordered_map;
+using std::vector;
 
 namespace android {
 namespace vts {
@@ -188,6 +188,7 @@
   FuncSpec result{};
   iface_desc->second.hal_->CallFunction(func_spec, "", &result);
 
+  stats_.RegisterTouch(iface_name, func_spec.name());
   ProcessReturnValue(result);
 }
 
diff --git a/iface_fuzzer/ProtoFuzzerStats.cpp b/iface_fuzzer/ProtoFuzzerStats.cpp
new file mode 100644
index 0000000..659fc59
--- /dev/null
+++ b/iface_fuzzer/ProtoFuzzerStats.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#include "ProtoFuzzerStats.h"
+
+#include <iomanip>
+#include <iostream>
+#include <map>
+#include <sstream>
+
+using std::endl;
+using std::map;
+using std::string;
+using std::unordered_map;
+
+namespace android {
+namespace vts {
+namespace fuzzer {
+
+void ProtoFuzzerStats::RegisterTouch(string iface_name, string func_name) {
+  string key = iface_name + "::" + func_name;
+  touch_count_[key]++;
+}
+
+string ProtoFuzzerStats::StatsString() const {
+  std::map<string, uint64_t> ordered_result{touch_count_.cbegin(),
+                                            touch_count_.cend()};
+
+  std::stringstream ss{};
+  ss << "HAL api function touch count: " << endl;
+  for (const auto &entry : ordered_result) {
+    ss << std::left << std::setfill(' ') << std::setw(40) << entry.first
+       << std::setw(40) << entry.second << endl;
+  }
+  ss << endl;
+  return ss.str();
+}
+
+}  // namespace fuzzer
+}  // namespace vts
+}  // namespace android
diff --git a/iface_fuzzer/ProtoFuzzerUtils.cpp b/iface_fuzzer/ProtoFuzzerUtils.cpp
index 43710f0..6ae3019 100644
--- a/iface_fuzzer/ProtoFuzzerUtils.cpp
+++ b/iface_fuzzer/ProtoFuzzerUtils.cpp
@@ -145,7 +145,7 @@
   return params;
 }
 
-string ProtoFuzzerParams::DebugString() {
+string ProtoFuzzerParams::DebugString() const {
   std::stringstream ss;
   ss << "Execution size: " << exec_size_ << endl;
   ss << "Target interface: " << target_iface_ << endl;
diff --git a/iface_fuzzer/include/ProtoFuzzerRunner.h b/iface_fuzzer/include/ProtoFuzzerRunner.h
index 179b059..3f882a2 100644
--- a/iface_fuzzer/include/ProtoFuzzerRunner.h
+++ b/iface_fuzzer/include/ProtoFuzzerRunner.h
@@ -17,6 +17,7 @@
 #ifndef __VTS_PROTO_FUZZER_RUNNER_H_
 #define __VTS_PROTO_FUZZER_RUNNER_H_
 
+#include "ProtoFuzzerStats.h"
 #include "ProtoFuzzerUtils.h"
 
 #include <memory>
@@ -50,6 +51,8 @@
   // Accessor to interface descriptor table containing currently opened
   // interfaces.
   const IfaceDescTbl &GetOpenedIfaces() const { return opened_ifaces_; }
+  // Accessor to stats object.
+  const ProtoFuzzerStats &GetStats() const { return stats_; }
 
  private:
   // Looks up interface spec by name.
@@ -66,6 +69,9 @@
   std::unordered_map<std::string, CompSpec> comp_specs_;
   // Handle to the driver library.
   void *driver_handle_;
+
+  // Collects statistical information.
+  ProtoFuzzerStats stats_;
 };
 
 }  // namespace fuzzer
diff --git a/iface_fuzzer/include/ProtoFuzzerStats.h b/iface_fuzzer/include/ProtoFuzzerStats.h
new file mode 100644
index 0000000..6dfb164
--- /dev/null
+++ b/iface_fuzzer/include/ProtoFuzzerStats.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#ifndef __VTS_PROTO_FUZZER_STATS_H_
+#define __VTS_PROTO_FUZZER_STATS_H_
+
+#include <string>
+#include <unordered_map>
+
+namespace android {
+namespace vts {
+namespace fuzzer {
+
+// Holds stats about a fuzzer run.
+class ProtoFuzzerStats {
+ public:
+  // Registers fuzzer touching an interface function.
+  void RegisterTouch(std::string iface_name, std::string func_name);
+  // Returns collected stats in string form.
+  std::string StatsString() const;
+
+ private:
+  // Counts the number of times a function was touched.
+  // This object will be written to often, so we use unordered_map.
+  std::unordered_map<std::string, uint64_t> touch_count_;
+};
+
+}  // namespace fuzzer
+}  // namespace vts
+}  // namespace android
+
+#endif  // __VTS_PROTO_FUZZER_STATS__
diff --git a/iface_fuzzer/include/ProtoFuzzerUtils.h b/iface_fuzzer/include/ProtoFuzzerUtils.h
index 13e5665..145a40a 100644
--- a/iface_fuzzer/include/ProtoFuzzerUtils.h
+++ b/iface_fuzzer/include/ProtoFuzzerUtils.h
@@ -79,7 +79,7 @@
   // Seed used to initialize the random number generator.
   uint64_t seed_ = static_cast<uint64_t>(time(0));
   // Returns a string summarizing content of this object.
-  string DebugString();
+  string DebugString() const;
 };
 
 // Parses command-line flags to create a ProtoFuzzerParams instance.