/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pub mod remote_obj; pub mod remote_stub; pub mod macros; use crate::{ BorrowedMsgParcel, MsgParcel, IpcResult, DeathRecipient, FileDesc, IpcStatusCode, }; use std::ops::{Deref}; use std::cmp::Ordering; use crate::String16; // Export types of this module pub use crate::RemoteObj; /// Like C++ IRemoteObject class, define function for both proxy and stub object pub trait IRemoteObj { /// Send a IPC request to remote service fn send_request(&self, code: u32, data: &MsgParcel, is_async: bool) -> IpcResult; /// Add a death recipient fn add_death_recipient(&self, recipient: &mut DeathRecipient) -> bool; /// Remove a death recipient fn remove_death_recipient(&self, recipient: &mut DeathRecipient) -> bool; /// Determine whether it is a proxy object fn is_proxy(&self) -> bool; /// Dump a service through a String16 fn dump(&self, fd: i32, args: &mut Vec) -> i32; /// Judge whether the object is dead fn is_dead(&self) -> bool; /// get interface descriptor fn interface_descriptor(&self) -> IpcResult; } /// Like C++ IPCObjectStub class, define function for stub object only, like on_remote_request(). pub trait IRemoteStub: Send + Sync { /// Get object descriptor of this stub fn get_descriptor() -> &'static str; /// Callback for deal IPC request fn on_remote_request(&self, code: u32, data: &BorrowedMsgParcel, reply: &mut BorrowedMsgParcel) -> i32; /// Callback for IPC dump fn on_dump(&self, file: &FileDesc, args: &mut Vec) -> i32; } /// Like C++ IRemoteBroker class pub trait IRemoteBroker: Send + Sync { /// Convert self to RemoteObject fn as_object(&self) -> Option { panic!("This is not a RemoteObject.") } /// Default dump fn dump(&self, _file: &FileDesc, _args: &mut Vec) -> i32 { println!("This is the default dump function, and you can override it to implement your own dump function"); IpcStatusCode::Ok as i32 } } /// Define function which how to convert a RemoteObj to RemoteObjRef, the later contains a /// dynamic trait object: IRemoteObject. For example, "dyn ITest" should implements this trait pub trait FromRemoteObj: IRemoteBroker { /// Convert a RemoteObj to RemoteObjeRef fn try_from(object: RemoteObj) -> IpcResult>; } /// Strong reference for "dyn IRemoteBroker" object, for example T is "dyn ITest" pub struct RemoteObjRef(Box); impl RemoteObjRef { /// Create a RemoteObjRef object pub fn new(object: Box) -> Self { Self(object) } } impl Deref for RemoteObjRef { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl Clone for RemoteObjRef { fn clone(&self) -> Self { // Clone is a method in the RemoteObjRef structure. // T in RemoteObjRefimplements the trait FromRemoteObj, // so self.0.as_ Object(). unwrap() must be a RemoteObj object that exists FromRemoteObj::try_from(self.0.as_object().unwrap()).unwrap() } } impl Ord for RemoteObjRef { fn cmp(&self, other: &Self) -> Ordering { self.0.as_object().cmp(&other.0.as_object()) } } impl PartialOrd for RemoteObjRef { fn partial_cmp(&self, other: &Self) -> Option { self.0.as_object().partial_cmp(&other.0.as_object()) } } impl PartialEq for RemoteObjRef { fn eq(&self, other: &Self) -> bool { self.0.as_object().eq(&other.0.as_object()) } } impl Eq for RemoteObjRef {}