[statsd] Added placeholder for handling atom ids in use

- SocketLogEventControl will be handling atom ids in use list
  population for sharing with clients

Flag: EXEMPT refactoring
Bug: 407064406
Test: atest statsd_test
Change-Id: If06729eab1e5766b10769702a71c1d62c62b6212
diff --git a/statsd/src/StatsService.cpp b/statsd/src/StatsService.cpp
index 6227d2f..651d898 100644
--- a/statsd/src/StatsService.cpp
+++ b/statsd/src/StatsService.cpp
@@ -163,13 +163,15 @@
                   }
               })),
       mEventQueue(queue),
-      mLogEventFilter(logEventFilter),
       mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag},
                            [this]() { onStatsdInitCompleted(kStatsdInitDelaySecs); }),
       mStatsCompanionServiceDeathRecipient(
               AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)),
-      mAtomsInUseChangeDispatcher(std::make_shared<AtomsInUseChangeDispatcher>()) {
+      mAtomsInUseChangeDispatcher(std::make_shared<AtomsInUseChangeDispatcher>()),
+      mLogEventFilter(logEventFilter),
+      mSocketLogEventControl(std::make_shared<SocketLogEventControl>()) {
     mAtomsInUseChangeDispatcher->addListener(mLogEventFilter);
+    mAtomsInUseChangeDispatcher->addListener(mSocketLogEventControl);
     mPullerManager = new StatsPullerManager();
     StatsPuller::SetUidMap(mUidMap);
     mConfigManager = new ConfigManager();
@@ -970,6 +972,7 @@
     // Turning on print logs turns off pushed event filtering to enforce
     // complete log event buffer parsing
     mLogEventFilter->setFilteringEnabled(!enabled);
+    mSocketLogEventControl->setControlEnabled(!enabled);
     return NO_ERROR;
 }
 
@@ -1148,6 +1151,9 @@
     }
 
     mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs());
+    // to not stress I/O subsystem reasonable to postpone atom ids file creation and avoid
+    // high volume read file requests from many apps which will log their first atom
+    mSocketLogEventControl->setControlEnabled(true);
 }
 
 void StatsService::Startup() {
@@ -1166,6 +1172,9 @@
             pthread_setname_np(mLogsReaderThread->native_handle(), "statsd.reader");
         }
     }
+
+    // Enable the filter now since configs are initialized.
+    mLogEventFilter->setFilteringEnabled(true);
 }
 
 void StatsService::Terminate() {
diff --git a/statsd/src/StatsService.h b/statsd/src/StatsService.h
index 464c8d5..1dca891 100644
--- a/statsd/src/StatsService.h
+++ b/statsd/src/StatsService.h
@@ -34,6 +34,7 @@
 #include "logd/LogEventQueue.h"
 #include "packages/UidMap.h"
 #include "shell/ShellSubscriber.h"
+#include "socket/SocketLogEventControl.h"
 #include "statscompanion_util.h"
 #include "utils/MultiConditionTrigger.h"
 
@@ -465,7 +466,6 @@
      */
     mutable std::mutex mShellSubscriberMutex;
     std::shared_ptr<LogEventQueue> mEventQueue;
-    std::shared_ptr<LogEventFilter> mLogEventFilter;
 
     std::unique_ptr<std::thread> mLogsReaderThread;
 
@@ -485,6 +485,8 @@
     ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient;
 
     std::shared_ptr<AtomsInUseChangeDispatcher> mAtomsInUseChangeDispatcher;
+    std::shared_ptr<LogEventFilter> mLogEventFilter;
+    std::shared_ptr<SocketLogEventControl> mSocketLogEventControl;
 
     friend class StatsServiceConfigTest;
     friend class RestrictedConfigE2ETest;
diff --git a/statsd/src/main.cpp b/statsd/src/main.cpp
index b42414a..d87d900 100644
--- a/statsd/src/main.cpp
+++ b/statsd/src/main.cpp
@@ -138,9 +138,6 @@
 
     gStatsService->Startup();
 
-    // Enable the filter now since configs are initialized.
-    logEventFilter->setFilteringEnabled(true);
-
     // Use self-pipe to notify this thread to gracefully quit
     // when receiving SIGTERM
     registerSignalHandlers();
diff --git a/statsd/src/shell/ShellSubscriberClient.h b/statsd/src/shell/ShellSubscriberClient.h
index 05240f6..0890330 100644
--- a/statsd/src/shell/ShellSubscriberClient.h
+++ b/statsd/src/shell/ShellSubscriberClient.h
@@ -28,7 +28,7 @@
 #include "external/StatsPullerManager.h"
 #include "logd/LogEvent.h"
 #include "packages/UidMap.h"
-#include "socket/LogEventFilter.h"
+#include "socket/AtomsInUseChangeListener.h"
 #include "src/shell/shell_config.pb.h"
 #include "src/statsd_config.pb.h"
 
diff --git a/statsd/src/socket/AtomsInUseChangeListener.h b/statsd/src/socket/AtomsInUseChangeListener.h
index 71d896d..bef0c0e 100644
--- a/statsd/src/socket/AtomsInUseChangeListener.h
+++ b/statsd/src/socket/AtomsInUseChangeListener.h
@@ -40,6 +40,9 @@
     virtual void setAtomIds(AtomIdSet tagIds, ConsumerId consumer) = 0;
 };
 
