binder_rust/
service.rs

1use crate::{
2    binder::{Binder, BinderFlatObject, Transaction, TransactionFlags},
3    parcel::Parcel,
4};
5
6use std::ffi::c_void;
7use std::marker::PhantomData;
8
9use num_traits::FromPrimitive;
10
11const SERVICE_MANAGER_HANDLE: i32 = 0;
12const SERVICE_MANAGER_INTERFACE_TOKEN: &str = "android.os.IServiceManager";
13
14enum ServiceManagerFunctions {
15    GetService = 1,
16    CheckService = 2,
17    AddService = 3,
18    ListServices = 4,
19}
20
21pub struct Service<'a> {
22    service_manager: &'a mut ServiceManager<'a>,
23    handle: i32,
24    name: &'a str,
25    interface_name: &'a str,
26}
27
28impl<'a> Service<'a> {
29    pub fn new(service_manager: &'a mut ServiceManager<'a>, name: &'a str, interface_name: &'a str, handle: i32) -> Self {
30        Self {
31            service_manager,
32            name,
33            interface_name,
34            handle,
35        }
36    }
37    pub fn call(&mut self, function_index: u32, data: &mut Parcel) -> Parcel {
38        let mut parcel = Parcel::empty();
39        parcel.write_interface_token(self.interface_name);
40        if data.len() > 0 {
41            parcel.append_parcel(data);
42        };
43
44        let (_, mut parcel) = self
45            .service_manager
46            .binder
47            .transact(self.handle, function_index, TransactionFlags::AcceptFds, &mut parcel);
48
49        let status = parcel.read_u32();
50        if status != 0 {
51            panic!(
52                "service call failed with status: {:x}, {} - {}\n{}",
53                status,
54                parcel.read_str16(),
55                parcel.read_u32(),
56                parcel.read_str16()
57            );
58        };
59
60        parcel
61    }
62}
63
64pub trait BinderService {
65    fn process_request(&self, code: u32, data: &mut Parcel) -> Parcel;
66}
67
68pub struct ServiceListener<'a, BS>
69where
70    BS: BinderService,
71{
72    service_delegate: &'a BS,
73    service_manager: &'a mut ServiceManager<'a>,
74    name: &'a str,
75    interface_name: &'a str,
76}
77
78impl<'a, BS> ServiceListener<'a, BS>
79where
80    BS: BinderService,
81{
82    pub fn new(service_delegate: &'a BS, service_manager: &'a mut ServiceManager<'a>, name: &'a str, interface_name: &'a str) -> Self {
83        Self {
84            service_delegate,
85            service_manager,
86            name,
87            interface_name,
88        }
89    }
90
91    pub fn run(&mut self){
92        loop {
93
94            let (transaction, mut parcel) = self.service_manager.binder.do_write_read(&mut Parcel::empty());
95            match transaction {
96                Some(transaction) => {
97                    if transaction.code() >= Transaction::FirstCall as u32 && transaction.code() <= Transaction::LastCall as u32 {
98                        assert!(&parcel.read_interface_token() == self.interface_name);
99                        self.service_manager.binder.reply(&mut self.service_delegate.process_request(transaction.code(), &mut parcel), transaction.flags());
100                    } else {
101                        match Transaction::from_u32(transaction.code()) {
102                            Interface => {
103                                let mut parcel = Parcel::empty();
104                                parcel.write_u32(0);
105                                parcel.write_str16(self.interface_name);
106                                self.service_manager.binder.reply(&mut parcel, transaction.flags() | TransactionFlags::AcceptFds);
107                            }
108                            _ => {}
109                        }
110                    }
111                },
112                None => {}
113            }
114        }
115        }
116}
117
118pub struct ServiceManager<'a> {
119    binder: Binder,
120    phantom: &'a PhantomData<Binder>
121}
122
123impl<'a> ServiceManager<'a> {
124    pub fn new() -> Self {
125        let mut service_manager = Self {
126            binder: Binder::new(),
127            phantom: &PhantomData,
128        };
129
130        service_manager.ping();
131
132        service_manager
133    }
134
135    fn ping(&mut self) {
136        let mut parcel = Parcel::empty();
137        self.binder.transact(
138            SERVICE_MANAGER_HANDLE,
139            Transaction::Ping as u32,
140            TransactionFlags::empty(),
141            &mut parcel,
142        );
143    }
144
145    pub fn get_service(&'a mut self, service_name: &'a str, interface_name: &'a str) -> Service<'a> {
146        let mut parcel = Parcel::empty();
147        parcel.write_interface_token(SERVICE_MANAGER_INTERFACE_TOKEN);
148        parcel.write_str16(service_name);
149        let (transaction, mut parcel) = self.binder.transact(
150            SERVICE_MANAGER_HANDLE,
151            ServiceManagerFunctions::GetService as u32,
152            TransactionFlags::empty(),
153            &mut parcel,
154        );
155        parcel.read_u32();
156        let flat_object: BinderFlatObject = parcel.read_object();
157
158        self.binder.add_ref(flat_object.handle as i32);
159        self.binder.acquire(flat_object.handle as i32);
160
161        Service::new(self, service_name, interface_name, flat_object.handle as i32)
162    }
163
164    pub fn register_service<BS: BinderService>(
165        &'a mut self,
166        service_delegate: &'a BS,
167        name: &'a str,
168        interface_name: &'a str,
169        allow_isolated: bool,
170        dump_priority: u32,
171    ) -> ServiceListener<'a, BS> {
172
173        self.binder.enter_looper();
174
175        let mut parcel = Parcel::empty();
176        parcel.write_interface_token(SERVICE_MANAGER_INTERFACE_TOKEN);
177        parcel.write_str16(name);
178        parcel.write_binder(self as *const _ as *const c_void);
179        parcel.write_bool(allow_isolated);
180        parcel.write_u32(dump_priority);
181
182        let (transaction, mut parcel) = self.binder.transact(
183            SERVICE_MANAGER_HANDLE,
184            ServiceManagerFunctions::AddService as u32,
185            TransactionFlags::empty(),
186            &mut parcel,
187        );
188
189        ServiceListener::new(service_delegate, self, name, interface_name)
190    }
191}