1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include "system_ability_wrapper.h"
15 
16 #include <memory>
17 #include <string>
18 #include <utility>
19 
20 #include "cxx.h"
21 #include "system_ability.h"
22 #include "system_ability_ondemand_reason.h"
23 #include "wrapper.rs.h"
24 
25 namespace OHOS {
26 namespace SafwkRust {
27 
SystemAbilityWrapper(rust::Box<AbilityWrapper> ability_,int32_t systemAbilityId,bool runOnCreate)28 SystemAbilityWrapper::SystemAbilityWrapper(
29     rust::Box<AbilityWrapper> ability_, int32_t systemAbilityId, bool runOnCreate)
30     : SystemAbility(systemAbilityId, runOnCreate)
31 {
32     this->ability_ = ability_.into_raw();
33 }
34 
~SystemAbilityWrapper()35 SystemAbilityWrapper::~SystemAbilityWrapper()
36 {
37     rust::Box<AbilityWrapper>::from_raw(this->ability_);
38 }
39 
StopAbilityWrapper(int32_t systemAbilityId)40 void SystemAbilityWrapper::StopAbilityWrapper(int32_t systemAbilityId)
41 {
42     SystemAbility::StopAbility(systemAbilityId);
43 }
44 
GetClassName()45 std::string SystemAbilityWrapper::GetClassName()
46 {
47     return std::string("hello");
48 }
49 
OnDump()50 void SystemAbilityWrapper::OnDump()
51 {
52     ability_->OnDump();
53 }
54 
OnStart()55 void SystemAbilityWrapper::OnStart()
56 {
57     ability_->OnStart(this);
58 }
59 
OnStart(const OHOS::SystemAbilityOnDemandReason & startReason)60 void SystemAbilityWrapper::OnStart(const OHOS::SystemAbilityOnDemandReason &startReason)
61 {
62     ability_->OnStartWithReason(BuildReasonWrapper(startReason), this);
63 }
64 
CancelIdleWrapper()65 bool SystemAbilityWrapper::CancelIdleWrapper()
66 {
67     return this->CancelIdle();
68 }
69 
PublishWrapper(rust::Box<AbilityStub> ability)70 bool SystemAbilityWrapper::PublishWrapper(rust::Box<AbilityStub> ability)
71 {
72     auto stub = sptr<RemoteServiceStub>::MakeSptr(ability.into_raw());
73     if (stub == nullptr) {
74         return false;
75     }
76     return this->Publish(stub);
77 }
78 
OnIdle(const OHOS::SystemAbilityOnDemandReason & idleReason)79 int32_t SystemAbilityWrapper::OnIdle(const OHOS::SystemAbilityOnDemandReason &idleReason)
80 {
81     return ability_->OnIdle(BuildReasonWrapper(idleReason));
82 }
83 
OnActive(const OHOS::SystemAbilityOnDemandReason & activeReason)84 void SystemAbilityWrapper::OnActive(const OHOS::SystemAbilityOnDemandReason &activeReason)
85 {
86     ability_->OnActive(BuildReasonWrapper(activeReason));
87 }
88 
OnStop()89 void SystemAbilityWrapper::OnStop()
90 {
91     ability_->OnStop();
92 }
93 
OnStop(const OHOS::SystemAbilityOnDemandReason & stopReason)94 void SystemAbilityWrapper::OnStop(const OHOS::SystemAbilityOnDemandReason &stopReason)
95 {
96     ability_->OnStopWithReason(BuildReasonWrapper(stopReason));
97 }
98 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)99 void SystemAbilityWrapper::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
100 {
101     ability_->OnAddSystemAbility(systemAbilityId, deviceId);
102 }
103 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)104 void SystemAbilityWrapper::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
105 {
106     ability_->OnRemoveSystemAbility(systemAbilityId, deviceId);
107 }
108 
OnDeviceLevelChanged(int32_t type,int32_t level,std::string & action)109 void SystemAbilityWrapper::OnDeviceLevelChanged(int32_t type, int32_t level, std::string &action)
110 {
111     ability_->OnDeviceLevelChanged(type, level, action);
112 }
113 
RegisterAbility(SystemAbilityWrapper * system_ability)114 bool RegisterAbility(SystemAbilityWrapper *system_ability)
115 {
116     return SystemAbility::MakeAndRegisterAbility(static_cast<SystemAbility *>(system_ability));
117 }
118 
DeserializeOnDemandReasonExtraData(MessageParcel & parcel)119 OnDemandReasonExtraData DeserializeOnDemandReasonExtraData(MessageParcel &parcel)
120 {
121     OHOS::OnDemandReasonExtraData *reason = parcel.ReadParcelable<OHOS::OnDemandReasonExtraData>();
122 
123     if (reason == nullptr) {
124         return OnDemandReasonExtraData{};
125     }
126     rust::vec<rust::string> want;
127     auto map = reason->GetWant();
128     for (auto i = map.begin(); i != map.end(); ++i) {
129         want.push_back(rust::string(i->first.data()));
130         want.push_back(rust::string(i->second.data()));
131     }
132 
133     auto res = OnDemandReasonExtraData{
134         .data = rust::string(reason->GetData()),
135         .code = reason->GetCode(),
136         .want = want,
137     };
138     delete reason;
139     return res;
140 }
141 
SerializeOnDemandReasonExtraData(const OnDemandReasonExtraData & extraData,MessageParcel & parcel)142 bool SerializeOnDemandReasonExtraData(const OnDemandReasonExtraData &extraData, MessageParcel &parcel)
143 {
144     size_t mapInterval = 2;
145     auto data = std::string(extraData.data);
146     auto code = extraData.code;
147     auto want = extraData.want;
148     std::map<std::string, std::string> wantMap;
149 
150     for (size_t i = 0; i + 1 < want.size(); i += mapInterval) {
151         wantMap.insert({ want[i].data(), want[i + 1].data() });
152     }
153     OHOS::OnDemandReasonExtraData reason(code, data, wantMap);
154     return parcel.WriteParcelable(&reason);
155 }
156 
BuildReasonWrapper(const OHOS::SystemAbilityOnDemandReason & reason)157 SystemAbilityOnDemandReason BuildReasonWrapper(const OHOS::SystemAbilityOnDemandReason &reason)
158 {
159     rust::vec<rust::string> want;
160 
161     auto map = reason.GetExtraData().GetWant();
162     for (auto i = map.begin(); i != map.end(); ++i) {
163         want.push_back(rust::string(i->first.data()));
164         want.push_back(rust::string(i->second.data()));
165     }
166 
167     return SystemAbilityOnDemandReason{
168         .name = rust::string(reason.GetName().data()),
169         .value = rust::string(reason.GetValue().data()),
170         .reason_id = reason.GetId(),
171         .extra_data = OnDemandReasonExtraData{ .data = rust::string(reason.GetExtraData().GetData().data()),
172             .code = reason.GetExtraData().GetCode(),
173             .want = want },
174         .extra_data_id = reason.GetExtraDataId(),
175     };
176 }
177 
BuildSystemAbility(rust::Box<AbilityWrapper> ability_,int32_t systemAbilityId,bool runOnCreate)178 std::unique_ptr<SystemAbilityWrapper> BuildSystemAbility(
179     rust::Box<AbilityWrapper> ability_, int32_t systemAbilityId, bool runOnCreate)
180 {
181     return std::make_unique<SystemAbilityWrapper>(std::move(ability_), systemAbilityId, runOnCreate);
182 }
183 
RemoteServiceStub(AbilityStub * ability)184 RemoteServiceStub::RemoteServiceStub(AbilityStub *ability)
185 {
186     this->inner_ = ability;
187 }
188 
~RemoteServiceStub()189 RemoteServiceStub::~RemoteServiceStub()
190 {
191     auto ability = rust::Box<AbilityStub>::from_raw(this->inner_);
192 }
193 
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)194 int RemoteServiceStub ::OnRemoteRequest(
195     uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply, OHOS::MessageOption &option)
196 {
197     return inner_->on_remote_request(code, data, reply);
198 }
199 
Dump(int fd,const std::vector<std::u16string> & args)200 int RemoteServiceStub::Dump(int fd, const std::vector<std::u16string> &args)
201 {
202     rust::vec<rust::string> rust_v;
203     for (auto arg : args) {
204         rust_v.push_back(arg.data());
205     }
206     return inner_->dump(fd, rust_v);
207 }
208 
209 } // namespace SafwkRust
210 } // namespace OHOS
211