+/**
+ * Propagates changes in atoms ids to its listeners
+ */
 class AtomsInUseChangeDispatcher : public AtomsInUseChangeListener {
 public:
     void setAtomIds(AtomIdSet tagIds, ConsumerId consumer) override {
diff --git a/statsd/src/socket/LogEventFilter.h b/statsd/src/socket/LogEventFilter.h
index 98cab0e..40fdc4f 100644
--- a/statsd/src/socket/LogEventFilter.h
+++ b/statsd/src/socket/LogEventFilter.h
@@ -21,7 +21,6 @@
 #include <atomic>
 #include <cstdint>
 #include <mutex>
-#include <unordered_set>
 
 #include "LogEventFilterUtils.h"
 #include "socket/AtomsInUseChangeListener.h"
diff --git a/statsd/src/socket/SocketLogEventControl.h b/statsd/src/socket/SocketLogEventControl.h
new file mode 100644
index 0000000..b9a8515
--- /dev/null
+++ b/statsd/src/socket/SocketLogEventControl.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2025 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 <com_android_os_statsd_flags.h>
+#include <gtest/gtest_prod.h>
+
+#include <mutex>
+
+#include "LogEventFilterUtils.h"
+#include "socket/AtomsInUseChangeListener.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+namespace flags = com::android::os::statsd::flags;
+
+/**
+ * Configures socket logging control based on list af atom ids in use
+ */
+class SocketLogEventControl : public AtomsInUseChangeListener {
+public:
+    virtual ~SocketLogEventControl() = default;
+
+    void setControlEnabled(bool isEnabled) {
+        if (!isActive()) {
+            return;
+        }
+
+        if (isEnabled) {
+            std::lock_guard lock(mTagIdsMutex);
+            setLoggingConfig(mAtomIdSetManager.getAtomIds());
+        } else {
+            // to allow clients to log any atom
+            resetConfig();
+        }
+    }
+
+    void setAtomIds(AtomIdSet tagIds, ConsumerId consumer) override {
+        if (!isActive()) {
+            return;
+        }
+
+        std::lock_guard lock(mTagIdsMutex);
+        mAtomIdSetManager.setAtomIds(tagIds, consumer);
+        setLoggingConfig(mAtomIdSetManager.getAtomIds());
+    }
+
+private:
+    mutable std::mutex mTagIdsMutex;
+    mutable AtomIdSetManager mAtomIdSetManager;
+
+    void setLoggingConfig(const AtomIdSet& atomsInUse) {
+        // TODO (b/407064406): sets system property & creates atom list file
+    }
+
+    void resetConfig() {
+        // TODO: resets system property & removes atom list file
+    }
+
+    static bool isActive() {
+        static const bool featureActive = isAtLeastB() && flags::logging_control_enabled();
+        return featureActive;
+    }
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/statsd/src/stats_util.h b/statsd/src/stats_util.h
index 89fbc36..db179bb 100644
--- a/statsd/src/stats_util.h
+++ b/statsd/src/stats_util.h
@@ -61,6 +61,11 @@
     return isAtLeastU;
 }
 
+inline bool isAtLeastB() {
+    const static bool isAtLeastB = android::modules::sdklevel::IsAtLeastB();
+    return isAtLeastB;
+}
+
 inline bool shouldKeepRandomSample(int samplingPercentage) {
     return (rand() % (100) + 1) <= samplingPercentage;
 }