persist ringbuffer to flash when vendor hal stops

Need to write ringbuffer to flash or else the data become lost.
Also added logic to make sure ringbuffer files over the max limit
get deleted.

Bug: 78025947
Test: compile
Manual test:
flash to device
connect to wifi network
toggle wifi off and observe that ringbuffer files are persisted
keep toggling until the number of files get over the max allowed amount
and verified that old files got deleted

Change-Id: I7d6cff81cf5400a79d1c93a1e12e72fd1a766dad
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index dcd0a3c..ab96ef1 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -48,6 +48,7 @@
 constexpr char kCpioMagic[] = "070701";
 constexpr size_t kMaxBufferSizeBytes = 1024 * 1024;
 constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60;
+constexpr uint32_t kMaxRingBufferFileNum = 20;
 constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
 
 template <typename Iface>
@@ -104,7 +105,9 @@
     return buffer.data();
 }
 
-// delete files older than a predefined time in the wifi tombstone dir
+// delete files that meet either conditions:
+// 1. older than a predefined time in the wifi tombstone dir.
+// 2. Files in excess to a predefined amount, starting from the oldest ones
 bool removeOldFilesInternal() {
     time_t now = time(0);
     const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
@@ -116,6 +119,7 @@
     unique_fd dir_auto_closer(dirfd(dir_dump));
     struct dirent* dp;
     bool success = true;
+    std::list<std::pair<const time_t, std::string>> valid_files;
     while ((dp = readdir(dir_dump))) {
         if (dp->d_type != DT_REG) {
             continue;
@@ -129,12 +133,23 @@
             success = false;
             continue;
         }
-        if (cur_file_stat.st_mtime >= delete_files_before) {
-            continue;
-        }
-        if (unlink(cur_file_path.c_str()) != 0) {
-            LOG(ERROR) << "Error deleting file " << strerror(errno);
-            success = false;
+        const time_t cur_file_time = cur_file_stat.st_mtime;
+        valid_files.push_back(
+            std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
+    }
+    valid_files.sort();  // sort the list of files by last modified time from
+                         // small to big.
+    uint32_t cur_file_count = valid_files.size();
+    for (auto cur_file : valid_files) {
+        if (cur_file_count > kMaxRingBufferFileNum ||
+            cur_file.first < delete_files_before) {
+            if (unlink(cur_file.second.c_str()) != 0) {
+                LOG(ERROR) << "Error deleting file " << strerror(errno);
+                success = false;
+            }
+            cur_file_count--;
+        } else {
+            break;
         }
     }
     return success;
@@ -309,6 +324,9 @@
 }
 
 void WifiChip::invalidate() {
+    if (!writeRingbufferFilesInternal()) {
+        LOG(ERROR) << "Error writing files to flash";
+    }
     invalidateAndRemoveAllIfaces();
     legacy_hal_.reset();
     event_cb_handler_.invalidate();