1 /*
2  * Copyright (C) 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 "remote_object_wrapper.h"
17 
18 #include <iostream>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include "cxx.h"
24 #include "iremote_object.h"
25 #include "message_parcel.h"
26 #include "refbase.h"
27 #include "remote/wrapper.rs.h"
28 #include "string_ex.h"
29 
30 namespace OHOS {
31 namespace IpcRust {
IRemoteObjectWrapper()32 IRemoteObjectWrapper::IRemoteObjectWrapper(): raw_(nullptr)
33 {
34 }
35 
SendRequest(const uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option) const36 int32_t IRemoteObjectWrapper::SendRequest(
37     const uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) const
38 {
39     return GetInner()->SendRequest(code, data, reply, option);
40 }
41 
GetInner() const42 IRemoteObject *IRemoteObjectWrapper::GetInner() const
43 {
44     if (is_raw_) {
45         return raw_;
46     } else {
47         return sptr_;
48     }
49 }
50 
GetInterfaceDescriptor() const51 rust::string IRemoteObjectWrapper::GetInterfaceDescriptor() const
52 {
53     return GetInner()->GetInterfaceDescriptor().data();
54 }
55 
GetObjectDescriptor() const56 rust::string IRemoteObjectWrapper::GetObjectDescriptor() const
57 {
58     return GetInner()->GetObjectDescriptor().data();
59 }
60 
AddDeathRecipient(rust::Fn<void (rust::Box<RemoteObj>)> callback) const61 std::unique_ptr<DeathRecipientRemoveHandler> IRemoteObjectWrapper::AddDeathRecipient(
62     rust::Fn<void(rust::Box<RemoteObj>)> callback) const
63 {
64     sptr<IRemoteObject::DeathRecipient> recipient(new DeathRecipientWrapper(callback));
65     bool res = sptr_->AddDeathRecipient(recipient);
66     if (!res) {
67         return nullptr;
68     }
69     return std::make_unique<DeathRecipientRemoveHandler>(sptr(sptr_), sptr(recipient));
70 }
71 
GetObjectRefCount() const72 int32_t IRemoteObjectWrapper::GetObjectRefCount() const
73 {
74     return GetInner()->GetObjectRefCount();
75 }
76 
IsProxyObject() const77 bool IRemoteObjectWrapper::IsProxyObject() const
78 {
79     return GetInner()->IsProxyObject();
80 }
IsObjectDead() const81 bool IRemoteObjectWrapper::IsObjectDead() const
82 {
83     return GetInner()->IsObjectDead();
84 }
CheckObjectLegality() const85 bool IRemoteObjectWrapper::CheckObjectLegality() const
86 {
87     return GetInner()->CheckObjectLegality();
88 }
89 
Dump(int fd,const rust::Slice<const rust::string> args) const90 int IRemoteObjectWrapper::Dump(int fd, const rust::Slice<const rust::string> args) const
91 {
92     std::vector<std::u16string> res;
93     for (auto rust_s : args) {
94         std::u16string s_u16 = Str8ToStr16(std::string(rust_s));
95         res.push_back(s_u16);
96     }
97     return GetInner()->Dump(fd, res);
98 }
99 
DeathRecipientWrapper(rust::Fn<void (rust::Box<RemoteObj>)> cb)100 DeathRecipientWrapper::DeathRecipientWrapper(rust::Fn<void(rust::Box<RemoteObj>)> cb)
101 {
102     this->inner_ = cb;
103 }
104 
OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> & object)105 void DeathRecipientWrapper::OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject> &object)
106 {
107     auto obj = object.promote();
108     if (obj == nullptr) {
109         return;
110     }
111 
112     auto wrapper = std::make_unique<IRemoteObjectWrapper>();
113 
114     wrapper->is_raw_ = false;
115     wrapper->sptr_ = obj;
116 
117     auto rust_remote_obj = new_remote_obj(std::move(wrapper));
118     inner_(std::move(rust_remote_obj));
119 }
120 
DeathRecipientRemoveHandler(sptr<IRemoteObject> remote,sptr<IRemoteObject::DeathRecipient> recipient)121 DeathRecipientRemoveHandler::DeathRecipientRemoveHandler(
122     sptr<IRemoteObject> remote, sptr<IRemoteObject::DeathRecipient> recipient)
123 {
124     this->remote_ = std::move(remote);
125     this->inner_ = std::move(recipient);
126 }
127 
remove() const128 void DeathRecipientRemoveHandler::remove() const
129 {
130     remote_->RemoveDeathRecipient(inner_);
131 }
132 
RemoteServiceStub(RemoteStubWrapper * ability,std::u16string descriptor)133 RemoteServiceStub::RemoteServiceStub(RemoteStubWrapper *ability, std::u16string descriptor) : IPCObjectStub(descriptor)
134 {
135     this->inner_ = ability;
136 }
137 
~RemoteServiceStub()138 RemoteServiceStub::~RemoteServiceStub()
139 {
140     auto ability = rust::Box<RemoteStubWrapper>::from_raw(this->inner_);
141 }
142 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)143 int RemoteServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
144 {
145     return inner_->on_remote_request(code, data, reply);
146 }
147 
Dump(int fd,const std::vector<std::u16string> & args)148 int RemoteServiceStub::Dump(int fd, const std::vector<std::u16string> &args)
149 {
150     auto v = rust::vec<rust::string>();
151     for (auto arg : args) {
152         v.push_back(rust::string(arg.data()));
153     }
154     return inner_->dump(fd, v);
155 }
156 
FromSptrRemote(std::unique_ptr<sptr<IRemoteObject>> remote)157 std::unique_ptr<IRemoteObjectWrapper> FromSptrRemote(std::unique_ptr<sptr<IRemoteObject>> remote)
158 {
159     if (remote == nullptr) {
160         return nullptr;
161     }
162     auto wrapper = std::make_unique<IRemoteObjectWrapper>();
163 
164     wrapper->is_raw_ = false;
165     wrapper->sptr_ = std::move(*remote.release());
166 
167     return wrapper;
168 }
169 
CloneRemoteObj(const IRemoteObjectWrapper & remote)170 std::unique_ptr<IRemoteObjectWrapper> CloneRemoteObj(const IRemoteObjectWrapper &remote)
171 {
172     if (remote.is_raw_) {
173         auto raw_ptr = remote.raw_;
174         if (raw_ptr == nullptr) {
175             return nullptr;
176         }
177         return FromCIRemoteObject(raw_ptr);
178     } else {
179         auto sptr = remote.sptr_;
180         if (sptr == nullptr) {
181             return nullptr;
182         }
183         auto wrapper = std::make_unique<IRemoteObjectWrapper>();
184 
185         wrapper->is_raw_ = false;
186         wrapper->sptr_ = sptr;
187         return wrapper;
188     }
189 }
190 
FromRemoteStub(rust::Box<RemoteStubWrapper> stub)191 std::unique_ptr<IRemoteObjectWrapper> FromRemoteStub(rust::Box<RemoteStubWrapper> stub)
192 {
193     auto raw = stub.into_raw();
194     auto rust_s = raw->descriptor();
195     std::string s = std::string(rust_s);
196     std::u16string descriptor = Str8ToStr16(s);
197 
198     auto stub_sptr = sptr<RemoteServiceStub>::MakeSptr(raw, descriptor);
199 
200     auto wrapper = std::make_unique<IRemoteObjectWrapper>();
201 
202     wrapper->is_raw_ = false;
203     wrapper->sptr_ = stub_sptr;
204 
205     return wrapper;
206 }
207 
FromCIRemoteObject(IRemoteObject * stub)208 std::unique_ptr<IRemoteObjectWrapper> FromCIRemoteObject(IRemoteObject *stub)
209 {
210     if (stub == nullptr) {
211         return nullptr;
212     }
213     auto wrapper = std::make_unique<IRemoteObjectWrapper>();
214 
215     wrapper->is_raw_ = true;
216     wrapper->raw_ = stub;
217 
218     return wrapper;
219 }
220 
221 } // namespace IpcRust
222 } // namespace OHOS