Android – Programmatically Connect and Disconnect Android Device

androiddisconnectusb

I need to find a way to (using an Android application) programmatically connect and disconnect an Android device from a host.

I am using a Galaxy Nexus. My goal is to keep everything as close to stock as possible, though I have already enabled verbose debug messages in the kernel and in order to view them have enabled root access on the phone to access /proc/kmsg (and the shell command dmesg).

I am certain that there is a way to leverage root access to do what I need to do, but all of my attempts have lead to nix.

  • Mess with /proc/bus/usb
  • Mess with /dev/bus/usb
  • Change between MTP/PTP (unable to do programatically)
  • Making the Android USB gadget driver into a module <- ???

I am going to try to figure out how to do the last object on the list, as then I would be able to rmmod and insmod the resulting *.ko in my application and that would connect and disconnect the phone. I am unsure of the feasibility of this option though.

Best Answer

Solution came when close to a deadline, so I am almost sure it is not the best way of doing things, but it met my requirements.

Build Modded kernel (to allow hooking of particular function)

  • Modify kernel config to support Kprobes (set CONFIG_KPROBES to Y)
  • Remove "static" keyword from android_setup() definition (driver/usb/gadget/android.c)
  • Build that kernel

Build kernel module (which gives the actual functionality of connecting and disconnecting)

  • Use Kallsyms to dynamically pull the absolute address of android_setup()
  • Using kprobes, hook android_setup()
  • Set up two timers to execute every time android_setup() is called
  • First timer set for 2 seconds from now, Second set for 2.005 seconds from now
  • Both timers take a pointer to the struct usb_gadget as their data
  • In respective callback functions, call usb_gadget_connect() and usb_gadget_disconnect(), which forces physical disconnect followed by reconnect on the Samsung Galaxy Nexus

Build Application

  • Gotta have a rooted device
  • Simply make a shell call with SU privilege - "insmod module_name." Until you call rmmod, the module will force the device into an enumeration cycle, disconnecting and reconnecting continuously.

If you are interested in repeating these results, read the document posted here and feel free to send me any questions.

https://docs.google.com/uc?export=download&id=0B9WchRkSOWwJbi10MGhLWUljT2s