1a34a8711Sopenharmony_ci// Copyright (C) 2024 Huawei Device Co., Ltd.
2a34a8711Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
3a34a8711Sopenharmony_ci// you may not use this file except in compliance with the License.
4a34a8711Sopenharmony_ci// You may obtain a copy of the License at
5a34a8711Sopenharmony_ci//
6a34a8711Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
7a34a8711Sopenharmony_ci//
8a34a8711Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
9a34a8711Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
10a34a8711Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11a34a8711Sopenharmony_ci// See the License for the specific language governing permissions and
12a34a8711Sopenharmony_ci// limitations under the License.
13a34a8711Sopenharmony_ci
14a34a8711Sopenharmony_ci//! cxx wrapper
15a34a8711Sopenharmony_ci#![allow(missing_docs)]
16a34a8711Sopenharmony_ci
17a34a8711Sopenharmony_ciuse std::fs::File;
18a34a8711Sopenharmony_ciuse std::os::fd::FromRawFd;
19a34a8711Sopenharmony_ciuse std::pin::Pin;
20a34a8711Sopenharmony_ci
21a34a8711Sopenharmony_ciuse cxx::UniquePtr;
22a34a8711Sopenharmony_cipub use ffi::*;
23a34a8711Sopenharmony_ci
24a34a8711Sopenharmony_cipub use super::obj::RemoteObj;
25a34a8711Sopenharmony_ciuse super::stub::RemoteStub;
26a34a8711Sopenharmony_ciuse crate::parcel::MsgParcel;
27a34a8711Sopenharmony_ci
28a34a8711Sopenharmony_ci#[cxx::bridge(namespace = "OHOS::IpcRust")]
29a34a8711Sopenharmony_cipub mod ffi {
30a34a8711Sopenharmony_ci
31a34a8711Sopenharmony_ci    extern "Rust" {
32a34a8711Sopenharmony_ci        type RemoteObj;
33a34a8711Sopenharmony_ci        pub type RemoteStubWrapper;
34a34a8711Sopenharmony_ci
35a34a8711Sopenharmony_ci        fn on_remote_request(
36a34a8711Sopenharmony_ci            self: &mut RemoteStubWrapper,
37a34a8711Sopenharmony_ci            code: u32,
38a34a8711Sopenharmony_ci            data: Pin<&mut MessageParcel>,
39a34a8711Sopenharmony_ci            reply: Pin<&mut MessageParcel>,
40a34a8711Sopenharmony_ci        ) -> i32;
41a34a8711Sopenharmony_ci
42a34a8711Sopenharmony_ci        fn dump(self: &mut RemoteStubWrapper, fd: i32, args: Vec<String>) -> i32;
43a34a8711Sopenharmony_ci
44a34a8711Sopenharmony_ci        fn descriptor(self: &mut RemoteStubWrapper) -> &'static str;
45a34a8711Sopenharmony_ci
46a34a8711Sopenharmony_ci        fn new_remote_obj(wrap: UniquePtr<IRemoteObjectWrapper>) -> Box<RemoteObj>;
47a34a8711Sopenharmony_ci
48a34a8711Sopenharmony_ci    }
49a34a8711Sopenharmony_ci
50a34a8711Sopenharmony_ci    unsafe extern "C++" {
51a34a8711Sopenharmony_ci        include!("remote_object_wrapper.h");
52a34a8711Sopenharmony_ci        type IRemoteObjectWrapper;
53a34a8711Sopenharmony_ci
54a34a8711Sopenharmony_ci        #[namespace = "OHOS"]
55a34a8711Sopenharmony_ci        type IRemoteObject;
56a34a8711Sopenharmony_ci        #[namespace = "OHOS"]
57a34a8711Sopenharmony_ci        type MessageParcel = crate::parcel::wrapper::MessageParcel;
58a34a8711Sopenharmony_ci        #[namespace = "OHOS"]
59a34a8711Sopenharmony_ci        type MessageOption = crate::parcel::wrapper::MessageOption;
60a34a8711Sopenharmony_ci        type DeathRecipientRemoveHandler;
61a34a8711Sopenharmony_ci
62a34a8711Sopenharmony_ci        #[namespace = "OHOS"]
63a34a8711Sopenharmony_ci        type SptrIRemoteObject;
64a34a8711Sopenharmony_ci
65a34a8711Sopenharmony_ci        fn FromSptrRemote(sptr: UniquePtr<SptrIRemoteObject>) -> UniquePtr<IRemoteObjectWrapper>;
66a34a8711Sopenharmony_ci
67a34a8711Sopenharmony_ci        fn FromRemoteStub(stub: Box<RemoteStubWrapper>) -> UniquePtr<IRemoteObjectWrapper>;
68a34a8711Sopenharmony_ci
69a34a8711Sopenharmony_ci        unsafe fn FromCIRemoteObject(remote: *mut IRemoteObject)
70a34a8711Sopenharmony_ci            -> UniquePtr<IRemoteObjectWrapper>;
71a34a8711Sopenharmony_ci
72a34a8711Sopenharmony_ci        fn SendRequest(
73a34a8711Sopenharmony_ci            self: &IRemoteObjectWrapper,
74a34a8711Sopenharmony_ci            code: u32,
75a34a8711Sopenharmony_ci            data: Pin<&mut MessageParcel>,
76a34a8711Sopenharmony_ci            reply: Pin<&mut MessageParcel>,
77a34a8711Sopenharmony_ci            option: Pin<&mut MessageOption>,
78a34a8711Sopenharmony_ci        ) -> i32;
79a34a8711Sopenharmony_ci
80a34a8711Sopenharmony_ci        fn GetInterfaceDescriptor(self: &IRemoteObjectWrapper) -> String;
81a34a8711Sopenharmony_ci        fn GetObjectDescriptor(self: &IRemoteObjectWrapper) -> String;
82a34a8711Sopenharmony_ci
83a34a8711Sopenharmony_ci        fn IsProxyObject(self: &IRemoteObjectWrapper) -> bool;
84a34a8711Sopenharmony_ci        fn IsObjectDead(self: &IRemoteObjectWrapper) -> bool;
85a34a8711Sopenharmony_ci        fn CheckObjectLegality(self: &IRemoteObjectWrapper) -> bool;
86a34a8711Sopenharmony_ci
87a34a8711Sopenharmony_ci        fn Dump(self: &IRemoteObjectWrapper, fd: i32, args: &[String]) -> i32;
88a34a8711Sopenharmony_ci        fn AddDeathRecipient(
89a34a8711Sopenharmony_ci            self: &IRemoteObjectWrapper,
90a34a8711Sopenharmony_ci            cb: fn(Box<RemoteObj>),
91a34a8711Sopenharmony_ci        ) -> UniquePtr<DeathRecipientRemoveHandler>;
92a34a8711Sopenharmony_ci
93a34a8711Sopenharmony_ci        fn remove(self: &DeathRecipientRemoveHandler);
94a34a8711Sopenharmony_ci
95a34a8711Sopenharmony_ci        fn CloneRemoteObj(remote: &IRemoteObjectWrapper) -> UniquePtr<IRemoteObjectWrapper>;
96a34a8711Sopenharmony_ci    }
97a34a8711Sopenharmony_ci    impl UniquePtr<IRemoteObjectWrapper> {}
98a34a8711Sopenharmony_ci}
99a34a8711Sopenharmony_ci
100a34a8711Sopenharmony_cifn new_remote_obj(wrap: UniquePtr<ffi::IRemoteObjectWrapper>) -> Box<RemoteObj> {
101a34a8711Sopenharmony_ci    Box::new(RemoteObj::try_new(wrap).unwrap())
102a34a8711Sopenharmony_ci}
103a34a8711Sopenharmony_ci
104a34a8711Sopenharmony_cipub struct RemoteStubWrapper {
105a34a8711Sopenharmony_ci    inner: Box<dyn RemoteStub>,
106a34a8711Sopenharmony_ci}
107a34a8711Sopenharmony_ci
108a34a8711Sopenharmony_ciimpl RemoteStubWrapper {
109a34a8711Sopenharmony_ci    pub fn new<A: RemoteStub + 'static>(remote: A) -> Self {
110a34a8711Sopenharmony_ci        Self {
111a34a8711Sopenharmony_ci            inner: Box::new(remote),
112a34a8711Sopenharmony_ci        }
113a34a8711Sopenharmony_ci    }
114a34a8711Sopenharmony_ci
115a34a8711Sopenharmony_ci    pub fn on_remote_request(
116a34a8711Sopenharmony_ci        &mut self,
117a34a8711Sopenharmony_ci        code: u32,
118a34a8711Sopenharmony_ci        data: Pin<&mut MessageParcel>,
119a34a8711Sopenharmony_ci        reply: Pin<&mut MessageParcel>,
120a34a8711Sopenharmony_ci    ) -> i32 {
121a34a8711Sopenharmony_ci        unsafe {
122a34a8711Sopenharmony_ci            let mut data = MsgParcel::from_ptr(data.get_unchecked_mut() as *mut MessageParcel);
123a34a8711Sopenharmony_ci            let mut reply = MsgParcel::from_ptr(reply.get_unchecked_mut() as *mut MessageParcel);
124a34a8711Sopenharmony_ci            self.inner.on_remote_request(code, &mut data, &mut reply)
125a34a8711Sopenharmony_ci        }
126a34a8711Sopenharmony_ci    }
127a34a8711Sopenharmony_ci
128a34a8711Sopenharmony_ci    pub fn dump(&mut self, fd: i32, args: Vec<String>) -> i32 {
129a34a8711Sopenharmony_ci        let file = unsafe { File::from_raw_fd(fd) };
130a34a8711Sopenharmony_ci        self.inner.dump(file, args)
131a34a8711Sopenharmony_ci    }
132a34a8711Sopenharmony_ci
133a34a8711Sopenharmony_ci    pub fn descriptor(&self) -> &'static str {
134a34a8711Sopenharmony_ci        self.inner.descriptor()
135a34a8711Sopenharmony_ci    }
136a34a8711Sopenharmony_ci
137a34a8711Sopenharmony_ci    pub fn into_remote(self) -> Option<RemoteObj> {
138a34a8711Sopenharmony_ci        RemoteObj::try_new(FromRemoteStub(Box::new(self)))
139a34a8711Sopenharmony_ci    }
140a34a8711Sopenharmony_ci}
141