Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ATV Castable? #6

Open
rijnhard opened this issue Sep 29, 2024 · 10 comments
Open

Make ATV Castable? #6

rijnhard opened this issue Sep 29, 2024 · 10 comments

Comments

@rijnhard
Copy link

rijnhard commented Sep 29, 2024

Context: running waydroid on a fedora 40 HTPC.

So I have already figured out one part of the equation, which is bridging waydroid to the ethernet port so that it gets its own IP, and that at least makes waydroid show up on my phone.

But it still not casable...

The issue is these logcat logs (and the chatgpt output from it helping me debug):

> waydroid logcat

I chromium: [2115:3086:INFO:ssdp_device.c(101)] SSDP packets sent for 60 seconds = 1
E chromium: [2115:2115:ERROR:dial_request_handler.cc(253)] Illegal DIAL application resource CORS origin: package:com.google.android.youtube
E chromium: [2115:2115:ERROR:dial_request_handler.cc(253)] Illegal DIAL application resource CORS origin: package:com.google.android.youtube
I chromium: [2115:2251:INFO:metrics_recorder.cc(188)] Cast v2 action(socket_id=6ca87428-ef45-efbc-ec6e-c008de72634f.14): CastV2.Connection.Connect.In
I chromium: [2115:2211:INFO:setup_namespace_handler.cc(91)] Added a peer for setup namespace: 6ca87428-ef45-efbc-ec6e-c008de72634f.14:gms_cast_prober-1
I chromium: [2115:2211:INFO:setup_state.cc(542)] EurekaInfoCalled: wifi_state=0, is_usable_ip_address=1, connected=1, is_initial_setup=0
I chromium: [2115:2251:INFO:v2_ssl_socket.cc(359)] Stop reading on pending closed socket
I chromium: [2115:2211:INFO:setup_namespace_handler.cc(101)] Removed a peer for setup namespace: 6ca87428-ef45-efbc-ec6e-c008de72634f.14:gms_cast_prober-1
W chromium: [2115:2251:WARNING:client_auth_signer.cc(168)] No private key, hence empty signature.
I chromium: [2115:2251:INFO:v2_ssl_socket.cc(359)] Stop reading on pending closed socket
I chromium: [2115:2251:INFO:v2_ssl_socket.cc(359)] Stop reading on pending closed socket

part 2 logs:

I chromium: [metrics_stat_logger] Cast.ConnectionType.Ethernet=1
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Request.AppId.In=2
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Request.In=1
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Request.Namespace.In=1
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Response.AppId.Out=2
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Response.Error.NamespaceNotSupported=1
I chromium: [metrics_stat_logger] Cast.Discovery.Mdns.Response.Out=1
I chromium: [metrics_stat_logger] Cast.Network.CheckIn=1
I chromium: [2115:2250:INFO:mdns_cast_service.cc(949)] Recent mDNS app subtypes: [supported:'233637DE','CFE7FEDA',] [unsupported:]

1. CORS Origin Error

