USB Power Delivery Power Role Swap in Android - android

TLDR
When I connect two USB-C Android phones together in the USB Preferences I can hot swap the power roles via the "Charge connected device" option.
How can I duplicate this functionality outside of two Android phones connecting together (i.e. when I connect my own custom 3rd party hardware)? I understand I will have to implement or make use of some USB stack hardware/firmware on the 3rd party hardware side, but I'm not sure exactly what standards are necessary. For example Digi-key produced a nice article describing the various USB specifications. So for Android Power Swapping comparability, do I need USB PD 3.0, or would USB Type-C 1.2 work, or USB BC 1.2, etc.?
Also I would like a link to some official confirmation that Android Open Accessory is NOT the current way to handle powering an Android phone from an external device despite what is suggested by the official dev docs. Instead it appears that USB-PD, or some other USB type C standard with Android remaining the DATA Host, while the external device being the POWER SOURCE is the current standard way of doing this. I haven't found anything about this in the Android dev docs so far and it seems very strange to me that something they haven't updated since 2012 is still in the official docs as the ONLY way of doing things.
It appears this USB Power Swapping functionality is not listed in the Android dev docs that I could find, but you can find the source code responsible for the hot swapping of power roles here
Detailed Background
I have a project where I need to power an Android phone via an external battery powered MCU. According to the android dev docs on usb connectivity, I'm supposed to have my MCU act as a host and implement the Android Open Accessory Protocol (AOA).
Looking for how to do so turned out to be a fairly deep rabbit hole, but in short I found manufacturers like FTDI that make dedicated ICs for handling AOA protocol, but their examples haven't been updated since 2012 and the AOA is hardcoded so any future changes to the protocol would require making new hardware.
I also have worked on the IOIO Board repo a bit (from the Android side), but looking into the firmware used on the PIC24F it looks like the original developer created a custom USB-Host stack that implemented the AOA and makes several comments in the repo wiki about how this is VERY hard.
Finally, I found repo that implements AOA on a MAX3421E. It appears this may have stemmed off or related to other projects in 2011/2012 surrounding the AOA like the Arduino ADK which is now obsolete.
It summary it appears anything surrounding the AOA or "ADK" is completely user or 3rd-party driven and nothing officially supported by Android/Google. For example, in the docs there is a link to viewing the "source code" for the ADK, but this link redirects you back to the same documentation (not the source code). I actually found the mentioned source code from a copy of it on an Instructables page by a 12 year kid with a link to the official repo. You're free to have a look at this code, but it is OLD and does not work with the current Android build system and you'd find the USB_Host_Shield_2.0 project to be much more well organized and easy to understand, which is based on the hardware from what I understand.
With how little support Android appears to be providing for this, it looks like it was all but abandoned since 2012 a year after it was introduced in 2011. Thus, I was looking for a more future-proof solution to power the Android device from an external controller. From what I can tell the modern way to approach this is to use a USB-PD controller to allow power roles to be independently selected from the data roles. For example, if I connect to Android phones with a USB-C cable, it appears the orientation of the plug/cable determines the Host/Accessory role with the default Power Source being the accessory. (i.e. from the screenshot before, this is the Host since "USB Controller By" set to "This device" and the Power Source is the opposite phone since "Charge connected device" is disabled here (and enabled on the other device).

I'll go ahead an post a potential answer, though I'm hoping for some official answer to override my assumptions and guesses.
From what I can see in the source code handling this functionality, there are three power roles of {POWER_ROLE_NONE, POWER_ROLE_SINK, POWER_ROLE_SOURCE}.
Following these imports, I can see here that there is a clear separation between power roles and data roles.
If I plug in the phone to a USB port not supporting USB-PD, this "Charge connected device" option disappears. It also does not appear when connecting the phone to a USB-PD charger. So I'm assuming the connected device has to show that is a Dual Role UFP | DFP in order for this option to appear.
If anyone can add any official documentation on this, and what USB standard (3.0, 3.1, 3.2, 4.0, etc.) is necessary and how this relates to which Android versions are supported for this functionality, etc., this would override this answer.

Related

Android as an UVC Camera

I'm stuck at home with a rather bad webcam. I was considering upgrading, but then it struck me: phones these days have really good cameras embedded in them. So why not use it as a webcam?
However, as I was researching this further I was really disappointed with the available apps for this. As far as I was able to find, we have Android apps that work roughly as follows:
Present phone camera as a network attached camera. Then you can use local software to use that feed as a webcam. See e.g., IP Webcam. This may be sufficient, but it's a complicated setup, and network latency makes this far from ideal.
The Android app sends the camera feed to an custom host application that in turn creates a virtual web camera. See e.g., DroidCam. This mostly solves the latency problem, but it is still rather complicated, and requiring us to install a specific third party application is troublesome in regard to user privacy. Especially since the applications are closed source.
So, I took the engineering approach and tried to see if it was even possible to improve the situation. As far as I was able to find, Android supports being used as a custom USB accessory. And looking over the USB video class documentation, it strikes me that it should be possible to create an Android app that presents the phone as a generic UVC webcam, such that we do not have to resort to tricks such as the ones above.
Ideally, I would have liked Android to add another USB device option ("Use USB connection as webcam") in addition to debug mode, file-transfer, etc. This seems quite unlikely to happen in the short term however.
So, my question is this: Does an application that does the above already exist? My searching thus far haven't yielded any results, but I might be missing something as googling for this turned out a bit harder than I expected.
Alternatively, am I wrong in my assumption above, such that there is some fundamental issue why an Android application cannot be made to work in that way?
There does not seem to be any complete app yet as of 2020-10, but the parts are mostly there:
https://github.com/tejado/android-usb-gadget has code to switch the Android device into gadget mode (but no UVC yet)
https://git.ideasonboard.org/uvc-gadget.git feeds v4l2 into the uvc gadget output
Sources:
http://www.davidhunt.ie/raspberry-pi-zero-with-pi-camera-as-usb-webcam/
https://www.raspberrypi.org/forums/viewtopic.php?t=148361
https://www.reddit.com/r/androiddev/comments/iabc2o/can_i_use_my_android_as_wired_camera_ie_as_a/g1nrijl/
It appears Google has started to take notice on this issue and are currently working on a "DeviceAsWebcam" service, which is exactly the solution to this problem, as seen in the Android review below:
https://android-review.googlesource.com/c/platform/system/sepolicy/+/2410788
Naturally though, this is a Android 14 feature, so it will like take a while before this is usable on a lot of devices. Hopefully, someone is able to backport this feature to older versions of Android.
If android / the version of Android that comes on your target phone provides / permits use of the USB gadget driver, then libguvc,
https://developer.ridgerun.com/wiki/index.php?title=USB_Video_Class_Gadget_Library_-_libguvc
can be used to "make an application appear as a USB webcam".
Potentially relevant to get you started would be https://stackoverflow.com/search?q=Android+USB+gadget (other SO references to the use of the USB gadget driver on Android).

Gameboy-like keys and D-Pad for Android

I wanted to make an RPG for Android 2.3 Mobile Phone and thought that the good old Gameboy had the perfect format for such games. So I want to build a "Case" with a D-Pad and a few keys and connect them with the Android Device over USB. I don't want Bluetooth, because it needs to much energy. I thought about giving the Case its own Battery Cell and maybe loading the Android Device with it. So my Question is:
How can I access the Keys of this Case from the Android Device?
You might consider the Android Open Accessory Development Kit.
Even if you don't want to buy the ADK, the above link has information that will be useful to you in developing an interface to your accessory. In particular, the section on implementing the accessory protocol and the following section on how the ADK implements the protocol should prove informative. In addition, you'll probably want to look at the USB Accessory link which contains a section concerning communication with an accessory.
You can use USB on devices that have a host USB port unfortunately, not many devices have this. Your other options are bluetooth or wifi both can be accomplished in a multitude of ways. If you Google Arduino + Android I believe you will find examples of people connecting hardware to Android devices via Arduino. This is not the only way to do it, just an example of one way you could do it.
Android USB documentation
http://developer.android.com/guide/topics/usb/index.html
EDIT
You, could I suppose, use Arduino as the USB host also and use accessory mode on the Android end. In any case this none of these options are incredibly straightforward and you will need to do a lot of research to accomplish what you are envisioning.

Communicate with external MIDI device from Android device

What classes are available for Android platform to communicate (in/out) with external MIDI device? I have HTC Desire smartphone, it has USB port, I'd assume it is possible to connect it to a MIDI synthesizer, using standard USB cable + [Type A -> Mini A] converter. I'd like to write a MIDI sequencer app that would be able to record MIDI stream from the synthesizer and then play it back later.
Short answer: None. Slightly longer answer: On the HTC Desire there is no built-in support for USB host mode (which you need, since the usb-midi adapter would be the USB client).
(Android 3.1 does have some support for USB Host mode, but that's not available for the HTC Desire)
If you're not afraid of a soldering iron, you could go the midi-over-bluetooth route: http://nettoyeur.noisepages.com/2011/01/midi-over-bluetooth-part-iii-new-hardware/
Much has changed on this front. The following library allows for MIDI i/o with a USB OTG adapter on API 12+:
https://github.com/kshoji/USB-MIDI-Driver
It's far from perfect, and in my testing, pretty crashy, but it should at least be a good starting point for someone looking for the relevant classes.
As #edovino said, you need USB host mode, and then drivers.
If you don't mind rooting around your phone, and the hardware supports it, you do have some options. Check out this link: http://sven.killig.de/android/N1/2.2/usb_host/
This guy was able to get audio, video, keyboard, and some other stuff working. He includes audio/MIDI drivers.
Yes, as pointed above, it is not feasible using the phone because it does not provide USB-host capability. I have been working religiously over the past few months to make an XY-controller for my synthesizer so that I can transmit controller values to use for performances. I reckon, that is what you want to do with additional functionality.
Bluetooth is definitely an option and if you look up for libpd, Peter Brinkmann himself has addressed this issue and acknowledged that Bluetooth dongles for MIDI are not far away.
WiFi is also something one may be willing to look at. Using rtpMIDI, we can create sessions on the PC side of things and use just about any WiFI enabled MIDI device to transmit/receive data. IF you are looking to control software synthesizers using a phone, this seems ideal. TouchDAW and TouchOSC, applications on android, make use of this feature.
With the USB-Android driver, the only problem I see is no support for isochronous transfers using USB host. So, we cannot guarantee latency deterministic. But, considering no other bus accessories attached, the performance seems pretty decent in my tests.

How to send Bluetooth AVRCP vendor dependent and pass through commands from app?

I would like to communicate with another Bluetooth device using the AVRCP vendor dependent or pass through command. From the API available, there does not seem to be any way to make such calls from an android application. Can anyone advise on whether this is possible and how this can be done if it is possible?
What you should do is to go directly and speak with the HCI layer of the BlueZ Bluetooth stack. You could do this through D-Buss daemon which you can do it from Userspace. Next you take the ARVCP specs for example 1.0, but you can find on Bluetooth SIG AVRCP 1.3 or 1.4 specs too, and start parsing the commands. This presentation should be helpful: Android Bluetooth Introduction and this stackoverflow question.
Refer the below link:
Adding AVRCP Plugin in Android GB
It seems like you confront the most common problem between Bluetooth devices, the Bluetooth compatible problem. Because the Bluetooth profiles do not strictly defined the audio related behaviors, the different behaviors implemented by different manufacturer would lead this problem. That's why every Bluetooth device should pass the Bluetooth Compatible Test of Bluetooth organization, however, it can not eliminate all problems.
As an open source implementation of Bluetooth Protocol Stack, Blue Z is not the best one in my mind and abnormal behavior of Bluetooth device also making trouble. If you have some test tool like PTS (profile tuning suite), try to use it to find out which side lead the problem. If everything is ok in profile side, that's good news for you, the problem may lead by some bugs of the related application. And if something wrong in the profile communication, it means you can not modified in API level, you may need some dirty work in profile stack and if you are phone manufacturer it can solve you problem, if you are not you can not slove the problem neither.

Serial port on an APAD - where to discuss this?

I've got an application that is written in Java and which talks to a device using virtual serial port (ie a USB CDC ACM device). Currently it runs an a PC (Windows/Linux/Mac OS X),
but it would be a perfect match to be able to port this to a cheap tablet PC to create a stand alone system.
I've been googling for hours now and it seems quite a lot of people are interested in this sort of thin (no surprise there) and some have managed, but I've not found a good match for what I'm looking for or a good place to discuss this.
I'm looking at something like this:
http://www.prlog.org/10776061-101-inch-android-ipad-android-google-mid-tablet-pc.html
I would like to discuss the following:
This says that it supports USB host so it should be doable, eh?
Android is a kind of Linux so I should be able to use a serial dongle there, right?
Has Android got drivers so that I could just plug in a serial port dongle and open it as /dev/tty?
Would the above quoted APAD be usable as a development platform ?
So where would be a best place to discuss this?
br Kusti
To keep this at least partly programming-related: If your application has a GUI, moving to Android is not going to be a load-it-and-go effort. Android has a very different application structure that you're used to and doesn't have Swing (if that's what you're using) or any GUI toolkits other than its own.
On your USB problem: There is support for a few USB-to-RS232C adapters in the stock kernel, but there are a bunch of practical reasons not to use it. Most involve limiting yourself to devices that support host mode, cabling and powering the Android device and the serial adapter. You might be better off using a Bluetooth-to-RS232 adapter on your serial device, which would allow your app to run on a wider variety of devices and gets you the bonus feature of being wireless to put in your marketing material.
I just ported the RXTX library to the Android. Unfortunately I had to fork it to accomodate for different layout of the android projects. More details are here http://v-lad.org/projects/gnu.io.android/
You need to have a device that supports host USB mode. Also the kernel on the device has to support the USB to Serial converter or you have to recompile the kernel yourslef.

Categories

Resources