Merge changes I8a31ad3a,I8b385d51,I3fdcdc33,Ia4571cd3 am: bc4e9cb94e am: f9ba055853
am: 3fc9ed681c

Change-Id: I9437b272298b0b27bfd65b0c3cbb0abf0aa6be9c
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 8a63007..c40c5ef 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -15,7 +15,6 @@
 //
 
 liblog_sources = [
-    "config_write.cpp",
     "log_event_list.cpp",
     "log_event_write.cpp",
     "logger_lock.cpp",
diff --git a/liblog/README.md b/liblog/README.md
index 98bee9f..871399a 100644
--- a/liblog/README.md
+++ b/liblog/README.md
@@ -96,11 +96,6 @@
 
     int android_log_destroy(android_log_context *ctx)
 
-    #include <log/log_transport.h>
-
-    int android_set_log_transport(int transport_flag)
-    int android_get_log_transport()
-
 Description
 -----------
 
@@ -144,11 +139,6 @@
 that was used when opening the sub-log.  It is recommended to open the log `ANDROID_LOG_RDONLY` in
 these cases.
 
-`android_set_log_transport()` selects transport filters.  Argument is either `LOGGER_DEFAULT`,
-`LOGGER_LOGD`, or `LOGGER_NULL`. Log to logger daemon for default or logd, or drop contents on floor
-respectively.  `Both android_set_log_transport()` and `android_get_log_transport()` return the
-current transport mask, or a negative errno for any problems.
-
 Errors
 ------
 
diff --git a/liblog/config_write.cpp b/liblog/config_write.cpp
deleted file mode 100644
index 6ed893d..0000000
--- a/liblog/config_write.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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 <log/log_transport.h>
-
-#include "config_write.h"
-#include "logger.h"
-
-struct listnode __android_log_transport_write = {&__android_log_transport_write,
-                                                 &__android_log_transport_write};
-struct listnode __android_log_persist_write = {&__android_log_persist_write,
-                                               &__android_log_persist_write};
-
-static void __android_log_add_transport(struct listnode* list,
-                                        struct android_log_transport_write* transport) {
-  uint32_t i;
-
-  /* Try to keep one functioning transport for each log buffer id */
-  for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
-    struct android_log_transport_write* transp;
-
-    if (list_empty(list)) {
-      if (!transport->available || ((*transport->available)(static_cast<log_id_t>(i)) >= 0)) {
-        list_add_tail(list, &transport->node);
-        return;
-      }
-    } else {
-      write_transport_for_each(transp, list) {
-        if (!transp->available) {
-          return;
-        }
-        if (((*transp->available)(static_cast<log_id_t>(i)) < 0) &&
-            (!transport->available || ((*transport->available)(static_cast<log_id_t>(i)) >= 0))) {
-          list_add_tail(list, &transport->node);
-          return;
-        }
-      }
-    }
-  }
-}
-
-void __android_log_config_write() {
-  if ((__android_log_transport == LOGGER_DEFAULT) || (__android_log_transport & LOGGER_LOGD)) {
-#if (FAKE_LOG_DEVICE == 0)
-    extern struct android_log_transport_write logdLoggerWrite;
-    extern struct android_log_transport_write pmsgLoggerWrite;
-
-    __android_log_add_transport(&__android_log_transport_write, &logdLoggerWrite);
-    __android_log_add_transport(&__android_log_persist_write, &pmsgLoggerWrite);
-#else
-    extern struct android_log_transport_write fakeLoggerWrite;
-
-    __android_log_add_transport(&__android_log_transport_write, &fakeLoggerWrite);
-#endif
-  }
-}
-
-void __android_log_config_write_close() {
-  struct android_log_transport_write* transport;
-  struct listnode* n;
-
-  write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
-    transport->logMask = 0;
-    list_remove(&transport->node);
-  }
-  write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
-    transport->logMask = 0;
-    list_remove(&transport->node);
-  }
-}
diff --git a/liblog/config_write.h b/liblog/config_write.h
deleted file mode 100644
index a901f13..0000000
--- a/liblog/config_write.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#pragma once
-
-#include <cutils/list.h>
-
-#include "log_portability.h"
-
-__BEGIN_DECLS
-
-extern struct listnode __android_log_transport_write;
-extern struct listnode __android_log_persist_write;
-
-#define write_transport_for_each(transp, transports)                           \
-  for ((transp) = node_to_item((transports)->next,                             \
-                               struct android_log_transport_write, node);      \
-       ((transp) != node_to_item((transports),                                 \
-                                 struct android_log_transport_write, node)) && \
-       ((transp) != node_to_item((transp)->node.next,                          \
-                                 struct android_log_transport_write, node));   \
-       (transp) = node_to_item((transp)->node.next,                            \
-                               struct android_log_transport_write, node))
-
-#define write_transport_for_each_safe(transp, n, transports)                   \
-  for ((transp) = node_to_item((transports)->next,                             \
-                               struct android_log_transport_write, node),      \
-      (n) = (transp)->node.next;                                               \
-       ((transp) != node_to_item((transports),                                 \
-                                 struct android_log_transport_write, node)) && \
-       ((transp) !=                                                            \
-        node_to_item((n), struct android_log_transport_write, node));          \
-       (transp) = node_to_item((n), struct android_log_transport_write, node), \
-      (n) = (transp)->node.next)
-
-void __android_log_config_write();
-void __android_log_config_write_close();
-
-__END_DECLS
diff --git a/liblog/fake_writer.cpp b/liblog/fake_writer.cpp
index c0b0e69..4d07caa 100644
--- a/liblog/fake_writer.cpp
+++ b/liblog/fake_writer.cpp
@@ -20,7 +20,6 @@
 
 #include <log/log.h>
 
