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
14use std::fs::File;
15use std::sync::Arc;
16
17use crate::parcel::MsgParcel;
18use crate::IpcResult;
19
20/// Impl this trait to build a remote stub, that can be published to
21/// SystemAbilityManager and handle remote requests.
22pub trait RemoteStub {
23    /// core method for RemoteStub, that handle remote request.
24    fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32;
25
26    /// Dump the contents.
27    fn dump(&self, _file: File, _args: Vec<String>) -> i32 {
28        0
29    }
30
31    // RemoteStub Descriptor
32    fn descriptor(&self) -> &'static str {
33        ""
34    }
35}
36
37impl<R: RemoteStub> RemoteStub for Arc<R> {
38    fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 {
39        R::on_remote_request(self, code, data, reply)
40    }
41
42    fn dump(&self, file: File, args: Vec<String>) -> i32 {
43        R::dump(self, file, args)
44    }
45    fn descriptor(&self) -> &'static str {
46        R::descriptor(self)
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use std::fs::{self, OpenOptions};
53    use std::os::fd::AsRawFd;
54
55    use super::*;
56    use crate::remote::RemoteObj;
57
58    const TEST_NUM: i32 = 2024;
59    struct TestStub;
60    impl RemoteStub for TestStub {
61        fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 {
62            0
63        }
64        fn dump(&self, _file: File, _args: Vec<String>) -> i32 {
65            TEST_NUM
66        }
67        fn descriptor(&self) -> &'static str {
68            "TEST STUB"
69        }
70    }
71
72    #[test]
73    fn remote_stub() {
74        let remote = RemoteObj::from_stub(TestStub).unwrap();
75        assert_eq!("TEST STUB", remote.interface_descriptor().unwrap());
76        let file = File::create("ipc_rust_test_temp").unwrap();
77        assert_eq!(TEST_NUM, remote.dump(file.as_raw_fd(), &[]));
78        fs::remove_file("ipc_rust_test_temp").unwrap();
79    }
80}
81