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