Use a thread pool to write to ConscryptStatsLog.

This is to avoid blocking the calling thread.

Change-Id: I6d4886583ea8ec3176b7f2fd9e45326827c7ec53
diff --git a/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java b/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
index e8f463a..a6f7fec 100644
--- a/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
+++ b/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
@@ -16,6 +16,13 @@
 package org.conscrypt.metrics;
 
 import org.conscrypt.Internal;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.lang.Thread.UncaughtExceptionHandler;
 
 /**
  * Reimplement with reflection calls the logging class,
@@ -35,13 +42,36 @@
 public final class ConscryptStatsLog {
     public static final int TLS_HANDSHAKE_REPORTED = 317;
 
+    private static final ExecutorService e =
+        Executors.newSingleThreadExecutor(
+                        new ThreadFactory() {
+                            @Override
+                            public Thread newThread(Runnable r) {
+                                Thread thread = new Thread(r);
+                                thread.setUncaughtExceptionHandler(
+                                    new UncaughtExceptionHandler() {
+                                        @Override
+                                        public void uncaughtException(Thread t, Throwable e) {
+                                           // Ignore
+                                        }
+                                    });
+                                return thread;
+                            }
+                        });
+
     private ConscryptStatsLog() {}
 
     public static void write(int atomId, boolean success, int protocol, int cipherSuite,
             int duration, Source source, int[] uids) {
-        ReflexiveStatsEvent event = ReflexiveStatsEvent.buildEvent(
-                atomId, success, protocol, cipherSuite, duration, source.ordinal(), uids);
+        e.execute(new Runnable() {
+            @Override
+            public void run() {
+                ReflexiveStatsEvent event = ReflexiveStatsEvent.buildEvent(
+                        atomId, success, protocol, cipherSuite, duration,
+                        source.ordinal(), uids);
 
-        ReflexiveStatsLog.write(event);
+                ReflexiveStatsLog.write(event);
+            }
+        });
     }
 }
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ConscryptStatsLog.java b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ConscryptStatsLog.java
index 8a7a8e5..2f93e5a 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ConscryptStatsLog.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ConscryptStatsLog.java
@@ -17,6 +17,13 @@
 package com.android.org.conscrypt.metrics;
 
 import com.android.org.conscrypt.Internal;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.lang.Thread.UncaughtExceptionHandler;
 
 /**
  * Reimplement with reflection calls the logging class,
@@ -37,13 +44,36 @@
 public final class ConscryptStatsLog {
     public static final int TLS_HANDSHAKE_REPORTED = 317;
 
+    private static final ExecutorService e =
+        Executors.newSingleThreadExecutor(
+                        new ThreadFactory() {
+                            @Override
+                            public Thread newThread(Runnable r) {
+                                Thread thread = new Thread(r);
+                                thread.setUncaughtExceptionHandler(
+                                    new UncaughtExceptionHandler() {
+                                        @Override
+                                        public void uncaughtException(Thread t, Throwable e) {
+                                           // Ignore
+                                        }
+                                    });
+                                return thread;
+                            }
+                        });
+
     private ConscryptStatsLog() {}
 
     public static void write(int atomId, boolean success, int protocol, int cipherSuite,
             int duration, Source source, int[] uids) {
-        ReflexiveStatsEvent event = ReflexiveStatsEvent.buildEvent(
-                atomId, success, protocol, cipherSuite, duration, source.ordinal(), uids);
+      e.execute(new Runnable() {
+            @Override
+            public void run() {
+                ReflexiveStatsEvent event = ReflexiveStatsEvent.buildEvent(
+                        atomId, success, protocol, cipherSuite, duration,
+                        source.ordinal(), uids);
 
-        ReflexiveStatsLog.write(event);
+                ReflexiveStatsLog.write(event);
+            }
+        });
     }
 }