-#include "config_write.h"
 #include "fake_log_device.h"
 #include "log_portability.h"
 #include "logger.h"
@@ -32,9 +31,9 @@
 static int logFds[(int)LOG_ID_MAX] = {-1, -1, -1, -1, -1, -1};
 
 struct android_log_transport_write fakeLoggerWrite = {
-    .node = {&fakeLoggerWrite.node, &fakeLoggerWrite.node},
-    .context.priv = &logFds,
     .name = "fake",
+    .logMask = 0,
+    .context.priv = &logFds,
     .available = NULL,
     .open = fakeOpen,
     .close = fakeClose,
diff --git a/liblog/include/log/log_transport.h b/liblog/include/log/log_transport.h
deleted file mode 100644
index bda7c25..0000000
--- a/liblog/include/log/log_transport.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-**
-** Copyright 2017, The Android Open Source Project
-**
-** This file is dual licensed.  It may be redistributed and/or modified
-** under the terms of the Apache 2.0 License OR version 2 of the GNU
-** General Public License.
-*/
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Logging transports, bit mask to select features. Function returns selection.
- */
-/* clang-format off */
-#define LOGGER_DEFAULT 0x00
-#define LOGGER_LOGD    0x01
-#define LOGGER_KERNEL  0x02 /* Reserved/Deprecated */
-#define LOGGER_NULL    0x04 /* Does not release resources of other selections */
-#define LOGGER_RESERVED 0x08 /* Reserved, previously for logging to local memory */
-#define LOGGER_RESERVED2  0x10 /* Reserved, previously for logs sent to stderr */
-/* clang-format on */
-
-/* Both return the selected transport flag mask, or negative errno */
-int android_set_log_transport(int transport_flag);
-int android_get_log_transport();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index d5bf844..e372dce 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -66,7 +66,6 @@
                             struct android_log_transport_context* transp, char* buf, size_t len);
 
 struct android_log_transport_read logdLoggerRead = {
-    .node = {&logdLoggerRead.node, &logdLoggerRead.node},
     .name = "logd",
     .available = logdAvailable,
     .version = logdVersion,
diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp
index 2c64b0b..09aaffb 100644
--- a/liblog/logd_writer.cpp
+++ b/liblog/logd_writer.cpp
@@ -34,7 +34,6 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
@@ -48,9 +47,9 @@
 static int logdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
 
 struct android_log_transport_write logdLoggerWrite = {
-    .node = {&logdLoggerWrite.node, &logdLoggerWrite.node},
-    .context.sock = -EBADF,
     .name = "logd",
+    .logMask = 0,
+    .context.sock = -EBADF,
     .available = logdAvailable,
     .open = logdOpen,
     .close = logdClose,
diff --git a/liblog/logger.h b/liblog/logger.h
index 4b4ef5f..8cae66c 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -31,12 +31,9 @@
   void* priv;
   atomic_int sock;
   atomic_int fd;
-  struct listnode* node;
-  atomic_uintptr_t atomic_pointer;
 };
 
 struct android_log_transport_write {
-  struct listnode node;
   const char* name;                  /* human name to describe the transport */
   unsigned logMask;                  /* mask cache of available() success */
   union android_log_context_union context; /* Initialized by static allocation */
@@ -54,7 +51,6 @@
 struct android_log_logger;
 
 struct android_log_transport_read {
-  struct listnode node;
   const char* name; /* human name to describe the transport */
 
   /* Does not cause resources to be taken */
@@ -149,6 +145,4 @@
 int __android_log_trylock();
 void __android_log_unlock();
 
-extern int __android_log_transport;
-
 __END_DECLS
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index 7fc8747..abcead7 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -25,17 +25,18 @@
 #endif
 
 #include <log/event_tag_map.h>
-#include <log/log_transport.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
 
 #define LOG_BUF_SIZE 1024
 
+android_log_transport_write* android_log_write = nullptr;
+android_log_transport_write* android_log_persist_write = nullptr;
+
 static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
 static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
 
@@ -105,7 +106,6 @@
  * Release any logger resources. A new log write will immediately re-acquire.
  */
 void __android_log_close() {
-  struct android_log_transport_write* transport;
 #if defined(__ANDROID__)
   EventTagMap* m;
 #endif
@@ -124,19 +124,16 @@
    * disengenuous use of this function.
    */
 
-  write_transport_for_each(transport, &__android_log_persist_write) {
-    if (transport->close) {
-      (*transport->close)();
-    }
+  if (android_log_write != nullptr) {
+    android_log_write->close();
   }
 
-  write_transport_for_each(transport, &__android_log_transport_write) {
-    if (transport->close) {
-      (*transport->close)();
-    }
+  if (android_log_persist_write != nullptr) {
+    android_log_persist_write->close();
   }
 
-  __android_log_config_write_close();
+  android_log_write = nullptr;
+  android_log_persist_write = nullptr;
 
 #if defined(__ANDROID__)
   /*
@@ -161,52 +158,52 @@
 #endif
 }
 
+static bool transport_initialize(android_log_transport_write* transport) {
+  if (transport == nullptr) {
+    return false;
+  }
+
+  __android_log_cache_available(transport);
+  if (!transport->logMask) {
+    return false;
+  }
+
+  // TODO: Do we actually need to call close() if open() fails?
+  if (transport->open() < 0) {
+    transport->close();
+    return false;
+  }
+
+  return true;
+}
+
 /* log_init_lock assumed */
 static int __write_to_log_initialize() {
-  struct android_log_transport_write* transport;
-  struct listnode* n;
-  int i = 0, ret = 0;
+#if (FAKE_LOG_DEVICE == 0)
+  extern struct android_log_transport_write logdLoggerWrite;
+  extern struct android_log_transport_write pmsgLoggerWrite;
 
-  __android_log_config_write();
-  write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
-    __android_log_cache_available(transport);
-    if (!transport->logMask) {
-      list_remove(&transport->node);
-      continue;
-    }
-    if (!transport->open || ((*transport->open)() < 0)) {
-      if (transport->close) {
-        (*transport->close)();
-      }
-      list_remove(&transport->node);
-      continue;
-    }
-    ++ret;
-  }
-  write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
-    __android_log_cache_available(transport);
-    if (!transport->logMask) {
-      list_remove(&transport->node);
-      continue;
-    }
-    if (!transport->open || ((*transport->open)() < 0)) {
-      if (transport->close) {
-        (*transport->close)();
-      }
-      list_remove(&transport->node);
-      continue;
-    }
-    ++i;
-  }
-  if (!ret && !i) {
+  android_log_write = &logdLoggerWrite;
+  android_log_persist_write = &pmsgLoggerWrite;
+#else
+  extern struct android_log_transport_write fakeLoggerWrite;
+
+  android_log_write = &fakeLoggerWrite;
+#endif
+
+  if (!transport_initialize(android_log_write)) {
+    android_log_write = nullptr;
     return -ENODEV;
   }
 
-  return ret;
+  if (!transport_initialize(android_log_persist_write)) {
+    android_log_persist_write = nullptr;
+  }
+
+  return 1;
 }
 
 static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
-  struct android_log_transport_write* node;
   int ret, save_errno;
   struct timespec ts;
   size_t len, i;
@@ -283,28 +280,11 @@
       return -EPERM;
     }
   } else {
-    /* Validate the incoming tag, tag content can not split across iovec */
-    char prio = ANDROID_LOG_VERBOSE;
-    const char* tag = static_cast<const char*>(vec[0].iov_base);
-    size_t len = vec[0].iov_len;
-    if (!tag) {
-      len = 0;
-    }
-    if (len > 0) {
-      prio = *tag;
-      if (len > 1) {
-        --len;
-        ++tag;
-      } else {
-        len = vec[1].iov_len;
-        tag = ((const char*)vec[1].iov_base);
-        if (!tag) {
-          len = 0;
-        }
-      }
-    }
+    int prio = *static_cast<int*>(vec[0].iov_base);
+    const char* tag = static_cast<const char*>(vec[1].iov_base);
+    size_t len = vec[1].iov_len;
     /* tag must be nul terminated */
-    if (tag && strnlen(tag, len) >= len) {
+    if (strnlen(tag, len) >= len) {
       tag = NULL;
     }
 
@@ -325,20 +305,17 @@
 
   ret = 0;
   i = 1 << log_id;
-  write_transport_for_each(node, &__android_log_transport_write) {
-    if (node->logMask & i) {
-      ssize_t retval;
-      retval = (*node->write)(log_id, &ts, vec, nr);
-      if (ret >= 0) {
-        ret = retval;
-      }
+
+  if (android_log_write != nullptr && (android_log_write->logMask & i)) {
+    ssize_t retval;
+    retval = android_log_write->write(log_id, &ts, vec, nr);
+    if (ret >= 0) {
+      ret = retval;
     }
   }
 
-  write_transport_for_each(node, &__android_log_persist_write) {
-    if (node->logMask & i) {
-      (void)(*node->write)(log_id, &ts, vec, nr);
-    }
+  if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
+    android_log_persist_write->write(log_id, &ts, vec, nr);
   }
 
   errno = save_errno;
@@ -354,9 +331,6 @@
     ret = __write_to_log_initialize();
     if (ret < 0) {
       __android_log_unlock();
-      if (!list_empty(&__android_log_persist_write)) {
-        __write_to_log_daemon(log_id, vec, nr);
-      }
       errno = save_errno;
       return ret;
     }
@@ -546,81 +520,3 @@
 
   return write_to_log(LOG_ID_SECURITY, vec, 4);
 }
-
-static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) {
-  size_t len, i;
-
-  if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
-    return -EINVAL;
-  }
-
-  for (len = i = 0; i < nr; ++i) {
-    len += vec[i].iov_len;
-  }
-  if (!len) {
-    return -EINVAL;
-  }
-  return len;
-}
-
-/* Following functions need access to our internal write_to_log status */
-
-int __android_log_transport;
-
-int android_set_log_transport(int transport_flag) {
-  int retval;
-
-  if (transport_flag < 0) {
-    return -EINVAL;
-  }
-
-  retval = LOGGER_NULL;
-
-  __android_log_lock();
-
-  if (transport_flag & LOGGER_NULL) {
-    write_to_log = __write_to_log_null;
-
-    __android_log_unlock();
-
-    return retval;
-  }
-
-  __android_log_transport &= LOGGER_LOGD;
-
-  transport_flag &= LOGGER_LOGD;
-
-  if (__android_log_transport != transport_flag) {
-    __android_log_transport = transport_flag;
-    __android_log_config_write_close();
-
-    write_to_log = __write_to_log_init;
-    /* generically we only expect these two values for write_to_log */
-  } else if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
-    write_to_log = __write_to_log_init;
-  }
-
-  retval = __android_log_transport;
-
-  __android_log_unlock();
-
-  return retval;
-}
-
-int android_get_log_transport() {
-  int ret = LOGGER_DEFAULT;
-
-  __android_log_lock();
-  if (write_to_log == __write_to_log_null) {
-    ret = LOGGER_NULL;
-  } else {
-    __android_log_transport &= LOGGER_LOGD;
-    ret = __android_log_transport;
-    if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
-      ret = -EINVAL;
-    }
-  }
-  __android_log_unlock();
-
-  return ret;
-}
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index 005fec8..2db45a1 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -37,7 +37,6 @@
                      struct android_log_transport_context* transp);
 
 struct android_log_transport_read pmsgLoggerRead = {
-    .node = {&pmsgLoggerRead.node, &pmsgLoggerRead.node},
     .name = "pmsg",
     .available = pmsgAvailable,
     .version = pmsgVersion,
diff --git a/liblog/pmsg_writer.cpp b/liblog/pmsg_writer.cpp
index 69720ed..f74fd4c 100644
--- a/liblog/pmsg_writer.cpp
+++ b/liblog/pmsg_writer.cpp
@@ -29,7 +29,6 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
@@ -40,9 +39,9 @@
 static int pmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
 
 struct android_log_transport_write pmsgLoggerWrite = {
-    .node = {&pmsgLoggerWrite.node, &pmsgLoggerWrite.node},
-    .context.fd = -1,
     .name = "pmsg",
+    .logMask = 0,
+    .context.fd = -1,
     .available = pmsgAvailable,
     .open = pmsgOpen,
     .close = pmsgClose,
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 7163743..4642b9b 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -29,7 +29,6 @@
 #include <benchmark/benchmark.h>
 #include <cutils/sockets.h>
 #include <log/event_tag_map.h>
-#include <log/log_transport.h>
 #include <private/android_logger.h>
 
 BENCHMARK_MAIN();
@@ -73,21 +72,6 @@
 }
 BENCHMARK(BM_log_maximum);
 
-static void set_log_null() {
-  android_set_log_transport(LOGGER_NULL);
-}
-
-static void set_log_default() {
-  android_set_log_transport(LOGGER_DEFAULT);
-}
-
-static void BM_log_maximum_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_maximum(state);
-  set_log_default();
-}
-BENCHMARK(BM_log_maximum_null);
-
 /*
  *	Measure the time it takes to collect the time using
  * discrete acquisition (state.PauseTiming() to state.ResumeTiming())
@@ -618,13 +602,6 @@
 }
 BENCHMARK(BM_log_event_overhead_42);
 
-static void BM_log_event_overhead_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_event_overhead(state);
-  set_log_default();
-}
-BENCHMARK(BM_log_event_overhead_null);
-
 /*
  *	Measure the time it takes to submit the android event logging call
  * using discrete acquisition under very-light load (<1% CPU utilization).
@@ -639,15 +616,6 @@
 }
 BENCHMARK(BM_log_light_overhead);
 
-static void BM_log_light_overhead_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_light_overhead(state);
-  set_log_default();
-}
-// Default gets out of hand for this test, so we set a reasonable number of
-// iterations for a timely result.
-BENCHMARK(BM_log_light_overhead_null)->Iterations(500);
-
 static void caught_latency(int /*signum*/) {
   unsigned long long v = 0xDEADBEEFA55A5AA5ULL;
 
diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp
index ebf0b15..c7dd8e8 100644
--- a/liblog/tests/log_wrap_test.cpp
+++ b/liblog/tests/log_wrap_test.cpp
@@ -27,12 +27,9 @@
 #include <log/log_properties.h>
 #include <log/log_read.h>
 #include <log/log_time.h>
-#include <log/log_transport.h>
 
 #ifdef __ANDROID__
 static void read_with_wrap() {
-  android_set_log_transport(LOGGER_LOGD);
-
   // Read the last line in the log to get a starting timestamp. We're assuming
   // the log is not empty.
   const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;