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}