diff --git a/BUILD.gn b/BUILD.gn index 884e744a09f7f85e7d3e2a85a40cfc2b5cc7f9ff..961577316ca7b14e1fff6de4e70a18c5e2adfeb6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -233,6 +233,7 @@ ohos_shared_library("usagestatservice") { "services/common/src/bundle_active_continuous_task_observer.cpp", "services/common/src/bundle_active_core.cpp", "services/common/src/bundle_active_debug_mode.cpp", + "services/common/src/bundle_active_event_reporter.cpp", "services/common/src/bundle_active_open_callback.cpp", "services/common/src/bundle_active_power_state_callback_service.cpp", "services/common/src/bundle_active_service.cpp", @@ -314,6 +315,7 @@ ohos_static_library("usagestatservice_static") { "services/common/src/bundle_active_continuous_task_observer.cpp", "services/common/src/bundle_active_core.cpp", "services/common/src/bundle_active_debug_mode.cpp", + "services/common/src/bundle_active_event_reporter.cpp", "services/common/src/bundle_active_open_callback.cpp", "services/common/src/bundle_active_power_state_callback_service.cpp", "services/common/src/bundle_active_service.cpp", diff --git a/services/common/include/bundle_active_config_reader.h b/services/common/include/bundle_active_config_reader.h index a320202146096c69b6ea50461590daae8bd44da0..23dc226de56d15afe1dbd359bf364b28852fbd49 100644 --- a/services/common/include/bundle_active_config_reader.h +++ b/services/common/include/bundle_active_config_reader.h @@ -29,11 +29,14 @@ class BundleActiveConfigReader { public: void LoadConfig(); AppUsePeriodicallyConfig GetApplicationUsePeriodicallyConfig(); + uint64_t GetMaxDataSize(); private: void LoadApplicationUsePeriodically(const char* path); bool GetJsonFromFile(const char* filePath, cJSON *&root); bool ConvertFullPath(const std::string& partialPath, std::string& fullPath); + void LoadMaxDataSize(const char *filePath); AppUsePeriodicallyConfig appUsePeriodicallyConfig_; + uint64_t maxDataSize_ = 0; }; } // namespace DeviceUsageStats diff --git a/services/common/include/bundle_active_constant.h b/services/common/include/bundle_active_constant.h index 6276a4d4ed202d83e7669e0914b6c40deb4fdd98..b26848d38e4088d3ff140cfcabe43f8d3b321b7f 100644 --- a/services/common/include/bundle_active_constant.h +++ b/services/common/include/bundle_active_constant.h @@ -80,6 +80,7 @@ const int32_t FORM_LAST_TIME_COLUMN_INDEX = 7; const int32_t FORM_UID_COLUMN_INDEX = 8; const int32_t QUERY_CONDITION_VALID = 0; const int32_t QUERY_CONDITION_INVALID = -1; +const int32_t DEFAULT_DELETE_EVENT_DALIYS = 0; const uint32_t BUNDLE_ACTIVE_DB_NAME_MAX_LENGTH = 100; const int64_t TWO_SECONDS = 2 * 1000LL; const int64_t TEN_MINUTES = 10 * 60 * 1000LL; diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h index 3c5f46a3690e784082b31f1db04f81a352ae66fa..64bbe3d4b273ff57969f7d1dc690e341cf57ca86 100644 --- a/services/common/include/bundle_active_core.h +++ b/services/common/include/bundle_active_core.h @@ -249,11 +249,15 @@ private: void OnObserverDiedInner(const wptr &remote); void AddbundleUninstalledUid(const int32_t uid); void DelayRemoveBundleUninstalledUid(const int32_t uid); + bool IsUserSpaceMemoryLimit(); + void ProcessDataSize(); + bool IsFolderSizeLimit(); + void DeleteExcessiveTableData(); int64_t flushInterval_; static const int64_t TIME_CHANGE_THRESHOLD_MILLIS = TEN_MINUTES; const int32_t DEFAULT_USER_ID = -1; std::map visibleActivities_; - + double percentUserSpaceLimit_ = 0; int64_t systemTimeShot_; int64_t realTimeShot_; ffrt::mutex mutex_; diff --git a/services/common/include/bundle_active_event_reporter.h b/services/common/include/bundle_active_event_reporter.h new file mode 100644 index 0000000000000000000000000000000000000000..75217d91ac1adc1394c8284865196143c2ee447d --- /dev/null +++ b/services/common/include/bundle_active_event_reporter.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef BUNDLE_ACTIVE_EVENT_REPORTER_H +#define BUNDLE_ACTIVE_EVENT_REPORTER_H + +#include +#include +#include +#include + +#include "ffrt.h" +#include "single_instance.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveEventReporter { + DECLARE_SINGLE_INSTANCE(BundleActiveEventReporter); +public: + + /** + * @brief report file size event,the files must in path '/data'. + * + */ + void ReportFileSizeEvent(); +private: + void SubmitDelayTask(int64_t delayTime); + void ReportFileSizeDaily(); + void ReportFileSizeInner(); + + std::unordered_set allFilePaths_; + ffrt::mutex mutex_; + bool isTaskSubmit_ = false; + std::string fileSizeRecorderName_; + int64_t lastReportTime_ = -1; +}; +} // namespace DeviceUsageStats +} // namespace OHOS + +#endif // BUNDLE_ACTIVE_EVENT_REPORTER_H \ No newline at end of file diff --git a/services/common/include/bundle_active_usage_database.h b/services/common/include/bundle_active_usage_database.h index b1439717c7fcd17d763beccf03ff02c69694ff97..b0f429f01fdc8735a24fa1109d602b127eebdaf6 100644 --- a/services/common/include/bundle_active_usage_database.h +++ b/services/common/include/bundle_active_usage_database.h @@ -80,6 +80,7 @@ public: std::map& eventStats, int32_t userId); void QueryNotificationEventStats(int32_t eventId, int64_t beginTime, int64_t endTime, std::map& notificationEventStats, int32_t userId); + void DeleteExcessiveEventTableData(int32_t deleteDays); private: void CheckDatabaseVersion(); diff --git a/services/common/src/bundle_active_config_reader.cpp b/services/common/src/bundle_active_config_reader.cpp index fe13125f54cd97647ff4c19b7af9ab8320a81521..16777ef32468f21aad129561fa9441172bc7686b 100644 --- a/services/common/src/bundle_active_config_reader.cpp +++ b/services/common/src/bundle_active_config_reader.cpp @@ -26,10 +26,12 @@ const static char* APPLICATION_USE_PERIODICALLY_KEY = "application_use_periodica const static char* MIN_USE_TIMES = "MinUseTimes"; const static char* MAX_USE_TIMES = "MaxUseTimes"; const static char* MIN_USE_DAYS = "MinUseDays"; +const static char* MAX_DATA_SIZE = "MaxDataSize"; const int32_t DEFAULT_MIN_USE_TIMES = 1; const int32_t DEFAULT_MAX_USE_TIMES = 10; const int32_t DEFAULT_MIN_USE_DAYS = 3; const int32_t MAX_BUFFER = 2048; +const uint64_t DEFAULT_MAX_DATA_SIZE = 5 * 1024 * 1024; void BundleActiveConfigReader::LoadConfig() @@ -42,10 +44,12 @@ void BundleActiveConfigReader::LoadConfig() } for (const auto& filePath : cfgFiles->paths) { LoadApplicationUsePeriodically(filePath); + LoadMaxDataSize(filePath); } BUNDLE_ACTIVE_LOGI("appUsePeriodicallyConfig minUseTimes:%{public}d, maxUseTimes:%{public}d," - "minUseDays:%{public}d", appUsePeriodicallyConfig_.minUseTimes, - appUsePeriodicallyConfig_.maxUseTimes, appUsePeriodicallyConfig_.minUseDays); + "minUseDays:%{public}d maxDataSize:%{public}lu", appUsePeriodicallyConfig_.minUseTimes, + appUsePeriodicallyConfig_.maxUseTimes, appUsePeriodicallyConfig_.minUseDays, + static_cast(maxDataSize_)); FreeCfgFiles(cfgFiles); }; @@ -132,5 +136,33 @@ AppUsePeriodicallyConfig BundleActiveConfigReader::GetApplicationUsePeriodically return appUsePeriodicallyConfig_; }; +void BundleActiveConfigReader::LoadMaxDataSize(const char *filePath) +{ + if (!filePath) { + return; + } + cJSON *root = nullptr; + if (!GetJsonFromFile(filePath, root) || !root) { + BUNDLE_ACTIVE_LOGE("file is empty %{private}s", filePath); + return; + } + cJSON *maxDataSizeItem = cJSON_GetObjectItem(root, MAX_DATA_SIZE); + if (!maxDataSizeItem || !cJSON_IsNumber(maxDataSizeItem)) { + BUNDLE_ACTIVE_LOGE("not have max data size key"); + cJSON_Delete(root); + return; + } + maxDataSize_ = static_cast(maxDataSizeItem->valueint); + cJSON_Delete(root); +}; + +uint64_t BundleActiveConfigReader::GetMaxDataSize() +{ + if (maxDataSize_ == 0) { + return DEFAULT_MAX_DATA_SIZE; + } + return maxDataSize_; +}; + } // namespace DeviceUsageStats } // namespace OHOS \ No newline at end of file diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp index b04f42a21cf17b8c667d33ce783f0b2ca391807a..e31432ea25d5aa605e5c718cfba77a3d5837ccd4 100644 --- a/services/common/src/bundle_active_core.cpp +++ b/services/common/src/bundle_active_core.cpp @@ -28,6 +28,7 @@ #include "bundle_constants.h" #include "hisysevent.h" #include "bundle_active_report_controller.h" +#include "bundle_active_event_reporter.h" namespace OHOS { namespace DeviceUsageStats { @@ -36,7 +37,11 @@ const int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no #endif // OS_ACCOUNT_PART_ENABLED constexpr int32_t BUNDLE_UNINSTALL_DELAY_TIME = 5 * 1000 * 1000; constexpr int32_t MIN_USER_ID = -1; +constexpr int32_t MAX_DELETE_EVENT_DALIYS = 6; +constexpr double DEFAULT_PERCENT_USER_SPACE_LIMIT = 0.1; static constexpr char RSS[] = "RSS"; +static constexpr char FILEMANAGEMENT[] = "FILEMANAGEMENT"; +static constexpr char DATA_PATH[] = "/data"; BundleActiveReportHandlerObject::BundleActiveReportHandlerObject() { @@ -71,6 +76,7 @@ BundleActiveCore::BundleActiveCore() flushInterval_ = THIRTY_MINUTE; debugCore_ = false; } + percentUserSpaceLimit_ = DEFAULT_PERCENT_USER_SPACE_LIMIT; } BundleActiveCore::~BundleActiveCore() @@ -254,6 +260,7 @@ void BundleActiveCore::Init() BUNDLE_ACTIVE_LOGD("system time shot is %{public}lld", (long long)systemTimeShot_); bundleActiveConfigReader_ = std::make_shared(); bundleActiveConfigReader_->LoadConfig(); + BundleActiveEventReporter::GetInstance().ReportFileSizeEvent(); } void BundleActiveCore::InitBundleGroupController() @@ -397,6 +404,10 @@ void BundleActiveCore::RestoreAllData() void BundleActiveCore::RestoreToDatabase(const int32_t userId) { + if (IsUserSpaceMemoryLimit()) { + BUNDLE_ACTIVE_LOGE("The available memory in user space is too low and is not on the disk"); + return; + } BUNDLE_ACTIVE_LOGD("RestoreToDatabase called"); BundleActiveEvent event; event.eventId_ = BundleActiveEvent::FLUSH; @@ -407,6 +418,13 @@ void BundleActiveCore::RestoreToDatabase(const int32_t userId) it->second->ReportEvent(event); } RestoreToDatabaseLocked(userId); + std::shared_ptr bundleActiveCore = shared_from_this(); + ffrt::submit([bundleActiveCore]() { + if (bundleActiveCore == nullptr) { + return; + } + bundleActiveCore->ProcessDataSize(); + }); } void BundleActiveCore::RestoreToDatabaseLocked(const int32_t userId) @@ -973,6 +991,41 @@ void BundleActiveCore::OnObserverDiedInner(const wptr &remote) } recipientMap_.erase(objectProxy); } + +bool BundleActiveCore::IsUserSpaceMemoryLimit() +{ + return BundleActiveUtil::GetPercentOfAvailableUserSpace(DATA_PATH) <= percentUserSpaceLimit_; +} + +void BundleActiveCore::ProcessDataSize() +{ + if (!bundleActiveConfigReader_ || !IsFolderSizeLimit()) { + return; + } + DeleteExcessiveTableData(); +} + +bool BundleActiveCore::IsFolderSizeLimit() +{ + return BundleActiveUtil::GetFolderOrFileSize(BUNDLE_ACTIVE_DATABASE_DIR) >= + bundleActiveConfigReader_->GetMaxDataSize(); +} + +void BundleActiveCore::DeleteExcessiveTableData() +{ + std::lock_guard lock(mutex_); + auto it = userStatServices_.find(currentUsedUser_); + if (it == userStatServices_.end()) { + BUNDLE_ACTIVE_LOGE("currentUsedUser_ is not exit, delete exceeive table data failed"); + return; + } + for (int32_t deleteDays = DEFAULT_DELETE_EVENT_DALIYS; deleteDays <= MAX_DELETE_EVENT_DALIYS; deleteDays++) { + it->second->DeleteExcessiveEventTableData(deleteDays); + if (!IsFolderSizeLimit()) { + return; + } + } +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_event_reporter.cpp b/services/common/src/bundle_active_event_reporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63853d6b0346fd5e181cdf3deb8a14ec73007e7a --- /dev/null +++ b/services/common/src/bundle_active_event_reporter.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +#include "bundle_active_event_reporter.h" +#include "file_ex.h" +#include "hisysevent.h" +#include "bundle_active_log.h" +#include "bundle_active_util.h" +#include "bundle_active_constant.h" + + +namespace OHOS { +namespace DeviceUsageStats { +namespace { +static const int64_t FIRST_REPORT_TIME = 10 * 1000 * 1000; +static const int64_t ONE_DAY_MICRO_SECOND = static_cast(24) * 60 * 60 * 1000 * 1000; +static const char* DATA_FILE_PATH = "/data"; +static const char* FILE_SIZE_REPORTER_RECORDER = "/data/service/el1/public/bundle_usage/file_size_report_time"; +} + +IMPLEMENT_SINGLE_INSTANCE(BundleActiveEventReporter); + +void BundleActiveEventReporter::ReportFileSizeEvent() +{ + std::lock_guard autoLock(mutex_); + if (!isTaskSubmit_) { + fileSizeRecorderName_ = std::string(FILE_SIZE_REPORTER_RECORDER); + SubmitDelayTask(FIRST_REPORT_TIME); + isTaskSubmit_ = true; + } +} + +void BundleActiveEventReporter::SubmitDelayTask(int64_t delayTime) +{ + ffrt::submit([]() { + BundleActiveEventReporter::GetInstance().ReportFileSizeDaily(); + }, ffrt::task_attr().delay(delayTime)); +} + +void BundleActiveEventReporter::ReportFileSizeDaily() +{ + std::string lastReportTime; + LoadStringFromFile(fileSizeRecorderName_, lastReportTime); + if (lastReportTime.empty()) { + ReportFileSizeInner(); + } else { + int64_t lastReportTimeValue = BundleActiveUtil::StringToInt64(lastReportTime); + if (lastReportTimeValue <= 0) { + ReportFileSizeInner(); + } else { + int64_t nowTime = BundleActiveUtil::GetSteadyTime(); + if (nowTime - lastReportTimeValue < ONE_DAY_MICRO_SECOND) { + int64_t nextReportTime = ONE_DAY_MICRO_SECOND - (nowTime - lastReportTimeValue); + SubmitDelayTask(nextReportTime); + } else { + ReportFileSizeInner(); + } + } + } +} + +void BundleActiveEventReporter::ReportFileSizeInner() +{ + BUNDLE_ACTIVE_LOGI("ReportFileSizeInner call"); + std::lock_guard autoLock(mutex_); + std::vector filesPath; + std::vector filesPathSize; + filesPath.emplace_back(BUNDLE_ACTIVE_DATABASE_DIR); + filesPathSize.emplace_back(BundleActiveUtil::GetFolderOrFileSize(BUNDLE_ACTIVE_DATABASE_DIR)); + double remainSize = BundleActiveUtil::GetDeviceValidSize(DATA_FILE_PATH); + HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT, "USER_DATA_SIZE", + HiviewDFX::HiSysEvent::EventType::STATISTIC, + "COMPONENT_NAME", "device_usage_statistics", + "PARTITION_NAME", DATA_FILE_PATH, + "REMAIN_PARTITION_SIZE", remainSize, + "FILE_OR_FOLDER_PATH", filesPath, + "FILE_OR_FOLDER_SIZE", filesPathSize); + int64_t nowMicroTime = BundleActiveUtil::GetNowMicroTime(); + SaveStringToFile(fileSizeRecorderName_, std::to_string(nowMicroTime)); + SubmitDelayTask(ONE_DAY_MICRO_SECOND); +} +} // namespace ResourceSchedule +} // namespace OHOS \ No newline at end of file diff --git a/services/common/src/bundle_active_usage_database.cpp b/services/common/src/bundle_active_usage_database.cpp index e8c4e778eb816258c184160cefa03f0d083d73de..68950e1f9748b914fef5e11ebf864fa8115fb7c6 100644 --- a/services/common/src/bundle_active_usage_database.cpp +++ b/services/common/src/bundle_active_usage_database.cpp @@ -1904,5 +1904,30 @@ int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime, } return QUERY_CONDITION_VALID; } + +void BundleActiveUsageDatabase::DeleteExcessiveEventTableData(int32_t deleteDays) +{ + lock_guard lock(databaseMutex_); + // 删除多余event表数据 + if ((eventTableName_ == UNKNOWN_TABLE_NAME) || (eventBeginTime_ == EVENT_BEGIN_TIME_INITIAL_VALUE)) { + return; + } + int64_t eventTableTime = ParseStartTime(eventTableName_); + int64_t deleteTimePoint = eventBeginTime_ - (SIX_DAY_IN_MILLIS_MAX - deleteDays * ONE_DAY_TIME) - eventTableTime; + if (deleteTimePoint <= 0) { + return; + } + shared_ptr rdbStore = GetBundleActiveRdbStore(EVENT_DATABASE_INDEX); + if (rdbStore == nullptr) { + BUNDLE_ACTIVE_LOGE("delete excessive tableData fail, rdbStore is nullptr"); + return; + } + string deleteEventDataSql = "delete from " + eventTableName_ + " where timeStamp <= " + + to_string(deleteTimePoint); + int32_t deleteResult = rdbStore->ExecuteSql(deleteEventDataSql); + if (deleteResult != NativeRdb::E_OK) { + BUNDLE_ACTIVE_LOGE("delete event data failed, rdb error number: %{public}d", deleteResult); + } +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packageusage/include/bundle_active_report_handler.h b/services/packageusage/include/bundle_active_report_handler.h index 0956833269cb1473b5f5880d908a24e5706b60aa..bae6532c8295e84a8e4f9f1f1f186b8697c389db 100644 --- a/services/packageusage/include/bundle_active_report_handler.h +++ b/services/packageusage/include/bundle_active_report_handler.h @@ -42,6 +42,7 @@ public: bool HasEvent(const int32_t& eventId); void Init(const std::shared_ptr& bundleActiveCore); void DeInit(); + static const int32_t MSG_REPORT_EVENT; static const int32_t MSG_FLUSH_TO_DISK; static const int32_t MSG_REMOVE_USER; diff --git a/services/packageusage/include/bundle_active_user_service.h b/services/packageusage/include/bundle_active_user_service.h index 299f1c4adc3a202d2335282185e79480f4f31a1c..7fe18d932fc210e0637631f03ffd5d102e845d30 100644 --- a/services/packageusage/include/bundle_active_user_service.h +++ b/services/packageusage/include/bundle_active_user_service.h @@ -77,6 +77,7 @@ public: std::vector& eventStats, int32_t userId); void LoadActiveStats(const int64_t timeStamp, const bool& force, const bool& timeChanged); void LoadModuleAndFormStats(); + void DeleteExcessiveEventTableData(int32_t deleteDays); private: static const int64_t ONE_SECOND_MILLISECONDS = 1000; diff --git a/services/packageusage/src/bundle_active_user_service.cpp b/services/packageusage/src/bundle_active_user_service.cpp index 672549c95747b520bc04ca314e33f5cf1f6d22e3..2333d013159d0b257b6b07e1faba8a276a8061ad 100644 --- a/services/packageusage/src/bundle_active_user_service.cpp +++ b/services/packageusage/src/bundle_active_user_service.cpp @@ -746,5 +746,13 @@ std::shared_ptr BundleActiveUserService::GetOrCreateMo } return moduleRecords_[combinedInfo]; } + +void BundleActiveUserService::DeleteExcessiveEventTableData(int32_t deleteDays) +{ + if (deleteDays < 0) { + return; + } + database_.DeleteExcessiveEventTableData(deleteDays); +} } // namespace DeviceUsageStats } // namespace OHOS \ No newline at end of file diff --git a/test/resource/deviceUsage/deviceUsageConfig.xml b/test/resource/deviceUsage/deviceUsageConfig.xml index 2dacadb0ee22ee5a03baee42aaf3061cd45f245f..b24a502963632cc7dc3874657c1561a6073ebef0 100644 --- a/test/resource/deviceUsage/deviceUsageConfig.xml +++ b/test/resource/deviceUsage/deviceUsageConfig.xml @@ -20,6 +20,13 @@