Posts | Tags | Archive

Adding Xbox 360 controller support to a Nexus 5

Update

CyanogenMod has effectively been replaced by LineageOS. The links in this article originally all pointed to CyanogenMod but since it no longer exists, I've updated them to use the LineageOS equivilents where possible. The instructions will also need to be slightly modified for use with LineageOS builds.

Introduction

I finally just bought a new phone (a Nexus 5), and after flashing CyanogenMod onto it, I've been messing around with its OTG support. My old phone (a Nexus 4) didn't have the capability so being able to plug in keyboards, mice, external hard drives, and various other peripherals was (embarrassingly enough) a thrill.

Keyboards worked, mice worked, but when an Xbox 360 controller was plugged in, nothing happened. Turns out that while the kernel didn't have support for it enabled out of the box, getting it enabled and pushing the change upstream into the CyanogenMod project was easier than I thought.

Beware that this post is going to be more of a record of what I did so that I can do it again and less of a coherent tutorial.

Building CyanogenMod

First step was to download and compile CyanogenMod for my phone. I'm not going to go into this in any detail on this because there's already a good overview on the CyanogenMod wiki that covers the entire process, as well as a customized guide for the Nexus 5. If those articles are followed correctly, you should be able to build a fresh CyanogenMod image with:

1
brunch hammerhead

Enabling the kernel module

Once the image was flashed to the phone and verified to be working, the next step was to enable the xpad kernel module.

Copy current kernel config to the kernel directory for editing:

1
2
cd <build dir>/kernel/lge/hammerhead/
cp arch/arm/configs/cyanogenmod_hammerhead_defconfig .config

Edit the config:

1
make menuconfig ARCH=arm

At this point, a menu will come up. Search for xpad (type /xpad), and take note of the paths. ESC out of the search, navigate the tree and enable the modules found with the search. Save and exit.

Copy the config back and clean up any stray *.o files:

1
2
cp .config arch/arm/configs/cyanogenmod_hammerhead_defconfig
make mrproper

After enabling the module, rebuild CyanogenMod using the normal brunch hammerhead and flash it to the phone.

Submitting the change upstream

Since Xbox controller support had already been requested in a JIRA ticket(dead link), I went through the process to submit the change on the CyanogenMod Gerrit instance for inclusion in the next release. There's a guide for this here. As well as the guide, I found the people in #cyanogenmod-dev on Freenode to be very helpful.

A short while after submitting the change to Gerrit, it was merged into the cm-11.0 branch as commit i7ef4f6a and pushed out in the next nightly build (changelog screenshot).

Wrap-up

It feels great to be able to contribute to an amazing open source project that had at least a million people using it at one point or another. I recognize that the change by itself was just changing a config file to enable functionality that already existed, but it's helped me get through some of the non-coding hurdles of contributing to an Android fork like CyanogenMod (adb, fastboot, unlocking and rooting phones, compiling AOSP, flashing images, the contribution process, etc). This time the actual contribution itself was minor, but it's gotten me more familier with the process, hopefully making it easier to contribute something more substantial in the future.

In the end, I learned a lot about Android development and how all the different pieces that I had read about at one point or another actually fit together. During the whole process I also lost a lot of the fear I had about messing with phones and other more expensive locked down devices. Going forward, I'm going to attempt to compile and flash open source operating systems like CyanogenMod onto more devices that I own. I like being able to tweak things and feel like I really own them, hardware and software.


Fixing save file corruption in Ridiculous Fishing

Ridiculous Fishing is a game by Vlambeer about fishing. That's if you can call chainsawing fish and blowing them out of the sky with a bazooka "fishing".

I've been playing this game on and off for a while now, but just recently I had a problem where my save file somehow got corrupted, making the app refuse to open.

The problem first manifested as the game freezing for up to 5 seconds when navigating around the UI or buying items in the in-game store. Since I was running the game on a Nexus 5 (not the latest and greatest, but pretty close), it seemed weird. The delay got longer and longer until the game eventually crashed and refused to reopen.

Since I was pretty far into the game (I only needed to catch one more species of fish!), I opted to try to fix it instead of just wiping the app's data and starting again. I initially tried clearing the app's cache and reinstalling the app, but the problem persisted.

The next step was to dump the games's data to my computer so I could do some analysis on it. Some exploration on the device revealed that the settings and data were stored in the folder /data/data/com.vlambeer.RidiculousFishing.humble (I have the Humble Bundle version of the app).

To pull that folder to my current directory, I used ADB:

1
2
adb root #Restart adbd on the device with root permissions
adb pull /data/data/com.vlambeer.RidiculousFishing.humble/

A quick du -h revealed that something was very wrong in the files/Library/Preferences/com.vlambeer.RidiculousFishing.humble.plist file. It should've been just a text document, but was well over 200MB.

After trying out of habit to open the file in Vim and having it hang (oops), I paged through the document with less. About halfway through the file, there was a line containing &amp;lt;message&amp;gt;@eggbirdTBA Take it to the Smartypants Bar (no, that's not a formatting error, in the plist there's XML data stored in a <string> element, requiring the < and > characters to be escaped) followed by about 200MB of garbage.

Apparently there are ways to load huge files in Vim, as well as other text editors that handle them nicely, but since I already knew what line was causing the issue, a simple sed command would do the trick.

1
sed '/Take it to the Smartypants Bar/d' com.vlambeer.RidiculousFishing.humble.plist > temp.plist

Total size of temp.plist: 107.11KB. Much better.

After going though and deleting some lines around the one that was removed (to make the XML valid again), I pushed the file back to the device:

1
adb push temp.plist /data/data/com.vlambeer.RidiculousFishing.humble/files/Library/Preferences/com.vlambeer.RidiculousFishing.humble.plist

Success! The game opened properly, all the freezing issues were gone, and my save data was still there.

Now to find that stupid Mimic Fish...


Reinstalling an Android app without losing data

When an application isn't opening (and clearing the cache doesn't help) it sometimes helps to reinstall it. However, uninstalling then reinstalling the app normally will delete all the data associated with it.

The way around this is to directly call the package manager from the shell and give it the -k argument, which tells it to keep the data and cache directories.

Simply connect the device to a computer with ADB installed and run:

1
adb -d shell "pm uninstall -k com.package.name"

Then just reinstall the app (either from an apk file or the Play Store) and the app will be back with all of its data intact.

© Carey Metcalfe. Built using Pelican. Theme is subtle by Carey Metcalfe. Based on svbhack by Giulio Fidente.