📜 ⬆️ ⬇️

Forcing the car dock mode (using root)

Introduction


Not so long ago, the released Galaxy S3, in addition to other innovations in the field of accessories, received a new, terribly boring car dock. Unlike the previous devices of the line (S, S2, Note), this one was made “universal”, and therefore did not have a special resistor forcing the phone to switch to car mode. And I, as a person who used a full-fledged docking station for the first SGS at one time, was already used to the fact that when I installed the dock, I switched on the speakerphone mode and had a landscape orientation in TouchWiz. But in the new dock it was impossible to achieve this ...

However, a solution was found, and required only one NFC tag, root, as well as several hours of searching and programming.

Finding a solution


The first thing I did, even when I did not have this "universal" dock - it disassembled the docking station from the first SGS. The result was close enough to what was desired, although it looked quite funny:


')
The picture shows that in the notification area there is a “car” icon - so, it has nothing to do with Driving Mode (which is S-Voice), this is the notification from Android itself.

However, SGS itself and its dock had to be given away, and then a new dock came to me, and the issue of switching the mode was already in full growth. The obvious solution was to use the NFC tag to enable auto mode, but how to achieve this? There are applications on Google Play that allegedly include Car Mode, but in fact they use the standard UiModeManager method that just launches Car Home, and the loud communication and landscape orientation that I like so much is not included.



The Android documentation has a standard method for determining whether a device is in the docking station:
registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT)).getIntExtra(Intent.EXTRA_DOCK_STATE, -1); 

and also mentioned the method that sets this state:
 sendStickyBroadcast((new Intent(Intent.ACTION_DOCK_EVENT)).putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_CAR)); 

However, it will not work in a real program, since specifically, this event requires special rights (after all, it is, in fact, generated by the USB controller). But even with root, how can this be done?

There is a simple and fairly well-known solution:
 su -c /system/bin/am broadcast -a android.intent.action.DOCK_EVENT --ei android.intent.extra.DOCK_STATE 2 

which, alas, is incomplete. Yes, this call will successfully enable the full-fledged car mode, however, because it is a normal broadcast and not “sticky” (am utility doesn’t know how), the above mentioned method for determining the status of the docking station will not work, so you have to either The application has two buttons (“on” and “off”), or find a way to send a full system message.

Having a little rummaged in source codes of Android, it is possible to find the class DockObserver which just is engaged in sending this message. After examining it, it is easy to see that in fact he does a little bit more than just notifies of a mode change (for example, reproduces the sound of an insert into the dock), as well as what he does when a special event arrives (UEvent). That is, if you learn to create such an event, you can simulate not only the effect, but also the cause!

Well, this is done in a fairly simple code using NDK:

 char event[] = "ACTION=change\0DEVPATH=/devices/virtual/switch/dock\0SUBSYSTEM=switch\0SWITCH_NAME=state\0SWITCH_STATE=2"; int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (sock != -1) { struct sockaddr_nl snl; struct iovec iov = { event, sizeof(event) }; struct msghdr msg = { &snl, sizeof(snl), &iov, 1, NULL, 0, 0 }; memset(&snl, 0, sizeof(struct sockaddr_nl)); snl.nl_family = AF_NETLINK; snl.nl_pid = getpid(); snl.nl_groups = -1; sendmsg(sock, &msg, 0); close(sock); } 

It remains only to pack this utility into an application that reads the current state in the standard way described above and switches it with a console call from under the root.

Conclusion


So, the application itself is available on Google Play (now for some reason it has been removed from the store, but you can download the .apk file ).
At startup, it switches the phone to car mode, when restarting, it goes out of it.
If you hang it up on the NFC-tag, you can get the same full-fledged car dock.

Well and, all source codes can be found on GitHub .

Source: https://habr.com/ru/post/184280/


All Articles