binder/binder.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
/*
* Copyright (C) 2020 The Android Open Source Project
*
* 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.
*/
//! Trait definitions for binder objects
use crate::error::{status_t, Result, StatusCode};
use crate::parcel::{BorrowedParcel, Parcel};
use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
use crate::sys;
use downcast_rs::{impl_downcast, DowncastSync};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::ffi::{c_void, CStr, CString};
use std::fmt;
use std::io::Write;
use std::marker::PhantomData;
use std::ops::Deref;
use std::os::fd::AsRawFd;
use std::os::raw::c_char;
use std::ptr;
/// Binder action to perform.
///
/// This must be a number between [`FIRST_CALL_TRANSACTION`] and
/// [`LAST_CALL_TRANSACTION`].
pub type TransactionCode = u32;
/// Additional operation flags.
///
/// `FLAG_*` values.
pub type TransactionFlags = u32;
/// Super-trait for Binder interfaces.
///
/// This trait allows conversion of a Binder interface trait object into an
/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
/// interfaces) must implement this trait.
///
/// This is equivalent `IInterface` in C++.
pub trait Interface: Send + Sync + DowncastSync {
/// Convert this binder object into a generic [`SpIBinder`] reference.
fn as_binder(&self) -> SpIBinder {
panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
}
/// Dump transaction handler for this Binder object.
///
/// This handler is a no-op by default and should be implemented for each
/// Binder service struct that wishes to respond to dump transactions.
fn dump(&self, _writer: &mut dyn Write, _args: &[&CStr]) -> Result<()> {
Ok(())
}
}
impl_downcast!(sync Interface);
/// Implemented by sync interfaces to specify what the associated async interface is.
/// Generic to handle the fact that async interfaces are generic over a thread pool.
///
/// The binder in any object implementing this trait should be compatible with the
/// `Target` associated type, and using `FromIBinder` to convert it to the target
/// should not fail.
pub trait ToAsyncInterface<P>
where
Self: Interface,
Self::Target: FromIBinder,
{
/// The async interface associated with this sync interface.
type Target: ?Sized;
}
/// Implemented by async interfaces to specify what the associated sync interface is.
///
/// The binder in any object implementing this trait should be compatible with the
/// `Target` associated type, and using `FromIBinder` to convert it to the target
/// should not fail.
pub trait ToSyncInterface
where
Self: Interface,
Self::Target: FromIBinder,
{
/// The sync interface associated with this async interface.
type Target: ?Sized;
}
/// Interface stability promise
///
/// An interface can promise to be a stable vendor interface ([`Stability::Vintf`]),
/// or makes no stability guarantees ([`Stability::Local`]). [`Stability::Local`] is
/// currently the default stability.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum Stability {
/// Default stability, visible to other modules in the same compilation
/// context (e.g. modules on system.img)
#[default]
Local,
/// A Vendor Interface Object, which promises to be stable
Vintf,
}
impl From<Stability> for i32 {
fn from(stability: Stability) -> i32 {
use Stability::*;
match stability {
Local => 0,
Vintf => 1,
}
}
}
impl TryFrom<i32> for Stability {
type Error = StatusCode;
fn try_from(stability: i32) -> Result<Stability> {
use Stability::*;
match stability {
0 => Ok(Local),
1 => Ok(Vintf),
_ => Err(StatusCode::BAD_VALUE),
}
}
}
/// A local service that can be remotable via Binder.
///
/// An object that implement this interface made be made into a Binder service
/// via `Binder::new(object)`.
///
/// This is a low-level interface that should normally be automatically
/// generated from AIDL via the [`crate::declare_binder_interface!`] macro.
/// When using the AIDL backend, users need only implement the high-level AIDL-defined
/// interface. The AIDL compiler then generates a container struct that wraps
/// the user-defined service and implements `Remotable`.
pub trait Remotable: Send + Sync + 'static {
/// The Binder interface descriptor string.
///
/// This string is a unique identifier for a Binder interface, and should be
/// the same between all implementations of that interface.
fn get_descriptor() -> &'static str;
/// Handle and reply to a request to invoke a transaction on this object.
///
/// `reply` may be [`None`] if the sender does not expect a reply.
fn on_transact(
&self,
code: TransactionCode,
data: &BorrowedParcel<'_>,
reply: &mut BorrowedParcel<'_>,
) -> Result<()>;
/// Handle a request to invoke the dump transaction on this
/// object.
fn on_dump(&self, file: &mut dyn Write, args: &[&CStr]) -> Result<()>;
/// Retrieve the class of this remote object.
///
/// This method should always return the same InterfaceClass for the same
/// type.
fn get_class() -> InterfaceClass;
}
/// First transaction code available for user commands (inclusive)
pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
/// Last transaction code available for user commands (inclusive)
pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
/// Corresponds to TF_ONE_WAY -- an asynchronous call.
pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
/// Set to the vendor flag if we are building for the VNDK, 0 otherwise
pub const FLAG_PRIVATE_LOCAL: TransactionFlags = sys::FLAG_PRIVATE_LOCAL;
/// Internal interface of binder local or remote objects for making
/// transactions.
///
/// This trait corresponds to the parts of the interface of the C++ `IBinder`
/// class which are internal implementation details.
pub trait IBinderInternal: IBinder {
/// Is this object still alive?
fn is_binder_alive(&self) -> bool;
/// Indicate that the service intends to receive caller security contexts.
#[cfg(not(android_vndk))]
fn set_requesting_sid(&mut self, enable: bool);
/// Dump this object to the given file handle
fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
/// Get a new interface that exposes additional extension functionality, if
/// available.
fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
/// Create a Parcel that can be used with `submit_transact`.
fn prepare_transact(&self) -> Result<Parcel>;
/// Perform a generic operation with the object.
///
/// The provided [`Parcel`] must have been created by a call to
/// `prepare_transact` on the same binder.
///
/// # Arguments
///
/// * `code` - Transaction code for the operation.
/// * `data` - [`Parcel`] with input data.
/// * `flags` - Transaction flags, e.g. marking the transaction as
/// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
fn submit_transact(
&self,
code: TransactionCode,
data: Parcel,
flags: TransactionFlags,
) -> Result<Parcel>;
/// Perform a generic operation with the object. This is a convenience
/// method that internally calls `prepare_transact` followed by
/// `submit_transact.
///
/// # Arguments
/// * `code` - Transaction code for the operation
/// * `flags` - Transaction flags, e.g. marking the transaction as
/// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
/// * `input_callback` A callback for building the `Parcel`.
fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
&self,
code: TransactionCode,
flags: TransactionFlags,
input_callback: F,
) -> Result<Parcel> {
let mut parcel = self.prepare_transact()?;
input_callback(parcel.borrowed())?;
self.submit_transact(code, parcel, flags)
}
}
/// Interface of binder local or remote objects.
///
/// This trait corresponds to the parts of the interface of the C++ `IBinder`
/// class which are public.
pub trait IBinder {
/// Register the recipient for a notification if this binder
/// goes away. If this binder object unexpectedly goes away
/// (typically because its hosting process has been killed),
/// then the `DeathRecipient`'s callback will be called.
///
/// You will only receive death notifications for remote binders,
/// as local binders by definition can't die without you dying as well.
/// Trying to use this function on a local binder will result in an
/// INVALID_OPERATION code being returned and nothing happening.
///
/// This link only holds a weak reference to its recipient. If the
/// `DeathRecipient` is dropped then it will be unlinked.
///
/// Note that the notifications won't work if you don't first start at least
/// one Binder thread by calling
/// [`ProcessState::start_thread_pool`](crate::ProcessState::start_thread_pool)
/// or
/// [`ProcessState::join_thread_pool`](crate::ProcessState::join_thread_pool).
fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
/// Remove a previously registered death notification.
/// The recipient will no longer be called if this object
/// dies.
fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
/// Send a ping transaction to this object
fn ping_binder(&mut self) -> Result<()>;
}
/// Opaque reference to the type of a Binder interface.
///
/// This object encapsulates the Binder interface descriptor string, along with
/// the binder transaction callback, if the class describes a local service.
///
/// A Binder remotable object may only have a single interface class, and any
/// given object can only be associated with one class. Two objects with
/// different classes are incompatible, even if both classes have the same
/// interface descriptor.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct InterfaceClass(*const sys::AIBinder_Class);
impl InterfaceClass {
/// Get a Binder NDK `AIBinder_Class` pointer for this object type.
///
/// Note: the returned pointer will not be constant. Calling this method
/// multiple times for the same type will result in distinct class
/// pointers. A static getter for this value is implemented in
/// [`crate::declare_binder_interface!`].
pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
let descriptor = CString::new(I::get_descriptor()).unwrap();
// Safety: `AIBinder_Class_define` expects a valid C string, and three
// valid callback functions, all non-null pointers. The C string is
// copied and need not be valid for longer than the call, so we can drop
// it after the call. We can safely assign null to the onDump and
// handleShellCommand callbacks as long as the class pointer was
// non-null. Rust None for a Option<fn> is guaranteed to be a NULL
// pointer. Rust retains ownership of the pointer after it is defined.
let ptr = unsafe {
let class = sys::AIBinder_Class_define(
descriptor.as_ptr(),
Some(I::on_create),
Some(I::on_destroy),
Some(I::on_transact),
);
if class.is_null() {
panic!("Expected non-null class pointer from AIBinder_Class_define!");
}
sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
sys::AIBinder_Class_setHandleShellCommand(class, None);
class
};
InterfaceClass(ptr)
}
/// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
/// pointer.
///
/// # Safety
///
/// This function is safe iff `ptr` is a valid, non-null pointer to an
/// `AIBinder_Class`.
pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
InterfaceClass(ptr)
}
/// Get the interface descriptor string of this class.
pub fn get_descriptor(&self) -> String {
// SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is
// always a two-byte null terminated sequence of u16s. Thus, we can
// continue reading from the pointer until we hit a null value, and this
// pointer can be a valid slice if the slice length is <= the number of
// u16 elements before the null terminator.
unsafe {
let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
CStr::from_ptr(raw_descriptor)
.to_str()
.expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
.into()
}
}
}
impl From<InterfaceClass> for *const sys::AIBinder_Class {
fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
class.0
}
}
/// Strong reference to a binder object
pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);
impl<I: FromIBinder + ?Sized> Strong<I> {
/// Create a new strong reference to the provided binder object
pub fn new(binder: Box<I>) -> Self {
Self(binder)
}
/// Construct a new weak reference to this binder
pub fn downgrade(this: &Strong<I>) -> Weak<I> {
Weak::new(this)
}
/// Convert this synchronous binder handle into an asynchronous one.
pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target>
where
I: ToAsyncInterface<P>,
{
// By implementing the ToAsyncInterface trait, it is guaranteed that the binder
// object is also valid for the target type.
FromIBinder::try_from(self.0.as_binder()).unwrap()
}
/// Convert this asynchronous binder handle into a synchronous one.
pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target>
where
I: ToSyncInterface,
{
// By implementing the ToSyncInterface trait, it is guaranteed that the binder
// object is also valid for the target type.
FromIBinder::try_from(self.0.as_binder()).unwrap()
}
}
impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
fn clone(&self) -> Self {
// Since we hold a strong reference, we should always be able to create
// a new strong reference to the same interface type, so try_from()
// should never fail here.
FromIBinder::try_from(self.0.as_binder()).unwrap()
}
}
impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
fn borrow(&self) -> &I {
&self.0
}
}
impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
fn as_ref(&self) -> &I {
&self.0
}
}
impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
type Target = I;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.as_binder().cmp(&other.0.as_binder())
}
}
impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
fn eq(&self, other: &Self) -> bool {
self.0.as_binder().eq(&other.0.as_binder())
}
}
impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}
/// Weak reference to a binder object
#[derive(Debug)]
pub struct Weak<I: FromIBinder + ?Sized> {
weak_binder: WpIBinder,
interface_type: PhantomData<I>,
}
impl<I: FromIBinder + ?Sized> Weak<I> {
/// Construct a new weak reference from a strong reference
fn new(binder: &Strong<I>) -> Self {
let weak_binder = binder.as_binder().downgrade();
Weak { weak_binder, interface_type: PhantomData }
}
/// Upgrade this weak reference to a strong reference if the binder object
/// is still alive
pub fn upgrade(&self) -> Result<Strong<I>> {
self.weak_binder.promote().ok_or(StatusCode::DEAD_OBJECT).and_then(FromIBinder::try_from)
}
}
impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
fn clone(&self) -> Self {
Self { weak_binder: self.weak_binder.clone(), interface_type: PhantomData }
}
}
impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
fn cmp(&self, other: &Self) -> Ordering {
self.weak_binder.cmp(&other.weak_binder)
}
}
impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
fn eq(&self, other: &Self) -> bool {
self.weak_binder == other.weak_binder
}
}
impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}
/// Create a function implementing a static getter for an interface class.
///
/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
/// [`Interface`]) must have global, static class that uniquely identifies
/// it. This macro implements an [`InterfaceClass`] getter to simplify these
/// implementations.
///
/// The type of a structure that implements [`InterfaceClassMethods`] must be
/// passed to this macro. For local services, this should be `Binder<Self>`
/// since [`Binder`] implements [`InterfaceClassMethods`].
///
/// # Examples
///
/// When implementing a local [`Remotable`] service `ExampleService`, the
/// `get_class` method is required in the [`Remotable`] impl block. This macro
/// should be used as follows to implement this functionality:
///
/// ```rust
/// impl Remotable for ExampleService {
/// fn get_descriptor() -> &'static str {
/// "android.os.IExampleInterface"
/// }
///
/// fn on_transact(
/// &self,
/// code: TransactionCode,
/// data: &BorrowedParcel,
/// reply: &mut BorrowedParcel,
/// ) -> Result<()> {
/// // ...
/// }
///
/// binder_fn_get_class!(Binder<Self>);
/// }
/// ```
macro_rules! binder_fn_get_class {
($class:ty) => {
binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>());
};
($constructor:expr) => {
fn get_class() -> $crate::binder_impl::InterfaceClass {
static CLASS_INIT: std::sync::Once = std::sync::Once::new();
static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
// Safety: This assignment is guarded by the `CLASS_INIT` `Once`
// variable, and therefore is thread-safe, as it can only occur
// once.
CLASS_INIT.call_once(|| unsafe {
CLASS = Some($constructor);
});
// Safety: The `CLASS` variable can only be mutated once, above, and
// is subsequently safe to read from any thread.
unsafe { CLASS.unwrap() }
}
};
}
pub trait InterfaceClassMethods {
/// Get the interface descriptor string for this object type.
fn get_descriptor() -> &'static str
where
Self: Sized;
/// Called during construction of a new `AIBinder` object of this interface
/// class.
///
/// The opaque pointer parameter will be the parameter provided to
/// `AIBinder_new`. Returns an opaque userdata to be associated with the new
/// `AIBinder` object.
///
/// # Safety
///
/// Callback called from C++. The parameter argument provided to
/// `AIBinder_new` must match the type expected here. The `AIBinder` object
/// will take ownership of the returned pointer, which it will free via
/// `on_destroy`.
unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
/// Called when a transaction needs to be processed by the local service
/// implementation.
///
/// # Safety
///
/// Callback called from C++. The `binder` parameter must be a valid pointer
/// to a binder object of this class with userdata initialized via this
/// class's `on_create`. The parcel parameters must be valid pointers to
/// parcel objects.
unsafe extern "C" fn on_transact(
binder: *mut sys::AIBinder,
code: u32,
data: *const sys::AParcel,
reply: *mut sys::AParcel,
) -> status_t;
/// Called whenever an `AIBinder` object is no longer referenced and needs
/// to be destroyed.
///
/// # Safety
///
/// Callback called from C++. The opaque pointer parameter must be the value
/// returned by `on_create` for this class. This function takes ownership of
/// the provided pointer and destroys it.
unsafe extern "C" fn on_destroy(object: *mut c_void);
/// Called to handle the `dump` transaction.
///
/// # Safety
///
/// Must be called with a non-null, valid pointer to a local `AIBinder` that
/// contains a `T` pointer in its user data. fd should be a non-owned file
/// descriptor, and args must be an array of null-terminated string
/// poiinters with length num_args.
unsafe extern "C" fn on_dump(
binder: *mut sys::AIBinder,
fd: i32,
args: *mut *const c_char,
num_args: u32,
) -> status_t;
}
/// Interface for transforming a generic SpIBinder into a specific remote
/// interface trait.
///
/// # Example
///
/// For Binder interface `IFoo`, the following implementation should be made:
/// ```no_run
/// # use binder::{FromIBinder, SpIBinder, Result};
/// # trait IFoo {}
/// impl FromIBinder for dyn IFoo {
/// fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
/// // ...
/// # Err(binder::StatusCode::OK)
/// }
/// }
/// ```
pub trait FromIBinder: Interface {
/// Try to interpret a generic Binder object as this interface.
///
/// Returns a trait object for the `Self` interface if this object
/// implements that interface.
fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
}
/// Trait for transparent Rust wrappers around android C++ native types.
///
/// The pointer return by this trait's methods should be immediately passed to
/// C++ and not stored by Rust. The pointer is valid only as long as the
/// underlying C++ object is alive, so users must be careful to take this into
/// account, as Rust cannot enforce this.
///
/// # Safety
///
/// For this trait to be a correct implementation, `T` must be a valid android
/// C++ type. Since we cannot constrain this via the type system, this trait is
/// marked as unsafe.
pub unsafe trait AsNative<T> {
/// Return a pointer to the native version of `self`
fn as_native(&self) -> *const T;
/// Return a mutable pointer to the native version of `self`
fn as_native_mut(&mut self) -> *mut T;
}
// Safety: If V is a valid Android C++ type then we can either use that or a
// null pointer.
unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
fn as_native(&self) -> *const T {
self.as_ref().map_or(ptr::null(), |v| v.as_native())
}
fn as_native_mut(&mut self) -> *mut T {
self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
}
}
/// The features to enable when creating a native Binder.
///
/// This should always be initialised with a default value, e.g.:
/// ```
/// # use binder::BinderFeatures;
/// BinderFeatures {
/// set_requesting_sid: true,
/// ..BinderFeatures::default(),
/// }
/// ```
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BinderFeatures {
/// Indicates that the service intends to receive caller security contexts. This must be true
/// for `ThreadState::with_calling_sid` to work.
#[cfg(not(android_vndk))]
pub set_requesting_sid: bool,
// Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
// when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
// expressions entirely.
#[doc(hidden)]
pub _non_exhaustive: (),
}
/// Declare typed interfaces for a binder object.
///
/// Given an interface trait and descriptor string, create a native and remote
/// proxy wrapper for this interface. The native service object (`$native`)
/// implements `Remotable` and will dispatch to the function `$on_transact` to
/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
/// objects for this interface and can optionally contain additional fields.
///
/// Assuming the interface trait is `Interface`, `$on_transact` function must
/// have the following type:
///
/// ```
/// # use binder::{Interface, TransactionCode, BorrowedParcel};
/// # trait Placeholder {
/// fn on_transact(
/// service: &dyn Interface,
/// code: TransactionCode,
/// data: &BorrowedParcel,
/// reply: &mut BorrowedParcel,
/// ) -> binder::Result<()>;
/// # }
/// ```
///
/// # Examples
///
/// The following example declares the local service type `BnServiceManager` and
/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
/// proxy respectively) for the `IServiceManager` Binder interface. The
/// interfaces will be identified by the descriptor string
/// "android.os.IServiceManager". The local service will dispatch transactions
/// using the provided function, `on_transact`.
///
/// ```
/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
///
/// pub trait IServiceManager: Interface {
/// // remote methods...
/// }
///
/// declare_binder_interface! {
/// IServiceManager["android.os.IServiceManager"] {
/// native: BnServiceManager(on_transact),
/// proxy: BpServiceManager,
/// }
/// }
///
/// fn on_transact(
/// service: &dyn IServiceManager,
/// code: TransactionCode,
/// data: &BorrowedParcel,
/// reply: &mut BorrowedParcel,
/// ) -> binder::Result<()> {
/// // ...
/// Ok(())
/// }
///
/// impl IServiceManager for BpServiceManager {
/// // parceling/unparceling code for the IServiceManager emitted here
/// }
///
/// impl IServiceManager for Binder<BnServiceManager> {
/// // Forward calls to local implementation
/// }
/// ```
#[macro_export]
macro_rules! declare_binder_interface {
{
$interface:path[$descriptor:expr] {
native: $native:ident($on_transact:path),
proxy: $proxy:ident,
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
}
} => {
$crate::declare_binder_interface! {
$interface[$descriptor] {
native: $native($on_transact),
proxy: $proxy {},
$(async: $async_interface $(($try_into_local_async))?,)?
stability: $crate::binder_impl::Stability::default(),
}
}
};
{
$interface:path[$descriptor:expr] {
native: $native:ident($on_transact:path),
proxy: $proxy:ident,
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
stability: $stability:expr,
}
} => {
$crate::declare_binder_interface! {
$interface[$descriptor] {
native: $native($on_transact),
proxy: $proxy {},
$(async: $async_interface $(($try_into_local_async))?,)?
stability: $stability,
}
}
};
{
$interface:path[$descriptor:expr] {
native: $native:ident($on_transact:path),
proxy: $proxy:ident {
$($fname:ident: $fty:ty = $finit:expr),*
},
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
}
} => {
$crate::declare_binder_interface! {
$interface[$descriptor] {
native: $native($on_transact),
proxy: $proxy {
$($fname: $fty = $finit),*
},
$(async: $async_interface $(($try_into_local_async))?,)?
stability: $crate::binder_impl::Stability::default(),
}
}
};
{
$interface:path[$descriptor:expr] {
native: $native:ident($on_transact:path),
proxy: $proxy:ident {
$($fname:ident: $fty:ty = $finit:expr),*
},
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
stability: $stability:expr,
}
} => {
$crate::declare_binder_interface! {
$interface[$descriptor] {
@doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")]
native: $native($on_transact),
@doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
proxy: $proxy {
$($fname: $fty = $finit),*
},
$(async: $async_interface $(($try_into_local_async))?,)?
stability: $stability,
}
}
};
{
$interface:path[$descriptor:expr] {
@doc[$native_doc:expr]
native: $native:ident($on_transact:path),
@doc[$proxy_doc:expr]
proxy: $proxy:ident {
$($fname:ident: $fty:ty = $finit:expr),*
},
$(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
stability: $stability:expr,
}
} => {
#[doc = $proxy_doc]
pub struct $proxy {
binder: $crate::SpIBinder,
$($fname: $fty,)*
}
impl $crate::Interface for $proxy {
fn as_binder(&self) -> $crate::SpIBinder {
self.binder.clone()
}
}
impl $crate::binder_impl::Proxy for $proxy
where
$proxy: $interface,
{
fn get_descriptor() -> &'static str {
$descriptor
}
fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> {
Ok(Self { binder, $($fname: $finit),* })
}
}
#[doc = $native_doc]
#[repr(transparent)]
pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
impl $native {
/// Create a new binder service.
pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability);
#[cfg(not(android_vndk))]
$crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
$crate::Strong::new(Box::new(binder))
}
/// Tries to downcast the interface to another type.
/// When receiving this object from a binder call, make sure that the object received is
/// a binder native object and that is of the right type for the Downcast:
///
/// let binder = received_object.as_binder();
/// if !binder.is_remote() {
/// let binder_native: Binder<BnFoo> = binder.try_into()?;
/// let original_object = binder_native.downcast_binder::<MyFoo>();
/// // Check that returned type is not None before using it
/// }
///
/// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a
/// malicious caller to mount a Denial of Service attack.
pub fn downcast_binder<T: $interface>(&self) -> Option<&T> {
self.0.as_any().downcast_ref::<T>()
}
}
impl $crate::binder_impl::Remotable for $native {
fn get_descriptor() -> &'static str {
$descriptor
}
fn on_transact(&self, code: $crate::binder_impl::TransactionCode, data: &$crate::binder_impl::BorrowedParcel<'_>, reply: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
match $on_transact(&*self.0, code, data, reply) {
// The C++ backend converts UNEXPECTED_NULL into an exception
Err($crate::StatusCode::UNEXPECTED_NULL) => {
let status = $crate::Status::new_exception(
$crate::ExceptionCode::NULL_POINTER,
None,
);
reply.write(&status)
},
result => result
}
}
fn on_dump(&self, writer: &mut dyn std::io::Write, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> {
self.0.dump(writer, args)
}
fn get_class() -> $crate::binder_impl::InterfaceClass {
static CLASS_INIT: std::sync::Once = std::sync::Once::new();
static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
// Safety: This assignment is guarded by the `CLASS_INIT` `Once`
// variable, and therefore is thread-safe, as it can only occur
// once.
CLASS_INIT.call_once(|| unsafe {
CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
});
// Safety: The `CLASS` variable can only be mutated once, above,
// and is subsequently safe to read from any thread.
unsafe {
CLASS.unwrap()
}
}
}
impl $crate::FromIBinder for dyn $interface {
fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> {
use $crate::binder_impl::AssociateClass;
let existing_class = ibinder.get_class();
if let Some(class) = existing_class {
if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
{
// The binder object's descriptor string matches what we
// expect. We still need to treat this local or already
// associated object as remote, because we can't cast it
// into a Rust service object without a matching class
// pointer.
return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
}
}
if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
std::convert::TryFrom::try_from(ibinder.clone());
if let Ok(service) = service {
// We were able to associate with our expected class and
// the service is local.
return Ok($crate::Strong::new(Box::new(service)));
} else {
// Service is remote
return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
}
}
Err($crate::StatusCode::BAD_TYPE.into())
}
}
impl $crate::binder_impl::Serialize for dyn $interface + '_
where
dyn $interface: $crate::Interface
{
fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
let binder = $crate::Interface::as_binder(self);
parcel.write(&binder)
}
}
impl $crate::binder_impl::SerializeOption for dyn $interface + '_ {
fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
parcel.write(&this.map($crate::Interface::as_binder))
}
}
impl std::fmt::Debug for dyn $interface + '_ {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.pad(stringify!($interface))
}
}
/// Convert a &dyn $interface to Strong<dyn $interface>
impl std::borrow::ToOwned for dyn $interface {
type Owned = $crate::Strong<dyn $interface>;
fn to_owned(&self) -> Self::Owned {
self.as_binder().into_interface()
.expect(concat!("Error cloning interface ", stringify!($interface)))
}
}
$(
// Async interface trait implementations.
impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> {
fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
use $crate::binder_impl::AssociateClass;
let existing_class = ibinder.get_class();
if let Some(class) = existing_class {
if class != <$native as $crate::binder_impl::Remotable>::get_class() &&
class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor()
{
// The binder object's descriptor string matches what we
// expect. We still need to treat this local or already
// associated object as remote, because we can't cast it
// into a Rust service object without a matching class
// pointer.
return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
}
}
if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
std::convert::TryFrom::try_from(ibinder.clone());
$(
// This part is only generated if the user of the macro specifies that the
// trait has an `try_into_local_async` implementation.
if let Ok(service) = service {
if let Some(async_service) = $native::$try_into_local_async(service) {
// We were able to associate with our expected class,
// the service is local, and the local service is async.
return Ok(async_service);
}
// The service is local but not async. Fall back to treating it as a
// remote service. This means that calls to this local service have an
// extra performance cost due to serialization, but async handle to
// non-async server is considered a rare case, so this is okay.
}
)?
// Treat service as remote.
return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
}
Err($crate::StatusCode::BAD_TYPE.into())
}
}
impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
let binder = $crate::Interface::as_binder(self);
parcel.write(&binder)
}
}
impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
parcel.write(&this.map($crate::Interface::as_binder))
}
}
impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.pad(stringify!($async_interface))
}
}
/// Convert a &dyn $async_interface to Strong<dyn $async_interface>
impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> {
type Owned = $crate::Strong<dyn $async_interface<P>>;
fn to_owned(&self) -> Self::Owned {
self.as_binder().into_interface()
.expect(concat!("Error cloning interface ", stringify!($async_interface)))
}
}
impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
type Target = dyn $async_interface<P>;
}
impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
type Target = dyn $interface;
}
)?
};
}
/// Declare an AIDL enumeration.
///
/// This is mainly used internally by the AIDL compiler.
#[macro_export]
macro_rules! declare_binder_enum {
{
$( #[$attr:meta] )*
$enum:ident : [$backing:ty; $size:expr] {
$( $( #[$value_attr:meta] )* $name:ident = $value:expr, )*
}
} => {
$( #[$attr] )*
#[derive(Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub struct $enum(pub $backing);
impl $enum {
$( $( #[$value_attr] )* #[allow(missing_docs)] pub const $name: Self = Self($value); )*
#[inline(always)]
#[allow(missing_docs)]
pub const fn enum_values() -> [Self; $size] {
[$(Self::$name),*]
}
}
impl std::fmt::Debug for $enum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.0 {
$($value => f.write_str(stringify!($name)),)*
_ => f.write_fmt(format_args!("{}", self.0))
}
}
}
impl $crate::binder_impl::Serialize for $enum {
fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
parcel.write(&self.0)
}
}
impl $crate::binder_impl::SerializeArray for $enum {
fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
<$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel)
}
}
impl $crate::binder_impl::Deserialize for $enum {
type UninitType = Self;
fn uninit() -> Self::UninitType { Self::UninitType::default() }
fn from_init(value: Self) -> Self::UninitType { value }
fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> {
parcel.read().map(Self)
}
}
impl $crate::binder_impl::DeserializeArray for $enum {
fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> {
let v: Option<Vec<$backing>> =
<$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?;
Ok(v.map(|v| v.into_iter().map(Self).collect()))
}
}
};
}