• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2024 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 use std::mem;
15 use std::sync::Arc;
16 
17 use cxx::UniquePtr;
18 
19 use super::wrapper::{
20     CloneRemoteObj, DeathRecipientRemoveHandler, FromCIRemoteObject, FromSptrRemote, IRemoteObject,
21     IRemoteObjectWrapper, RemoteStubWrapper, SptrIRemoteObject,
22 };
23 use super::RemoteStub;
24 use crate::errors::{IpcResult, IpcStatusCode};
25 use crate::ipc_async::{IpcAsyncRuntime, Runtime};
26 use crate::parcel::msg::ParcelMem;
27 use crate::parcel::{MsgOption, MsgParcel};
28 
29 /// Remote Object
30 pub struct RemoteObj {
31     pub(crate) inner: UniquePtr<IRemoteObjectWrapper>,
32 }
33 
34 pub struct ClosureWrapper {
35     inner: Box<dyn FnMut(Box<RemoteObj>)>,
36 }
37 
38 impl ClosureWrapper {
execute(&mut self, obj: Box<RemoteObj>)39     pub fn execute(&mut self, obj: Box<RemoteObj>) {
40         (self.inner)(obj);
41     }
42 }
43 
44 impl Clone for RemoteObj {
clone(&self) -> Self45     fn clone(&self) -> Self {
46         Self {
47             inner: CloneRemoteObj(self.inner.as_ref().unwrap()),
48         }
49     }
50 }
51 
52 unsafe impl Send for RemoteObj {}
53 unsafe impl Sync for RemoteObj {}
54 
55 pub struct RecipientRemoveHandler {
56     inner: UniquePtr<DeathRecipientRemoveHandler>,
57 }
58 
59 impl RemoteObj {
60     /// Creates a Remote Object from C++ IRemoteObejectWrapper.
try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self>61     pub fn try_new(wrap: UniquePtr<IRemoteObjectWrapper>) -> Option<Self> {
62         if wrap.is_null() {
63             return None;
64         }
65         Some(Self { inner: wrap })
66     }
67 
68     /// Creates a Remote Object from C++ IRemoteObejectWrapper.
new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self69     pub unsafe fn new_unchecked(wrap: UniquePtr<IRemoteObjectWrapper>) -> Self {
70         Self { inner: wrap }
71     }
72 
from_ciremote(remote: *mut IRemoteObject) -> Option<Self>73     pub unsafe fn from_ciremote(remote: *mut IRemoteObject) -> Option<Self> {
74         if remote.is_null() {
75             return None;
76         }
77 
78         let inner = FromCIRemoteObject(remote);
79         if inner.is_null() {
80             return None;
81         }
82 
83         Some(Self { inner })
84     }
85 
86     /// Creates a RemoteObj from RemoteStub.
from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self>87     pub fn from_stub<T: RemoteStub + 'static>(stub: T) -> Option<Self> {
88         RemoteStubWrapper::new(stub).into_remote()
89     }
90 
91     /// Creates a RemoteObj from sptr
from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self>92     pub fn from_sptr(sptr: UniquePtr<SptrIRemoteObject>) -> Option<Self> {
93         Self::try_new(FromSptrRemote(sptr))
94     }
95 
96     /// Sends a IPC request to remote service
send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel>97     pub fn send_request(&self, code: u32, data: &mut MsgParcel) -> IpcResult<MsgParcel> {
98         let mut reply = MsgParcel::new();
99         let mut option = MsgOption::new();
100         match mem::replace(&mut data.inner, ParcelMem::Null) {
101             ParcelMem::Unique(mut p) => {
102                 let res = self.inner.SendRequest(
103                     code,
104                     p.pin_mut(),
105                     reply.pin_mut().unwrap(),
106                     option.inner.pin_mut(),
107                 );
108                 data.inner = ParcelMem::Unique(p);
109                 match res {
110                     0 => Ok(reply),
111                     29189 => Err(IpcStatusCode::ServiceDied),
112                     _ => Err(IpcStatusCode::Failed),
113                 }
114             }
115             _ => Err(IpcStatusCode::Failed),
116         }
117     }
118 
119     /// Sends asynchronous IPC requests to remote services, The current
120     /// interface will use ylong runtime to start a separate thread to execute
121     /// requests
async_send_request<F, R>( self: &Arc<Self>, code: u32, mut data: MsgParcel, mut option: MsgOption, call_back: F, ) where F: FnOnce(MsgParcel) -> R, F: Send + 'static, R: Send + 'static,122     pub fn async_send_request<F, R>(
123         self: &Arc<Self>,
124         code: u32,
125         mut data: MsgParcel,
126         mut option: MsgOption,
127         call_back: F,
128     ) where
129         F: FnOnce(MsgParcel) -> R,
130         F: Send + 'static,
131         R: Send + 'static,
132     {
133         let remote = self.clone();
134         Runtime::spawn_blocking(move || {
135             let reply = remote.send_request(code, &mut data);
136             match reply {
137                 Ok(reply) => {
138                     call_back(reply);
139                     IpcStatusCode::Ok
140                 }
141                 _ => IpcStatusCode::Failed,
142             }
143         });
144     }
145 
146     /// Registries a death recipient, and returns a RecipientRemoveHandler, if
147     /// the registration is successful.
add_death_recipient<F: FnMut(Box<RemoteObj>) + 'static>( &self, f: F, ) -> Option<RecipientRemoveHandler>148     pub fn add_death_recipient<F: FnMut(Box<RemoteObj>) + 'static>(
149         &self,
150         f: F,
151     ) -> Option<RecipientRemoveHandler> {
152         let inner = self.inner.AddDeathRecipient(Box::new(ClosureWrapper { inner: Box::new(f) }));
153         inner.is_null().then_some(RecipientRemoveHandler { inner })
154     }
155 
156     /// Returns true if it is a proxy object.
is_proxy(&self) -> bool157     pub fn is_proxy(&self) -> bool {
158         self.inner.IsProxyObject()
159     }
160 
161     /// Dumps a service through a String
dump(&self, fd: i32, args: &[String]) -> i32162     pub fn dump(&self, fd: i32, args: &[String]) -> i32 {
163         self.inner.Dump(fd, args)
164     }
165 
166     ///
check_legalit(&self) -> bool167     pub fn check_legalit(&self) -> bool {
168         self.inner.CheckObjectLegality()
169     }
170 
171     /// Returns true if the object is dead.
is_dead(&self) -> bool172     pub fn is_dead(&self) -> bool {
173         self.inner.IsObjectDead()
174     }
175 
176     /// Returns interface descriptor.
interface_descriptor(&self) -> IpcResult<String>177     pub fn interface_descriptor(&self) -> IpcResult<String> {
178         Ok(self.inner.GetInterfaceDescriptor())
179     }
180 
181     /// Returns Object descriptor.
object_descriptor(&self) -> IpcResult<String>182     pub fn object_descriptor(&self) -> IpcResult<String> {
183         Ok(self.inner.GetObjectDescriptor())
184     }
185 }
186 
187 impl RecipientRemoveHandler {
remove_recipient(self)188     pub fn remove_recipient(self) {
189         self.inner.remove();
190     }
191 }
192