memevents: Create new API to verify listener state

Expose an API that allows the client to know whether or not the bpf ring
buffer manager was initialized correctly.

Test: atest memevents_test
Bug: 330393131
Change-Id: I69400486bfa942f446620bce3868b5a24bd8bf84
Signed-off-by: Carlos Galo <carlosgalo@google.com>
diff --git a/libmemevents/include/memevents/memevents.h b/libmemevents/include/memevents/memevents.h
index e17270c..9282ab9 100644
--- a/libmemevents/include/memevents/memevents.h
+++ b/libmemevents/include/memevents/memevents.h
@@ -47,10 +47,28 @@
 
 class MemEventListener final {
   public:
+    /*
+     * MemEventListener will `std::abort` when failing to initialize
+     * the bpf ring buffer manager, on a bpf-rb supported kernel.
+     *
+     * If running on a kernel that doesn't support bpf-rb, the listener
+     * will initialize in an invalid state, preventing it from making
+     * any actions/calls.
+     * To check if the listener initialized correctly use `ok()`.
+     */
     MemEventListener(MemEventClient client, bool attachTpForTests = false);
     ~MemEventListener();
 
     /**
+     * Check if the listener was initialized correctly, with a valid bpf
+     * ring buffer manager on a bpf-rb supported kernel.
+     *
+     * @return true if initialized with a valid bpf rb manager, false
+     * otherwise.
+     */
+    bool ok();
+
+    /**
      * Registers the requested memory event to the listener.
      *
      * @param event_type Memory event type to listen for.
diff --git a/libmemevents/memevents.cpp b/libmemevents/memevents.cpp
index eefbd46..db61612 100644
--- a/libmemevents/memevents.cpp
+++ b/libmemevents/memevents.cpp
@@ -43,6 +43,8 @@
 static const std::string kClientRingBuffers[MemEventClient::NR_CLIENTS] = {
         MEM_EVENTS_AMS_RB, MEM_EVENTS_LMKD_RB, MEM_EVENTS_TEST_RB};
 
+static const bool isBpfRingBufferSupported = isAtLeastKernelVersion(5, 8, 0);
+
 class MemBpfRingbuf : public BpfRingbufBase {
   public:
     using EventCallback = std::function<void(const mem_event_t&)>;
@@ -174,9 +176,14 @@
          * throughout the public APIs to prevent the listener to do any actions.
          */
         memBpfRb.reset(nullptr);
-        if (isAtLeastKernelVersion(5, 8, 0)) {
+        if (isBpfRingBufferSupported) {
             LOG(ERROR) << "memevent listener MemBpfRingbuf init failed: "
                        << status.error().message();
+            /*
+             * Do not perform an `std::abort()`, there are some AMS test suites inadvertently
+             * initialize a memlistener to resolve test dependencies. We don't expect it
+             * to succeed since the test doesn't have the correct permissions.
+             */
         } else {
             LOG(ERROR) << "memevent listener failed to initialize, not supported kernel";
         }
@@ -187,8 +194,12 @@
     deregisterAllEvents();
 }
 
+bool MemEventListener::ok() {
+    return isBpfRingBufferSupported && memBpfRb;
+}
+
 bool MemEventListener::registerEvent(mem_event_type_t event_type) {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent register failed, failure to initialize";
         return false;
     }
@@ -247,7 +258,7 @@
 }
 
 bool MemEventListener::listen(int timeout_ms) {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent listen failed, failure to initialize";
         return false;
     }
@@ -260,7 +271,7 @@
 }
 
 bool MemEventListener::deregisterEvent(mem_event_type_t event_type) {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent failed to deregister, failure to initialize";
         return false;
     }
@@ -301,7 +312,7 @@
 }
 
 void MemEventListener::deregisterAllEvents() {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent deregister all events failed, failure to initialize";
         return;
     }
@@ -312,7 +323,7 @@
 }
 
 bool MemEventListener::getMemEvents(std::vector<mem_event_t>& mem_events) {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent failed getting memory events, failure to initialize";
         return false;
     }
@@ -330,7 +341,7 @@
 }
 
 int MemEventListener::getRingBufferFd() {
-    if (!memBpfRb) {
+    if (!ok()) {
         LOG(ERROR) << "memevent failed getting ring-buffer fd, failure to initialize";
         return -1;
     }
diff --git a/libmemevents/memevents_test.cpp b/libmemevents/memevents_test.cpp
index 611912c..b846e38 100644
--- a/libmemevents/memevents_test.cpp
+++ b/libmemevents/memevents_test.cpp
@@ -69,6 +69,10 @@
         }
     }
 
+    void SetUp() override {
+        ASSERT_FALSE(memevent_listener.ok()) << "BPF ring buffer manager shouldn't initialize";
+    }
+
     void TearDown() override { memevent_listener.deregisterAllEvents(); }
 };
 
@@ -190,6 +194,11 @@
         }
     }
 
+    void SetUp() override {
+        ASSERT_TRUE(memevent_listener.ok())
+                << "Memory listener failed to initialize bpf ring buffer manager";
+    }
+
     void TearDown() override { memevent_listener.deregisterAllEvents(); }
 };
 
@@ -226,6 +235,7 @@
         listener = std::make_unique<MemEventListener>(client);
         ASSERT_TRUE(listener) << "MemEventListener failed to initialize with valid client value: "
                               << client;
+        ASSERT_TRUE(listener->ok()) << "MemEventListener failed to initialize with bpf rb manager";
     }
 }
 
@@ -396,6 +406,10 @@
         }
     }
 
+    void SetUp() override {
+        ASSERT_TRUE(mem_listener.ok()) << "Listener failed to initialize bpf rb manager";
+    }
+
     void TearDown() override { mem_listener.deregisterAllEvents(); }
 
     /*
@@ -587,6 +601,10 @@
   protected:
     MemEventListener mem_listener = MemEventListener(mem_test_client, true);
 
+    void SetUp() override {
+        ASSERT_TRUE(mem_listener.ok()) << "listener failed to initialize bpf ring buffer manager";
+    }
+
     void TearDown() override { mem_listener.deregisterAllEvents(); }
 
     /**