1 /*
2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <unordered_map>
17
18 #include "form_ability_connection_reporter.h"
19 #include "fms_log_wrapper.h"
20 #include "form_mgr_errors.h"
21 #include "form_util.h"
22 #include "iremote_proxy.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #ifdef RES_SCHEDULE_ENABLE
26 #include "res_sched_client.h"
27 #include "res_type.h"
28 #endif
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 const std::string FORM_CONNECTION_PROCESS_NAME_SUFFIX = ":form";
34 }
35
FormAbilityConnectionReporter()36 FormAbilityConnectionReporter::FormAbilityConnectionReporter()
37 {
38 HILOG_INFO("Call");
39 }
40
~FormAbilityConnectionReporter()41 FormAbilityConnectionReporter::~FormAbilityConnectionReporter()
42 {
43 HILOG_INFO("Call");
44 }
45
ReportFormAbilityConnection(const std::string & bundleName)46 void FormAbilityConnectionReporter::ReportFormAbilityConnection(const std::string &bundleName)
47 {
48 if (bundleName.empty()) {
49 HILOG_ERROR("Invalid bundleName");
50 return;
51 }
52 std::lock_guard<std::mutex> lock(formConnectionInfoMapMutex_);
53 auto iter = formConnectionInfoMap_.find(bundleName);
54 if (iter != formConnectionInfoMap_.end()) {
55 FormConnectionInfo &connectionInfo = iter->second;
56 connectionInfo.connectCount_++;
57 return;
58 }
59 auto appMgr = GetAppMgr();
60 std::vector<AppExecFwk::RunningProcessInfo> infos;
61 int32_t userId = FormUtil::GetCurrentAccountId();
62 int32_t ret = appMgr->GetRunningProcessInformation(bundleName, userId, infos);
63 if (ret != ERR_OK) {
64 HILOG_ERROR("Get running process info failed");
65 return;
66 }
67 HILOG_INFO("BundleName:%{public}s, infosSize:%{public}zu",
68 bundleName.c_str(), infos.size());
69 AddFormAbilityConnectProcessInfo(bundleName, infos);
70 ReportConnectionInfosToRss(bundleName, true);
71 }
72
ReportFormAbilityDisconnection(const std::string & bundleName)73 void FormAbilityConnectionReporter::ReportFormAbilityDisconnection(const std::string &bundleName)
74 {
75 if (bundleName.empty()) {
76 HILOG_ERROR("Invalid bundleName");
77 return;
78 }
79 std::lock_guard<std::mutex> lock(formConnectionInfoMapMutex_);
80 auto iter = formConnectionInfoMap_.find(bundleName);
81 if (iter == formConnectionInfoMap_.end()) {
82 HILOG_ERROR("Disconnect ability connection:%{public}s, but without created connection notified!",
83 bundleName.c_str());
84 return;
85 }
86 int count = iter->second.connectCount_ - 1;
87 if (count > 0) {
88 formConnectionInfoMap_[bundleName].connectCount_ = count;
89 return;
90 }
91
92 ReportConnectionInfosToRss(bundleName, false);
93 formConnectionInfoMap_.erase(bundleName);
94 HILOG_INFO("bundleName:%{public}s", bundleName.c_str());
95 }
96
GetAppMgr()97 sptr<OHOS::AppExecFwk::IAppMgr> FormAbilityConnectionReporter::GetAppMgr()
98 {
99 if (appManager_ == nullptr) {
100 sptr<ISystemAbilityManager> systemMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
101 if (systemMgr == nullptr) {
102 HILOG_ERROR("connect systemAbilityManager failed");
103 return nullptr;
104 }
105 sptr<IRemoteObject> remoteObject = systemMgr->GetSystemAbility(APP_MGR_SERVICE_ID);
106 if (remoteObject == nullptr) {
107 HILOG_ERROR("connect appMgrService failed");
108 return nullptr;
109 }
110 HILOG_INFO("ConnectAMS succeed");
111 appManager_ = iface_cast<OHOS::AppExecFwk::IAppMgr>(remoteObject);
112 }
113 return appManager_;
114 }
115
AddFormAbilityConnectProcessInfo(const std::string & bundleName,std::vector<AppExecFwk::RunningProcessInfo> & infos)116 void FormAbilityConnectionReporter::AddFormAbilityConnectProcessInfo(const std::string& bundleName,
117 std::vector<AppExecFwk::RunningProcessInfo>& infos)
118 {
119 if (bundleName.empty()) {
120 HILOG_WARN("Empty bundle name");
121 infos.clear();
122 return;
123 }
124 std::string targetProceName = bundleName + FORM_CONNECTION_PROCESS_NAME_SUFFIX;
125 for (std::vector<AppExecFwk::RunningProcessInfo>::iterator iter = infos.begin(); iter != infos.end(); iter++) {
126 if ((*iter).processName_ != targetProceName) {
127 continue;
128 }
129 HILOG_INFO("Get running process:%{public}s, pid:%{public}" PRId32, targetProceName.c_str(),
130 (*iter).pid_);
131 FormConnectionInfo connectionInfo;
132 connectionInfo.pid_ = (*iter).pid_;
133 connectionInfo.connectCount_ = 1;
134 formConnectionInfoMap_.emplace(bundleName, connectionInfo);
135 return;
136 }
137 }
138
ReportConnectionInfosToRss(const std::string & bundleName,bool isConnected)139 void FormAbilityConnectionReporter::ReportConnectionInfosToRss(const std::string &bundleName,
140 bool isConnected)
141 {
142 auto iter = formConnectionInfoMap_.find(bundleName);
143 if (iter == formConnectionInfoMap_.end()) {
144 HILOG_WARN("Report connection info failed, empty info, bundle name:%{public}s",
145 bundleName.c_str());
146 return;
147 }
148 #ifdef RES_SCHEDULE_ENABLE
149 auto status = isConnected ? ResourceSchedule::ResType::FormCreateStatus::FormCreateStart
150 : ResourceSchedule::ResType::FormCreateStatus::FormCreateEnd;
151 std::unordered_map<std::string, std::string> payload = {
152 {"saId", std::to_string(FORM_MGR_SERVICE_ID)},
153 {"pid", std::to_string(iter->second.pid_)}
154 };
155 ResourceSchedule::ResSchedClient::GetInstance().ReportData(
156 ResourceSchedule::ResType::RES_TYPE_FORM_STATE_CHANGE_EVENT, status, payload);
157 #endif
158 }
159 } // namespace AppExecFwk
160 } // namespace OHOS