Introduction
Prerequisites
Some extra steps that you may need
Few weeks ago, I got a Pixel 1 as my backup phone, when I try to connect it to the Microsoft Wireless Display Adapter, it couldn't find the Adapter.
I haven't used Android phones for a long time. In my mind, Android natively supports Miracast. After some searching, I was frightened to find that Google has removed Miracast from Android.
I was really disappointed because I often cast my Windows devices easily by using Miracast. My Projector has only two HDMI ports, one for HDMI cable, and one for Wireless Display Adapter. I can't add a Chromecast unless a HDMI switch is used.
One possible solution is to add a line "persist.debug.wfd.enable=1" in "build.prop" to enable WiFi-Display, but many people say that it doesn't work since Android N, the phone can discover WiFi-Displays but unable to cast.
Since Android framework is open source, I did some searching and found that some WiFi-Display related code still exists. Android 9 still keeps the WifiDisplayAdapter in DisplayManagerService, but removed WifiDisplay from MediaPlayerService, that's why we can discover WiFi-Displays but can't cast.
I recovered some code from AOSP history commits, fixed the build errors, and debugged on my Pixel, finally the Miracast can work on my Pixel.
If you also want Miracast to work on your Google phones, you can follow my steps, but first make sure your ROM is open source so that you can change and rebuild it.
I haven't used Android phones for a long time. In my mind, Android natively supports Miracast. After some searching, I was frightened to find that Google has removed Miracast from Android.
I was really disappointed because I often cast my Windows devices easily by using Miracast. My Projector has only two HDMI ports, one for HDMI cable, and one for Wireless Display Adapter. I can't add a Chromecast unless a HDMI switch is used.
One possible solution is to add a line "persist.debug.wfd.enable=1" in "build.prop" to enable WiFi-Display, but many people say that it doesn't work since Android N, the phone can discover WiFi-Displays but unable to cast.
Since Android framework is open source, I did some searching and found that some WiFi-Display related code still exists. Android 9 still keeps the WifiDisplayAdapter in DisplayManagerService, but removed WifiDisplay from MediaPlayerService, that's why we can discover WiFi-Displays but can't cast.
I recovered some code from AOSP history commits, fixed the build errors, and debugged on my Pixel, finally the Miracast can work on my Pixel.
If you also want Miracast to work on your Google phones, you can follow my steps, but first make sure your ROM is open source so that you can change and rebuild it.
- If you have a Pixel 1 running the same version of system, you can simply replace some files in your system with the files I built.
- If you have other Google phones or running different versions, you can apply my patch to AOSP, and build it by yourself. I have built the latest version for all Google Pixel phones, but I haven't tested except Pixel 1.
- If your ROM is not open source, I will no longer be able to help, since MediaPlayerService may have been changed by your ROM, you may can't replace it with the AOSP version.
Prerequisites
- Pixel running Android 9.0.0 build number PQ1A.181205.002.A1 or PQ1A.190105.004.
- Bootloader unlocked.
- adb and fastboot tools and drivers are working for your device.
- These steps will change files in your system, your Pixel should run the exact same version of system. Pushing files to different versions of system may cause unknown problems.
- Please check carefully before running each command, a mistaken operation may result in unable to boot up, or destroy your data, or even damage your phone.
- If you are not sure about what these steps are doing, but still want to go ahead, please backup your phone firstly, you may not be able to recover your phone to its original state.
- I have only tested on Pixel 1 with build number PQ1A.181205.002.A1 and PQ1A.190105.004, for other phones or versions, you should build and test on your own.
- Flash the same version of factory image for your phone.
- Download the prebuilt files from https://github.com/sbjbs/android-wfd-patch
- Add this line into "build.prop", without it, we will not be able to enable WiFi-Display:
Code:persist.debug.wfd.enable=1
- Replace some files in system:
Code:system/lib/libaudioflinger.so system/lib64/libaudioflinger.so system/lib/libserviceutility.so system/lib64/libserviceutility.so system/lib/libmedia.so system/lib64/libmedia.so system/lib/libwilhelm.so system/lib64/libwilhelm.so system/lib/libandroid_runtime.so system/lib64/libandroid_runtime.so system/lib/libstagefright.so system/lib64/libstagefright.so system/lib/libstagefright_wfd.so system/lib64/libstagefright_wfd.so system/lib/libmediaplayerservice.so
- If you have magisk installed, you can refer to Phoenix Wright's post:
using "setprop" to set that property once is enough, no need to touch build.prop; given it's a "persist" property it'll be permanent.
using magisk to overlay them on /system
Some extra steps that you may need
- Remove dm-verity metadata of system.img
The dm-verity can prevent us from changing the system, and what's more it has a forward-error-correction(FEC) feature, which can detect and correct some corrupted data.
I spend a lot of time on attempting to change the build.prop but fail again and again, it just always correct the file, and I can't enable wifi-display.
I don't know how to disable it. Since the error-correcting info should be stored in the dm-verity metadata, I just removed the dm-verity metadata from the stock system.img, and flash the system.img.
I will list the steps to remove dm-verity metadata, but if you can disable dm-verity entirely, that should work too.
For phones that have a vbmeta partition (like Pixel 2), seems you can flash an special vbmeta.img to disable AVB. You can build the empty vbmeta image by this command, but I don't have a device to test if it works:
Code:avbtool make_vbmeta_image --flag 2 --padding_size 4096 --output vbmeta.img
For Pixel 1, we need to remove dm-verity metadata that attached to system.img, first convert the sparse system.img to an ext4 image:
Code:simg2img system.img system.ext4.img
Code:od -j 1028 -An -N4 -tu system.ext4.img
so the real system partition size is 516099 * 4096 = 2113941504 bytes.
we need to set the data to zero after that position. It's important to do this, since we need to overwrite the metadata in that area, rather than just truncate the size of system.img.
next get the ext4 image size, for Pixel PQ1A.181205.002.A1, it should be 2147483648.
so we need to write 2147483648 - 2113941504 = 33542144 bytes:
Code:dd if=/dev/zero of=system.ext4.img seek=2113941504 count=33542144 oflag=seek_bytes iflag=count_bytes
after that, flash the changed system.ext4.img to Pixel:
Code:fastboot flash system system.ext4.img
- Temporary boot up by TWRP image
We don't have to install TWRP, but just use it to temporary boot up, so that we can mount the system partition for writing. If you have TWRP installed, you can just boot to TWRP.
Download TWRP image for pixel, just need the twrp.img, we won't install the zip file.
boot your device to bootloader:
Code:adb reboot bootloader
Code:fastboot boot twrp.img
- Mount system partition for writing.
In the current version of TWRP for Pixel (twrp-3.2.3-1-sailfish.img), its fstab has an entry for system partition, we can directly mount it.
Code:adb shell mount /system
Code:adb shell mount
Code:/dev/block/sda34 on /system type ext4 (rw,seclabel,relatime)
after mount, we can use adb to push files into system.
Last edited: