diff --git a/BUILD.gn b/BUILD.gn index 3ba65c5b4c6ac18ac1d23d579bf53a74692984ae..eb0eaf2535e3aa057ba213e30c801c924cd9a6b6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -234,6 +234,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", @@ -313,6 +314,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 1400e4efe278cf8dc51634d6ef75a507e5226024..28f97c0b221622fccbfd947e5f2504fc5761abdb 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(); + int32_t GetMaxDataSize(); private: void LoadApplicationUsePeriodically(const char* path); bool GetJsonFromFile(const char* filePath, Json::Value& root); bool ConvertFullPath(const std::string& partialPath, std::string& fullPath); + void LoadMaxDataSize(const char *filePath); AppUsePeriodicallyConfig appUsePeriodicallyConfig_; + int32_t maxDataSize_ = -1; }; } // namespace DeviceUsageStats diff --git a/services/common/include/bundle_active_constant.h b/services/common/include/bundle_active_constant.h index f4ee663ffe28230c38903f03016b680bdc78798b..1c1e651b7048391bc62bca10615bacabd051b305 100644 --- a/services/common/include/bundle_active_constant.h +++ b/services/common/include/bundle_active_constant.h @@ -78,6 +78,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 = 1; const uint32_t BUNDLE_ACTIVE_DB_NAME_MAX_LENGTH = 100; const int64_t TWO_SECONDS = 2 * 1000LL; const int64_t THIRTY_MINUTE = 30 * 60 * 1000LL; diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h index ca02dab5e53e268d03a5422a08e8222eebbe10ca..379a6673986286d8e78daba3ea5ebc975aa2d0d7 100644 --- a/services/common/include/bundle_active_core.h +++ b/services/common/include/bundle_active_core.h @@ -258,6 +258,10 @@ 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 = TWO_SECONDS; const int32_t DEFAULT_USER_ID = -1; 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..1bb58821863f6e68e61b2ea760afda6544cb165a --- /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(const std::vector& filePaths); +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 41123f45a36e259a46c80f2d5633dd3b9ae34734..8914e9a6e587cea32ce211aaecbd587f48cd5e29 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 13f93cfa2f9ceeee481bcab22bc908d4b4981b33..85cb52694201bd20cb1bf81d81e10ed28e8f03a8 100644 --- a/services/common/src/bundle_active_config_reader.cpp +++ b/services/common/src/bundle_active_config_reader.cpp @@ -27,9 +27,11 @@ const std::string APPLICATION_USE_PERIODICALLY_KEY = "application_use_periodical const std::string MIN_USE_TIMES = "MinUseTimes"; const std::string MAX_USE_TIMES = "MaxUseTimes"; const std::string MIN_USE_DAYS = "MinUseDays"; +const std::string MAX_DATA_SIZE = "max_data_size"; 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 DEFAULT_MAX_DATA_SIZE = 5 * 1024 * 1024; const int32_t MAX_BUFFER = 2048; @@ -43,6 +45,7 @@ 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, @@ -87,6 +90,28 @@ void BundleActiveConfigReader::LoadApplicationUsePeriodically(const char *filePa appUsePeriodicallyConfig_ = { minUseTimes, maxUseTimes, minUseDays}; }; +void BundleActiveConfigReader::LoadMaxDataSize(const char *filePath) +{ + if (!filePath) { + return; + } + Json::Value root; + if (!GetJsonFromFile(filePath, root) || root.empty()) { + BUNDLE_ACTIVE_LOGE("file is empty %{private}s", filePath); + return; + } + if (!root.isMember(MAX_DATA_SIZE)) { + BUNDLE_ACTIVE_LOGE("not have max_data_size key"); + return; + } + Json::Value maxDataSizeRoot = root[MAX_DATA_SIZE]; + if (maxDataSizeRoot.empty() || !maxDataSizeRoot.isInt()) { + BUNDLE_ACTIVE_LOGE("application_use_periodically content is empty"); + return; + } + int32_t maxDataSize_ = maxDataSizeRoot.asInt(); +}; + bool BundleActiveConfigReader::GetJsonFromFile(const char *filePath, Json::Value &root) { ifstream fin; @@ -137,6 +162,14 @@ AppUsePeriodicallyConfig BundleActiveConfigReader::GetApplicationUsePeriodically return appUsePeriodicallyConfig_; }; +int32_t BundleActiveConfigReader::GetMaxDataSize() +{ + if (maxDataSize_ <= -1) { + return DEFAULT_MAX_DATA_SIZE; + } + return maxDataSize_; +}; + } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp index 35f26779dc3cf26ce78b738267f90ec3c222c495..16e7457c4e4793cb9edb79ec9d2a81ef54399845 100644 --- a/services/common/src/bundle_active_core.cpp +++ b/services/common/src/bundle_active_core.cpp @@ -27,7 +27,7 @@ #include "ffrt_inner.h" #include "bundle_constants.h" #include "hisysevent.h" - +#include "bundle_active_event_reporter.h" namespace OHOS { namespace DeviceUsageStats { @@ -35,7 +35,11 @@ namespace DeviceUsageStats { const int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part #endif // OS_ACCOUNT_PART_ENABLED constexpr int32_t BUNDLE_UNINSTALL_DELAY_TIME = 5 * 1000 * 1000; +constexpr int32_t MAX_DELETE_EVENT_DALIYS = 6; +constexpr int32_t DEFALUT_PERCENT_USER_SPACE_LIMIT = 10; static constexpr char RSS[] = "RSS"; +static constexpr char FILEMANAGEMENT[] = "FILEMANAGEMENT"; +static constexpr char DATA_PATH[] = "/data"; BundleActiveReportHandlerObject::BundleActiveReportHandlerObject() { @@ -260,6 +264,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() @@ -414,6 +419,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; @@ -424,6 +433,10 @@ void BundleActiveCore::RestoreToDatabase(const int32_t userId) it->second->ReportEvent(event); } RestoreToDatabaseLocked(userId); + std::shared_ptr bundleActiveCore = shared_from_this(); + ffrt::submit([bundleActiveCore]() { + bundleActiveCore->ProcessDataSize(); + }); } void BundleActiveCore::RestoreToDatabaseLocked(const int32_t userId) @@ -988,6 +1001,39 @@ void BundleActiveCore::OnObserverDiedInner(const wptr &remote) } recipientMap_.erase(objectProxy); } + +bool BundleActiveCore::isUserSpaceMemoryLimit() +{ + return BundleActiveUtil::GetPercentOfAvaildUserSpace(DATA_PATH) <= DEFALUT_PERCENT_USER_SPACE_LIMIT; +} + +void BundleActiveCore::ProcessDataSize() +{ + if (!ISFolderSizeLimit()) { + return; + } + DeleteExcessiveTableData(); +} + +bool BundleActiveCore::ISFolderSizeLimit() +{ + return BundleActiveUtil::GetFloderOrFileSize(BUNDLE_ACTIVE_DATABASE_DIR) >= + bundleActiveConfigReader_->GetMaxDataSize(); +} + +void BundleActiveCore::DeleteExcessiveTableData() +{ + auto it = userStatServices_.find(currentUsedUser_); + if (it == userStatServices_.end()) { + BUNDLE_ACTIVE_LOGE("currentUsedUser_ is not exit, delete exceeive table data failed"); + } + 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..21d0dc77a12c1178473001d6745b368c8e6a5fbc --- /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::GetNowTime(); + 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::GetFloderOrFileSize(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::GetNowTime(); + 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 cf03ac8bdbd0f73124ba3344644e7c378ddeec9c..e2c30f3d51c73944dca1cc487887d59848c6bd06 100644 --- a/services/common/src/bundle_active_usage_database.cpp +++ b/services/common/src/bundle_active_usage_database.cpp @@ -321,31 +321,7 @@ void BundleActiveUsageDatabase::DeleteExcessiveTableData(uint32_t databaseType) "database type %{public}d", deleteNumber, databaseType); } } else if (databaseType == EVENT_DATABASE_INDEX) { - // 删除多余数据 - if ((eventTableName_ == UNKNOWN_TABLE_NAME) || (eventBeginTime_ == EVENT_BEGIN_TIME_INITIAL_VALUE)) { - return; - } - int64_t eventTableTime = ParseStartTime(eventTableName_); - int64_t deleteTimePoint = 0; - if (debugDatabase_) { - deleteTimePoint = eventBeginTime_ - SIX_DAY_IN_MILLIS_MAX_DEBUG - eventTableTime; - } else { - deleteTimePoint = eventBeginTime_ - SIX_DAY_IN_MILLIS_MAX - eventTableTime; - } - if (deleteTimePoint <= 0) { - return; - } - shared_ptr rdbStore = GetBundleActiveRdbStore(databaseType); - 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); - } + DeleteExcessiveEventTableData(DEFAULT_DELETE_EVENT_DALIYS); } else if (databaseType == APP_GROUP_DATABASE_INDEX) { // 无数据删除 } else { @@ -1985,6 +1961,37 @@ int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime, } return QUERY_CONDITION_VALID; } + +void BundleActiveUsageDatabase::DeleteExcessiveEventTableData(int32_t deleteDays) +{ + // 删除多余event表数据 + if ((eventTableName_ == UNKNOWN_TABLE_NAME) || (eventBeginTime_ == EVENT_BEGIN_TIME_INITIAL_VALUE)) { + return; + } + int64_t eventTableTime = ParseStartTime(eventTableName_); + int64_t deleteTimePoint = 0; + if (debugDatabase_) { + deleteTimePoint = eventBeginTime_ - + (SIX_DAY_IN_MILLIS_MAX_DEBUG - deleteDays * ONE_DAY_TIME_DEBUG) - eventTableTime; + } else { + 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_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..5de812ea8459fa0e58bb762af11216835f0c1f0f 100644 --- a/services/packageusage/src/bundle_active_user_service.cpp +++ b/services/packageusage/src/bundle_active_user_service.cpp @@ -746,5 +746,10 @@ std::shared_ptr BundleActiveUserService::GetOrCreateMo } return moduleRecords_[combinedInfo]; } + +void BundleActiveUserService::DeleteExcessiveEventTableData(int32_t deleteDays) +{ + database_.DeleteExcessiveEventTableData(deleteDays); +} } // namespace DeviceUsageStats } // namespace OHOS \ No newline at end of file diff --git a/utils/include/bundle_active_util.h b/utils/include/bundle_active_util.h index 67f3805957976f19cd4b9ee0dae0fa7e72212a85..d406474e87e691fec8abc0b1489fa098ef4e1175 100644 --- a/utils/include/bundle_active_util.h +++ b/utils/include/bundle_active_util.h @@ -32,6 +32,11 @@ public: static int64_t GetIntervalTypeStartTime(const int64_t& timeStamp, const int32_t& intervalType); static int32_t StringToInt32(const std::string& str); static int64_t StringToInt64(const std::string& str); + static int64_t GetNowTime(); + static uint64_t GetFloderOrFileSize(const std::string& path); + static double GetDeviceValidSize(const std::string& path); + static std::string GetPartitionName(const std::string& path); + static double GetPercentOfAvaildUserSpace(const std::string& path); }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/utils/src/bundle_active_util.cpp b/utils/src/bundle_active_util.cpp index 8bc74445d9a2a75ed4398e11985ef7366aaa042e..fd679c3312ba3029063378b21cac571d41b0d22f 100644 --- a/utils/src/bundle_active_util.cpp +++ b/utils/src/bundle_active_util.cpp @@ -16,13 +16,15 @@ #include #include #include "bundle_active_util.h" - +#include +#include +#include namespace OHOS { namespace DeviceUsageStats { const int32_t MILLISECOND_TO_MICROSECOND = 1000; const int32_t MILLISECOND_TO_SECOND = 1000; const int32_t SECOND_TO_MILLISECOND = 1000; -const int64_t ONE_DAY_TIME = 24 * 60 * 60 *1000LL; +const int64_t ONE_DAY_TIME = 24 * 60 * 60 * 1000LL; const int64_t WEEK_OFFSET = 6LL; const int64_t DAYS_OF_WEEK = 7LL; const int64_t HOUR_OF_MIDNIGHT = 0; @@ -99,6 +101,98 @@ int64_t BundleActiveUtil::StringToInt64(const std::string& str) } return res; } + +int64_t BundleActiveUtil::GetNowTime() +{ + std::chrono::seconds secs = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + return static_cast(secs.count()); +} + +uint64_t BundleActiveUtil::GetFloderOrFileSize(const std::string& path) +{ + struct stat st; + if (stat(path.c_str(), &st) != 0) { + return 0; + } + if (S_ISDIR(st.st_mode)) { + return static_cast(st.st_size); + } + uint64_t totalSize = 0; + DIR *dir = opendir(filePath.c_str()); + // input invaild, open failed + if (dir == nullptr) { + return 0; + } + struct dirent *entry; + while ((entry = readdir(dir)) != nullptr) { + // current dir is path of '.' or '..' + std::string entryPath = path + "/" + entry->d_name; + if (entry->d_name[0] == '.') { + continue; + } + + struct stat entryStat; + if (stat(entryPath.c_str(), &entryStat) != 0) { + continue; + } + if (S_ISDIR(entryStat.st_mode)) { + uint64_t subDirSize = GetFloderSize(entryPath); + totalSize += subDirSize; + } else { + totalSize += entryStat.st_size; + } + } + closedir(dir); + return totalSize; +} + +std::string BundleActiveUtil::GetPartitionName(const std::string& path) +{ + std::string partition; + std::size_t first = path.find_first_of("/"); + if (first == std::string::npos) { + partition = "/" + path; + return partition; + } + std::size_t second = path.find_first_of("/", first + 1); + if (second == std::string::npos) { + if (path.at(0) != '/') { + partition = "/" + path.substr(0, first); + } else { + partition = path; + } + return partition; + } + partition = path.substr(0, second - first); + return partition; +} + +double BundleActiveUtil::GetDeviceValidSize(const std::string& path) +{ + std::string partitionName = GetPartitionName(path); + struct statfs stat; + if (statfs(partitionName.c_str(), &stat) != 0) { + return 0; + } + constexpr double units = 1024.0; + return (static_cast(stat.f_bfree) / units) * (static_cast(stat.f_bsize) / units); +} + +double BundleActiveUtil::GetPercentOfAvaildUserSpace(const std::string& path) +{ + std::string partitionName = GetPartitionName(path); + struct statfs stat; + if (statfs(partitionName.c_str(), &stat) != 0) { + return 0; + } + uint64_t totalBytes = static_cast(stat.f_blocks) * stat.f_bsize; + uint64_t availableBytes = static_cast(stat.f_bfree) * stat.f_bsize; + if (totalBytes == 0 || availableBytes == 0) { + return 0; + } + return static_cast(availableBytes/ totalBytes); +} } // namespace DeviceUsageStats } // namespace OHOS