• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "ecological_rule/ability_ecological_rule_mgr_service.h"
17 
18 #include "ability_manager_errors.h"
19 #include "iservice_registry.h"
20 #include "hilog_tag_wrapper.h"
21 #include "hitrace_meter.h"
22 #include "ipc_capacity_wrap.h"
23 #include "record_cost_time_util.h"
24 
25 namespace OHOS {
26 using AAFwk::RecordCostTimeUtil;
27 namespace EcologicalRuleMgrService {
28 
29 using namespace std::chrono;
30 
31 static inline const std::u16string ERMS_INTERFACE_TOKEN =
32     u"ohos.cloud.ecologicalrulemgrservice.IEcologicalRuleMgrService";
33 constexpr int32_t CYCLE_LIMIT = 1000;
34 const int32_t ECOLOGICALRULEMANAGERSERVICE_ID = 6105;
35 
36 std::mutex AbilityEcologicalRuleMgrServiceClient::instanceLock_;
37 std::mutex AbilityEcologicalRuleMgrServiceClient::proxyLock_;
38 sptr<AbilityEcologicalRuleMgrServiceClient> AbilityEcologicalRuleMgrServiceClient::instance_;
39 sptr<IAbilityEcologicalRuleMgrService> AbilityEcologicalRuleMgrServiceClient::ecologicalRuleMgrServiceProxy_;
40 sptr<IRemoteObject::DeathRecipient> AbilityEcologicalRuleMgrServiceClient::deathRecipient_;
41 
42 std::string AbilityEcologicalRuleMgrServiceClient::ERMS_ORIGINAL_TARGET = "ecological_experience_original_target";
43 
GetCurrentTimeMicro()44 inline int64_t GetCurrentTimeMicro()
45 {
46     return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
47 }
48 
~AbilityEcologicalRuleMgrServiceClient()49 AbilityEcologicalRuleMgrServiceClient::~AbilityEcologicalRuleMgrServiceClient()
50 {
51     std::lock_guard<std::mutex> autoLock(proxyLock_);
52     if (ecologicalRuleMgrServiceProxy_ != nullptr) {
53         auto remoteObj = ecologicalRuleMgrServiceProxy_->AsObject();
54         if (remoteObj != nullptr) {
55             remoteObj->RemoveDeathRecipient(deathRecipient_);
56         }
57     }
58 }
59 
GetInstance()60 sptr<AbilityEcologicalRuleMgrServiceClient> AbilityEcologicalRuleMgrServiceClient::GetInstance()
61 {
62     if (instance_ == nullptr) {
63         std::lock_guard<std::mutex> autoLock(instanceLock_);
64         if (instance_ == nullptr) {
65             instance_ = new AbilityEcologicalRuleMgrServiceClient;
66         }
67     }
68     return instance_;
69 }
70 
ConnectService()71 sptr<IAbilityEcologicalRuleMgrService> AbilityEcologicalRuleMgrServiceClient::ConnectService()
72 {
73     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
74     if (samgr == nullptr) {
75         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null samgr");
76         return nullptr;
77     }
78 
79     auto systemAbility = samgr->CheckSystemAbility(ECOLOGICALRULEMANAGERSERVICE_ID);
80     if (systemAbility == nullptr) {
81         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null systemAbility");
82         return nullptr;
83     }
84 
85     deathRecipient_ = new AbilityEcologicalRuleMgrServiceDeathRecipient();
86     systemAbility->AddDeathRecipient(deathRecipient_);
87 
88     sptr<IAbilityEcologicalRuleMgrService> service = iface_cast<IAbilityEcologicalRuleMgrService>(systemAbility);
89     if (service == nullptr) {
90         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "erms transfered to foundation");
91         service = new AbilityEcologicalRuleMgrServiceProxy(systemAbility);
92     }
93     return service;
94 }
95 
CheckConnectService()96 bool AbilityEcologicalRuleMgrServiceClient::CheckConnectService()
97 {
98     std::lock_guard<std::mutex> autoLock(proxyLock_);
99     if (ecologicalRuleMgrServiceProxy_ == nullptr) {
100         TAG_LOGW(AAFwkTag::ECOLOGICAL_RULE, "redo ConnectService");
101         ecologicalRuleMgrServiceProxy_ = ConnectService();
102     }
103     if (ecologicalRuleMgrServiceProxy_ == nullptr) {
104         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "Connect SA Failed");
105         return false;
106     }
107     return true;
108 }
109 
OnRemoteSaDied(const wptr<IRemoteObject> & object)110 void AbilityEcologicalRuleMgrServiceClient::OnRemoteSaDied(const wptr<IRemoteObject> &object)
111 {
112     std::lock_guard<std::mutex> autoLock(proxyLock_);
113     ecologicalRuleMgrServiceProxy_ = ConnectService();
114 }
115 
EvaluateResolveInfos(const AAFwk::Want & want,const AbilityCallerInfo & callerInfo,int32_t type,vector<AbilityInfo> & abilityInfos,const vector<AppExecFwk::ExtensionAbilityInfo> & extInfos)116 int32_t AbilityEcologicalRuleMgrServiceClient::EvaluateResolveInfos(const AAFwk::Want &want,
117     const AbilityCallerInfo &callerInfo, int32_t type, vector<AbilityInfo> &abilityInfos,
118     const vector<AppExecFwk::ExtensionAbilityInfo> &extInfos)
119 {
120     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
121     RecordCostTimeUtil("EvaluateResolveInfos");
122     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "want: %{private}s, callerInfo: %{public}s, type: %{public}d",
123         want.ToString().c_str(), callerInfo.ToString().c_str(), type);
124     if (!CheckConnectService()) {
125         return AAFwk::ERR_CONNECT_ERMS_FAILED;
126     }
127     return ecologicalRuleMgrServiceProxy_->EvaluateResolveInfos(want, callerInfo, type, abilityInfos);
128 }
129 
QueryStartExperience(const OHOS::AAFwk::Want & want,const AbilityCallerInfo & callerInfo,AbilityExperienceRule & rule)130 int32_t AbilityEcologicalRuleMgrServiceClient::QueryStartExperience(const OHOS::AAFwk::Want &want,
131     const AbilityCallerInfo &callerInfo, AbilityExperienceRule &rule)
132 {
133     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
134     RecordCostTimeUtil("QueryStartExperience");
135     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "callerInfo: %{public}s, want: %{private}s", callerInfo.ToString().c_str(),
136         want.ToString().c_str());
137 
138     if (!CheckConnectService()) {
139         return AAFwk::ERR_CONNECT_ERMS_FAILED;
140     }
141     int32_t res = ecologicalRuleMgrServiceProxy_->QueryStartExperience(want, callerInfo, rule);
142     if (rule.replaceWant != nullptr) {
143         rule.replaceWant->SetParam(ERMS_ORIGINAL_TARGET, want.ToString());
144         TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE,
145             "queryStart finish: resultCode = %{public}d, sceneCode = %{public}s, replaceWant = %{private}s",
146             rule.resultCode, rule.sceneCode.c_str(), (*(rule.replaceWant)).ToString().c_str());
147     }
148     return res;
149 }
150 
OnRemoteDied(const wptr<IRemoteObject> & object)151 void AbilityEcologicalRuleMgrServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
152 {
153     if (AbilityEcologicalRuleMgrServiceClient::GetInstance()) {
154         AbilityEcologicalRuleMgrServiceClient::GetInstance()->OnRemoteSaDied(object);
155     }
156 }
157 
AbilityEcologicalRuleMgrServiceProxy(const sptr<IRemoteObject> & impl)158 AbilityEcologicalRuleMgrServiceProxy::AbilityEcologicalRuleMgrServiceProxy(
159     const sptr<IRemoteObject>& impl) : IRemoteProxy<IAbilityEcologicalRuleMgrService>(impl)
160 {}
161 
EvaluateResolveInfos(const Want & want,const AbilityCallerInfo & callerInfo,int32_t type,std::vector<AbilityInfo> & abilityInfos)162 int32_t AbilityEcologicalRuleMgrServiceProxy::EvaluateResolveInfos(const Want &want,
163     const AbilityCallerInfo &callerInfo, int32_t type, std::vector<AbilityInfo> &abilityInfos)
164 {
165     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "called");
166     MessageParcel data;
167     AAFwk::ExtendMaxIpcCapacityForInnerWant(data);
168 
169     if (!data.WriteInterfaceToken(ERMS_INTERFACE_TOKEN)) {
170         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write token failed");
171         return ERR_FAILED;
172     }
173 
174     if (!data.WriteParcelable(&want)) {
175         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write want failed");
176         return ERR_FAILED;
177     }
178 
179     if (!data.WriteInt32(type)) {
180         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write type failed");
181         return ERR_FAILED;
182     }
183 
184     if (!data.WriteInt32(abilityInfos.size())) {
185         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write abilityInfos size failed");
186         return ERR_FAILED;
187     }
188 
189     for (auto &abilityInfo : abilityInfos) {
190         if (!data.WriteParcelable(&abilityInfo)) {
191             TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write abilityInfo failed");
192             return ERR_FAILED;
193         }
194     }
195 
196     if (!data.WriteParcelable(&callerInfo)) {
197         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write callerInfo failed");
198         return ERR_FAILED;
199     }
200 
201     MessageOption option = { MessageOption::TF_SYNC };
202     MessageParcel reply;
203 
204     auto remote = Remote();
205     if (remote == nullptr) {
206         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null remote");
207         return ERR_FAILED;
208     }
209 
210     int32_t ret = remote->SendRequest(EVALUATE_RESOLVE_INFO_CMD, data, reply, option);
211     if (ret != ERR_NONE) {
212         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "SendRequest error:%{public}d", ret);
213         return ERR_FAILED;
214     }
215 
216     if (!ReadParcelableVector(abilityInfos, reply)) {
217         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "GetParcelableInfos fail");
218     }
219     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "end");
220     return ERR_OK;
221 }
222 
223 template <typename T>
ReadParcelableVector(std::vector<T> & parcelableVector,MessageParcel & reply)224 bool AbilityEcologicalRuleMgrServiceProxy::ReadParcelableVector(std::vector<T> &parcelableVector, MessageParcel &reply)
225 {
226     int32_t infoSize = reply.ReadInt32();
227     if (infoSize > CYCLE_LIMIT) {
228         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "size too large");
229         return false;
230     }
231     parcelableVector.clear();
232     for (int32_t i = 0; i < infoSize; i++) {
233         sptr<T> info = reply.ReadParcelable<T>();
234         if (info == nullptr) {
235             TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null info");
236             return false;
237         }
238         parcelableVector.emplace_back(*info);
239     }
240     return true;
241 }
242 
QueryStartExperience(const Want & want,const AbilityCallerInfo & callerInfo,AbilityExperienceRule & rule)243 int32_t AbilityEcologicalRuleMgrServiceProxy::QueryStartExperience(const Want &want,
244     const AbilityCallerInfo &callerInfo, AbilityExperienceRule &rule)
245 {
246     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "called");
247     MessageParcel data;
248     AAFwk::ExtendMaxIpcCapacityForInnerWant(data);
249     if (!data.WriteInterfaceToken(ERMS_INTERFACE_TOKEN)) {
250         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write token failed");
251         return ERR_FAILED;
252     }
253 
254     if (!data.WriteParcelable(&want)) {
255         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write want failed");
256         return ERR_FAILED;
257     }
258 
259     if (!data.WriteParcelable(&callerInfo)) {
260         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write callerInfo failed");
261         return ERR_FAILED;
262     }
263 
264     MessageOption option = { MessageOption::TF_SYNC };
265     MessageParcel reply;
266 
267     auto remote = Remote();
268     if (remote == nullptr) {
269         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null remote");
270         return ERR_FAILED;
271     }
272 
273     int32_t ret = remote->SendRequest(QUERY_START_EXPERIENCE_CMD, data, reply, option);
274     if (ret != ERR_NONE) {
275         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "SendRequest error: %{public}d", ret);
276         return ERR_FAILED;
277     }
278 
279     sptr<AbilityExperienceRule> sptrRule = reply.ReadParcelable<AbilityExperienceRule>();
280     if (sptrRule == nullptr) {
281         TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "null sptrRule");
282         return ERR_FAILED;
283     }
284 
285     rule = *sptrRule;
286     TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "end");
287     return ERR_OK;
288 }
289 } // namespace EcologicalRuleMgrService
290 } // namespace OHOS
291