/* * Copyright (c) 2022-2024 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 <parameters.h> #include "time_service_client.h" #ifdef DEVICE_USAGES_STATISTICS_POWERMANGER_ENABLE #include "power_mgr_client.h" #include "shutdown/shutdown_client.h" #endif #include "unistd.h" #include "accesstoken_kit.h" #include "bundle_active_log.h" #include "bundle_state_inner_errors.h" #include "bundle_active_event.h" #include "bundle_active_package_stats.h" #include "bundle_active_account_helper.h" #include "bundle_active_bundle_mgr_helper.h" #include "bundle_active_shutdown_callback_service.h" #include "tokenid_kit.h" #include "xcollie/watchdog.h" #include "bundle_active_util.h" #include "bundle_active_service.h" namespace OHOS { namespace DeviceUsageStats { using namespace OHOS::Security; static const int32_t PERIOD_BEST_JS = 0; static const int32_t PERIOD_YEARLY_JS = 4; static const int32_t PERIOD_BEST_SERVICE = 4; static const int32_t DELAY_TIME = 2000 * 1000; static const std::string PERMITTED_PROCESS_NAME = "foundation"; static const int32_t MAXNUM_UP_LIMIT = 1000; const int32_t EVENTS_PARAM = 5; static constexpr int32_t NO_DUMP_PARAM_NUMS = 0; const int32_t PACKAGE_USAGE_PARAM = 6; const int32_t MODULE_USAGE_PARAM = 4; const std::string NEEDED_PERMISSION = "ohos.permission.BUNDLE_ACTIVE_INFO"; const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0); const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton<BundleActiveService>::GetInstance().get()); BundleActiveService::BundleActiveService() : SystemAbility(DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID, true) { } BundleActiveService::~BundleActiveService() { } void BundleActiveService::OnStart() { BUNDLE_ACTIVE_LOGI("OnStart() called"); if (ready_) { BUNDLE_ACTIVE_LOGI("service is ready. nothing to do."); return; } std::shared_ptr<BundleActiveService> service = shared_from_this(); ffrt::submit([service]() { service->InitNecessaryState(); }); } void BundleActiveService::InitNecessaryState() { std::set<int32_t> serviceIdSets{ APP_MGR_SERVICE_ID, BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, POWER_MANAGER_SERVICE_ID, COMMON_EVENT_SERVICE_ID, BACKGROUND_TASK_MANAGER_SERVICE_ID, TIME_SERVICE_ID, }; sptr<ISystemAbilityManager> systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (systemAbilityManager == nullptr) { BUNDLE_ACTIVE_LOGI("GetSystemAbilityManager fail!"); std::shared_ptr<BundleActiveService> service = shared_from_this(); ffrt::submit([service]() { service->InitNecessaryState(); }, ffrt::task_attr().delay(DELAY_TIME)); return; } for (const auto& serviceItem : serviceIdSets) { auto checkResult = systemAbilityManager->CheckSystemAbility(serviceItem); if (!checkResult) { BUNDLE_ACTIVE_LOGI("request system service is not ready yet!"); std::shared_ptr<BundleActiveService> service = shared_from_this(); ffrt::submit([service]() { service->InitNecessaryState(); }, ffrt::task_attr().delay(DELAY_TIME)); return; } } for (const auto& serviceItem : serviceIdSets) { auto getAbility = systemAbilityManager->GetSystemAbility(serviceItem); if (!getAbility) { BUNDLE_ACTIVE_LOGI("request system service object is not ready yet!"); std::shared_ptr<BundleActiveService> service = shared_from_this(); ffrt::submit([service]() { service->InitNecessaryState(); }, ffrt::task_attr().delay(DELAY_TIME)); return; } } InitService(); ready_ = true; int32_t ret = Publish(DelayedSingleton<BundleActiveService>::GetInstance().get()); if (!ret) { BUNDLE_ACTIVE_LOGE("[Server] OnStart, Register SystemAbility[1907] FAIL."); return; } BUNDLE_ACTIVE_LOGI("[Server] OnStart, Register SystemAbility[1907] SUCCESS."); } void BundleActiveService::InitService() { HiviewDFX::Watchdog::GetInstance().InitFfrtWatchdog(); if (bundleActiveCore_ == nullptr) { bundleActiveCore_ = std::make_shared<BundleActiveCore>(); bundleActiveCore_->Init(); } if (reportHandler_ == nullptr) { reportHandler_ = std::make_shared<BundleActiveReportHandler>(); if (reportHandler_ == nullptr) { return; } reportHandler_->Init(bundleActiveCore_); } if (reportHandler_ != nullptr && bundleActiveCore_ != nullptr) { BUNDLE_ACTIVE_LOGI("core and handler is not null"); bundleActiveCore_->SetHandler(reportHandler_); } else { return; } #ifdef DEVICE_USAGES_STATISTICS_POWERMANGER_ENABLE shutdownCallback_ = new (std::nothrow) BundleActiveShutdownCallbackService(bundleActiveCore_); powerStateCallback_ = new (std::nothrow) BundleActivePowerStateCallbackService(bundleActiveCore_); auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); auto& shutdownClient = OHOS::PowerMgr::ShutdownClient::GetInstance(); if (shutdownCallback_) { shutdownClient.RegisterShutdownCallback(shutdownCallback_); } if (powerStateCallback_) { powerManagerClient.RegisterPowerStateCallback(powerStateCallback_); } #endif InitAppStateSubscriber(reportHandler_); InitContinuousSubscriber(reportHandler_); bundleActiveCore_->InitBundleGroupController(); SubscribeAppState(); SubscribeContinuousTask(); } OHOS::sptr<OHOS::AppExecFwk::IAppMgr> BundleActiveService::GetAppManagerInstance() { OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); OHOS::sptr<OHOS::IRemoteObject> object = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID); if (!object) { return nullptr; } return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(object); } void BundleActiveService::InitAppStateSubscriber(const std::shared_ptr<BundleActiveReportHandler>& reportHandler) { if (!appStateObserver_) { appStateObserver_ = new (std::nothrow)BundleActiveAppStateObserver(); if (!appStateObserver_) { BUNDLE_ACTIVE_LOGE("malloc app state observer failed"); return; } appStateObserver_->Init(reportHandler); } } void BundleActiveService::InitContinuousSubscriber(const std::shared_ptr<BundleActiveReportHandler>& reportHandler) { #ifdef BGTASKMGR_ENABLE if (continuousTaskObserver_ == nullptr) { continuousTaskObserver_ = std::make_shared<BundleActiveContinuousTaskObserver>(); continuousTaskObserver_->Init(reportHandler); } #endif } bool BundleActiveService::SubscribeAppState() { sptr<OHOS::AppExecFwk::IAppMgr> appManager = GetAppManagerInstance(); if (appStateObserver_ == nullptr || appManager == nullptr) { BUNDLE_ACTIVE_LOGE("SubscribeAppState appstateobserver is null, return"); return false; } int32_t err = appManager->RegisterApplicationStateObserver(appStateObserver_); if (err != 0) { BUNDLE_ACTIVE_LOGE("RegisterApplicationStateObserver failed. err:%{public}d", err); return false; } BUNDLE_ACTIVE_LOGD("RegisterApplicationStateObserver success."); return true; } bool BundleActiveService::SubscribeContinuousTask() { #ifdef BGTASKMGR_ENABLE if (continuousTaskObserver_ == nullptr) { BUNDLE_ACTIVE_LOGE("SubscribeContinuousTask continuousTaskObserver_ is null, return"); return false; } ErrCode errCode = BackgroundTaskMgr::BackgroundTaskMgrHelper::SubscribeBackgroundTask(*continuousTaskObserver_); if (errCode != ERR_OK) { BUNDLE_ACTIVE_LOGE("SubscribeBackgroundTask failed."); return false; } #endif return true; } void BundleActiveService::OnStop() { #ifdef DEVICE_USAGES_STATISTICS_POWERMANGER_ENABLE if (shutdownCallback_ != nullptr) { auto& shutdownClient = OHOS::PowerMgr::ShutdownClient::GetInstance(); auto& powerManagerClient = OHOS::PowerMgr::PowerMgrClient::GetInstance(); shutdownClient.UnRegisterShutdownCallback(shutdownCallback_); powerManagerClient.UnRegisterPowerStateCallback(powerStateCallback_); return; } #endif BUNDLE_ACTIVE_LOGI("[Server] OnStop"); ready_ = false; } ErrCode BundleActiveService::ReportEvent(BundleActiveEvent& event, const int32_t userId) { AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); if (CheckNativePermission(tokenId) == ERR_OK) { AccessToken::NativeTokenInfo callingTokenInfo; AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, callingTokenInfo); int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGI("calling process name is %{public}s, uid is %{public}d", callingTokenInfo.processName.c_str(), callingUid); if (callingTokenInfo.processName == PERMITTED_PROCESS_NAME) { BundleActiveReportHandlerObject tmpHandlerObject(userId, ""); tmpHandlerObject.event_ = event; sptr<MiscServices::TimeServiceClient> timer = MiscServices::TimeServiceClient::GetInstance(); tmpHandlerObject.event_.timeStamp_ = timer->GetBootTimeMs(); std::shared_ptr<BundleActiveReportHandlerObject> handlerobjToPtr = std::make_shared<BundleActiveReportHandlerObject>(tmpHandlerObject); reportHandler_->SendEvent(BundleActiveReportHandler::MSG_REPORT_EVENT, handlerobjToPtr); return ERR_OK; } else { BUNDLE_ACTIVE_LOGE("token does not belong to fms service process, return"); return ERR_PERMISSION_DENIED; } } else { BUNDLE_ACTIVE_LOGE("token does not belong to native process, return"); return ERR_PERMISSION_DENIED; } } ErrCode BundleActiveService::IsBundleIdle(bool& isBundleIdle, const std::string& bundleName, int32_t userId) { // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ErrCode ret = ERR_OK; std::string callingBundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(callingUid, callingBundleName); BUNDLE_ACTIVE_LOGI("UID is %{public}d, bundle name is %{public}s", callingUid, callingBundleName.c_str()); // get user id int32_t result = -1; if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ret; } } if (callingBundleName == bundleName) { if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { BUNDLE_ACTIVE_LOGE("%{public}s is not system app", bundleName.c_str()); return ERR_NOT_SYSTEM_APP; } BUNDLE_ACTIVE_LOGI("%{public}s check its own idle state", bundleName.c_str()); result = bundleActiveCore_->IsBundleIdle(bundleName, userId); } else { ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { result = bundleActiveCore_->IsBundleIdle(bundleName, userId); } else { return ret; } } if (result == 0 || result == -1) { isBundleIdle = false; } else { isBundleIdle = true; } return ERR_OK; } ErrCode BundleActiveService::IsBundleUsePeriod(bool& IsUsePeriod, const std::string& bundleName, int32_t userId) { int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); if (AccessToken::AccessTokenKit::GetTokenType(tokenId) != AccessToken::ATokenTypeEnum::TOKEN_NATIVE) { return ERR_PERMISSION_DENIED; } auto ret = CheckNativePermission(tokenId); if (ret != ERR_OK) { return ret; } if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ret; } } IsUsePeriod = bundleActiveCore_->IsBundleUsePeriod(bundleName, userId); BUNDLE_ACTIVE_LOGI("IsBundleUsePeriod %{public}d", IsUsePeriod); return ERR_OK; } ErrCode BundleActiveService::QueryBundleStatsInfoByInterval(std::vector<BundleActivePackageStats>& PackageStats, const int32_t intervalType, const int64_t beginTime, const int64_t endTime, int32_t userId) { BUNDLE_ACTIVE_LOGD("QueryBundleStatsInfoByInterval stats called, intervaltype is %{public}d", intervalType); int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ErrCode ret = ERR_OK; if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ret; } } BUNDLE_ACTIVE_LOGI("QueryBundleStatsInfos user id is %{public}d", userId); ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { int32_t convertedIntervalType = ConvertIntervalType(intervalType); ret = bundleActiveCore_->QueryBundleStatsInfos( PackageStats, userId, convertedIntervalType, beginTime, endTime, ""); } return ret; } ErrCode BundleActiveService::QueryBundleEvents(std::vector<BundleActiveEvent>& bundleActiveEvents, const int64_t beginTime, const int64_t endTime, int32_t userId) { ErrCode ret = ERR_OK; int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ret; } } BUNDLE_ACTIVE_LOGI("QueryBundleEvents userid is %{public}d", userId); ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { ret = bundleActiveCore_->QueryBundleEvents(bundleActiveEvents, userId, beginTime, endTime, ""); BUNDLE_ACTIVE_LOGI("QueryBundleEvents result is %{public}zu", bundleActiveEvents.size()); } return ret; } ErrCode BundleActiveService::SetAppGroup(const std::string& bundleName, int32_t newGroup, int32_t userId) { ErrCode ret = ERR_OK; int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); bool isFlush = false; if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ERR_SYSTEM_ABILITY_SUPPORT_FAILED; } isFlush = true; } BUNDLE_ACTIVE_LOGI("SetAppGroup userId is %{public}d", userId); std::string localBundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(callingUid, localBundleName); if (localBundleName == bundleName) { BUNDLE_ACTIVE_LOGI("SetAppGroup can not set its bundleName"); return ERR_PERMISSION_DENIED; } AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { ret = bundleActiveCore_->SetAppGroup(bundleName, newGroup, userId, isFlush); } return ret; } ErrCode BundleActiveService::QueryBundleStatsInfos(std::vector<BundleActivePackageStats>& bundleActivePackageStats, const int32_t intervalType, const int64_t beginTime, const int64_t endTime) { // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); BUNDLE_ACTIVE_LOGD("UID is %{public}d", callingUid); // get userid int32_t userId = -1; ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret == ERR_OK && userId != -1) { BUNDLE_ACTIVE_LOGD("QueryBundleStatsInfos userid is %{public}d", userId); std::string bundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(callingUid, bundleName); ErrCode isSystemAppAndHasPermission = CheckBundleIsSystemAppAndHasPermission(callingUid, tokenId); if (!bundleName.empty() && isSystemAppAndHasPermission == ERR_OK) { int32_t convertedIntervalType = ConvertIntervalType(intervalType); ret = bundleActiveCore_->QueryBundleStatsInfos(bundleActivePackageStats, userId, convertedIntervalType, beginTime, endTime, bundleName); } } return ret; } ErrCode BundleActiveService::QueryCurrentBundleEvents(std::vector<BundleActiveEvent>& bundleActiveEvents, const int64_t beginTime, const int64_t endTime) { // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGD("QueryCurrentBundleEvents UID is %{public}d", callingUid); // get userid int32_t userId = -1; ErrCode ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret == ERR_OK && userId != -1) { std::string bundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(callingUid, bundleName); if (!bundleName.empty()) { if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { BUNDLE_ACTIVE_LOGE("%{public}s is not system app", bundleName.c_str()); return ERR_NOT_SYSTEM_APP; } BUNDLE_ACTIVE_LOGI("QueryCurrentBundleEvents buindle name is %{public}s", bundleName.c_str()); ret = bundleActiveCore_->QueryBundleEvents(bundleActiveEvents, userId, beginTime, endTime, bundleName); } } BUNDLE_ACTIVE_LOGD("QueryCurrentBundleEvents bundleActiveEvents size is %{public}zu", bundleActiveEvents.size()); return ret; } ErrCode BundleActiveService::QueryAppGroup(int32_t& appGroup, std::string& bundleName, int32_t userId) { // get uid int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGD("QueryAppGroup UID is %{public}d", callingUid); ErrCode ret = ERR_OK; if (userId == -1) { ret = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (ret != ERR_OK || userId == -1) { return ERR_SYSTEM_ABILITY_SUPPORT_FAILED; } } if (bundleName.empty()) { std::string localBundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(callingUid, localBundleName); if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { BUNDLE_ACTIVE_LOGE("%{public}s is not system app", localBundleName.c_str()); return ERR_NOT_SYSTEM_APP; } bundleName = localBundleName; ret = bundleActiveCore_->QueryAppGroup(appGroup, bundleName, userId); } else { AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { ret = bundleActiveCore_->QueryAppGroup(appGroup, bundleName, userId); } } return ret; } ErrCode BundleActiveService::RegisterAppGroupCallBack(const sptr<IAppGroupCallback> &observer) { if (!bundleActiveCore_) { return ERR_MEMORY_OPERATION_FAILED; } int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ErrCode ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { ret = bundleActiveCore_->RegisterAppGroupCallBack(tokenId, observer); } return ret; } ErrCode BundleActiveService::UnRegisterAppGroupCallBack(const sptr<IAppGroupCallback> &observer) { if (!bundleActiveCore_) { return ERR_MEMORY_OPERATION_FAILED; } int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); ErrCode ret = CheckSystemAppOrNativePermission(callingUid, tokenId); if (ret == ERR_OK) { ret = bundleActiveCore_->UnRegisterAppGroupCallBack(tokenId, observer); } return ret; } int32_t BundleActiveService::ConvertIntervalType(const int32_t intervalType) { if (intervalType == PERIOD_BEST_JS) { return PERIOD_BEST_SERVICE; } else if (intervalType > PERIOD_BEST_JS && intervalType <= PERIOD_YEARLY_JS) { return intervalType - 1; } return -1; } ErrCode BundleActiveService::CheckBundleIsSystemAppAndHasPermission(const int32_t uid, OHOS::Security::AccessToken::AccessTokenID tokenId) { std::string bundleName = ""; BundleActiveBundleMgrHelper::GetInstance()->GetNameForUid(uid, bundleName); if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) { BUNDLE_ACTIVE_LOGE("%{public}s is not system app", bundleName.c_str()); return ERR_NOT_SYSTEM_APP; } int32_t bundleHasPermission = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, NEEDED_PERMISSION); if (bundleHasPermission != 0) { BUNDLE_ACTIVE_LOGE("%{public}s hasn't permission", bundleName.c_str()); return ERR_PERMISSION_DENIED; } BUNDLE_ACTIVE_LOGI("%{public}s has permission", bundleName.c_str()); return ERR_OK; } ErrCode BundleActiveService::CheckNativePermission(OHOS::Security::AccessToken::AccessTokenID tokenId) { int32_t bundleHasPermission = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, NEEDED_PERMISSION); if (bundleHasPermission != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { BUNDLE_ACTIVE_LOGE("check native permission not have permission"); return ERR_PERMISSION_DENIED; } auto tokenFlag = AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); if (tokenFlag == AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) { return ERR_OK; } if (tokenFlag == AccessToken::TypeATokenTypeEnum::TOKEN_SHELL) { return ERR_OK; } return ERR_PERMISSION_DENIED; } ErrCode BundleActiveService::CheckSystemAppOrNativePermission(const int32_t uid, OHOS::Security::AccessToken::AccessTokenID tokenId) { if (AccessToken::AccessTokenKit::GetTokenType(tokenId) == AccessToken::ATokenTypeEnum::TOKEN_HAP) { return CheckBundleIsSystemAppAndHasPermission(uid, tokenId); } return CheckNativePermission(tokenId); } ErrCode BundleActiveService::QueryModuleUsageRecords(int32_t maxNum, std::vector<BundleActiveModuleRecord>& results, int32_t userId) { ErrCode errCode = ERR_OK; if (maxNum > MAXNUM_UP_LIMIT || maxNum <= 0) { BUNDLE_ACTIVE_LOGE("MaxNum is Invalid!"); return ERR_FIND_APP_USAGE_RECORDS_FAILED; } int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); if (userId == -1) { errCode = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (errCode != ERR_OK || userId == -1) { return errCode; } } BUNDLE_ACTIVE_LOGI("QueryModuleUsageRecords userid is %{public}d", userId); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); errCode = CheckSystemAppOrNativePermission(callingUid, tokenId); if (errCode == ERR_OK) { errCode = bundleActiveCore_->QueryModuleUsageRecords(maxNum, results, userId); for (auto& oneResult : results) { QueryModuleRecordInfos(oneResult); } } return errCode; } ErrCode BundleActiveService::QueryDeviceEventStats(int64_t beginTime, int64_t endTime, std::vector<BundleActiveEventStats>& eventStats, int32_t userId) { int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); ErrCode errCode = ERR_OK; if (userId == -1) { errCode = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (errCode != ERR_OK || userId == -1) { return errCode; } } BUNDLE_ACTIVE_LOGI("QueryDeviceEventStats userid is %{public}d", userId); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); errCode = CheckSystemAppOrNativePermission(callingUid, tokenId); if (errCode == ERR_OK) { errCode = bundleActiveCore_->QueryDeviceEventStats(beginTime, endTime, eventStats, userId); } BUNDLE_ACTIVE_LOGD("QueryDeviceEventStats result size is %{public}zu", eventStats.size()); return errCode; } ErrCode BundleActiveService::QueryNotificationEventStats(int64_t beginTime, int64_t endTime, std::vector<BundleActiveEventStats>& eventStats, int32_t userId) { int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); BUNDLE_ACTIVE_LOGD("QueryNotificationEventStats UID is %{public}d", callingUid); // get userid when userId is -1 ErrCode errCode = ERR_OK; if (userId == -1) { errCode = BundleActiveAccountHelper::GetUserId(callingUid, userId); if (errCode != ERR_OK || userId == -1) { return errCode; } } BUNDLE_ACTIVE_LOGI("QueryNotificationEventStats userid is %{public}d", userId); AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); errCode = CheckSystemAppOrNativePermission(callingUid, tokenId); if (errCode == ERR_OK) { errCode = bundleActiveCore_->QueryNotificationEventStats(beginTime, endTime, eventStats, userId); } return errCode; } void BundleActiveService::QueryModuleRecordInfos(BundleActiveModuleRecord& moduleRecord) { ApplicationInfo appInfo; bool getInfoIsSuccess = BundleActiveBundleMgrHelper::GetInstance()->GetApplicationInfo(moduleRecord.bundleName_, ApplicationFlag::GET_BASIC_APPLICATION_INFO, moduleRecord.userId_, appInfo); if (!getInfoIsSuccess) { BUNDLE_ACTIVE_LOGE("GetApplicationInfo failed!"); return; } BundleInfo bundleInfo; getInfoIsSuccess = BundleActiveBundleMgrHelper::GetInstance()->GetBundleInfo(moduleRecord.bundleName_, BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, moduleRecord.userId_); if (!getInfoIsSuccess) { BUNDLE_ACTIVE_LOGE("GetBundleInfo failed!"); return; } for (const auto& oneModuleInfo : bundleInfo.hapModuleInfos) { if (oneModuleInfo.moduleName == moduleRecord.moduleName_) { std::string mainAbility = oneModuleInfo.mainAbility; for (auto oneAbilityInfo : oneModuleInfo.abilityInfos) { if (oneAbilityInfo.type != AbilityType::PAGE) { continue; } if (mainAbility.empty() || mainAbility.compare(oneAbilityInfo.name) == 0) { SerModuleProperties(oneModuleInfo, appInfo, oneAbilityInfo, moduleRecord); break; } } } } } void BundleActiveService::SerModuleProperties(const HapModuleInfo& hapModuleInfo, const ApplicationInfo& appInfo, const AbilityInfo& abilityInfo, BundleActiveModuleRecord& moduleRecord) { moduleRecord.deviceId_ = appInfo.deviceId; moduleRecord.abilityName_ = abilityInfo.name; moduleRecord.appLabelId_ = appInfo.labelId; moduleRecord.labelId_ = static_cast<uint32_t>(hapModuleInfo.labelId); moduleRecord.abilityLableId_ = abilityInfo.labelId; moduleRecord.descriptionId_ = abilityInfo.descriptionId; moduleRecord.abilityIconId_ = abilityInfo.iconId; moduleRecord.installFreeSupported_ = hapModuleInfo.installationFree; } bool BundleActiveService::AllowDump() { if (ENG_MODE == 0) { BUNDLE_ACTIVE_LOGE("Not eng mode"); return false; } Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetFirstTokenID(); int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP"); if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { BUNDLE_ACTIVE_LOGE("CheckPermission failed"); return false; } return true; } int32_t BundleActiveService::Dump(int32_t fd, const std::vector<std::u16string> &args) { if (!AllowDump()) { return ERR_PERMISSION_DENIED; } std::vector<std::string> argsInStr; std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), [](const std::u16string &arg) { return Str16ToStr8(arg); }); std::string result; int32_t ret = ERR_OK; if (argsInStr.size() == NO_DUMP_PARAM_NUMS) { DumpUsage(result); } else { std::vector<std::string> infos; if (argsInStr[0] == "-h") { DumpUsage(result); } else if (argsInStr[0] == "-A") { ret = ShellDump(argsInStr, infos); } else { infos.emplace_back("BundleActiveService Error params.\n"); ret = ERR_USAGE_STATS_INVALID_PARAM; } for (auto info : infos) { result.append(info); } } if (!SaveStringToFd(fd, result)) { BUNDLE_ACTIVE_LOGE("BundleActiveService dump save string to fd failed!"); ret = ERR_USAGE_STATS_METHOD_CALLED_FAILED; } return ret; } int32_t BundleActiveService::ShellDump(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo) { int32_t ret = -1; if (!bundleActiveCore_) { return ret; } if (dumpOption[1] == "Events") { ret = DumpEvents(dumpOption, dumpInfo); } else if (dumpOption[1] == "PackageUsage") { ret = DumpPackageUsage(dumpOption, dumpInfo); } else if (dumpOption[1] == "ModuleUsage") { ret = DumpModuleUsage(dumpOption, dumpInfo); } return ret; } int32_t BundleActiveService::DumpEvents(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo) { int32_t ret = -1; std::vector<BundleActiveEvent> eventResult; if (static_cast<int32_t>(dumpOption.size()) != EVENTS_PARAM) { return ret; } int64_t beginTime = BundleActiveUtil::StringToInt64(dumpOption[2]); int64_t endTime = BundleActiveUtil::StringToInt64(dumpOption[3]); int32_t userId = BundleActiveUtil::StringToInt32(dumpOption[4]); bundleActiveCore_->QueryBundleEvents(eventResult, userId, beginTime, endTime, ""); for (auto& oneEvent : eventResult) { dumpInfo.emplace_back(oneEvent.ToString()); } return ret; } int32_t BundleActiveService::DumpPackageUsage(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo) { int32_t ret = -1; std::vector<BundleActivePackageStats> packageUsageResult; if (static_cast<int32_t>(dumpOption.size()) != PACKAGE_USAGE_PARAM) { return ret; } int32_t intervalType = ConvertIntervalType(BundleActiveUtil::StringToInt32(dumpOption[2])); int64_t beginTime = BundleActiveUtil::StringToInt64(dumpOption[3]); int64_t endTime = BundleActiveUtil::StringToInt64(dumpOption[4]); int32_t userId = BundleActiveUtil::StringToInt32(dumpOption[5]); bundleActiveCore_->QueryBundleStatsInfos( packageUsageResult, userId, intervalType, beginTime, endTime, ""); for (auto& onePackageRecord : packageUsageResult) { dumpInfo.emplace_back(onePackageRecord.ToString()); } return ret; } int32_t BundleActiveService::DumpModuleUsage(const std::vector<std::string> &dumpOption, std::vector<std::string> &dumpInfo) { int32_t ret = -1; std::vector<BundleActiveModuleRecord> moduleResult; if (static_cast<int32_t>(dumpOption.size()) != MODULE_USAGE_PARAM) { return ret; } int32_t maxNum = BundleActiveUtil::StringToInt32(dumpOption[2]); int32_t userId = BundleActiveUtil::StringToInt32(dumpOption[3]); BUNDLE_ACTIVE_LOGI("M is %{public}d, u is %{public}d", maxNum, userId); ret = bundleActiveCore_->QueryModuleUsageRecords(maxNum, moduleResult, userId); for (auto& oneResult : moduleResult) { QueryModuleRecordInfos(oneResult); } for (auto& oneModuleRecord : moduleResult) { dumpInfo.emplace_back(oneModuleRecord.ToString()); for (uint32_t i = 0; i < oneModuleRecord.formRecords_.size(); i++) { std::string oneFormInfo = "form " + std::to_string(static_cast<int32_t>(i) + 1) + ", "; dumpInfo.emplace_back(oneFormInfo + oneModuleRecord.formRecords_[i].ToString()); } } return ret; } void BundleActiveService::DumpUsage(std::string &result) { std::string dumpHelpMsg = "usage: bundleactive dump [<options>]\n" "options list:\n" " -h help menu\n" " -A \n" " Events [beginTime] [endTime] [userId] get events for one user\n" " PackageUsage [intervalType] [beginTime] [endTime] [userId] get package usage for one user\n" " ModuleUsage [maxNum] [userId] get module usage for one user\n"; result.append(dumpHelpMsg); } } // namespace DeviceUsageStats } // namespace OHOS