Is it possible to connect to Android emulators running on a Mac from a Windows VM?


Yes. The methods vary a bit depending on whether you're using the Xamarin Android Player, a Google Android emulator, or Genymotion.

Xamarin Android Player

See http://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/android-player-with-visual-studio-in-vm/.

Google Android emulators

Here's one approach that seems to work:

  1. Start the emulator on the Mac.

  2. Kill the adb server on the Mac:

    adb kill-server
  3. Note that the emulator is listening on 2 TCP ports on the loopback network interface:

    lsof -iTCP -sTCP:LISTEN -P | grep 'emulator\|qemu'
    emulator6 94105 macuser   20u  IPv4 0xa8dacfb1d4a1b51f      0t0  TCP localhost:5555 (LISTEN)
    emulator6 94105 macuser   21u  IPv4 0xa8dacfb1d845a51f      0t0  TCP localhost:5554 (LISTEN)

    The odd-numbered port is the one used to connect to adb. See also http://developer.android.com/tools/devices/emulator.html#emulatornetworking.

  4. Option 1: Use nc to forward inbound TCP packets received externally on port 5555 (or any other port you like) to the odd-numbered port on the loopback interface ("127.0.0.1 5555" in this example), and to forward the outbound packets back the other way:

    cd /tmp
    mkfifo backpipe
    nc -kl 5555 0<backpipe | nc 127.0.0.1 5555 > backpipe

    As long as the nc commands stay running in a Terminal window, the packets will be forwarded as expected. You can type Control-C in the Terminal window to quit the nc commands once you're done using the emulator.

    (Option 1 is usually easier than Option 2, especially if "System Preferences -> Security & Privacy -> Firewall" is switched on.)

    Option 2: Use pfctl to redirect TCP packets from port 5555 (or any other port you like) on the "Shared Networking" interface to the odd-numbered port on the loopback interface ("127.0.0.1:5555" in this example):

    sed '/rdr-anchor/a\
    rdr pass on vmnet8 inet proto tcp from any to any port 5555 -> 127.0.0.1 port 5555
    ' /etc/pf.conf | sudo pfctl -ef -

    This command sets up port forwarding using the "pf" packet filter system service. The line breaks are important. Be sure to keep them intact when copy-pasting. You will also need to adjust the interface name from "vmnet8" if you're using Parallels. "vmnet8" is the name of the special "NAT device" for the "Shared Networking" mode in VMWare Fusion. The appropriate network interface in Parallels is likely "vnic0".

  5. Connect to the emulator from the Windows machine:

    C:\> adb connect ip-address-of-the-mac:5555

    Replace "ip-address-of-the-mac" with the IP address of the Mac, for example as listed by ifconfig vmnet8 | grep 'inet '. If needed, replace "5555" with the "other port you like" from step 4. (Note: one easy way to get command-line access to adb is via "Tools -> Android -> Android Adb Command Prompt" in Visual Studio.)

Alternate technique using ssh

If you have enabled Remote Login on the Mac, then you can use ssh port forwarding to connect to the emulator.

  1. Install an SSH client on Windows. One option is to install Git for Windows. The ssh command will then be available in the Git Bash command prompt.

  2. Follow steps 1–3 from above to start the emulator, kill the adb server on the Mac, and identify the emulator ports.

  3. Run ssh on Windows to set up two-way port forwarding between a local port on Windows ("localhost:15555" in this example) and the odd-numbered emulator port on the Mac's loopback interface ("127.0.0.1:5555" in this example):

    C:\> ssh -L localhost:15555:127.0.0.1:5555 mac-username@ip-address-of-the-mac

    Replace "mac-username" with your Mac username as listed by whoami. Replace "ip-address-of-the-mac" with the IP address of the Mac.

  4. Connect to the emulator using the local port on Windows:

    C:\> adb connect localhost:15555

    (Note: one easy way to get command-line access to adb is via "Tools -> Android -> Android Adb Command Prompt" in Visual Studio.)

A small caution: if you use port 5555 for the local port, adb will "think" that the emulator is running locally on Windows. This doesn't cause any trouble in Visual Studio, but in Xamarin Studio it causes the app to exit immediately after launch.

Alternate technique using adb -H is not yet supported

In theory, another approach would be to use adb's built-in capability to connect to an adb server running on a remote machine (see for example http://stackoverflow.com/a/18551325). But the Xamarin.Android IDE extensions do not currently provide a way to configure that option.

Contact information

This document discusses the current behavior as of March, 2016. The technique described in this document is not part of the stable testing suite for Xamarin, so it could break in the future.

If you notice that the technique no longer works, or if you notice any other mistakes in the document, feel free to add to the discussion on the following forum thread: http://forums.xamarin.com/discussion/33702/android-emulator-from-host-device-inside-windows-vm. Thanks!

Last Updated: Oct 21, 2016 05:14PM EDT