Skip to content

Instantly share code, notes, and snippets.

@RuslanUC
Last active July 21, 2025 12:33
Show Gist options
  • Select an option

  • Save RuslanUC/8b8343102635a532dd95d482eefb32d6 to your computer and use it in GitHub Desktop.

Select an option

Save RuslanUC/8b8343102635a532dd95d482eefb32d6 to your computer and use it in GitHub Desktop.
[ROOT] Add android.permission.CAMERA to com.android.shell to allow streaming camera via scrcpy on android <12

Warning

This will probably break many of adb functions such as "adb install", "adb shell pm", "adb shell appops", etc. if you are using non-system (non-platform) signing key.

You will need rooted device, adb, apktool (2.11.1 was used, on 2.8.1 i had compilation errors, other versions were not tested), android build-tools (keytool, zipalign and apksigner need to be in $PATH), and (optionally) custom recovery such as TWRP. Also you will need all tools that are needed to build scrcpy: https://github.com/Genymobile/scrcpy/blob/master/doc/build.md.

If you are doing everything while device is booted into system, you need to execute adb root or add su -c to every adb shell command after shell, e.g.

adb shell mount -o remount,rw /system

becomes

adb shell su -c mount -o remount,rw /system

I used recovery to replace Shell.apk, but replacing might work while device is booted into system. If you are using recovery, you need to mount system:

adb shell mount /system

If you are not using recovery, you need to remount system as rw:

adb shell mount -o remount,rw /system

Next, you need to pull existing Shell.apk from device

mkdir shell_camera_permission
cd shell_camera_permission

adb pull /system/priv-app/Shell/Shell.apk

Decompile it, add android.permission.CAMERA permission to AndroidManifest.xml and recompile

apktool d Shell.apk --no-src
sed -i 's,<uses-permission android:name="android.permission.SEND_SMS"/>,<uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.SEND_SMS"/>,g' Shell/AndroidManifest.xml
apktool b Shell --use-aapt2 -o Shell-camera.apk

Then you need to sign new Shell-camera.apk, for this you need to have keytool, zipalign and apksigner in your $PATH

keytool -genkey -keypass 123456789 -storepass 123456789 \
    -dname "CN=AndroidShell" -keystore shell.keystore -keyalg RSA \
    -keysize 2048 -validity 10000 -alias shell -noprompt
zipalign -v 4 Shell-camera.apk Shell-camera-signed.apk
apksigner sign --ks-key-alias shell --ks shell.keystore --ks-pass pass:123456789 Shell-camera-signed.apk

You can use your existing keystore instead of generating new one.

Next, backup old Shell.apk so you can restore it if something goes wrong

adb shell mkdir -p /system/priv-app-bak/Shell
adb shell mv /system/priv-app/Shell/Shell.apk /system/priv-app-bak/Shell/

And push new shell apk

adb push Shell-camera-signed.apk /system/priv-app/Shell/Shell.apk
adb shell chmod 0755 /system/priv-app/Shell
adb shell chmod 0644 /system/priv-app/Shell/Shell.apk

Then reboot

adb reboot

And grant camera permission to shell package

adb shell su -c pm grant com.android.shell android.permission.CAMERA

Now you have shell with camera permission, but you also need to build scrcpy without android version check.

Clone scrcpy repo

git clone https://github.com/Genymobile/scrcpy
cd scrcpy

Then open server/src/main/java/com/genymobile/scrcpy/Server.java, around lines 77-80 you will see android version check when video source is camera:

if (Build.VERSION.SDK_INT < AndroidVersions.API_31_ANDROID_12 && options.getVideoSource() == VideoSource.CAMERA) {
    Ln.e("Camera mirroring is not supported before Android 12");
    throw new ConfigurationException("Camera mirroring is not supported");
}

You can completely remove that check, but I just commented throw line and replaced Ln.e with Ln.i:

if (Build.VERSION.SDK_INT < AndroidVersions.API_31_ANDROID_12 && options.getVideoSource() == VideoSource.CAMERA) {
    Ln.i("Camera mirroring is not supported before Android 12");
    //throw new ConfigurationException("Camera mirroring is not supported");
}

Next, build scrcpy

meson setup x --buildtype=release --strip -Db_lto=true
ninja -Cx

And, finally, you can run scrcpy with camera as video source:

./run x --video-source=camera
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment