/* * Copyright (c) 2021-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 "form_mgr_service.h" #include #include #include #include #include "accesstoken_kit.h" #include "bundle_common_event.h" #include "common_event_manager.h" #include "common_event_support.h" #include "fms_log_wrapper.h" #include "form_ams_helper.h" #include "form_bms_helper.h" #include "form_bundle_forbid_mgr.h" #include "form_cache_mgr.h" #include "form_constants.h" #include "form_data_mgr.h" #include "form_data_proxy_mgr.h" #include "form_db_cache.h" #include "form_event_handler.h" #include "form_event_report.h" #include "form_info_mgr.h" #include "form_mgr_adapter.h" #include "form_mgr_errors.h" #include "form_serial_queue.h" #include "form_share_mgr.h" #include "form_task_mgr.h" #include "form_timer_mgr.h" #include "form_trust_mgr.h" #include "form_util.h" #include "form_xml_parser.h" #include "in_process_call_wrapper.h" #include "ipc_skeleton.h" #include "iservice_registry.h" #include "mem_status_listener.h" #include "os_account_manager.h" #include "permission_constants.h" #include "permission_verification.h" #include "system_ability_definition.h" #include "tokenid_kit.h" #include "hisysevent.h" #include "xcollie/watchdog.h" #include "xcollie/xcollie.h" #include "xcollie/xcollie_define.h" #ifdef MEM_MGR_ENABLE #include "mem_mgr_client.h" #endif #include "form_report.h" #ifdef RES_SCHEDULE_ENABLE #include "form_systemload_listener.h" #include "res_sched_client.h" #include "res_type.h" #endif // RES_SCHEDULE_ENABLE namespace OHOS { namespace AppExecFwk { namespace { const int32_t MAIN_USER_ID = 100; constexpr int MILLISECOND_WIDTH = 3; constexpr char MILLISECOND_FILLCHAR = '0'; const int32_t API_TIME_OUT = 5; const int32_t API_TIME_OUT_8S = 8; const int32_t API_TIME_OUT_30S = 30; #ifdef RES_SCHEDULE_ENABLE constexpr int32_t SYSTEMLOADLEVEL_TIMERSTOP_THRESHOLD = static_cast(ResourceSchedule::ResType::SystemloadLevel::HIGH); #endif // RES_SCHEDULE_ENABLE } using namespace std::chrono; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); const std::string NAME_FORM_MGR_SERVICE = "FormMgrService"; const std::string FORM_MGR_SERVICE_QUEUE = "FormMgrServiceQueue"; constexpr int32_t FORM_DUMP_ARGC_MAX = 2; const std::string FORM_DUMP_HELP = "options list:\n" " -h, --help list available commands\n" " -b, --bundle-form-info query all form infos from bundle, Un-added form info will also be dumped\n" " -v, --visible query form visible infos from args like bundleName_userId_instIndex\n" " -s, --storage query form storage info\n" " -t, --temp query temporary form info\n" " -n query form info by a bundle name\n" " -i query form info by a form ID\n" " -r --running query running form info\n" " -a --apps-blocked query blocked app name list\n"; const std::map FormMgrService::dumpKeyMap_ = { {"-h", FormMgrService::DumpKey::KEY_DUMP_HELP}, {"--help", FormMgrService::DumpKey::KEY_DUMP_HELP}, {"-b", FormMgrService::DumpKey::KEY_DUMP_STATIC}, // ***** {"--bundle-form-info", FormMgrService::DumpKey::KEY_DUMP_STATIC}, {"-v", FormMgrService::DumpKey::KEY_DUMP_VISIBLE}, {"--visible", FormMgrService::DumpKey::KEY_DUMP_VISIBLE}, {"-s", FormMgrService::DumpKey::KEY_DUMP_STORAGE}, {"--storage", FormMgrService::DumpKey::KEY_DUMP_STORAGE}, {"-t", FormMgrService::DumpKey::KEY_DUMP_TEMPORARY}, {"--temp", FormMgrService::DumpKey::KEY_DUMP_TEMPORARY}, {"-n", FormMgrService::DumpKey::KEY_DUMP_BY_BUNDLE_NAME}, {"-i", FormMgrService::DumpKey::KEY_DUMP_BY_FORM_ID}, {"-r", FormMgrService::DumpKey::KEY_DUMP_RUNNING}, {"--running", FormMgrService::DumpKey::KEY_DUMP_RUNNING}, {"-a", FormMgrService::DumpKey::KEY_DUMP_BLOCKED_APPS}, {"--apps-blocked", FormMgrService::DumpKey::KEY_DUMP_BLOCKED_APPS}, }; FormMgrService::FormMgrService() : SystemAbility(FORM_MGR_SERVICE_ID, true), state_(ServiceRunningState::STATE_NOT_START), serialQueue_(nullptr) { HILOG_INFO("call"); } FormMgrService::~FormMgrService() { HILOG_INFO("call"); if (formSysEventReceiver_ != nullptr) { EventFwk::CommonEventManager::UnSubscribeCommonEvent(formSysEventReceiver_); formSysEventReceiver_ = nullptr; FormBmsHelper::GetInstance().UnregisterBundleEventCallback(); } #ifdef MEM_MGR_ENABLE if (memStatusListener_ != nullptr) { Memory::MemMgrClient::GetInstance().UnsubscribeAppState(*memStatusListener_); } #endif } /** * @brief Check form manager service ready. * @return Return true if form manager service Ready; return false otherwise. */ bool FormMgrService::CheckFMSReady() { if (state_ != ServiceRunningState::STATE_RUNNING) { return false; } int32_t userId = FormUtil::GetCurrentAccountId(); if (userId == Constants::ANY_USERID) { HILOG_ERROR("empty account"); return false; } int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_CheckFMSReady", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); bool result = FormInfoMgr::GetInstance().HasReloadedFormInfos(); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return result; } bool FormMgrService::IsSystemAppForm(const std::string &bundleName) { HILOG_DEBUG("check %{public}s is system form.", bundleName.c_str()); std::vector formRecords; FormDataMgr::GetInstance().GetFormRecord(bundleName, formRecords); if (formRecords.empty()) { return false; } return formRecords.front().isSystemApp; } /** * @brief Add form with want, send want to form manager service. * @param formId The Id of the forms to add. * @param want The want of the form to add. * @param callerToken Caller ability token. * @param formInfo Form info. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::AddForm(const int64_t formId, const Want &want, const sptr &callerToken, FormJsInfo &formInfo) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("add form permission denied"); return ret; } ReportAddFormEvent(formId, want); int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_AddForm", API_TIME_OUT_30S, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ret = FormMgrAdapter::GetInstance().AddForm(formId, want, callerToken, formInfo); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Add form with want, send want to form manager service. * @param want The want of the form to add. * @param runningFormInfo Running form info. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::CreateForm(const Want &want, RunningFormInfo &runningFormInfo) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("create form permission denied"); return ret; } ReportAddFormEvent(0, want); return FormMgrAdapter::GetInstance().CreateForm(want, runningFormInfo); } void FormMgrService::ReportAddFormEvent(const int64_t formId, const Want &want) { FormEventInfo eventInfo; eventInfo.formId = formId; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); int ret = FormBmsHelper::GetInstance().GetCallerBundleName(eventInfo.hostBundleName); if (ret != ERR_OK || eventInfo.hostBundleName.empty()) { HILOG_ERROR("cannot get host bundle name by uid"); } FormEventReport::SendFormEvent(FormEventName::ADD_FORM, HiSysEventType::BEHAVIOR, eventInfo); } /** * @brief Delete forms with formIds, send formIds to form manager service. * @param formId The Id of the forms to delete. * @param callerToken Caller ability token. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DeleteForm(const int64_t formId, const sptr &callerToken) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("delete form permission denied"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; std::vector formHostRecords; FormDataMgr::GetInstance().GetFormHostRecord(formId, formHostRecords); if (formHostRecords.size() != 0) { eventInfo.hostBundleName = formHostRecords.begin()->GetHostBundleName(); } FormEventReport::SendSecondFormEvent(FormEventName::DELETE_FORM, HiSysEventType::BEHAVIOR, eventInfo); int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_DeleteForm", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ret = FormMgrAdapter::GetInstance().DeleteForm(formId, callerToken); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Stop rendering form. * @param formId The Id of the forms to delete. * @param compId The compId of the forms to delete. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::StopRenderingForm(const int64_t formId, const std::string &compId) { ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("delete form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("invalid formId or not under currentActiveUser"); return ret; } return FormMgrAdapter::GetInstance().StopRenderingForm(formId, compId); } /** * @brief Release forms with formIds, send formIds to form manager service. * @param formId The Id of the forms to release. * @param callerToken Caller ability token. * @param delCache Delete Cache or not. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::ReleaseForm(const int64_t formId, const sptr &callerToken, const bool delCache) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("release form permission denied"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; FormEventReport::SendSecondFormEvent(FormEventName::RELEASE_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().ReleaseForm(formId, callerToken, delCache); } /** * @brief Update form with formId, send formId to form manager service. * @param formId The Id of the form to update. * @param formBindingData Form binding data. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::UpdateForm(const int64_t formId, const FormProviderData &formBindingData) { HILOG_DEBUG("call"); auto callingUid = IPCSkeleton::GetCallingUid(); return FormMgrAdapter::GetInstance().UpdateForm(formId, callingUid, formBindingData); } /** * @brief Request form with formId and want, send formId and want to form manager service. * @param formId The Id of the form to update. * @param callerToken Caller ability token. * @param want The want of the form to add. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::RequestForm(const int64_t formId, const sptr &callerToken, const Want &want) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); FormEventReport::SendSecondFormEvent(FormEventName::REQUEST_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().RequestForm(formId, callerToken, want); } /** * @brief set next refresh time. * @param formId The id of the form. * @param nextTime next refresh time. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::SetNextRefreshTime(const int64_t formId, const int64_t nextTime) { HILOG_DEBUG("call"); FormEventInfo eventInfo; eventInfo.formId = formId; FormEventReport::SendSecondFormEvent( FormEventName::SET_NEXT_REFRESH_TIME_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().SetNextRefreshTime(formId, nextTime); } int FormMgrService::ReleaseRenderer(int64_t formId, const std::string &compId) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } return FormMgrAdapter::GetInstance().ReleaseRenderer(formId, compId); } ErrCode FormMgrService::RequestPublishForm(Want &want, bool withFormBindingData, std::unique_ptr &formBindingData, int64_t &formId) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); bool isFormAgent = want.GetBoolParam(Constants::IS_FORM_AGENT, false); HILOG_INFO("isFormAgent:%{public}d", isFormAgent); if (isFormAgent) { ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_AGENT_REQUIRE_FORM); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } } else { if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } } return FormMgrAdapter::GetInstance().RequestPublishForm(want, withFormBindingData, formBindingData, formId); } ErrCode FormMgrService::SetPublishFormResult(const int64_t formId, Constants::PublishFormResult &errorCodeInfo) { HILOG_INFO("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_REQUIRE_FORM); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } return FormMgrAdapter::GetInstance().SetPublishFormResult(formId, errorCodeInfo); } ErrCode FormMgrService::AcquireAddFormResult(const int64_t formId) { HILOG_INFO("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_AGENT_REQUIRE_FORM); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } return FormMgrAdapter::GetInstance().AcquireAddFormResult(formId); } /** * @brief Form visible/invisible notify, send formIds to form manager service. * @param formIds The Id list of the forms to notify. * @param callerToken Caller ability token. * @param formVisibleType The form visible type, including FORM_VISIBLE and FORM_INVISIBLE. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::NotifyWhetherVisibleForms(const std::vector &formIds, const sptr &callerToken, const int32_t formVisibleType) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("event notify visible permission denied"); return ret; } int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_NotifyWhetherVisibleForms", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ret = FormMgrAdapter::GetInstance().NotifyWhetherVisibleForms(formIds, callerToken, formVisibleType); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Query whether has visible form by tokenId. * @param tokenId Unique identification of application. * @return Returns true if has visible form, false otherwise. */ bool FormMgrService::HasFormVisible(const uint32_t tokenId) { HILOG_DEBUG("call"); if (!FormUtil::IsSACall()) { HILOG_ERROR("query form visible with tokenid not a SACall"); return false; } return FormMgrAdapter::GetInstance().HasFormVisible(tokenId); } /** * @brief temp form to normal form. * @param formId The Id of the form. * @param callerToken Caller ability token. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::CastTempForm(const int64_t formId, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("cast temp form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("invalid formId or not under currentActiveUser"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; FormEventReport::SendSecondFormEvent(FormEventName::CASTTEMP_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().CastTempForm(formId, callerToken); } /** * @brief lifecycle update. * @param formIds formIds of host client. * @param callerToken Caller ability token. * @param updateType update type,enable or disable. * @return Returns true on success, false on failure. */ int FormMgrService::LifecycleUpdate(const std::vector &formIds, const sptr &callerToken, bool updateType) { HILOG_INFO("updateType:%{public}d", updateType); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("delete form permission denied"); return ret; } if (updateType) { return FormMgrAdapter::GetInstance().EnableUpdateForm(formIds, callerToken); } else { return FormMgrAdapter::GetInstance().DisableUpdateForm(formIds, callerToken); } } /** * @brief Dump all of form storage infos. * @param formInfos All of form storage infos. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DumpStorageFormInfos(std::string &formInfos) { if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } return FormMgrAdapter::GetInstance().DumpStorageFormInfos(formInfos); } /** * @brief Dump form info by a bundle name. * @param bundleName The bundle name of form provider. * @param formInfos Form infos. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DumpFormInfoByBundleName(const std::string &bundleName, std::string &formInfos) { if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } return FormMgrAdapter::GetInstance().DumpFormInfoByBundleName(bundleName, formInfos); } /** * @brief Dump form info by a bundle name. * @param formId The id of the form. * @param formInfo Form info. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DumpFormInfoByFormId(const std::int64_t formId, std::string &formInfo) { if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } return FormMgrAdapter::GetInstance().DumpFormInfoByFormId(formId, formInfo); } /** * @brief Dump form timer by form id. * @param formId The id of the form. * @param formInfo Form info. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DumpFormTimerByFormId(const std::int64_t formId, std::string &isTimingService) { if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } return FormMgrAdapter::GetInstance().DumpFormTimerByFormId(formId, isTimingService); } /** * @brief Process js message event. * @param formId Indicates the unique id of form. * @param want information passed to supplier. * @param callerToken Caller ability token. * @return Returns true if execute success, false otherwise. */ int FormMgrService::MessageEvent(const int64_t formId, const Want &want, const sptr &callerToken) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("invalid formId or not under currentActiveUser"); return ret; } FormEventInfo eventInfo; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); std::vector formHostRecords; FormDataMgr::GetInstance().GetFormHostRecord(formId, formHostRecords); if (formHostRecords.size() != 0) { eventInfo.hostBundleName = formHostRecords.begin()->GetHostBundleName(); } FormReport::GetInstance().SetDurationStartTime(formId, FormUtil::GetCurrentSteadyClockMillseconds()); FormEventReport::SendFormEvent(FormEventName::MESSAGE_EVENT_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().MessageEvent(formId, want, callerToken); } /** * @brief Process js router event. * @param formId Indicates the unique id of form. * @param want the want of the ability to start. * @param callerToken Caller ability token. * @return Returns true if execute success, false otherwise. */ int FormMgrService::RouterEvent(const int64_t formId, Want &want, const sptr &callerToken) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("invalid formId or not under currentActiveUser"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); std::vector formHostRecords; FormDataMgr::GetInstance().GetFormHostRecord(formId, formHostRecords); if (formHostRecords.size() != 0) { eventInfo.hostBundleName = formHostRecords.begin()->GetHostBundleName(); } FormEventReport::SendFormEvent(FormEventName::ROUTE_EVENT_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().RouterEvent(formId, want, callerToken); } /** * @brief Process Background event. * @param formId Indicates the unique id of form. * @param want the want of the ability to start. * @param callerToken Caller ability token. * @return Returns true if execute success, false otherwise. */ int FormMgrService::BackgroundEvent(const int64_t formId, Want &want, const sptr &callerToken) { HILOG_INFO("begin:%{public}s,publish:%{public}s,end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("the formId is not under currentActiveUser or invalid"); return ret; } FormEventInfo eventInfo; eventInfo.formId = formId; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); FormEventReport::SendSecondFormEvent(FormEventName::BACKGROUND_EVENT_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().BackgroundEvent(formId, want, callerToken); } /** * @brief Start event for the form manager service. */ void FormMgrService::OnStart() { if (state_ == ServiceRunningState::STATE_RUNNING) { HILOG_WARN("start service failed since it's running"); return; } onStartBeginTime_ = GetCurrentDateTime(); HILOG_INFO("start,time:%{public}s", onStartBeginTime_.c_str()); ErrCode errCode = Init(); if (errCode != ERR_OK) { HILOG_ERROR("init failed,errCode:%{public}08x", errCode); return; } state_ = ServiceRunningState::STATE_RUNNING; // listener for FormDataProxyMgr AddSystemAbilityListener(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); #ifdef MEM_MGR_ENABLE AddSystemAbilityListener(MEMORY_MANAGER_SA_ID); #endif // MEM_MGR_ENABLE #ifdef RES_SCHEDULE_ENABLE AddSystemAbilityListener(RES_SCHED_SYS_ABILITY_ID); #endif // RES_SCHEDULE_ENABLE onStartEndTime_ = GetCurrentDateTime(); HILOG_INFO("success,time:%{public}s,onKvDataServiceAddTime:%{public}s", onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); } /** * @brief Stop event for the form manager service. */ void FormMgrService::OnStop() { HILOG_INFO("stop"); state_ = ServiceRunningState::STATE_NOT_START; if (serialQueue_) { serialQueue_.reset(); } if (handler_) { handler_.reset(); } FormAmsHelper::GetInstance().UnRegisterConfigurationObserver(); } ErrCode FormMgrService::ReadFormConfigXML() { FormXMLParser parser; int32_t ret = parser.Parse(); if (ret != ERR_OK) { HILOG_WARN("parse form config failed, use the default vaule"); return ret; } const std::map &configMap = parser.GetConfigMap(); FormDataMgr::GetInstance().SetConfigMap(configMap); return ERR_OK; } void FormMgrService::SubscribeSysEventReceiver() { if (formSysEventReceiver_ == nullptr) { EventFwk::MatchingSkills matchingSkills; matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_ABILITY_UPDATED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SECOND_MOUNTED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED); matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON); // init TimerReceiver EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); formSysEventReceiver_ = std::make_shared(subscribeInfo); formSysEventReceiver_->SetSerialQueue(serialQueue_); EventFwk::CommonEventManager::SubscribeCommonEvent(formSysEventReceiver_); } } /** * @brief initialization of form manager service. */ ErrCode FormMgrService::Init() { HILOG_INFO("call"); serialQueue_ = std::make_shared(FORM_MGR_SERVICE_QUEUE.c_str()); if (serialQueue_ == nullptr) { HILOG_ERROR("Init failed,null serialQueue_"); return ERR_INVALID_OPERATION; } handler_ = std::make_shared(serialQueue_); if (handler_ == nullptr) { HILOG_ERROR("init failed.null handler_"); return ERR_INVALID_OPERATION; } FormTaskMgr::GetInstance().SetSerialQueue(serialQueue_); FormAmsHelper::GetInstance().SetSerialQueue(serialQueue_); /* Publish service maybe failed, so we need call this function at the last, * so it can't affect the TDD test program */ if (!Publish(DelayedSingleton::GetInstance().get())) { FormEventReport::SendFormFailedEvent(FormEventName::INIT_FMS_FAILED, HiSysEventType::FAULT, static_cast(InitFmsFiledErrorType::PUBLISH_SER_FAILED)); HILOG_ERROR("FormMgrService::Init Publish failed"); return ERR_INVALID_OPERATION; } onStartPublishTime_ = GetCurrentDateTime(); HILOG_INFO("FMS onStart publish done, time:%{public}s", onStartPublishTime_.c_str()); SubscribeSysEventReceiver(); #ifdef MEM_MGR_ENABLE memStatusListener_ = std::make_shared(); Memory::MemMgrClient::GetInstance().SubscribeAppState(*memStatusListener_); #endif FormInfoMgr::GetInstance().Start(); FormDbCache::GetInstance().Start(); FormTimerMgr::GetInstance(); // Init FormTimerMgr FormCacheMgr::GetInstance().Start(); formSysEventReceiver_->InitFormInfosAndRegister(); // read param form form_config.xml. if (ReadFormConfigXML() != ERR_OK) { HILOG_WARN("parse form config failed, use the default vaule"); } FormMgrAdapter::GetInstance().Init(); FormAmsHelper::GetInstance().RegisterConfigurationObserver(); return ERR_OK; } ErrCode FormMgrService::CheckFormPermission(const std::string &permission) { HILOG_DEBUG("call"); if (FormUtil::IsSACall()) { return ERR_OK; } // check if system app if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } auto isCallingPerm = FormUtil::VerifyCallingPermission(permission); if (!isCallingPerm) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } // checks whether the current user is inactive if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } HILOG_DEBUG("Permission verification ok"); return ERR_OK; } /** * @brief Delete the invalid forms. * @param formIds Indicates the ID of the valid forms. * @param callerToken Caller ability token. * @param numFormsDeleted Returns the number of the deleted forms. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::DeleteInvalidForms(const std::vector &formIds, const sptr &callerToken, int32_t &numFormsDeleted) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("delete form permission denied"); return ret; } FormEventInfo eventInfo; FormEventReport::SendFormEvent(FormEventName::DELETE_INVALID_FORM, HiSysEventType::BEHAVIOR, eventInfo); int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_DeleteInvalidForms", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ret = FormMgrAdapter::GetInstance().DeleteInvalidForms(formIds, callerToken, numFormsDeleted); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Acquire form state info by passing a set of parameters (using Want) to the form provider. * @param want Indicates a set of parameters to be transparently passed to the form provider. * @param callerToken Caller ability token. * @param stateInfo Returns the form's state info of the specify. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::AcquireFormState(const Want &want, const sptr &callerToken, FormStateInfo &stateInfo) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("acquire form state permission denied"); return ret; } FormEventInfo eventInfo; eventInfo.bundleName = want.GetElement().GetBundleName(); eventInfo.moduleName = want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY); eventInfo.abilityName = want.GetElement().GetAbilityName(); FormEventReport::SendFormEvent(FormEventName::ACQUIREFORMSTATE_FORM, HiSysEventType::BEHAVIOR, eventInfo); return FormMgrAdapter::GetInstance().AcquireFormState(want, callerToken, stateInfo); } /** * @brief Register form router event proxy. * @param formIds Indicates the ID of the forms. * @param callerToken Host client. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::RegisterFormRouterProxy(const std::vector &formIds, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("register form router proxy permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterFormRouterProxy(formIds, callerToken); } /** * @brief Unregister form router event proxy. * @param formIds Indicates the ID of the forms. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::UnregisterFormRouterProxy(const std::vector &formIds) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("unregister form router proxy permission denied"); return ret; } return FormMgrAdapter::GetInstance().UnregisterFormRouterProxy(formIds); } /** * @brief Notify the form is visible or not. * @param formIds Indicates the ID of the forms. * @param isVisible Visible or not. * @param callerToken Host client. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::NotifyFormsVisible(const std::vector &formIds, bool isVisible, const sptr &callerToken) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("notify form visible permission denied"); return ret; } return FormMgrAdapter::GetInstance().NotifyFormsVisible(formIds, isVisible, callerToken); } int FormMgrService::NotifyFormsPrivacyProtected(const std::vector &formIds, bool isProtected, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("notify form is privacy protected permission denied"); return ret; } return ERR_APPEXECFWK_FORM_COMMON_CODE; } /** * @brief Notify the form is enable to be updated or not. * @param formIds Indicates the ID of the forms. * @param isEnableUpdate enable update or not. * @param callerToken Host client. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::NotifyFormsEnableUpdate(const std::vector &formIds, bool isEnableUpdate, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("notify form enable update permission denied"); return ret; } return FormMgrAdapter::GetInstance().NotifyFormsEnableUpdate(formIds, isEnableUpdate, callerToken); } /** * @brief Get All FormsInfo. * @param formInfos Return the form information of all forms provided. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::GetAllFormsInfo(std::vector &formInfos) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_GetAllFormsInfo", API_TIME_OUT_8S, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ErrCode ret = FormMgrAdapter::GetInstance().GetAllFormsInfo(formInfos); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Get forms info by bundle name. * @param bundleName Application name. * @param formInfos Return the form information of the specify application name. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::GetFormsInfoByApp(std::string &bundleName, std::vector &formInfos) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_GetFormsInfoByApp", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); ErrCode ret = FormMgrAdapter::GetInstance().GetFormsInfoByApp(bundleName, formInfos); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return ret; } /** * @brief Get forms info by bundle name and module name. * @param bundleName bundle name. * @param moduleName Module name of hap. * @param formInfos Return the forms information of the specify bundle name and module name. * @return Returns ERR_OK on success, others on failure. */ int FormMgrService::GetFormsInfoByModule(std::string &bundleName, std::string &moduleName, std::vector &formInfos) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } return FormMgrAdapter::GetInstance().GetFormsInfoByModule(bundleName, moduleName, formInfos); } int FormMgrService::GetFormsInfoByFilter(const FormInfoFilter &filter, std::vector &formInfos) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { HILOG_ERROR("Need system authority"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } return FormMgrAdapter::GetInstance().GetFormsInfoByFilter(filter, formInfos); } int32_t FormMgrService::GetFormsInfo(const FormInfoFilter &filter, std::vector &formInfos) { HILOG_DEBUG("call"); std::string callerBundleName; ErrCode ret = FormBmsHelper::GetInstance().GetCallerBundleName(callerBundleName); if (ret != ERR_OK) { HILOG_ERROR("get host bundle name failed"); return ret; } // retrieve moduleName from filter. std::string moduleName = filter.moduleName; if (moduleName.empty()) { // fulfill formInfos, the process should be the same as GetFormsInfoByApp. HILOG_INFO("flows to GetFormsInfoByAPP"); return FormMgrAdapter::GetInstance().GetFormsInfoByApp(callerBundleName, formInfos); } HILOG_INFO("flows to GetFormsInfoByModule"); return FormMgrAdapter::GetInstance().GetFormsInfoByModule(callerBundleName, moduleName, formInfos); } int32_t FormMgrService::AcquireFormData(int64_t formId, int64_t requestCode, const sptr &callerToken, AAFwk::WantParams &formData) { HILOG_DEBUG("call"); if (formId <= 0) { HILOG_ERROR("invalid formId"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } if (callerToken == nullptr) { HILOG_ERROR("null callerToken"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } if (requestCode <= 0) { HILOG_ERROR("invalid requestCode"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("request form permission denied"); return ret; } return FormMgrAdapter::GetInstance().AcquireFormData(formId, requestCode, callerToken, formData); } bool FormMgrService::IsRequestPublishFormSupported() { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return false; } return FormMgrAdapter::GetInstance().IsRequestPublishFormSupported(); } int32_t FormMgrService::StartAbility(const Want &want, const sptr &callerToken) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_START_ABILITIES_FROM_BACKGROUND); if (ret != ERR_OK) { HILOG_ERROR("start ability check permission denied"); return ret; } // check abilityName and uri to void implicit want. if (want.GetElement().GetAbilityName().empty() && want.GetUriString().empty()) { HILOG_ERROR("empty AbilityName and uri"); return ERR_APPEXECFWK_FORM_NO_SUCH_ABILITY; } sptr ams = FormAmsHelper::GetInstance().GetAbilityManager(); if (ams == nullptr) { HILOG_ERROR("fail get abilityMgr"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } return ams->StartAbility(want, callerToken, -1, -1); } void FormMgrService::InitFormShareMgrSerialQueue() { DelayedSingleton::GetInstance()->SetSerialQueue(serialQueue_); DelayedSingleton::GetInstance()->SetEventHandler(handler_); } int32_t FormMgrService::ShareForm(int64_t formId, const std::string &deviceId, const sptr &callerToken, int64_t requestCode) { HILOG_DEBUG("FormMgrService ShareForm call deviceId :%{public}s, formId:%{public}" PRId64 "", deviceId.c_str(), formId); if (formId <= 0) { HILOG_ERROR("invalid formId"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } if (deviceId.empty()) { HILOG_ERROR("empty deviceId"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } if (callerToken == nullptr) { HILOG_ERROR("null callerToken"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } if (requestCode <= 0) { HILOG_ERROR("invalid requestCode"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } auto ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("share form permission denied"); return ret; } ret = FormDataMgr::GetInstance().CheckInvalidForm(formId); if (ret != ERR_OK) { HILOG_ERROR("invalid formId or not under currentActiveUser"); return ret; } InitFormShareMgrSerialQueue(); return DelayedSingleton::GetInstance()->ShareForm(formId, deviceId, callerToken, requestCode); } int32_t FormMgrService::RecvFormShareInfoFromRemote(const FormShareInfo &info) { HILOG_DEBUG("call"); if (!FormUtil::IsSACall()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } InitFormShareMgrSerialQueue(); return DelayedSingleton::GetInstance()->RecvFormShareInfoFromRemote(info); } int FormMgrService::Dump(int fd, const std::vector &args) { if (!CheckFMSReady()) { HILOG_ERROR("fms not ready"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } std::string result; Dump(args, result); int ret = dprintf(fd, "%s\n", result.c_str()); if (ret < 0) { HILOG_ERROR("format dprintf error"); return ERR_APPEXECFWK_FORM_COMMON_CODE; } return ERR_OK; } void FormMgrService::Dump(const std::vector &args, std::string &result) { DumpKey key; std::string value; if (!ParseOption(args, key, value, result)) { result.append('\n' + FORM_DUMP_HELP); return; } switch (key) { case DumpKey::KEY_DUMP_HELP: return HiDumpHelp(value, result); case DumpKey::KEY_DUMP_STATIC: return HiDumpStaticBundleFormInfos(value, result); case DumpKey::KEY_DUMP_STORAGE: return HiDumpStorageFormInfos(value, result); case DumpKey::KEY_DUMP_VISIBLE: return HiDumpHasFormVisible(value, result); case DumpKey::KEY_DUMP_TEMPORARY: return HiDumpTemporaryFormInfos(value, result); case DumpKey::KEY_DUMP_BY_BUNDLE_NAME: return HiDumpFormInfoByBundleName(value, result); case DumpKey::KEY_DUMP_BY_FORM_ID: return HiDumpFormInfoByFormId(value, result); case DumpKey::KEY_DUMP_RUNNING: return HiDumpFormRunningFormInfos(value, result); case DumpKey::KEY_DUMP_BLOCKED_APPS: return HiDumpFormBlockedApps(value, result); default: result = "error: unknow function."; return; } } int32_t FormMgrService::RegisterPublishFormInterceptor(const sptr &interceptorCallback) { HILOG_DEBUG("call"); sptr bundleMgr = FormBmsHelper::GetInstance().GetBundleMgr(); if (bundleMgr == nullptr) { HILOG_ERROR("error to get bundleMgr"); return ERR_APPEXECFWK_FORM_GET_BMS_FAILED; } // check if system app auto callingUid = IPCSkeleton::GetCallingUid(); auto isSystemApp = bundleMgr->CheckIsSystemAppByUid(callingUid); if (!isSystemApp) { HILOG_ERROR("no permission"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } return FormMgrAdapter::GetInstance().RegisterPublishFormInterceptor(interceptorCallback); } int32_t FormMgrService::UnregisterPublishFormInterceptor(const sptr &interceptorCallback) { HILOG_DEBUG("call"); sptr bundleMgr = FormBmsHelper::GetInstance().GetBundleMgr(); if (bundleMgr == nullptr) { HILOG_ERROR("fail get bundleMgr"); return ERR_APPEXECFWK_FORM_GET_BMS_FAILED; } // check if system app auto callingUid = IPCSkeleton::GetCallingUid(); auto isSystemApp = bundleMgr->CheckIsSystemAppByUid(callingUid); if (!isSystemApp) { HILOG_ERROR("permission denied"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } return FormMgrAdapter::GetInstance().UnregisterPublishFormInterceptor(interceptorCallback); } void FormMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) { #ifdef RES_SCHEDULE_ENABLE if (systemAbilityId == RES_SCHED_SYS_ABILITY_ID) { auto formSystemloadLevelCb = [this](int32_t level) { this->OnSystemloadLevel(level); }; sptr formSystemloadListener = new (std::nothrow) FormSystemloadListener(formSystemloadLevelCb); ResourceSchedule::ResSchedClient::GetInstance().RegisterSystemloadNotifier(formSystemloadListener); HILOG_INFO("RegisterSystemloadNotifier for Systemloadlevel change"); return; } #endif // RES_SCHEDULE_ENABLE #ifdef MEM_MGR_ENABLE if (systemAbilityId == MEMORY_MANAGER_SA_ID) { HILOG_INFO("MEMORY_MANAGER_SA start,SubscribeAppState"); Memory::MemMgrClient::GetInstance().SubscribeAppState(*memStatusListener_); return; } #endif // MEM_MGR_ENABLE if (systemAbilityId != DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID) { return; } onKvDataServiceAddTime_ = GetCurrentDateTime(); FormDataProxyMgr::GetInstance().RetryFailureSubscribes(); HILOG_INFO("FMS KV data service add time:%{public}s", onKvDataServiceAddTime_.c_str()); } bool FormMgrService::ParseOption(const std::vector &args, DumpKey &key, std::string &value, std::string &result) { auto size = args.size(); if (size == 0) { result = "error: must contain arguments."; return false; } if (size > FORM_DUMP_ARGC_MAX) { result = "error: arguments numer out of limit."; return false; } std::string optionKey = Str16ToStr8(args[0]); auto iter = dumpKeyMap_.find(optionKey); if (iter == dumpKeyMap_.end()) { result = "error: unknown option."; return false; } key = iter->second; if (args.size() == FORM_DUMP_ARGC_MAX) { value = Str16ToStr8(args[1]); } return true; } void FormMgrService::HiDumpFormRunningFormInfos([[maybe_unused]]const std::string &args, std::string &result) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return; } FormMgrAdapter::GetInstance().DumpFormRunningFormInfos(result); } void FormMgrService::HiDumpHelp([[maybe_unused]] const std::string &args, std::string &result) { result = FORM_DUMP_HELP; } void FormMgrService::HiDumpStorageFormInfos([[maybe_unused]] const std::string &args, std::string &result) { DumpStorageFormInfos(result); } void FormMgrService::HiDumpTemporaryFormInfos([[maybe_unused]] const std::string &args, std::string &result) { if (!CheckCallerIsSystemApp()) { return; } FormMgrAdapter::GetInstance().DumpTemporaryFormInfos(result); } void FormMgrService::HiDumpStaticBundleFormInfos([[maybe_unused]] const std::string &args, std::string &result) { if (!CheckCallerIsSystemApp()) { return; } FormMgrAdapter::GetInstance().DumpStaticBundleFormInfos(result); } void FormMgrService::HiDumpFormInfoByBundleName(const std::string &args, std::string &result) { if (args.empty()) { result = "error: request a bundle name."; return; } DumpFormInfoByBundleName(args, result); } void FormMgrService::HiDumpHasFormVisible(const std::string &args, std::string &result) { if (args.empty()) { result = "error:request bundle info like bundleName_userId_instIndex."; } FormMgrAdapter::GetInstance().DumpHasFormVisible(args, result); } void FormMgrService::HiDumpFormBlockedApps([[maybe_unused]] const std::string &args, std::string &result) { if (!CheckCallerIsSystemApp()) { return; } FormTrustMgr::GetInstance().GetUntrustAppNameList(result); } void FormMgrService::HiDumpFormInfoByFormId(const std::string &args, std::string &result) { if (args.empty()) { result = "error: request a form ID."; return; } int64_t formId = atoll(args.c_str()); if (formId == 0) { result = "error: form ID is invalid."; return; } DumpFormInfoByFormId(formId, result); } bool FormMgrService::CheckCallerIsSystemApp() const { auto callerTokenID = IPCSkeleton::GetCallingFullTokenID(); if (!FormUtil::IsSACall() && !Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callerTokenID)) { HILOG_ERROR("The caller not system-app,can't use system-api"); return false; } return true; } std::string FormMgrService::GetCurrentDateTime() { auto cTimeNow = std::chrono::system_clock::now(); auto microPart = std::chrono::duration_cast( cTimeNow.time_since_epoch()).count() % 1000; std::time_t t1 = std::chrono::system_clock::to_time_t(cTimeNow); char buf[32]; std::tm t2; localtime_r(&t1, &t2); (void)strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.", &t2); std::stringstream ss; ss << buf << std::setw(MILLISECOND_WIDTH) << std::setfill(MILLISECOND_FILLCHAR) << microPart; return ss.str(); } bool FormMgrService::CheckAcrossLocalAccountsPermission() const { // checks whether the current user is inactive int callingUid = IPCSkeleton::GetCallingUid(); int32_t userId = callingUid / Constants::CALLING_UID_TRANSFORM_DIVISOR; int32_t currentActiveUserId = FormUtil::GetCurrentAccountId(); if (userId != currentActiveUserId) { HILOG_INFO("currentActiveUserId:%{public}d, userId:%{public}d", currentActiveUserId, userId); bool isCallingPermAccount = FormUtil::VerifyCallingPermission(AppExecFwk::Constants::PERMISSION_INTERACT_ACROSS_LOCAL_ACCOUNTS); if (!isCallingPermAccount) { HILOG_ERROR("Across local accounts permission failed"); return false; } } return true; } ErrCode FormMgrService::RegisterFormAddObserverByBundle(const std::string bundleName, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("register form add observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterFormAddObserverByBundle(bundleName, callerToken); } ErrCode FormMgrService::RegisterFormRemoveObserverByBundle(const std::string bundleName, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("register form remove observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterFormRemoveObserverByBundle(bundleName, callerToken); } int32_t FormMgrService::GetFormsCount(bool isTempFormFlag, int32_t &formCount) { HILOG_DEBUG("call"); return FormMgrAdapter::GetInstance().GetFormsCount(isTempFormFlag, formCount); } int32_t FormMgrService::GetHostFormsCount(std::string &bundleName, int32_t &formCount) { HILOG_DEBUG("call"); return FormMgrAdapter::GetInstance().GetHostFormsCount(bundleName, formCount); } ErrCode FormMgrService::GetRunningFormInfos(bool isUnusedIncluded, std::vector &runningFormInfos) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("get running form infos permission denied"); return ret; } return FormMgrAdapter::GetInstance().GetRunningFormInfos(isUnusedIncluded, runningFormInfos); } ErrCode FormMgrService::GetRunningFormInfosByBundleName( const std::string &bundleName, bool isUnusedIncluded, std::vector &runningFormInfos) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("get running form infos by bundle name permission denied"); return ret; } return FormMgrAdapter::GetInstance().GetRunningFormInfosByBundleName( bundleName, isUnusedIncluded, runningFormInfos); } ErrCode FormMgrService::GetFormInstancesByFilter(const FormInstancesFilter &formInstancesFilter, std::vector &formInstances) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("get form instances by filter permission denied"); return ret; } return FormMgrAdapter::GetInstance().GetFormInstancesByFilter(formInstancesFilter, formInstances); } ErrCode FormMgrService::GetFormInstanceById(const int64_t formId, FormInstance &formInstance) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("get form instance by id permission denied"); return ret; } return FormMgrAdapter::GetInstance().GetFormInstanceById(formId, formInstance); } ErrCode FormMgrService::GetFormInstanceById(const int64_t formId, bool isUnusedIncluded, FormInstance &formInstance) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("get form instance by id permission denied"); return ret; } return FormMgrAdapter::GetInstance().GetFormInstanceById(formId, isUnusedIncluded, formInstance); } ErrCode FormMgrService::RegisterAddObserver(const std::string &bundleName, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("register notifyVisible or notifyInVisible observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterAddObserver(bundleName, callerToken); } ErrCode FormMgrService::RegisterRemoveObserver(const std::string &bundleName, const sptr &callerToken) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("unregister notifyVisible or notifyInVisible observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterRemoveObserver(bundleName, callerToken); } ErrCode FormMgrService::UpdateProxyForm(int64_t formId, const FormProviderData &formBindingData, const std::vector &formDataProxies) { HILOG_DEBUG("call"); auto callingUid = IPCSkeleton::GetCallingUid(); return FormMgrAdapter::GetInstance().UpdateForm(formId, callingUid, formBindingData, formDataProxies); } ErrCode FormMgrService::RequestPublishProxyForm(Want &want, bool withFormBindingData, std::unique_ptr &formBindingData, int64_t &formId, const std::vector &formDataProxies) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } if (!CheckAcrossLocalAccountsPermission()) { HILOG_ERROR("Across local accounts permission failed"); return ERR_APPEXECFWK_FORM_PERMISSION_DENY; } return FormMgrAdapter::GetInstance().RequestPublishForm(want, withFormBindingData, formBindingData, formId, formDataProxies); } ErrCode FormMgrService::RegisterClickEventObserver( const std::string &bundleName, const std::string &formEventType, const sptr &observer) { HILOG_DEBUG("call"); if (observer == nullptr) { HILOG_ERROR("empty callerTokenParameter"); return ERR_APPEXECFWK_FORM_INVALID_PARAM; } ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("register form add observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().RegisterClickEventObserver(bundleName, formEventType, observer); } ErrCode FormMgrService::UnregisterClickEventObserver( const std::string &bundleName, const std::string &formEventType, const sptr &observer) { HILOG_DEBUG("call"); if (observer == nullptr) { HILOG_ERROR("empty callerTokenParameter"); return ERR_APPEXECFWK_FORM_INVALID_PARAM; } ErrCode ret = CheckFormPermission(AppExecFwk::Constants::PERMISSION_OBSERVE_FORM_RUNNING); if (ret != ERR_OK) { HILOG_ERROR("register form add observer permission denied"); return ret; } return FormMgrAdapter::GetInstance().UnregisterClickEventObserver(bundleName, formEventType, observer); } int32_t FormMgrService::SetFormsRecyclable(const std::vector &formIds) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("set forms recyclable permission denied"); return ret; } return FormMgrAdapter::GetInstance().SetFormsRecyclable(formIds); } int32_t FormMgrService::RecycleForms(const std::vector &formIds, const Want &want) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("recycle forms permission denied"); return ret; } return FormMgrAdapter::GetInstance().RecycleForms(formIds, want); } int32_t FormMgrService::RecoverForms(const std::vector &formIds, const Want &want) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("recover forms permission denied"); return ret; } return FormMgrAdapter::GetInstance().RecoverForms(formIds, want); } ErrCode FormMgrService::UpdateFormLocation(const int64_t &formId, const int32_t &formLocation) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("update formLocation form infos permission denied"); return ret; } return FormMgrAdapter::GetInstance().UpdateFormLocation(formId, formLocation); } ErrCode FormMgrService::BatchRefreshForms(const int32_t formRefreshType) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("batch update forms permission denied"); return ret; } return FormMgrAdapter::GetInstance().BatchRefreshForms(formRefreshType); } ErrCode FormMgrService::RequestPublishFormWithSnapshot(Want &want, bool withFormBindingData, std::unique_ptr &formBindingData, int64_t &formId) { HILOG_INFO("begin:%{public}s, publish:%{public}s, end:%{public}s, onKvDataServiceAddTime:%{public}s", onStartBeginTime_.c_str(), onStartPublishTime_.c_str(), onStartEndTime_.c_str(), onKvDataServiceAddTime_.c_str()); return FormMgrAdapter::GetInstance().RequestPublishForm(want, withFormBindingData, formBindingData, formId, {}, false); } #ifdef RES_SCHEDULE_ENABLE void FormMgrService::OnSystemloadLevel(int32_t level) { if (level >= SYSTEMLOADLEVEL_TIMERSTOP_THRESHOLD) { FormMgrAdapter::GetInstance().SetTimerTaskNeeded(false); } else { FormMgrAdapter::GetInstance().SetTimerTaskNeeded(true); } } #endif // RES_SCHEDULE_ENABLE int32_t FormMgrService::EnableForms(const std::string bundleName, const bool enable) { ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("disable forms permission denied"); return ret; } return FormMgrAdapter::GetInstance().EnableForms(bundleName, enable); } bool FormMgrService::IsFormBundleForbidden(const std::string &bundleName) { HILOG_DEBUG("call"); if (!CheckCallerIsSystemApp()) { return ERR_APPEXECFWK_FORM_PERMISSION_DENY_SYS; } int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FMS_IsFormBundleForbidden", API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG); bool result = FormBundleForbidMgr::GetInstance().IsBundleForbidden(bundleName); HiviewDFX::XCollie::GetInstance().CancelTimer(timerId); return result; } ErrCode FormMgrService::UpdateFormSize(const int64_t &formId, float width, float height, float borderWidth) { HILOG_DEBUG("call"); ErrCode ret = CheckFormPermission(); if (ret != ERR_OK) { HILOG_ERROR("update formSize permission denied"); return ret; } return FormMgrAdapter::GetInstance().UpdateFormSize(formId, width, height, borderWidth); } } // namespace AppExecFwk } // namespace OHOS