Merge "persist ringbuffer to flash when vendor hal stops" into pi-dev
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();