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 /systembecomes
adb shell su -c mount -o remount,rw /systemI 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 /systemIf you are not using recovery, you need to remount system as rw:
adb shell mount -o remount,rw /systemNext, you need to pull existing Shell.apk from device
mkdir shell_camera_permission
cd shell_camera_permission
adb pull /system/priv-app/Shell/Shell.apkDecompile 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.apkThen 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.apkYou 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.apkThen reboot
adb rebootAnd grant camera permission to shell package
adb shell su -c pm grant com.android.shell android.permission.CAMERANow 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 scrcpyThen 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 -CxAnd, finally, you can run scrcpy with camera as video source:
./run x --video-source=camera