Search This Blog

Friday, February 19, 2016

How to control your Android phone which has a broken screen

Who hasn't dropped their phone?

Well, alright, maybe some people never do but I'm not one of them.
I dropped mine a couple days ago and since then, the screen doesn't respond to touch.

I figured that that was it but while I'm waiting for my new phone to be delivered, I wanted to be able to still use the device.

Fortunately, since I am doing development on the phone, I have it set up for it. Only problem is that only my home desktop machine is authorized to access the phone via ADB. Bummer but it's still a good thing.

What do you need?

  • USB cable
  • Android SDK and more specifically adb
  • Python (to make things a little easier)

Connecting to the phone

I'm using Linux at home so the first thing is to do something like:

~ sudo ~/Android/Sdk/platform-tools/adb devices

This will start the adb daemon and you will be connected to the phone.
You can then use adb with your user account normally. We use sudo here to start the daemon and avoid authorization issues.

ADB provides a shell that you can use to do a lot of things:

~ adb shell
xx@mako> pull /sdata/DCIM/Camera 

Will copy the files inside /sdata/DCIM/Camera onto the hard disk of the computer (in the current directory).

~ adb shell input tap 100 100

This will instruct the phone to do a tap at the given coordinates.

Python to the rescue

I wrote a small python script to do a bunch of actions because typing adb shell input tap xx xx becomes rather annoying after a while.

It goes like this:


import subprocess

alive = True

while (alive):
    isCommand = False

    text = raw_input(">")
    if text == "send":
        isCommand = True
        subprocess.check_call("adb shell input tap 700 1150", shell=True)
        print "sent"

    if text == "sup":
        isCommand = True
        subprocess.check_call("adb shell input swipe 300 900 300 100", shell=True)

    if text.startswith("tap"):
        isCommand = True
        coords = text.split()
        subprocess.check_call("adb shell input tap " + coords[1] + " " + coords[2], shell=True)

    if text == "shownotif":
        isCommand = True
        subprocess.check_call("adb shell input swipe 400 10 400 1000", shell=True)

    if text == "unlock":
        isCommand = True
        subprocess.check_call("adb shell input swipe 400 1150 400 200", shell=True)
        subprocess.check_call("adb shell input text 0000", shell=True)
        subprocess.check_call("adb shell input keyevent 66", shell=True)

    if text == "home":
        isCommand = True
        subprocess.check_call("adb shell input keyevent 3", shell=True)

    if text == "end":
        isCommand = True
        alive = False

    if text == "enter":
        isCommand = True
        subprocess.check_call("adb shell input keyevent 66", shell=True)

    if text == "back":
        isCommand = True
        subprocess.check_call("adb shell input keyevent 4", shell=True)

    if isCommand == False:
        text = "\"" + text.replace(" ", "%s") + "\""
        subprocess.check_call(["adb", "shell", "input", "text", text])

Things to change

The script works well on my phone, which is a Nexus 4.

First thing to modify is the unlocking code: subprocess.check_call("adb shell input text 0000", shell=True)
For this line, replace the 0000 with your personal PIN

The 'send' command will also need to be changed to use the proper coordinates.
On my screen the WhatApp or Viber send buttons are bottom right, which is around 700,1150.

Your phone will most likely be different depending on the screen size and DPI.


send: Send the message
back: Back button
home: Goes to the home screen
enter: Enter button (for example after entering the PIN, [enter] will unlock the phone)
sup: swipe up (from bottom to top, here again you may need to change the numbers)
tap: taps at the given coordinates (example: tap 400 400)
unlock: Unlocks the phone with the hard coded PIN
shownotif: will show the notification list (swipe from the top to the bottom of the screen)

What's next?

You can also run apps with adb: 

adb shell am start com.whatsapp/.Main

This will launch the WhatsApp app.

After that, by using swipe, tap and whatever else, you can still use your phone and download files from it while you wait for your new device to appear at the front door.
Basically just experiment (I archived my notes from Google Keep using adb) and have fun.

Thursday, February 18, 2016

Running Opensuse (Tumbleweed) on a Dell XPS 13

I don't have a XPS 13 but I do have a XPS 15.

Installing Opensuse on it was not too hard really but my friend does have a 13" and the biggest problem is that the Wireless card won't work.

The problem is that the drivers included on Opensuse don't work with the Broadcomm 4352 that's on the machine.

The are some pre-requisites to make this work:
  • You need another machine with Opensuse and the same kernel (or at least, close enough)
  • You need to get the source RPM for the broadcom 43xx cards
  • You need the kernel source and what not (gcc, kernel-devel, etc)

Getting the driver source

You can get that RPM Here: Packman mirror

The file should be around 2.9MB

Preparing Linux for compiling the source

~ sudo zypper install kernel-devel
~ sudo zypper install kernel-headers
~ sudo zypper install gcc

Make sure that the kernel source are for the kernel you have on the machine.

~ uname -a
Linux linux-c0wc 4.4.0-3-default #1 SMP PREEMPT Thu Jan 28 08:15:06 UTC 2016 (9f68b90) x86_64 x86_64 x86_64 GNU/Linux

~ ll /usr/src

You should have a directory here named: linux-4.4.0-3

Extract the source RPM:

~ rpm -ivh broadcom-wl-

Apply the patches

~ cd ~/rpmbuild/SOURCES/
~ mkdir hybrid_wl
~ cd hybrid_wl
~ tar -xzf ../hybrid-v35_64-nodebug-pcoem-6_30_223_248.tar.gz
~ patch -p1 < ../broadcom-wl-4.2.patch
~ patch -p1 < ../broadcom-wl-6_30_223_248-disable-timestamps.patch
~ patch -p1 < ../broadcom-wl-6_30_223_248-linux-4.x.patch

Build it

~ make

 You should end up with a result like this:

Copy the wl.ko onto your trusty USB stick and mount it onto the XPS 13.

Then, install the driver according to the broadcomm document (here)

I'm copying parts of it here to make it a little simpler.

~ sudo su

# lsmod | grep "brcmsmac\|b43\|ssb\|bcma\|wl"
If any of these are installed, remove them:
# rmmod b43
# rmmod brcmsmac
# rmmod ssb
# rmmod bcma
# rmmod wl
To blacklist these drivers and prevent them from loading in the future: (this step is important since after reboot, if you haven't done this, the original modules will be loaded and your WiFi still won't work)
# echo "blacklist ssb" >> /etc/modprobe.d/blacklist.conf
# echo "blacklist bcma" >> /etc/modprobe.d/blacklist.conf
# echo "blacklist b43" >> /etc/modprobe.d/blacklist.conf
# echo "blacklist brcmsmac" >> /etc/modprobe.d/blacklist.conf
Insmod the driver.

# insmod wl.ko

wl.ko is now operational. It may take several seconds for the Network
Manager to notice a new network driver has been installed and show the
surrounding wireless networks.

You can also reboot and once you launch the Network Manager, you should see the different networks.