Skip to main content

coreshift_core/binder/
mod.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/
4
5//! NDK binder primitives for querying Android system services.
6//!
7//! Uses `dlopen` on `libbinder_ndk.so` to avoid hard-linking against a library
8//! absent from older NDK toolchains or non-Android targets.
9//!
10//! ## Transaction code resolution
11//!
12//! Transaction codes are resolved fresh from `framework.jar` DEX on each
13//! startup; no persistent cache.
14//!
15//! ## Observer mode
16//!
17//! `ActivityManager::open_with_observer` registers this process as an
18//! `IProcessObserver` with ActivityManager. Callbacks fire when foreground
19//! activities change and signal an `eventfd` that callers can poll via epoll.
20//! After the eventfd fires, call `get_focused_package` to read the new value.
21
22// ─────────────────────────────────────────────────────────────────────────────
23// Android-only implementation
24// ─────────────────────────────────────────────────────────────────────────────
25
26#[cfg(target_os = "android")]
27mod am;
28#[cfg(target_os = "android")]
29mod display;
30#[cfg(target_os = "android")]
31mod fps;
32#[cfg(target_os = "android")]
33mod raw;
34#[cfg(target_os = "android")]
35mod sys;
36#[cfg(target_os = "android")]
37mod task_stack;
38
39// ── Public re-exports ─────────────────────────────────────────────────────────
40
41#[cfg(target_os = "android")]
42pub use am::{ActivityManager, TxCodes, last_foreground_pid, resolve_tx_codes};
43#[cfg(target_os = "android")]
44pub use display::{DisplayInfo, DisplayManager};
45#[cfg(target_os = "android")]
46pub use fps::FpsListener;
47#[cfg(target_os = "android")]
48pub use raw::RawBinderService;
49#[cfg(target_os = "android")]
50pub use task_stack::TaskStackListener;
51
52// ── Non-Android stubs ─────────────────────────────────────────────────────────
53
54#[cfg(not(target_os = "android"))]
55pub struct ActivityManager;
56
57#[cfg(not(target_os = "android"))]
58impl ActivityManager {
59    pub fn open() -> Result<Self, crate::CoreError> {
60        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
61    }
62    pub fn open_with_observer() -> Result<(Self, std::os::fd::OwnedFd), crate::CoreError> {
63        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
64    }
65    pub fn open_with_fgproc_observer() -> Result<(Self, std::os::fd::OwnedFd), crate::CoreError> {
66        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
67    }
68    pub fn get_focused_task(&self) -> Result<Option<(i32, Option<String>)>, crate::CoreError> {
69        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
70    }
71    pub fn get_focused_package(&self) -> Result<Option<String>, crate::CoreError> {
72        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
73    }
74    pub fn get_focused_task_id(&self) -> Result<Option<i32>, crate::CoreError> {
75        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
76    }
77}
78
79#[cfg(not(target_os = "android"))]
80pub struct DisplayManager;
81
82#[cfg(not(target_os = "android"))]
83impl DisplayManager {
84    pub fn open_with_callback() -> Result<(Self, crate::fd::Fd), crate::CoreError> {
85        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
86    }
87    pub fn is_interactive(&self) -> Result<bool, crate::CoreError> {
88        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
89    }
90    pub fn info(&self, _display_id: i32) -> Result<DisplayInfo, crate::CoreError> {
91        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
92    }
93}
94
95#[cfg(not(target_os = "android"))]
96#[derive(Clone, Copy, Debug, PartialEq, Default)]
97pub struct DisplayInfo {
98    pub active_mode_id: i32,
99    pub vsync_rate: f32,
100    pub peak_refresh_rate: f32,
101    pub render_frame_rate: f32,
102    pub is_interactive: bool,
103}
104
105#[cfg(not(target_os = "android"))]
106pub struct RawBinderService;
107
108#[cfg(not(target_os = "android"))]
109impl RawBinderService {
110    pub fn open(_service_name: &str) -> Result<Self, crate::CoreError> {
111        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
112    }
113    pub fn transact_bool(&self, _code: u32) -> Result<bool, crate::CoreError> {
114        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
115    }
116    pub fn transact_i32(&self, _code: u32, _arg: i32) -> Result<(), crate::CoreError> {
117        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
118    }
119}
120
121#[cfg(not(target_os = "android"))]
122pub struct FpsListener;
123
124#[cfg(not(target_os = "android"))]
125impl FpsListener {
126    pub fn open() -> Result<(Self, std::os::fd::OwnedFd), crate::CoreError> {
127        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
128    }
129    pub fn register(&mut self, _task_id: i32) -> Result<(), crate::CoreError> {
130        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
131    }
132    pub fn unregister(&mut self) -> Result<(), crate::CoreError> {
133        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
134    }
135    pub fn last_fps(&self) -> Option<f32> {
136        None
137    }
138    pub fn task_id(&self) -> Option<i32> {
139        None
140    }
141}
142
143#[cfg(not(target_os = "android"))]
144pub struct TaskStackListener;
145
146#[cfg(not(target_os = "android"))]
147impl TaskStackListener {
148    pub fn open() -> Result<(Self, std::os::fd::OwnedFd), crate::CoreError> {
149        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
150    }
151    pub fn register(&self) -> Result<(), crate::CoreError> {
152        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
153    }
154    pub fn unregister(&self) -> Result<(), crate::CoreError> {
155        Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
156    }
157}
158
159#[cfg(not(target_os = "android"))]
160pub struct TxCodes {
161    pub observer_code: u32,
162    pub query_code: u32,
163    pub api_mode: u8,
164    pub fg_code: u32,
165}
166
167#[cfg(not(target_os = "android"))]
168pub fn resolve_tx_codes() -> Result<TxCodes, crate::CoreError> {
169    Err(crate::CoreError::binder(-1, "binder:unsupported platform"))
170}
171
172#[cfg(not(target_os = "android"))]
173pub fn last_foreground_pid() -> i32 {
174    0
175}