Touch-free Ubuntu touch

A while ago, I broke my 2012 Nexus 7. I cracked the front screen by putting it into the pocket of an airline seat. The pressure of the book I had with it in there, focussed by the metal edging of the pocket top, was enough to crack it in three places.

This didn't affect the display, but ruined the touch sensitivity almost everywhere on the screen.

Cracked Nexus 7

On the bright side, I now have a ARM-based computer with 1GB of RAM, about 16GB of storage, wifi, a headphone jack, mic and camera and some other sensors. Which I'm sure could be useful, if it wasn't running a touch-based operating system.

Step 0 - Make it boot again:

It's been powered off for a while. Charging doesn't seem to help. It doesn't respond to the on button. Black screen, nothing happening, even while plugged in and after being plugged in overnight.

It turns out, you need a really long press to get it to awaken from this state, even if fully charged. Like between 30-60 seconds. Then you get a nice android boot.

Step 1 - Install Ubuntu:

But we don't want android. With no touch-sensitivity, it's pretty useless. So, we want a useful, non-touchy OS on there.

If you have a system running Ubuntu 14.04 (trusty tahr), you can install the package ubuntu-device-flash, which will let us do this.

Details are here: http://developer.ubuntu.com/start/ubuntu-for-devices/installing-ubuntu-for-devices/, but we can't follow them since we lack the touch ability to, say, enable USB debugging.

No problem. Boot your Nexus 7 with the volume-down held and you'll end up in the bootloader. You'll need to unlock your device (WHICH WILL WIPE ALL YOUR DATA), then, back at the bootloader, you can run:

ubuntu-device-flash --bootstrap --channel=ubuntu-touch/stable

to start the installation process. (You can run --list-channels instead and pick your favourite channel if you don't want stable). The UI of Ubuntu Touch won't be useful to us, but we want the underlying ubuntu core.

Step 2 - Wait:

Don't interrupt this step (as I did the first time around). As the link says, wait for the device to reboot. Otherwise strangeness may occur. In my case, it was nothing that restarting the install couldn't resolve.

Step 3 - Get a prompt:

After a long time watching the green android-bootloader spin his internals, your Nexus 7 should reboot via the Google logo (with unlock symbol at the bottom), blank out, then bring up a familiar orangey-brown ubuntu hue, with text suggesting you swipe from the right edge to unlock the phone. Shame we can't touch it.

So we want to ssh in. But we'll need wifi working before we can do that. So we need to set up wifi. But we can't ssh in...

Handily, this installation process has enabled the equivalent of USB debugging which we couldn't manage under android. So we can run:

adb shell

and get a root prompt on a system rejoicing in the name of 'ubuntu-phablet'.

Step 4 - Basic hygiene:

Computers need names. Choose one. (e.g. "bob"). From your root prompt:

# Allow editing files in /etc
mount -o remount,rw /
# And have a writable root next time too
touch /userdata/.writable   
# Set running hostname
hostname bob            
# Remember it for next time
echo bob > /etc/hostname
# It's good if our hostname resolves to something sane
perl -p -i -e 's/ubuntu-phablet/bob/g' /etc/hosts
#  Lets try this again
exit            
# That prompt looks better!
adb shell

Step 5 - wifi up:

Network manager isn't buying us much in this setup, so lets stop it interfering:

service network-manager stop
apt-get remove --purge network-manager

But we will want wpasupplicant for wifi (which will otherwise be marked as no longer required). So tell apt that we want it.

apt-get install wpasupplicant

And we can set up the wifi connection manually in /etc/network/interfaces:

# Creating a file in /etc/network/interfaces.d didn't work for me. perms?
cat >> /etc/network/interfaces

auto wlan0

iface wlan0 inet dhcp wpa-driver nl80211,wext wpa-ssid YOURNETNAME
    # plaintext passphrase
    wpa-psk YOURSEKR1T
    wpa-key-mgmt WPA-PSK
    wpa-pairwise TKIP CCMP
    wpa-group TKIP CCMP
    wpa-proto WPA RSN
<ctrl-D>

That assumes you're using WPA with PSK. Look in /usr/share/doc/wpasupplicant/README.Debian.gz for other approaches if you're not (or possibly /usr/share/doc/wireless-tools/README.Debian).

Now bring up your interface:

ifup -v wlan0

and hopefully, you'll get some DHCP output, ending with 'bound to xxx.xxx.xxx.xxx', which is your new IP address. (You can set up a static IP via /etc/network/interfaces too. 'man interfaces').

Remember this IP address.

Step 6 - User setup:

You'll want a user to login as. Maybe 'alice'.

adduser alice --gecos 'Alice User'
# enter passwd for user

And you'll want to be able to do everything the 'phablet' user can do:

perl -p -i -e 's{phablet}{phablet,alice}' /etc/group

And test it out:

su - alice
# ...enter your password here...
sudo cat /etc/shadow > /dev/null
# Enter password again
# If you've got sudo privs, you should see no error.
exit
# Back to being root for now

Step 7 - Server setup:

To mix a metaphor, we now want to cut the cord and let it fly free.

# Mine said already installed, but worth checking
apt-get install openssh-server

# Start it up now
service ssh start

# Version dependent way to get your ssh to boot on startup:
# http://askubuntu.com/questions/348714/ubuntu-touch-apt-get-install-openssh-server-error
# For my channel it was:
perl -p -i -e 's{exit 0$}{mkdir /var/run/sshd\nchmod 755 /var/run/sshd\nservice ssh start\nexit 0}' /etc/rc.local 

This was a lot harder than I thought it would be. Really unsure why we needed to resort to rc.local there. Ah well.

Step 8 - Reboot and check...:

# On the tablet
sudo shutdown -r now
# (Mine doesn't always come back up - so you may need to long-press
# the power again)

# On some other machine on your network:
ssh alice@<tablet_ip_address>

# And if that works, run this on your non-tablet machine to 
# copy over your ssh keys
ssh-copy-id alice@<tablet_ip_address>

# You'll probably also want to add your tablets IP address to your
# local LAN DNS or hosts file setup

Step 9 - Fix the sound:

I want to do sound-related work with the Nexus 7. By installing rygel:

sudo apt-get install rygel

I can turn the nexus 7 into a DLNA rendering target. This means I can play music to it from anywhere on my local network (streaming from my media server). The speakers on the nexus7 aren't wonderful, but plugging the headphone jack into a larger system gives a pretty good sound.

However, on my 2012 nexus 7, the sound doesn't work from stock ubuntu :-(

But this bug: https://bugs.launchpad.net/ubuntu-nexus7/+bug/1068804 contains a fix :-)

# Get a root shell
sudo -s
# Add alsa card description
cat > /usr/share/alsa/cards/tegra-rt5640.conf
# default with dmix/dsnoop
tegra-rt5640.pcm.default {
       @args [ CARD ]
       @args.CARD {
           type string
       }
       type asym
       playback.pcm {
           type plug
           slave.pcm {
               @func concat
               strings [ "dmix:CARD=" $CARD ",RATE=44100" ]
           }
       }
       capture.pcm {
           type plug
           slave.pcm {
               @func concat
               strings [ "dsnoop:CARD=" $CARD ",RATE=44100" ]
           }
       }
}
<ctrl-D>

Step 10 - Use it:

I've now got a nice little low-power server humming along on my LAN (it doesn't even really hum). It can serve sound out and also act as a target for any ARM-related fun. Better than a paperweight.

