# How the FadRec Screen Recording Accessibility Service Works in FadCam

> Discover how the FadRec Screen Recording Accessibility Service in FadCam utilizes Android's AccessibilityService framework for background screen captures and persistent storage.

- Repository: [Faded/FadCam](https://github.com/anonfaded/FadCam)
- Tags: how-to-guide
- Published: 2026-05-13

---

**The FadRec Screen Recording Accessibility Service leverages Android's `AccessibilityService` framework to run with elevated background privileges, enabling it to orchestrate `MediaProjection` screen captures through a static coordination flag while persisting frames to the device's FadRec storage folder.**

FadCam is an open-source Android camera application that implements screen recording via a specialized service called `FadRecScreenshotAccessibilityService`. This service acts as the architectural bridge between the user interface and Android's low-level screen capture APIs, solving the security restriction that prevents standard background services from initiating MediaProjection requests.

## Service Declaration and Permissions

Before the service can operate, it must be declared in the AndroidManifest.xml with specific permissions that grant it system-level access. The declaration includes the `BIND_ACCESSIBILITY_SERVICE` permission and a metadata resource defining the service configuration.

In [`app/src/main/java/com/fadcam/service/FadRecScreenshotAccessibilityService.java`](https://github.com/anonfaded/FadCam/blob/main/app/src/main/java/com/fadcam/service/FadRecScreenshotAccessibilityService.java), the class extends `AccessibilityService` and is registered with intent filters that allow the Android system to bind it during accessibility events. The service configuration requests the `FLAG_CAN_REQUEST_TOUCH_EXPLORATION_MODE` flag, which is essential for receiving window state change notifications without requiring direct user interaction with the service component.

The manifest entry enables the service to remain bound in the background while the app is in use, providing the stable context required to manage MediaProjection resources across configuration changes.

## Core Implementation in FadRecScreenshotAccessibilityService

The service coordinates screen capture through a state machine driven by accessibility events and static flags. This architecture decouples the UI thread from the capture logic while maintaining strict control over system resources.

### Static Coordination via pendingCapture

Communication between the UI and the service relies on a static boolean flag named `pendingCapture` defined within the service's companion object. When the user requests a screenshot, the UI invokes `FadRecScreenshotAccessibilityService.markPendingCapture(context)`, which sets this flag to true and acquires a partial wake lock for two seconds to ensure the CPU remains active during the transition.

The service polls this flag within `onAccessibilityEvent()` to determine whether the current event should trigger a capture sequence. This pattern allows the UI to remain lightweight while the service handles the heavy lifting of MediaProjection initialization.

### Service Connection and Event Filtering

Upon binding, `onServiceConnected()` configures the service to listen for specific event types including `TYPE_WINDOW_STATE_CHANGED` and `TYPE_VIEW_CLICKED`. The method obtains a reference to the `MediaProjectionManager` system service, storing it for later use when the actual capture begins.

The service filters incoming accessibility events to identify the precise moment when the foreground activity matches the recording UI context. Only when `pendingCapture` is true and the window state event corresponds to the correct activity class does the service proceed to launch the MediaProjection intent.

## Triggering Captures from the UI Layer

The entry point for screen recording is managed through [`ScreenShotCaptureActivity.java`](https://github.com/anonfaded/FadCam/blob/main/ScreenShotCaptureActivity.java) located in `app/src/main/java/com/fadcam/`. This activity serves as a thin wrapper that validates service state before requesting captures.

### Service Validation

When the user taps the start recording button, the activity checks `FadRecScreenshotAccessibilityService.isServiceEnabled(context)` to verify the accessibility service is active in system settings. If disabled, the activity launches the system Accessibility Settings screen via `Settings.ACTION_ACCESSIBILITY_SETTINGS`, forcing the user to enable the service before proceeding.

### Initiating the Capture Sequence

Once validated, the activity calls `markPendingCapture()` and immediately finishes. This design keeps the activity lifecycle brief while ensuring the service has the necessary flag state to respond to the next accessibility event. The service then detects the flag, recognizes the window state change, and launches the MediaProjection permission dialog through a hidden activity context allowed by its elevated privileges.

## MediaProjection and Image Capture Flow

The actual screen capture utilizes Android's MediaProjection API combined with ImageReader surfaces to extract raw frame data from the display buffer.

### VirtualDisplay and ImageReader Configuration

When `startScreenCapture()` executes, the service creates an `ImageReader` instance configured with the device's current display dimensions and `PixelFormat.RGBA_8888`. A `VirtualDisplay` is then registered with the `MediaProjection` instance, directing output to the ImageReader's surface.

The service implements an `OnImageAvailableListener` that triggers when a new frame is ready. This listener acquires the latest `Image` from the reader, locks the pixel buffer, and converts the raw data into a `Bitmap` object suitable for storage.

### Resource Management and Cleanup

After extracting the frame, the service immediately releases the `VirtualDisplay`, closes the `ImageReader`, and clears the `pendingCapture` flag. This aggressive cleanup prevents memory leaks and ensures the MediaProjection token remains valid for subsequent captures. The bitmap is then passed to `PhotoStorageHelper` for persistence, naming the file with the pattern `FadRec_<timestamp>.png`.

## Integration with FadCam UI Components

The screen recording feature integrates with several UI components to provide a seamless user experience across different application modes.

### Mode Switching and State Visualization

[`ModeSwitcherComponent.java`](https://github.com/anonfaded/FadCam/blob/main/ModeSwitcherComponent.java) handles toggling between standard camera (FadCam) and screen recording (FadRec) modes. When switching to FadRec mode, the component updates badge colors and disables camera-specific controls like the lens switcher. The [`FadRecHomeFragment.java`](https://github.com/anonfaded/FadCam/blob/main/FadRecHomeFragment.java) subclass customizes the HomeFragment layout to remove camera-dependent UI elements while exposing the screen recording trigger.

### Watermark Rendering

Captured frames receive watermarks through [`GLWatermarkRenderer.java`](https://github.com/anonfaded/FadCam/blob/main/GLWatermarkRenderer.java), which adjusts its rendering logic for FadRec mode. The renderer accounts for status bar height when positioning watermarks on screenshots, ensuring consistent branding without obstructing system UI elements.

### File Persistence

The [`PhotoStorageHelper.java`](https://github.com/anonfaded/FadCam/blob/main/PhotoStorageHelper.java) utility completes the capture pipeline by writing bitmap data to `/Documents/FadRec/` (or the Pictures equivalent). It handles directory creation, file naming conventions, and media scanner notifications to ensure recordings appear immediately in gallery applications.

## Summary

- **FadRecScreenshotAccessibilityService.java** extends Android's AccessibilityService to gain background MediaProjection privileges unavailable to standard services.
- Communication occurs via a static `pendingCapture` flag set by `markPendingCapture()` and polled during `onAccessibilityEvent()`.
- The service initializes MediaProjection through `createScreenCaptureIntent()`, feeding frames into an **ImageReader** configured with `RGBA_8888` pixel format.
- **ScreenShotCaptureActivity.java** validates service state and triggers captures without maintaining a persistent activity window.
- **PhotoStorageHelper.java** persists captured frames as timestamped PNG files in the FadRec directory, while **ModeSwitcherComponent.java** coordinates UI state transitions between camera and recording modes.

## Frequently Asked Questions

### Why does FadCam use an AccessibilityService for screen recording?

Standard Android services cannot launch MediaProjection permission requests from the background due to security restrictions introduced in recent Android versions. The **AccessibilityService** runs with elevated system privileges that permit it to initiate screen capture intents without requiring a visible activity window, enabling the seamless background operation required for FadRec functionality.

### How does the UI communicate with the service without direct binding?

The implementation uses a **static boolean flag** named `pendingCapture` defined in [`FadRecScreenshotAccessibilityService.java`](https://github.com/anonfaded/FadCam/blob/main/FadRecScreenshotAccessibilityService.java). When the user presses the record button, the UI calls the static method `markPendingCapture()`, which flips this flag and acquires a brief wake lock. The service detects this state change during its next `onAccessibilityEvent()` callback and initiates the capture sequence.

### What happens if the AccessibilityService is disabled while recording?

If the user disables the service in system settings during an active recording session, the **MediaProjection** instance remains valid until explicitly stopped, but new captures cannot be initiated. The `isServiceEnabled()` check in [`ScreenShotCaptureActivity.java`](https://github.com/anonfaded/FadCam/blob/main/ScreenShotCaptureActivity.java) prevents starting new recordings until the service is re-enabled, ensuring the app never attempts unauthorized capture requests.

### Where are FadRec screenshots saved on the device?

Captured screenshots are saved to the device's shared storage directory (typically `/Documents/FadRec/` or `/Pictures/FadRec/`) via **PhotoStorageHelper.java**. Files follow the naming convention `FadRec_<timestamp>.png`, making them immediately accessible through standard gallery applications and file managers.