cloudfox-coreshift-core 2.26.1

Low-level Linux and Android systems primitives for CoreShift (CloudFox)
Documentation
# Binder Observer

`ActivityManager::open_with_observer()` registers the calling process as an
`IProcessObserver` with Android's ActivityManager. On success it returns
`(Self, OwnedFd)` — an owned duplicate of the observer's wake eventfd that
becomes readable whenever `onForegroundActivitiesChanged` fires. The core
retains the original fd; the caller may close its duplicate without breaking
the wake path.

## Observer variants and query surface

`ActivityManager` offers four open modes and three focused-task queries:

- `open()` — polling mode; no observer, no thread pool. Carries the focused-task
  query code (see below).
- `open_with_observer()``IProcessObserver`, pure wake-up on
  `onForegroundActivitiesChanged` (never parses arguments).
- `open_with_fgproc_observer()``IForegroundProcessObserver` with a
  pid-first custom-ROM fallback (`resolve_fgproc_codes_fallback`). Parses the
  callback argument; in the dual-layout mode it suppresses the eventfd write on
  background transitions (`fg == 0`), so the fd only fires on foreground.
- `open_with_uid_observer(watched_uid)``IUidObserver` scoped to one uid
  (`registerUidObserverForUids`); packs `(uid, kind)` into `last_uid_event()`.
- `get_focused_task()``(task_id, top_activity_package)` from one transaction.
- `get_focused_package()` / `get_focused_task_id()` — the same data split.
- `last_foreground_pid()` / `last_uid_event()` — free functions reading the
  most recent fgproc/uid callback state.

**Caveat**: only polling `open()` and `open_with_observer()` carry a usable
focused-task query code. Instances created with the fgproc/uid observers
transact code 0 on `get_focused_task*` — do not call them on such an instance.

`TxCodes { observer_code, query_code, api_mode, fg_code }` / `resolve_tx_codes()`
expose the resolved codes; `api_mode` is 1 (RootTaskInfo) or 2 (legacy
StackInfo, pre-Q).

## Usage

Add the returned fd to an epoll reactor. On event:

1. Drain the eventfd (read 8 bytes).
2. Call `get_focused_package()` on the **caller's thread** — the observer
   callback itself never queries; it only signals the eventfd. The focused-task
   transaction is a separate synchronous query re-issued on demand, so data is
   fresh relative to the wake but runs on the caller's thread.

## Transaction code resolution

Codes are resolved at runtime by parsing `TRANSACTION_*` static `int` fields
from `IActivityManager`, `IProcessObserver`, `IForegroundProcessObserver`,
`IUidObserver`, `IWindowManager`/`ITaskFpsCallback`, `IDisplayManager`/
`IPowerManager`, `IContentProvider`, and `IActivityTaskManager` directly from
the ZIP STORED DEX entries in `framework.jar`, with no subprocess or
`app_process` required.

Resolution re-runs on **every** `open*` call — resolved values land in
process-wide statics, but there is no persistent startup cache. The focused-task
query has a dual path: `getFocusedRootTaskInfo` (api_mode 1) with a
`getFocusedStackInfo` fallback (api_mode 2) for pre-Q frameworks.

## Lifetime

The binder thread pool (`ABinderProcess_joinThreadPool`) runs on a background
thread for the process lifetime. It is started by every `open_with_*` /
observer path **except** the polling `ActivityManager::open()` and
`Handoff::open()`. The loaded `libbinder_ndk.so` is intentionally never
unloaded — `dlclose` while the thread pool executes from the library causes
use-after-free. This is safe for daemon processes.

## Accessibility

`open_with_observer` requires:

- `/dev/binder` accessible to the calling process
- SELinux policy permits `registerProcessObserver` on `IActivityManager`
- `activity` service reachable via service manager

On rooted devices this typically succeeds. Failure surfaces as a `CoreError`
from `open_with_observer` so callers can fall back gracefully.

## Acknowledgement

The `binder` subsystem is co-owned with
**[sehan64](https://github.com/sehan64)**.