1 /*
2  * Copyright (c) 2023 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 "app_log_tag_wrapper.h"
17 #include "bms_ecological_rule_mgr_service_client.h"
18 #include "iservice_registry.h"
19 
20 namespace OHOS {
21 namespace AppExecFwk {
22 
23 using namespace std::chrono;
24 
25 static inline const std::u16string ERMS_INTERFACE_TOKEN =
26     u"ohos.cloud.ecologicalrulemgrservice.IEcologicalRuleMgrService";
27 
28 std::mutex BmsEcologicalRuleMgrServiceClient::instanceLock_;
29 sptr<BmsEcologicalRuleMgrServiceClient> BmsEcologicalRuleMgrServiceClient::instance_;
30 sptr<IBmsEcologicalRuleMgrService> BmsEcologicalRuleMgrServiceClient::bmsEcologicalRuleMgrServiceProxy_;
31 sptr<BmsEcologicalRuleMgrServiceDeathRecipient> BmsEcologicalRuleMgrServiceClient::deathRecipient_;
32 
33 std::string BmsEcologicalRuleMgrServiceClient::ERMS_ORIGINAL_TARGET = "ecological_experience_original_target";
34 
~BmsEcologicalRuleMgrServiceClient()35 BmsEcologicalRuleMgrServiceClient::~BmsEcologicalRuleMgrServiceClient()
36 {
37     if (bmsEcologicalRuleMgrServiceProxy_ != nullptr) {
38         auto remoteObj = bmsEcologicalRuleMgrServiceProxy_->AsObject();
39         if (remoteObj != nullptr) {
40             remoteObj->RemoveDeathRecipient(deathRecipient_);
41         }
42     }
43 }
44 
GetInstance()45 sptr<BmsEcologicalRuleMgrServiceClient> BmsEcologicalRuleMgrServiceClient::GetInstance()
46 {
47     if (instance_ == nullptr) {
48         std::lock_guard<std::mutex> autoLock(instanceLock_);
49         if (instance_ == nullptr) {
50             instance_ = (new (std::nothrow)  BmsEcologicalRuleMgrServiceClient);
51         }
52     }
53     return instance_;
54 }
55 
ConnectService()56 sptr<IBmsEcologicalRuleMgrService> BmsEcologicalRuleMgrServiceClient::ConnectService()
57 {
58     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59     if (samgr == nullptr) {
60         LOG_E(BMS_TAG_DEFAULT, "GetSystemAbilityManager error");
61         return nullptr;
62     }
63 
64     auto systemAbility = samgr->CheckSystemAbility(6105);
65     if (systemAbility == nullptr) {
66         LOG_E(BMS_TAG_DEFAULT, "CheckSystemAbility error, ECOLOGICALRULEMANAGERSERVICE_ID = 6105");
67         return nullptr;
68     }
69 
70     deathRecipient_ = (new (std::nothrow)   BmsEcologicalRuleMgrServiceDeathRecipient());
71     systemAbility->AddDeathRecipient(deathRecipient_);
72 
73     sptr<IBmsEcologicalRuleMgrService> iBmsErms = iface_cast<IBmsEcologicalRuleMgrService>(systemAbility);
74     if (iBmsErms == nullptr) {
75         LOG_E(BMS_TAG_DEFAULT, "systemAbility cast error");
76         iBmsErms = new BmsEcologicalRuleMgrServiceProxy(systemAbility);
77     }
78     return iBmsErms;
79 }
80 
CheckConnectService()81 bool BmsEcologicalRuleMgrServiceClient::CheckConnectService()
82 {
83     if (bmsEcologicalRuleMgrServiceProxy_ == nullptr) {
84         LOG_W(BMS_TAG_DEFAULT, "redo ConnectService");
85         bmsEcologicalRuleMgrServiceProxy_ = ConnectService();
86     }
87     if (bmsEcologicalRuleMgrServiceProxy_ == nullptr) {
88         LOG_E(BMS_TAG_DEFAULT, "Connect SA Failed");
89         return false;
90     }
91     return true;
92 }
93 
OnRemoteSaDied(const wptr<IRemoteObject> & object)94 void BmsEcologicalRuleMgrServiceClient::OnRemoteSaDied(const wptr<IRemoteObject> &object)
95 {
96     bmsEcologicalRuleMgrServiceProxy_ = ConnectService();
97 }
98 
QueryFreeInstallExperience(const OHOS::AAFwk::Want & want,const BmsCallerInfo & callerInfo,BmsExperienceRule & rule)99 int32_t BmsEcologicalRuleMgrServiceClient::QueryFreeInstallExperience(const OHOS::AAFwk::Want &want,
100     const BmsCallerInfo &callerInfo, BmsExperienceRule &rule)
101 {
102     LOG_D(BMS_TAG_DEFAULT, "want = %{public}s, callerInfo = %{public}s", want.ToString().c_str(),
103         callerInfo.ToString().c_str());
104 
105     if (!CheckConnectService()) {
106         LOG_W(BMS_TAG_DEFAULT, "check Connect SA Failed");
107         return OHOS::AppExecFwk::IBmsEcologicalRuleMgrService::ErrCode::ERR_FAILED;
108     }
109     int32_t res = bmsEcologicalRuleMgrServiceProxy_->QueryFreeInstallExperience(want, callerInfo, rule);
110     if (rule.replaceWant != nullptr) {
111         rule.replaceWant->SetParam(ERMS_ORIGINAL_TARGET, want.ToString());
112         LOG_D(BMS_TAG_DEFAULT, "isAllow = %{public}d, replaceWant = %{public}s", rule.isAllow,
113             (*(rule.replaceWant)).ToString().c_str());
114     }
115     return res;
116 }
117 
OnRemoteDied(const wptr<IRemoteObject> & object)118 void BmsEcologicalRuleMgrServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
119 {
120     BmsEcologicalRuleMgrServiceClient::GetInstance()->OnRemoteSaDied(object);
121 }
122 
BmsEcologicalRuleMgrServiceProxy(const sptr<IRemoteObject> & object)123 BmsEcologicalRuleMgrServiceProxy::BmsEcologicalRuleMgrServiceProxy(const sptr<IRemoteObject> &object)
124     : IRemoteProxy<IBmsEcologicalRuleMgrService>(object)
125 {}
126 
QueryFreeInstallExperience(const Want & want,const BmsCallerInfo & callerInfo,BmsExperienceRule & rule)127 int32_t BmsEcologicalRuleMgrServiceProxy::QueryFreeInstallExperience(const Want &want, const BmsCallerInfo &callerInfo,
128     BmsExperienceRule &rule)
129 {
130     LOG_I(BMS_TAG_DEFAULT, "QueryFreeInstallExperience called");
131     MessageParcel data;
132 
133     if (!data.WriteInterfaceToken(ERMS_INTERFACE_TOKEN)) {
134         LOG_E(BMS_TAG_DEFAULT, "write token failed");
135         return ERR_FAILED;
136     }
137 
138     if (!data.WriteParcelable(&want)) {
139         LOG_E(BMS_TAG_DEFAULT, "write want failed");
140         return ERR_FAILED;
141     }
142 
143     if (!data.WriteParcelable(&callerInfo)) {
144         LOG_E(BMS_TAG_DEFAULT, "write callerInfo failed");
145         return ERR_FAILED;
146     }
147 
148     MessageOption option = { MessageOption::TF_SYNC };
149     MessageParcel reply;
150 
151     auto remote = Remote();
152     if (remote == nullptr) {
153         LOG_E(BMS_TAG_DEFAULT, "get Remote failed");
154         return ERR_FAILED;
155     }
156 
157     int32_t ret = remote->SendRequest(QUERY_FREE_INSTALL_EXPERIENCE_CMD, data, reply, option);
158     if (ret != ERR_NONE) {
159         LOG_E(BMS_TAG_DEFAULT, "SendRequest error, ret = %{public}d", ret);
160         return ERR_FAILED;
161     }
162 
163     std::unique_ptr<BmsExperienceRule> sptrRule(reply.ReadParcelable<BmsExperienceRule>());
164     if (sptrRule == nullptr) {
165         LOG_E(BMS_TAG_DEFAULT, "readParcelable sptrRule error");
166         return ERR_FAILED;
167     }
168 
169     rule = *sptrRule;
170     LOG_I(BMS_TAG_DEFAULT, "QueryFreeInstallExperience end");
171     return ERR_OK;
172 }
173 
174 template <typename T>
ReadParcelableVector(std::vector<T> & parcelableVector,MessageParcel & reply)175 bool BmsEcologicalRuleMgrServiceProxy::ReadParcelableVector(std::vector<T> &parcelableVector, MessageParcel &reply)
176 {
177     int32_t infoSize = reply.ReadInt32();
178     parcelableVector.clear();
179     for (int32_t i = 0; i < infoSize; i++) {
180         std::unique_ptr<T> info(reply.ReadParcelable<T>());
181         if (info == nullptr) {
182             LOG_E(BMS_TAG_DEFAULT, "read Parcelable infos failed");
183             return false;
184         }
185         parcelableVector.emplace_back(*info);
186     }
187     return true;
188 }
189 } // namespace AppExecFwk
190 } // namespace OHOS
191