E chromium: [2115:2115:ERROR:dial_request_handler.cc(253)] Illegal DIAL application resource CORS origin: package:com.google.android.youtube
  • This suggests an issue related to Cross-Origin Resource Sharing (CORS), which occurs when an app (in this case, YouTube) tries to communicate with the cast target (Waydroid's emulated Android TV) but is blocked due to CORS restrictions.
  • DIAL (DIscovery And Launch) is the protocol used by many casting systems, including Chromecast. The error suggests that Waydroid might not be properly handling the CORS headers, causing the cast connection to fail.

2. NamespaceNotSupported

Basically, as I understand, its ATV not knowing what to do with the namespace being requested, in this case com.google.android.youtube (I assume)

@rijnhard
Copy link
Author

Instructions on how to setup the bridge on linux (as long as you have NetworkManager)

Bridge waydroid to the Network

This allows waydroid to be asigned its own IP, liek a virtual server, which is needed for things like casting.

When using bridged network mode, Waydroid will essentially behave like any other physical device on your local network, with its own IP address. This means it won't directly share your HTPC's IP address or ports, so there shouldn't be any conflicts with services running natively on your HTPC. Here’s how it works:

Key Details of the Bridged Network Setup:

  • Separate IPs: With a bridged network, Waydroid will get a separate IP address from your router's DHCP server, just like any other device (e.g., your phone or laptop). This ensures no port conflict between the services running on your HTPC and the Waydroid container.
  • mDNS and UPnP: Since Waydroid will be on the same network and get its own IP address, mDNS (and other local network protocols) should work just fine without special configuration. Your phone should see Waydroid's Android TV instance on the network.

Steps for the Bridged Network Configuration:

  1. Create the Bridge: This will connect Waydroid to your home network.

    • Ensure you have a network bridge on the HTPC that connects your network interface (enp1s0, for example) to Waydroid.
    • We'll modify the Waydroid config to tie its network interface to this bridge.
  2. Edit /var/lib/waydroid/lxc/waydroid/config:

    • Set the network mode to use the bridge.
    • Update the config to replace lxc.net.0.type = veth and lxc.net.0.link = waydroid0 with the actual bridge tied to your physical network interface (for example, waylanbr0).

Example Configuration (modify as needed):

# Use a bridged network instead of NAT
lxc.net.0.type = veth
lxc.net.0.link = waylanbr0  # Bridge connected to enp1s0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx  # Should be autogenerated, 00:16:3e is the prefix for virtual MAC's

Steps:

  1. Create a Network Bridge:

    • Use nmcli or ip to create a bridge tied to your primary interface:
      sudo nmcli connection add type bridge autoconnect yes con-name waylanbr0 ifname waylanbr0
      sudo nmcli connection modify waylanbr0 ipv4.method auto
      sudo nmcli connection add type ethernet slave-type bridge autoconnect yes con-name waylanbr0-slave ifname enp1s0 master waylanbr0
      sudo nmcli connection up waylanbr0
      sudo nmcli connection up waylanbr0-slave
    • This will create waylanbr0 as a bridge and add enp1s0 (your physical NIC) to it.
  2. Configure Waydroid to use the bridge:

    • Edit /var/lib/waydroid/lxc/waydroid/config to use waylanbr0 instead of veth or waydroid0.
  3. Restart Waydroid:

    • Ensure Waydroid now gets an IP from your router by rebooting Waydroid or restarting the Waydroid service:
      sudo systemctl restart waydroid-container

Once this is done, Waydroid will have its own IP and should be discoverable by your phone and other devices for casting. Your HTPC services and Waydroid won't clash because they'll have distinct IPs.

@rijnhard
Copy link
Author

I'm starting to think this is related to the gapps package. Will experiment with other LineageOS gapps later on.

@supechicken
Copy link
Owner

Umm, I have no idea about this 😅

Maybe you could try with the ATV13 image from here with GApps from here and see if it works?

@rijnhard
Copy link
Author

rijnhard commented Oct 3, 2024

@supechicken will give it a shot.
I have some more debug logs which indicate that it's not finding an "ID" that I'll share later when I get back to my htpc. It looks like everything is setup but something is missing.

@rijnhard
Copy link
Author

rijnhard commented Oct 3, 2024

Well outside of this #8
The upside is my phone at least attempts to connect to ATV now (it was also instantly discovered).

Now I get this error on my phone, but if the Mesa issues are sorted I may be able to bypass this by manually linking.

Untrusted device

WayDroid x86_64 Device couldn't be be verified, This could be caused by outdated device firmware.

So I'll take that as a step forward compared to hanging and not being able to connect at all.

@supechicken
Copy link
Owner

Now I get this error on my phone, but if the Mesa issues are sorted I may be able to bypass this by manually linking.

Will updating Play Service helps?

Not sure if this is related to Play Protect as we are using manual certificating way currently. You might try spoofing waydroid to a certified Android Phone/TV model as described here

@rijnhard
Copy link
Author

rijnhard commented Oct 4, 2024

Will give both a shot and report back.

@worstperson
Copy link

Wouldn't you need the private casting key to sign certificates (which get revoked if leaked/abused) or patch both the server and client to fakesign and bypass verification?

@rijnhard
Copy link
Author

rijnhard commented Dec 20, 2024 via email

@worstperson
Copy link

worstperson commented Dec 20, 2024

Here's what worked for me, ymmv.

I removed the profiles in my network manager gui and set up a bridge with these commands

nmcli connection add type bridge ifname br0 stp no
nmcli connection add type bridge-slave ifname enp1s0 master br0
nmcli connection up bridge-br0
nmcli connection up bridge-slave-enp1s0

Set lxc.net.0.link to my bridge interface /var/lib/waydroid/lxc/waydroid/config

lxc.net.0.link = br0

And set USE_LXC_BRIDGE to disable the NAT related code in /usr/lib/waydroid/data/scripts/waydroid-net.sh

USE_LXC_BRIDGE="false"`

That was enough to get networking working. Next was to find an app that offered an unofficial castv2 server and has native support for x86_64.
https://www.apkmirror.com/apk/softmedia/castreceiver/
I had to patch it to give myself premium or else it drops connections after 5 minutes (one function needs to return 1 in classes.dex and I had to jump past a pthread_create in libAirReceiver.so), but it did end up working just fine. Looks like it's using pregenerated certificates from a rooted Chromecast to get around needing the private key, so it's probably not going to work with DRM streams.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants