ShizuStore

Mirror

jqssun

0.0.34 · GitHub

Download APK
Display management Android 8.0+ 1 month ago GPL-3.0 Recommended
241 ShizuStore
6k GitHub
192 Stars
55 MB Size

More about this app

Screen mirroring hub with support for sharing screen content over AirPlay, Moonlight/Sunshine, and DisplayLink

Screen Mirroring Manager for Android

Stars GitHub license build release

Mirror is an all-in-one application that forwards your screen content to external displays and expands Android's built-in screen mirroring capabilities. It creates virtual displays and supports screen sharing to:

It can be used in conjunction with Extend to turn any connected display or sink device into a secondary display where you can cast and control any application. You can also use this with AirPlay Server for Android or Moonlight for Android to create a dummy display that stays in Picture-in-Picture.

Get it on Google Play Get it on F-Droid Get it on GitHub

Usage

Mirror supports creating virtual displays and streaming to them without Shizuku. Remote input requires Shizuku: enable it in any supported mode (wireless debugging, USB debugging, or root) and grant access to this application. See Shizuku documentation for details.

Using with Extend

Mirror gets pixels onto a display. What application runs on it, where it renders, and how input is routed are handled by Extend. The two applications connect through Android's display system via DisplayManager API.

Compatibility

  • Any device on Android 8.0+ (no privileged access required)
  • (Optional) Receiver on the same subnet for AirPlay and Moonlight sinks
  • (Optional) USB 2 or higher for DisplayLink sinks
  • (Optional) Extend for managing the secondary display
  • (Optional) Shizuku for hidden API access

Features

  • Outbound AirPlay 2 (modern) and AirPlay 1 (legacy) screen mirroring to Apple devices or third-party AirPlay receivers
  • Outbound Moonlight streaming and remote control, with Sunshine server built in
  • DisplayLink USB output via USB host mode (including USB 2)
  • Each display sink is registered as a virtual display via DisplayManager API allowing other applications to launch activities on it
  • Touchscreen relay for remote pointer and keyboard input directed at the mirrored display
Feature Shizuku Minimum API
AirPlay mirroring N 26 (MediaProjection.createVirtualDisplay)
34 (MediaProjectionConfig.createConfigForDefaultDisplay)
DisplayLink USB output N 26 (android.hardware.usb.host)
Moonlight video streaming N 26 (MediaCodec H.264)
28 (BT.709/BT.2020 color metadata)
30 (KEY_LOW_LATENCY)
Moonlight H.265/HEVC encoding N 29 (MediaCodecInfo.isHardwareAccelerated)
Audio capture (playback submix) N 29 (AudioPlaybackCaptureConfiguration)
Audio capture (remote submix) O 31 (REMOTE_SUBMIX)
Cursor overlay O 26 (TYPE_APPLICATION_OVERLAY)
Remote device input R 26 (IInputManager.injectInputEvent)
Touchscreen relay with live preview R 31 (setFocusedRootTask)
34 (focusTopTask)
Auto-match aspect ratio R 26 (IWindowManager.setForcedDisplaySize)
Trusted virtual display R 33 (VIRTUAL_DISPLAY_FLAG_TRUSTED, OWN_DISPLAY_GROUP, ALWAYS_UNLOCKED, TOUCH_FEEDBACK_DISABLED)
34 (DEVICE_DISPLAY_GROUP)
Untrusted virtual display F 26 (MediaProjection.createVirtualDisplay)
Application mirroring N 26 (ActivityOptions.setLaunchDisplayId)
29 (ActivityManager.isActivityStartAllowedOnDisplay)
Prevent auto-lock R 26 (WRITE_SECURE_SETTINGS)
Disable USB audio output R 26 (IAudioService.setWiredDeviceConnectionState)
33 (IAudioService.getDevicesForAttributes)
Display hotplug monitor I 26 (DisplayManager.DisplayListener)
Legend Description
R Required
O Optional
F Fallback
I Inherited
N Unused

Implementation

Native streaming servers are bridged to Android via JNI. The Moonlight path compiles Sunshine for Android and exposes a MediaProjection backed video source. Sunshine handles RTP packetization itself; moonlight-common-c supplies the Limelight protocol headers, RTSP parser, and ENet UDP control transport. The AirPlay path is built on doubletake, ported to Android via Go mobile and patched for Apple devices and legacy AirPlay receivers. The DisplayLink path uses Android USB host mode with a user-imported vendor driver.

flowchart LR
    Android["Mirror"]
    Sunshine["Sunshine (C/JNI)<br/><small>Moonlight (RTSP + RTP)</small>"]
    Doubletake["doubletake (Go/JNI)<br/><small>RAOP + FairPlay + H.264</small>"]
    DL["DisplayLink (USB)<br/><small>USB host mode</small>"]
    Moonlight["Moonlight clients"]
    AppleSink["Apple devices or third-party AirPlay receivers"]
    DLSink["USB Display"]
    Android -- "VirtualDisplay" --> Sunshine --> Moonlight
    Android -- "VirtualDisplay" --> Doubletake --> AppleSink
    Android -- "VirtualDisplay" --> DL --> DLSink

CMake drives the native C/C++ build under ./app/src/main/cpp. Submodules must be initialized before building. AirPlay is powered by doubletake with custom bindings under ./doubletake. This library needs to be built with ./build.sh first. Make sure go is available in $PATH before building.

git submodule update --init --recursive
./build.sh && ./gradlew assembleDebug

Check out the CI for reproducible build instructions.

Credits


Disclaimer: This project is not affiliated with Apple Inc or Synaptics Inc.

Close

How Shizuku is used

Can mirror screen over AirPlay, Sunshine and DisplayLink with trusted displays, remote input, global audio and display tweaks via Shizuku

This is an AI-assisted analysis of Shizuku-related usages in the app's public source code. It is best effort, so it may not catch every single usage.

How this app uses Shizuku

Mirror uses Shizuku to unlock system level display, input and audio features for its mirroring hub.

  • Create trusted virtual displays: builds own content virtual displays owned by the shell through Shizuku instead of plain mirroring, used for AirPlay, Sunshine/Moonlight and DisplayLink targets with selectable size, density and refresh rate.
  • Match main screen aspect: changes the built in display forced size to match the remote client aspect when auto match is enabled, and restores it when mirroring stops.
  • Send remote input: forwards touches, back key presses and remote mouse, keyboard and gamepad events from Sunshine clients and the touchscreen view to the mirrored or external display.
  • Focus apps on displays: moves focus to the top task on the target display so injected input lands on the shown app.
  • Keep screen awake: grants its own secure settings permission through Shizuku, then extends the screen timeout to prevent auto lock during projection.
  • Auto allow projection and overlay: runs fixed appops set operations through the privileged service to allow screen capture and overlay for the app.
  • Capture system audio: records the whole output mix in the privileged service for AirPlay and Sunshine streams when global audio capture is enabled.
  • Restore screen power: turns the physical screen back on through the privileged service when AirPlay, Sunshine or DisplayLink sessions end.
  • Export diagnostics logs: collects the system log buffer through the privileged service to create and share a log file.

Android APIs or commands used

  • IDisplayManager.createVirtualDisplay
  • IDisplayManager.getDisplayInfo
  • IDisplayManager.requestDisplayPower
  • IWindowManager.setForcedDisplaySize
  • IWindowManager.clearForcedDisplaySize
  • IWindowManager.getInitialDisplaySize
  • IWindowManager.getBaseDisplaySize
  • IInputManager.injectInputEvent
  • IActivityTaskManager.focusTopTask
  • IActivityTaskManager.setFocusedRootTask
  • IActivityTaskManager.setFocusedStack
  • IActivityTaskManager.getAllRootTaskInfosOnDisplay
  • IPermissionManager.grantRuntimePermission
  • IPackageManager.grantRuntimePermission
  • AudioRecord with MediaRecorder.AudioSource.REMOTE_SUBMIX
  • SurfaceControl.setDisplayPowerMode
  • appops set io.github.jqssun.displaymirror PROJECT_MEDIA allow
  • appops set io.github.jqssun.displaymirror SYSTEM_ALERT_WINDOW allow
  • logcat -d

Notable details

Without Shizuku the app falls back to normal MediaProjection mirroring and playback audio capture where available, without trusted own content displays, forced aspect matching, global mix capture or automatic permission grants.

Close

Changelog

What's new for version 0.0.34

Close

Permissions

12 permissions requested

  • android.permission.RECORD_AUDIO
  • android.permission.WRITE_SECURE_SETTINGS
  • android.permission.FOREGROUND_SERVICE
  • android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION
  • android.permission.SYSTEM_ALERT_WINDOW
  • android.permission.INTERNET
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.POST_NOTIFICATIONS
  • android.permission.MODIFY_AUDIO_SETTINGS
  • io.github.jqssun.displaymirror.permission.TOUCHSCREEN_BRIDGE
  • moe.shizuku.manager.permission.API_V23
  • io.github.jqssun.displaymirror.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
Close

Sources

2 sources

0.0.34 Universal GitHub · io.github.jqssun.displaymirror
Selected Download
0.0.33 arm64-v8a,armeabi-v7a,x86_64 F-Droid · io.github.jqssun.displaymirror · io.github.jqssun.displaymirror
Download