It looks like it may be possible to power the nexus7 from an OTG cable and so hook up some USB devices too: http://mehrvarz.github.io/usb-host-mode-power-management-nexus7/, which would allow it's use as a NAS or similar too, with some USB storage.

I often work from home, up two flights of stairs. Perhaps I could fix it facing out of the window and provide a two-way videophone for people calling at the door?

How do you know what you know?

There is a phenomenon I think most coders discover early on in their careers. You struggle with a problem for some time, then decide that you are stuck and so will ask a colleague for their help. As the words come out of your mouth (or sometimes, a little before) a possible answer bursts full-formed into your mind.

This has been much-discussed elsewhere and has been called RubberDucking, Rubber Duck but I first knew it as Debugging by confession. The link above gives some theories as to how it might work, this post describes mine.

I think the effect is unrelated to speaking aloud, because I have noticed it before I have even opened my mouth. I think it has its roots in some brain machinery which we have around for social use.

Ever since humans have been social animals, part of our fitness for survival has rested on our ability to persuade others. This in turn, depends on our reputation.

Consequently, we are good at fact checking what we are about to tell someone else. We might choose to lie or joke, but doing so accidentaly would needlessly decrease our reputation for accuracy, reliability and honesty. This could hurt our ability to get what we want.

So I suggest that the benefits of rubberducking could be caused by the sub-conscious examination of data in preparation for telling it to someone else. Social brain machinery does a once-over and checks each thing we are about to say for how likely we think it is to be true. It is this check which helps us find the shaky assumption in our thinking which leads in a flash to the solution.

The check would involve thinking about how we know what we are about to say is true, i.e. it checks meta-information about the information ("how long have we known it?", "who told us?", "how reliable are they?", etc.)

Problem solving involves a creative balance between thinking about what we know and the reliablility of each piece of information. We can do this consciously, but rubberducking also allows us to bring in additional, sub-conscious, brain machinery and go further and faster than we otherwise could.

It helps if we know how we know what we know.