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 #![allow(missing_docs, unused)]
15 use std::ffi::{c_char, c_uchar};
16 use std::io::{Read, Seek, SeekFrom, Write};
17 
18 use ipc::parcel::{Deserialize, MsgOption, MsgParcel, Serialize};
19 use ipc::remote::{RemoteObj, RemoteStub};
20 use ipc::{IpcResult, Skeleton};
21 
22 const TEST_SYSTEM_ABILITY_ID: i32 = 1011;
23 
init()24 fn init() {
25     #[cfg(gn_test)]
26     super::init_access_token();
27 }
28 
29 struct TestRemoteStub;
30 
31 impl RemoteStub for TestRemoteStub {
on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i3232     fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 {
33         reply.write("TestRemoteStub");
34         0
35     }
36 }
37 
38 /// UT test case for "contest object"
39 ///
40 /// # brief
41 /// 1. Get SAMGR context object
42 /// 2. Add a system ability by send request
43 /// 3. Check this system ability by send request
44 /// 4. Remove this system ability by send request
45 #[test]
context()46 fn context() {
47     init();
48     let context = Skeleton::get_context_object().unwrap();
49     let mut data = MsgParcel::new();
50     let mut option = MsgOption::new();
51     data.write_interface_token("ohos.samgr.accessToken");
52     data.write(&TEST_SYSTEM_ABILITY_ID);
53     data.write_remote(RemoteObj::from_stub(TestRemoteStub).unwrap())
54         .unwrap();
55     data.write(&false);
56     data.write(&0);
57     data.write("");
58     data.write("");
59 
60     let mut reply = context.send_request(3, &mut data).unwrap();
61     let value = reply.read::<i32>().unwrap();
62 
63     assert_eq!(value, 0);
64 
65     data.write_interface_token("ohos.samgr.accessToken");
66     data.write(&TEST_SYSTEM_ABILITY_ID);
67     let mut reply = context.send_request(2, &mut data).unwrap();
68     let remote = reply.read_remote().unwrap();
69     let mut reply = remote.send_request(0, &mut data).unwrap();
70     let s = reply.read::<String>().unwrap();
71     assert_eq!("TestRemoteStub", s);
72 
73     data.write_interface_token("ohos.samgr.accessToken");
74     data.write(&TEST_SYSTEM_ABILITY_ID);
75     let mut reply = context.send_request(4, &mut data).unwrap();
76     let value = reply.read::<i32>().unwrap();
77     assert_eq!(value, 0);
78 }
79 
80 #[test]
skeleton()81 fn skeleton() {
82     unsafe {
83         assert_eq!(
84             Skeleton::calling_device_id(),
85             (*GetCallingDeviceID()).to_string()
86         );
87         assert_eq!(Skeleton::calling_full_token_id(), GetCallingFullTokenID());
88         assert_eq!(Skeleton::calling_pid(), GetCallingPid());
89         assert_eq!(Skeleton::calling_real_pid(), GetCallingRealPid());
90         assert_eq!(Skeleton::calling_token_id(), GetCallingTokenID());
91         assert_eq!(Skeleton::calling_uid(), GetCallingUid());
92         assert_eq!(Skeleton::first_full_token_id(), GetFirstFullTokenID());
93         assert_eq!(Skeleton::first_token_id(), GetFirstTokenID());
94         assert_eq!(Skeleton::self_token_id(), SelfTokenID());
95         assert_eq!(Skeleton::is_local_calling(), IsLocalCalling());
96         assert_eq!(Skeleton::local_device_id(), (*LocalDeviceID()).to_string());
97         assert_eq!(
98             Skeleton::reset_calling_identity(),
99             (*ResetCallingIdentity()).to_string()
100         );
101     }
102 }
103 
104 #[repr(C)]
105 struct CStringWrapper {
106     c_str: *mut c_uchar,
107     len: usize,
108 }
109 
110 #[allow(clippy::inherent_to_string)]
111 impl CStringWrapper {
to_string(&self) -> String112     fn to_string(&self) -> String {
113         let bytes = unsafe { std::slice::from_raw_parts(self.c_str, self.len) };
114         unsafe { String::from_utf8_unchecked(bytes.to_vec()) }
115     }
116 }
117 
118 #[link(name = "ipc_rust_test_c")]
119 extern "C" {
GetCallingDeviceID() -> *mut CStringWrapper120     fn GetCallingDeviceID() -> *mut CStringWrapper;
GetCallingFullTokenID() -> u64121     fn GetCallingFullTokenID() -> u64;
GetCallingPid() -> u64122     fn GetCallingPid() -> u64;
GetCallingRealPid() -> u64123     fn GetCallingRealPid() -> u64;
GetCallingTokenID() -> u32124     fn GetCallingTokenID() -> u32;
GetCallingUid() -> u64125     fn GetCallingUid() -> u64;
GetFirstFullTokenID() -> u64126     fn GetFirstFullTokenID() -> u64;
GetFirstTokenID() -> u32127     fn GetFirstTokenID() -> u32;
SelfTokenID() -> u64128     fn SelfTokenID() -> u64;
IsLocalCalling() -> bool129     fn IsLocalCalling() -> bool;
LocalDeviceID() -> *mut CStringWrapper130     fn LocalDeviceID() -> *mut CStringWrapper;
ResetCallingIdentity() -> *mut CStringWrapper131     fn ResetCallingIdentity() -> *mut CStringWrapper;
132 }
133