增加内存管理接口
authorCaisking <Casiking@zhihuishixun.com>
Wed, 24 Sep 2025 08:51:04 +0000 (16:51 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Wed, 24 Sep 2025 08:51:04 +0000 (16:51 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/system/include/MemoryManager.h [new file with mode: 0644]
code/sdk/application/wearable/ln/nativeapp/nativeui/system/src/MemoryManager.cpp [new file with mode: 0644]

diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/system/include/MemoryManager.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/system/include/MemoryManager.h
new file mode 100644 (file)
index 0000000..01d4a94
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * @Author: Assistant
+ * @Date: 2024-12-19
+ * @Description: Memory Manager - 内存管理模块,用于OTA和表情文件下载时的内存检查
+ */
+#ifndef MEMORY_MANAGER_H
+#define MEMORY_MANAGER_H
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace OHOS
+{
+    /*
+        4个文件夹
+        默认文件:user/res/
+        系统文件:user/system/
+        用户数据:user/userdata/
+        更新文件:user/update/
+    */
+    #define DEFAULT_RES_PATH "/user/res/"
+    #define DEFAULT_SYSTEM_PATH "/user/system/"
+    #define DEFAULT_USERDATA_PATH "/user/userdata/"
+    #define DEFAULT_UPDATE_PATH "/user/update/"
+    
+    /**
+     * @brief 内存管理类
+     * @details 用于OTA和表情文件下载时的内存检查和管理
+     */
+    class MemoryManager
+    {
+    public:
+        /**
+         * @brief 获取MemoryManager单例实例
+         * @return MemoryManager* 单例实例指针
+         */
+        static MemoryManager *GetInstance();
+        
+        /**
+         * @brief 检查是否可以下载文件
+         * @param path 目标路径
+         * @param downloadSize 下载文件大小(字节)
+         * @param requiredFreeSpace 额外需要的空闲空间(字节),默认为0
+         * @return bool true-可以下载,false-空间不足
+         */
+        bool CanDownloadFile(const std::string &path, uint64_t downloadSize, uint64_t requiredFreeSpace = 0);
+        
+        /**
+         * @brief 检查系统内存是否充足
+         * @param requiredSize 需要的空间大小(字节)
+         * @return bool true-内存充足,false-内存不足
+         */
+        bool IsMemorySufficient(uint64_t requiredSize);
+        
+        /**
+         * @brief 获取指定路径的可用内存
+         * @param path 路径,默认为"/user/"
+         * @return uint64_t 可用内存大小(字节)
+         */
+        uint64_t GetAvailableMemory(const std::string &path = "/user/");
+        
+        /**
+         * @brief 获取文件夹大小
+         * @param folderPath 文件夹路径
+         * @return uint64_t 文件夹大小(字节)
+         */
+        uint64_t GetFolderSize(const char *folderPath);
+        
+        /**
+         * @brief 获取系统内存信息字符串
+         * @return std::string 格式化的内存信息字符串
+         */
+        std::string GetSystemMemoryInfo();
+        
+        /**
+         * @brief 获取系统总内存
+         * @return uint64_t 总内存大小(字节)
+         */
+        uint64_t GetTotalMemory();
+        
+        /**
+         * @brief 获取系统已用内存
+         * @return uint64_t 已用内存大小(字节)
+         */
+        uint64_t GetUsedMemory();
+        
+        /**
+         * @brief 获取系统剩余内存
+         * @return uint64_t 剩余内存大小(字节)
+         */
+        uint64_t GetFreeMemory();
+        
+        /**
+         * @brief 检查指定路径的内存是否充足
+         * @param path 路径
+         * @param requiredSize 需要的空间大小(字节)
+         * @return bool true-内存充足,false-内存不足
+         */
+        bool CheckPathMemory(const std::string &path, uint64_t requiredSize);
+        
+        /**
+         * @brief 获取内存清理建议
+         * @return std::string 清理建议字符串
+         */
+        std::string GetMemoryCleanupSuggestions();
+        
+    private:
+        /**
+         * @brief 构造函数(私有)
+         */
+        MemoryManager();
+        
+        /**
+         * @brief 析构函数(私有)
+         */
+        virtual ~MemoryManager();
+        
+        /**
+         * @brief 禁用拷贝构造函数
+         */
+        MemoryManager(const MemoryManager &) = delete;
+        
+        /**
+         * @brief 禁用赋值操作符
+         */
+        MemoryManager &operator=(const MemoryManager &) = delete;
+        
+        /**
+         * @brief 递归计算文件夹大小
+         * @param folderPath 文件夹路径
+         * @return uint64_t 文件夹大小(字节)
+         */
+        uint64_t CalculateFolderSize(const char *folderPath);
+        
+        /**
+         * @brief 获取文件系统信息
+         * @param path 路径
+         * @param totalSize 输出总大小(字节)
+         * @param freeSize 输出剩余大小(字节)
+         * @param usedSize 输出已用大小(字节)
+         * @return bool true-成功,false-失败
+         */
+        bool GetFileSystemInfo(const std::string &path, uint64_t &totalSize, uint64_t &freeSize, uint64_t &usedSize);
+        
+    };
+}
+
+#endif // MEMORY_MANAGER_H
diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/system/src/MemoryManager.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/system/src/MemoryManager.cpp
new file mode 100644 (file)
index 0000000..7f0f534
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * @Author: Assistant
+ * @Date: 2024-12-19
+ * @Description: Memory Manager - 内存管理模块实现
+ */
+#include "system/include/MemoryManager.h"
+#include "wearable_log.h"
+#include "custom_utils.h"
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <cstring>
+#include <sstream>
+#include <algorithm>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace OHOS
+{
+    static MemoryManager *g_pMemoryManager = nullptr;
+
+    /**
+     * @brief 构造函数
+     * @details 初始化MemoryManager实例,设置全局指针
+     */
+    MemoryManager::MemoryManager()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MemoryManager::MemoryManager");
+        g_pMemoryManager = this;
+    }
+
+    /**
+     * @brief 析构函数
+     * @details 清理资源,重置全局指针
+     */
+    MemoryManager::~MemoryManager()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MemoryManager::~MemoryManager");
+        g_pMemoryManager = nullptr;
+    }
+
+    /**
+     * @brief 获取MemoryManager单例实例
+     * @return MemoryManager* 单例实例指针
+     */
+    MemoryManager *MemoryManager::GetInstance()
+    {
+        if (g_pMemoryManager == nullptr) {
+            g_pMemoryManager = new MemoryManager();
+        }
+        return g_pMemoryManager;
+    }
+
+    /**
+     * @brief 检查是否可以下载文件
+     * @param path 目标路径
+     * @param downloadSize 下载文件大小(字节)
+     * @param requiredFreeSpace 额外需要的空闲空间(字节),默认为0
+     * @return bool true-可以下载,false-空间不足
+     */
+    bool MemoryManager::CanDownloadFile(const std::string &path, uint64_t downloadSize, uint64_t requiredFreeSpace)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MemoryManager::CanDownloadFile: path=%s, downloadSize=%llu, requiredFreeSpace=%llu", 
+                      path.c_str(), downloadSize, requiredFreeSpace);
+        
+        // 获取目标路径的已用空间
+        uint64_t usedSpace = GetFolderSize(path.c_str());
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Current used space: %llu bytes", usedSpace);
+        
+        // 计算总需求空间
+        uint64_t totalRequired = usedSpace + downloadSize + requiredFreeSpace;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Total required space: %llu bytes", totalRequired);
+        
+        // 获取文件系统信息
+        uint64_t totalSize, freeSize, usedSize;
+        if (!GetFileSystemInfo(path, totalSize, freeSize, usedSize)) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get filesystem info for path: %s", path.c_str());
+            return false;
+        }
+        
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Filesystem info - Total: %llu, Free: %llu, Used: %llu", 
+                      totalSize, freeSize, usedSize);
+        
+        // 检查是否有足够空间
+        bool hasEnoughSpace = (freeSize >= downloadSize + requiredFreeSpace);
+        
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Memory check result: %s", hasEnoughSpace ? "SUFFICIENT" : "INSUFFICIENT");
+        
+        return hasEnoughSpace;
+    }
+
+
+
+    /**
+     * @brief 获取指定路径的可用内存
+     * @param path 路径
+     * @return uint64_t 可用内存大小(字节)
+     */
+    uint64_t MemoryManager::GetAvailableMemory(const std::string &path)
+    {
+        uint64_t totalSize, freeSize, usedSize;
+        if (GetFileSystemInfo(path, totalSize, freeSize, usedSize)) {
+            return freeSize;
+        }
+        return 0;
+    }
+
+    /**
+     * @brief 获取文件夹大小
+     * @param folderPath 文件夹路径
+     * @return uint64_t 文件夹大小(字节)
+     */
+    uint64_t MemoryManager::GetFolderSize(const char *folderPath)
+    {
+        return CalculateFolderSize(folderPath);
+    }
+
+    /**
+     * @brief 获取系统内存信息字符串
+     * @return std::string 格式化的内存信息字符串
+     */
+    std::string MemoryManager::GetSystemMemoryInfo()
+    {
+        std::stringstream result;
+        
+        // 获取文件系统信息(只显示一次)
+        uint64_t totalSize, freeSize, usedSize;
+        if (GetFileSystemInfo("/user/", totalSize, freeSize, usedSize)) {
+            result << "[User Root]" << std::endl;
+            result << "  Path: /user/" << std::endl;
+            result << "  Total: " << totalSize / 1024 << " KB (" << totalSize / (1024 * 1024) << " MB)" << std::endl;
+            result << "  Used:  " << usedSize / 1024 << " KB (" << usedSize / (1024 * 1024) << " MB)" << std::endl;
+            result << "  Free:  " << freeSize / 1024 << " KB (" << freeSize / (1024 * 1024) << " MB)" << std::endl;
+            result << "  Usage: " << (totalSize > 0 ? (double)usedSize * 100.0 / totalSize : 0.0) << "%" << std::endl;
+            result << "  ====================" << std::endl;
+        }
+        
+        // 获取各个目录的文件夹大小
+        std::vector<std::pair<std::string, std::string>> directories = {
+            {"/user/update/", "更新文件"},
+            {"/user/res/", "资源文件"},
+            {"/user/system/", "系统文件"},
+            {"/user/userdata/", "用户数据"}
+        };
+        
+        result << std::endl << "[Directory Usage]" << std::endl;
+        for (const auto &dir : directories) {
+            uint64_t folderSize = GetFolderSize(dir.first.c_str());
+            if (folderSize > 0) {
+                result << "  " << dir.second << ": " << folderSize / 1024 << " KB (" << folderSize / (1024 * 1024) << " MB)" << std::endl;
+            }
+        }
+        
+        return result.str().empty() ? "No memory information available." : result.str();
+    }
+
+    /**
+     * @brief 获取系统总内存
+     * @return uint64_t 总内存大小(字节)
+     */
+    uint64_t MemoryManager::GetTotalMemory()
+    {
+        uint64_t totalSize, freeSize, usedSize;
+        if (GetFileSystemInfo("/user/", totalSize, freeSize, usedSize)) {
+            return totalSize;
+        }
+        return 0;
+    }
+
+    /**
+     * @brief 获取系统已用内存
+     * @return uint64_t 已用内存大小(字节)
+     */
+    uint64_t MemoryManager::GetUsedMemory()
+    {
+        uint64_t totalSize, freeSize, usedSize;
+        if (GetFileSystemInfo("/user/", totalSize, freeSize, usedSize)) {
+            return usedSize;
+        }
+        return 0;
+    }
+
+    /**
+     * @brief 获取系统剩余内存
+     * @return uint64_t 剩余内存大小(字节)
+     */
+    uint64_t MemoryManager::GetFreeMemory()
+    {
+        return GetAvailableMemory("/user/");
+    }
+
+    /**
+     * @brief 检查指定路径的内存是否充足
+     * @param path 路径
+     * @param requiredSize 需要的空间大小(字节)
+     * @return bool true-内存充足,false-内存不足
+     */
+    bool MemoryManager::CheckPathMemory(const std::string &path, uint64_t requiredSize)
+    {
+        return CanDownloadFile(path, requiredSize, 0);
+    }
+
+    /**
+     * @brief 获取内存清理建议
+     * @return std::string 清理建议字符串
+     */
+    std::string MemoryManager::GetMemoryCleanupSuggestions()
+    {
+        std::stringstream suggestions;
+        
+        // 检查各个目录的使用情况
+        std::vector<std::pair<std::string, std::string>> directories = {
+            {"/user/music/", "音乐文件"},
+            {"/user/dial/", "表盘文件"},
+            {"/user/userdata/", "用户数据"},
+            {"/user/res/", "资源文件"}
+        };
+        
+        suggestions << "内存清理建议:" << std::endl;
+        
+        for (const auto &dir : directories) {
+            uint64_t size = GetFolderSize(dir.first.c_str());
+            if (size > 10 * 1024 * 1024) { // 大于10MB
+                suggestions << "- " << dir.second << "占用 " << size / 1024 / 1024 << "MB" << std::endl;
+            }
+        }
+        
+        return suggestions.str();
+    }
+
+    /**
+     * @brief 递归计算文件夹大小
+     * @param folderPath 文件夹路径
+     * @return uint64_t 文件夹大小(字节)
+     */
+    uint64_t MemoryManager::CalculateFolderSize(const char *folderPath)
+    {
+        DIR *dir;
+        struct dirent *entry;
+        struct stat fileStat;
+        uint64_t totalSize = 0;
+
+        dir = opendir(folderPath);
+        if (dir == NULL) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error opening directory: %s", folderPath);
+            return 0;
+        }
+
+        while ((entry = readdir(dir)) != NULL) {
+            char filePath[1024];
+            snprintf(filePath, sizeof(filePath), "%s/%s", folderPath, entry->d_name);
+
+            if (stat(filePath, &fileStat) == -1) {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error getting file status: %s", filePath);
+                continue;
+            }
+
+            if (S_ISDIR(fileStat.st_mode)) {
+                if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+                    continue;
+                }
+                totalSize += CalculateFolderSize(filePath);
+            } else {
+                totalSize += fileStat.st_size;
+            }
+        }
+
+        closedir(dir);
+        return totalSize;
+    }
+
+    /**
+     * @brief 获取文件系统信息
+     * @param path 路径
+     * @param totalSize 输出总大小(字节)
+     * @param freeSize 输出剩余大小(字节)
+     * @param usedSize 输出已用大小(字节)
+     * @return bool true-成功,false-失败
+     */
+    bool MemoryManager::GetFileSystemInfo(const std::string &path, uint64_t &totalSize, uint64_t &freeSize, uint64_t &usedSize)
+    {
+        struct statfs file_buf = {0};
+        
+        if (statfs(path.c_str(), &file_buf) != 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get filesystem info for: %s", path.c_str());
+            return false;
+        }
+        
+        totalSize = static_cast<uint64_t>(file_buf.f_blocks) * file_buf.f_bsize;
+        freeSize = static_cast<uint64_t>(file_buf.f_bfree) * file_buf.f_bsize;
+        usedSize = totalSize - freeSize;
+        
+        return true;
+    }
+}