Get Chaps building under Linux again.

Define NO_METRICS if metrics library not available.
Encapsulate UMA event generation in a MetricsWrapper class.

TEST=Ran tests under Chromium OS and Linux
BUG=None
Change-Id: Ia39f07347d684e1c34bfea738e844378e27b6371
Reviewed-on: https://gerrit.chromium.org/gerrit/62987
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Tested-by: David Drysdale <drysdale@google.com>
Commit-Queue: David Drysdale <drysdale@google.com>
diff --git a/chaps/Makefile b/chaps/Makefile
index a7366bb..7d396690 100644
--- a/chaps/Makefile
+++ b/chaps/Makefile
@@ -35,7 +35,7 @@
 PC_LIBS := $(shell $(PKG_CONFIG) --libs $(PC_DEPS))
 
 CXXFLAGS += -I$(SRC)/.. -I$(OUT) $(PC_CFLAGS) -DNDEBUG
-LDLIBS += $(PC_LIBS) -lmetrics
+LDLIBS += $(PC_LIBS)
 
 # Test if libmemenv is available, and whether libsnappy is required to
 # compile LevelDB.
@@ -49,6 +49,12 @@
 	 return 0;}',\
 	 -lleveldb $(MEMENV_LIB), -lleveldb $(MEMENV_LIB) -lsnappy)
 
+# Test if libmetric is available
+METRICS_LIB := $(call check_cxx,-lmetrics)
+ifneq ($(METRICS_LIB), -lmetrics)
+  CPPFLAGS += -DNO_METRICS
+endif
+
 # Rules for Generated Code
 chaps_proxy_generated.h: $(SRC)/chaps_interface.xml
 	$(DBUSXX_XML2CPP) $< --proxy=$@
@@ -103,7 +109,7 @@
               chaps_factory_impl.o \
               object_store_impl.o \
               opencryptoki_importer.o
-chapsd_LIBS = -ldl -ltspi $(LEVELDB_LIBS)
+chapsd_LIBS = -ldl -ltspi $(LEVELDB_LIBS) $(METRICS_LIB)
 CXX_BINARY(chapsd): $(chapsd_OBJS)
 CXX_BINARY(chapsd): LDLIBS += $(chapsd_LIBS)
 clean: CLEAN(chapsd)
@@ -276,7 +282,7 @@
 tests: TEST(CXX_BINARY(object_pool_test))
 
 object_store_test_OBJS = $(COMMON_OBJS) object_store_test.o object_store_impl.o
-object_store_test_LIBS = -lgtest $(LEVELDB_LIBS)
+object_store_test_LIBS = -lgtest $(LEVELDB_LIBS) $(METRICS_LIB)
 
 CXX_BINARY(object_store_test): $(object_store_test_OBJS)
 CXX_BINARY(object_store_test): LDLIBS += $(object_store_test_LIBS)
diff --git a/chaps/object_store_impl.cc b/chaps/object_store_impl.cc
index 145d74d..ce1c86a 100644
--- a/chaps/object_store_impl.cc
+++ b/chaps/object_store_impl.cc
@@ -20,7 +20,9 @@
 #ifndef NO_MEMENV
 #include <leveldb/memenv.h>
 #endif
+#ifndef NO_METRICS
 #include <metrics/metrics_library.h>
+#endif
 
 #include "chaps/chaps_utility.h"
 #include "pkcs11/cryptoki.h"
@@ -30,6 +32,33 @@
 using std::string;
 using std::vector;
 
+namespace {
+
+// Encapsulate UMA event generation.
+class MetricsWrapper {
+ public:
+  MetricsWrapper() {
+#ifndef NO_METRICS
+    metrics_.Init();
+#endif
+  }
+
+  bool SendUMAEvent(const std::string& event) {
+#ifndef NO_METRICS
+    return metrics_.SendCrosEventToUMA(event);
+#else
+    return false;
+#endif
+  }
+
+ private:
+#ifndef NO_METRICS
+  MetricsLibrary metrics_;
+#endif
+};
+
+}  // namespace
+
 namespace chaps {
 
 const char ObjectStoreImpl::kInternalBlobKeyPrefix[] = "InternalBlob";
@@ -54,8 +83,7 @@
 ObjectStoreImpl::~ObjectStoreImpl() {}
 
 bool ObjectStoreImpl::Init(const FilePath& database_path) {
-  MetricsLibrary metrics;
-  metrics.Init();
+  MetricsWrapper metrics;
 
   LOG(INFO) << "Opening database in: " << database_path.value();
   leveldb::Options options;
@@ -79,7 +107,7 @@
                                              &db);
   if (!status.ok()) {
     LOG(ERROR) << "Failed to open database: " << status.ToString();
-    metrics.SendCrosEventToUMA("Chaps.DatabaseCorrupted");
+    metrics.SendUMAEvent("Chaps.DatabaseCorrupted");
     LOG(WARNING) << "Attempting to repair database.";
     status = leveldb::RepairDB(database_name.value(), leveldb::Options());
     if (status.ok())
@@ -88,7 +116,7 @@
 
   if (!status.ok()) {
     LOG(ERROR) << "Failed to repair database: " << status.ToString();
-    metrics.SendCrosEventToUMA("Chaps.DatabaseRepairFailure");
+    metrics.SendUMAEvent("Chaps.DatabaseRepairFailure");
     // We don't want to risk using a database that has been corrupted. Recreate
     // the database from scratch but save the corrupted database for diagnostic
     // purposes.
@@ -105,7 +133,7 @@
 
   if (!status.ok()) {
     LOG(ERROR) << "Failed to create new database: " << status.ToString();
-    metrics.SendCrosEventToUMA("Chaps.DatabaseCreateFailure");
+    metrics.SendUMAEvent("Chaps.DatabaseCreateFailure");
     return false;
   }