logd: separate PruneList from LogBuffer

logd needs a pointer to PruneList, but it should not own it and it
should not have initPrune() or formatPrune() functions.

Test: logging unit tests
Change-Id: Id1668c26d07eb5d1e4cf267f5748c20a79f711ae
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 4b94086..4044dc9 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -39,8 +39,8 @@
 #include "LogCommand.h"
 #include "LogUtils.h"
 
-CommandListener::CommandListener(LogBuffer* buf, LogTags* tags)
-    : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags) {
+CommandListener::CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune)
+    : FrameworkListener(getLogSocket()), buf_(buf), tags_(tags), prune_(prune) {
     registerCmd(new ClearCmd(this));
     registerCmd(new GetBufSizeCmd(this));
     registerCmd(new SetBufSizeCmd(this));
@@ -216,7 +216,7 @@
 int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli,
                                                  int /*argc*/, char** /*argv*/) {
     setname();
-    cli->sendMsg(PackageString(buf()->formatPrune()).c_str());
+    cli->sendMsg(PackageString(prune()->format()).c_str());
     return 0;
 }
 
@@ -236,7 +236,7 @@
         str += argv[i];
     }
 
-    int ret = buf()->initPrune(str.c_str());
+    int ret = prune()->init(str.c_str());
 
     if (ret) {
         cli->sendMsg("Invalid");
@@ -299,7 +299,7 @@
 
     android::prdebug("logd reinit");
     buf()->init();
-    buf()->initPrune(nullptr);
+    prune()->init(nullptr);
 
     // This only works on userdebug and eng devices to re-read the
     // /data/misc/logd/event-log-tags file right after /data is mounted.
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
index c50ab6e..c90c247 100644
--- a/logd/CommandListener.h
+++ b/logd/CommandListener.h
@@ -23,10 +23,11 @@
 #include "LogListener.h"
 #include "LogReader.h"
 #include "LogTags.h"
+#include "LogWhiteBlackList.h"
 
 class CommandListener : public FrameworkListener {
   public:
-    CommandListener(LogBuffer* buf, LogTags* tags);
+    CommandListener(LogBuffer* buf, LogTags* tags, PruneList* prune);
     virtual ~CommandListener() {}
 
   private:
@@ -34,6 +35,7 @@
 
     LogBuffer* buf_;
     LogTags* tags_;
+    PruneList* prune_;
 
 #define LogCmd(name, command_string)                            \
     class name##Cmd : public LogCommand {                       \
@@ -46,6 +48,7 @@
       private:                                                  \
         LogBuffer* buf() const { return parent_->buf_; }        \
         LogTags* tags() const { return parent_->tags_; }        \
+        PruneList* prune() const { return parent_->prune_; }    \
         CommandListener* parent_;                               \
     }
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 7e1bb0a..5c8a5f0 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -105,8 +105,11 @@
     LogTimeEntry::unlock();
 }
 
-LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags)
-    : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times), tags_(tags) {
+LogBuffer::LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune)
+    : monotonic(android_log_clockid() == CLOCK_MONOTONIC),
+      mTimes(*times),
+      tags_(tags),
+      prune_(prune) {
     pthread_rwlock_init(&mLogElementsLock, nullptr);
 
     log_id_for_each(i) {
@@ -694,7 +697,7 @@
     }
 
     // prune by worst offenders; by blacklist, UID, and by PID of system UID
-    bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty();
+    bool hasBlacklist = (id != LOG_ID_SECURITY) && prune_->naughty();
     while (!clearAll && (pruneRows > 0)) {
         // recalculate the worst offender on every batched pass
         int worst = -1;  // not valid for getUid() or getKey()
@@ -702,7 +705,7 @@
         size_t second_worst_sizes = 0;
         pid_t worstPid = 0;  // POSIX guarantees PID != 0
 
-        if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
+        if (worstUidEnabledForLogid(id) && prune_->worstUidEnabled()) {
             // Calculate threshold as 12.5% of available storage
             size_t threshold = log_buffer_size(id) / 8;
 
@@ -716,7 +719,7 @@
                     .findWorst(worst, worst_sizes, second_worst_sizes,
                                threshold);
 
-                if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) {
+                if ((worst == AID_SYSTEM) && prune_->worstPidOfSystemEnabled()) {
                     stats.sortPids(worst, (pid_t)0, 2, id)
                         .findWorst(worstPid, worst_sizes, second_worst_sizes);
                 }
@@ -798,7 +801,7 @@
                           ? element->getTag()
                           : element->getUid();
 
-            if (hasBlacklist && mPrune.naughty(element)) {
+            if (hasBlacklist && prune_->naughty(element)) {
                 last.clear(element);
                 it = erase(it);
                 if (dropped) {
@@ -895,13 +898,13 @@
         }
         last.clear();
 
-        if (!kick || !mPrune.worstUidEnabled()) {
+        if (!kick || !prune_->worstUidEnabled()) {
             break;  // the following loop will ask bad clients to skip/drop
         }
     }
 
     bool whitelist = false;
-    bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll;
+    bool hasWhitelist = (id != LOG_ID_SECURITY) && prune_->nice() && !clearAll;
     it = GetOldest(id);
     while ((pruneRows > 0) && (it != mLogElements.end())) {
         LogBufferElement* element = *it;
@@ -917,7 +920,7 @@
             break;
         }
 
-        if (hasWhitelist && !element->getDropped() && mPrune.nice(element)) {
+        if (hasWhitelist && !element->getDropped() && prune_->nice(element)) {
             // WhiteListed
             whitelist = true;
             it++;
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index b8e64d0..cf93c23 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -80,7 +80,6 @@
 
     LogStatistics stats;
 
-    PruneList mPrune;
     // Keeps track of the iterator to the oldest log message of a given log type, as an
     // optimization when pruning logs.  Use GetOldest() to retrieve.
     std::optional<LogBufferElementCollection::iterator> mOldest[LOG_ID_MAX];
@@ -104,7 +103,7 @@
    public:
     LastLogTimes& mTimes;
 
-    LogBuffer(LastLogTimes* times, LogTags* tags);
+    LogBuffer(LastLogTimes* times, LogTags* tags, PruneList* prune);
     ~LogBuffer();
     void init();
     bool isMonotonic() {
@@ -133,13 +132,6 @@
         stats.enableStatistics();
     }
 
-    int initPrune(const char* cp) {
-        return mPrune.init(cp);
-    }
-    std::string formatPrune() {
-        return mPrune.format();
-    }
-
     // helper must be protected directly or implicitly by wrlock()/unlock()
     const char* pidToName(pid_t pid) {
         return stats.pidToName(pid);
@@ -174,4 +166,5 @@
     LogBufferElementCollection::iterator GetOldest(log_id_t log_id);
 
     LogTags* tags_;
+    PruneList* prune_;
 };
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
index fa23dcc..14c5163 100644
--- a/logd/fuzz/log_buffer_log_fuzzer.cpp
+++ b/logd/fuzz/log_buffer_log_fuzzer.cpp
@@ -95,12 +95,13 @@
 
     LastLogTimes times;
     LogTags tags;
-    LogBuffer log_buffer(&times, &tags);
+    PruneList prune_list;
+    LogBuffer log_buffer(&times, &tags, &prune_list);
     size_t data_left = size;
     const uint8_t** pdata = &data;
 
     log_buffer.enableStatistics();
-    log_buffer.initPrune(nullptr);
+    prune_list.init(nullptr);
     // We want to get pruning code to get called.
     log_id_for_each(i) { log_buffer.setSize(i, 10000); }
 
diff --git a/logd/main.cpp b/logd/main.cpp
index c4750ec..cc45eb3 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -289,6 +289,8 @@
 
     // A cache of event log tags
     LogTags log_tags;
+    // Pruning configuration.
+    PruneList prune_list;
 
     // Serves the purpose of managing the last logs times read on a
     // socket connection, and as a reader lock on a range of log
@@ -299,7 +301,7 @@
     // LogBuffer is the object which is responsible for holding all
     // log entries.
 
-    LogBuffer* logBuf = new LogBuffer(times, &log_tags);
+    LogBuffer* logBuf = new LogBuffer(times, &log_tags, &prune_list);
 
     if (__android_logger_property_get_bool(
             "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
@@ -329,7 +331,7 @@
     // Command listener listens on /dev/socket/logd for incoming logd
     // administrative commands.
 
-    CommandListener* cl = new CommandListener(logBuf, &log_tags);
+    CommandListener* cl = new CommandListener(logBuf, &log_tags, &prune_list);
     if (cl->startListener()) {
         return EXIT_FAILURE;
     }