How to fix Secure Settings on Android devices with SuperSU systemless root

Secure Settings (Google Play) is a really helpful app to help Tasker (Google Play) do things automatically on your Android device.

However, it has not been updated for quite a while (January 2015 at the time of this writing) and since then SuperSU has changed its way of installing the su binary to your device, by preferring not to install this on the system partition.

As some older apps hardcode the complete path of this binary in their checks, and Secure Settings is one of these, it thinks it can not get root access.

On my quest of a fix for this problem, I found this post on XDA where a comment on Reddit was referenced, stating the following fix, running the commands from a command line (terminal) on your machine, having adb installed:


adb shell
su
mount -o remount,rw /system
touch /sbin/su /system/bin/su /system/xbin/su
mount -o remount,ro /system
exit
reboot

source

This creates some empty files in locations that older (incorrect) apps check for the su binary, so Secure Settings (and likely other applications) are made to believe they can get root (which they actually can, as you can not make those files without being root through su anyway).

You can also do this on your device by just omitting the first line and starting with su in a Terminal app (or for example JuiceSSH in a local session).

I hope this helps other people looking for a solution too.

  • Michiel Scholten
  • Work
  • 🕔

Nienke says "Hello World"

In the night of Sunday to Monday, at 4:17, Nienke rushed into this world. Where Daan took his time being delivered, I was barely awake (Ineke woke me at 4:01) when Nienke saw her first lamplight.

Needless to say, she was born at home, in the tub where Ineke thought she was going to relax a bit while the contractions that started at around 1AM where building up; the delivery went well (thankfully so, as the midwife/verloskundige wasn't even there yet - I was telling her live what was happening while she rushed to our place where she arrived just minutes late), and both Nienke and Ineke are fine, be it tired.

Of course, this was already a few days ago, so we had some interesting times already. She's doing great; a lot more quiet than Daan used to be her age, which is really welcome. We are enjoying our ruined nights, but are relaxed. Daan is being the sweet big brother.

Official "Hello World" post

  • Michiel Scholten
  • Home
  • 🕔

dammIT: 12 years of rants

Today it's 12 years ago I officially started this weblog and I finally have taken some steps to get the next generation of the codebase working on my server. It's getting there, looking forward to continue dammIT in its Django incarnation :)

This year has been fascinating; junior went from barely walking to running around, thrashing the place while ranting about the wind blowing a bit too hard outside. In the meanwhile, junior number two is about to be here too, so I'm sure next year we are going to have a really interesting, sleepless time.

Looking forward to all the weird, frustrating, wonderful, funny things waiting for us!

  • Michiel Scholten
  • Home
  • 🕔

I made a thing to make your phone go 'pling' (when your train goes 'whatever')

I made a thing: https://pypi.python.org/pypi/nsapi.

You can use it with my other thing at https://github.com/aquatix/ns-notifications to get notified when your train is late, or to know when you can do a sprint upstairs on the next station because your otherwise impossible transfer is delayed a bit and you can catch it now.

See the settings_example.py and the ns-notifications README to configure.

Enjoy!

PS: yeah, it makes use of the official Nationale Spoorwegen (NS/Dutch Railways) API, and you need to request a key with them to use it. That's easy though and worth it if you like timely notifications.

  • Michiel Scholten
  • Home
  • 🕔

ssh config.d to tidy up that archeology-worthy ~/.ssh/config

You might be in that same situation as I was until recently: you open up your ssh config file and start scrolling through the long list of nicely aliased private machines, that organically grown list of work - project A and the comment-section-divided work - project B, work - misc, work - are these still even on? and work - I have no clue why these are even in here.

At least you have them separated in sections.

However, to make my life a bit easier and to be able to generate parts of the list (for example), I decided that I would try my hand at a config.d directory with separate files that the real ~/.ssh/config file is generated from.

Here it is:

# SSH config merge
if [ -e ~/.ssh/config.d ]; then
    #if find ~/.ssh/config.d -mindepth 1 -print -quit | grep -q .; then
    # Do we have config files in that directory?
    if find ~/.ssh/config.d -print -quit | grep -q .; then
        newestconfig=$(find ~/.ssh/config.d/* -printf '%T+ %p\n' | sort -r | head -n1 | awk '{print $2}')
        if [ "$newestconfig" -nt ~/.ssh/config ]; then
            # We found a config that's newer than the generated config file, re-generate
            [ -e ~/.ssh/config ] && mv ~/.ssh/config ~/.ssh/config.bak.$(date -Ins)
            # Lets preserve order, so you can have  00_generic 10_homestuff 20_work1 21_work2  and such
            find ~/.ssh/config.d/* -type f -print0 | sort -z | xargs -0 -n1 cat > ~/.ssh/config
        fi
    fi
fi

Well, this is the supporting code that is supposed to go in your ~/.bashrc. When a new shell is opened, it checks whether there is a file in ~/.ssh/config.d/ that is newer than the file ~/.ssh/config is, and only then the files are concatenated together to that certain file. They are sorted alphanumerically, so you can have a naming scheme like:

00_base
10_homestuff
20_work_project_a
21_work_project_b
22_work_still_no_clue
30_sportclub

The 00_base one in my list contains some ssh configuration that might be of interest:

# == Generic config ======
TCPkeepAlive yes
ServerAliveInterval 30

# Re-use existing ssh connections
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600

If you are interested in my other dotfiles, I have them online in version control like the coding hipster I am ;)

  • Michiel Scholten
  • Home
  • 🕔

How to do location-based web requests with Tasker on Android

If you don't know Tasker go and check it out now. It's by far the greatest way to automate, well, about everything on your Android device and its surroundings.

However, one thing it is not, is really easy to start with. If you tap through the interface for the first (and second and third) time you will likely be wondering how to even start thinkering with the idea you have.

So, in the light of the ns-notifications service I recently completely rebuilt, I'm going to have a small step-by-step guide to set up a new Profile, which triggers a Task when arriving at a certain wifi network (say, your work office or your home) and then do an http request. This will show the basics of how Tasker works and how to set up your own scripts.

A Profile is really just a set of triggers (or just one generally) that are linked to a Task to perform when activated by the situation. There is also an exit state, so if the situation stops, another Task can be run (for example, enable wifi when your home network is detected, disable it again when the network goes out of reach).

To start, go to the Profiles tab and tap the + button in the bottom bar. You will be presented with a small list of trigger types. Because being in range of a certain network is state and not an event for example, now tap State and choose Net in the next overview. 'Wifi Near' is the option we are now looking for. This is a service of your device (provided for example by the background scanning Android can do for you) that tells your Android what wifi networks are in range.

Now you are in the properties window of the State. Tap the search button next to SSID (looking glass icon) and choose the relevant network. You can choose more options, but for our use case, this is enough. Now go Back.

A menu pops up with a list of Tasks already configured, with at the top 'New Task'. Choose this item and type a name. You've now created a new Task that will be triggered when coming in reach of the wifi network.

This empty window is the script window. Here you can add Actions. Do so by tapping the now familiar + button. You can add an Alert for testing. If you choose an Action by accident and don't want to save, choose Cancel (might be in the overflow menu on your phone). Otherwise, configure if there is anything to set and go Back.

To create our web request, choose a Net task called 'HTTP Get'. Fill in the server and port (if applicable), so for example: 'example.com:4242'. The server.py of ns-notifications listens on port 8086 by default, so you might want to use that one instead. Under Path you put the rest of the url you want to request, so for example 'disable/work' to trigger the disable alerts on the server, noting you arrived at work. You can leave the rest empty, but might want to put in a timeout of about 10 seconds or so to be save the Task will not hang when connectivity fails.

We are done :) You successfully made a web request on entering a certain wifi network. Or did we do so successfully? The 'HTTP Get' Action sets a variable when exiting successfully, which you can check. This variable is called %HTTPD (all variables in Tasker are prepended with a %).

So, add an Action: Task, If. Condition for the If is %HTTPD and choose 'Set' from the button next to the input field. This if statement checks whether the variable is set. You can now for example show an alert on your phone that everything went well, adding an Else with an alert that your request failed.

NS alerts disable because of arriving at %atLocation

Response: %HTTPR %HTTPD

The response variable '%HTTPR' shows the status code of the server.py response (generally 200, but -1 in case of network failure) and '%HTTPD' shows the response body ('Disabling notifications') or just the string '%HTTPD' itself in case of network failure.

%atLocation is a global variable I set myself based on my travels. More on that in a later post.

Further reading

A more elaborate example for actually retrieving information through a web call can be found on this http-get example on the Tasker wiki. Also, I just found this page which is a continuation of a tutorial you might want to play with.

There's also the Tasker Google+ community with people writing tutorials, scripts and answering questions.

  • Michiel Scholten
  • Train
  • 🕔

How to smooth up your Firefox on Linux, including video

After having one of our Hangouts videocalls, I started looking into why the browser plugin takes so much CPU-time (and makes the laptop hot and breezy in the process). Is stumbled upon the article How to tell if you're using hardware acceleration and dove into my own about:support page in Firefox. Lo and behold, the information behind 'GPU Accelerated Windows' told me it did no hardware acceleration (it showed the 0/1). OK, so how to fix?

Mozilla decided a while ago to blacklist Intel GPU's from hardware acceleration, based on the state of the Intel drivers. However, as I'm running Ubuntu 15.04 on this machine with a recent enough graphical stack, I'd say that my Intel driver would be recent enough. Still, Firefox says no.

On to force enabling it then. More digging revealed that some settings in about:config could be turned to true to enable rendering through hardware. Open a new tab, type about:config and search for those two:

layers.offmainthreadcomposition.enabled
layers.acceleration.force-enabled

If they are false, just double click them to toggle the value to true. It seems that only the first is really necessary, but lots of people need the second to be enabled to, so I did that. Restarting Firefox didn't show any improvement though, as it needs an environment variable too.

On a terminal, type export MOZ_USE_OMTC=1 and then start Firefox from there (firefox). Now, if you open about:support again, you should now see something better than '0/1' behind the 'GPU Accelerated Windows'. Of course, we want this environment variable be automatically set so we can start Firefox from a menu item; I looked at this forum thread discussing some ways of making this persistent and choose to add it to ~/.profile.

Source that most forum threads ultimately pointed to: No more main-thread OpenGL in Firefox (important note for Linux users who use OpenGL)

So, recap:

- set environment variable MOZ_USE_OMTC=1
- set firefox setting layers.offmainthreadcomposition.enabled = true
(both are necessary)

Most likely layers.acceleration.force-enabled = true is also required

It might be me (or the placebo effect), but scrolling and video's (and even Google Maps) seem to be more responsive after all of this.

  • Michiel Scholten
  • Work
  • 🕔

Short story time

The ants didn't know what they had coming. I almost pitied the little critters. Almost. Finishing my whisky I went to bed, chuckling softly.

  • Michiel Scholten
  • Home
  • 🕔

A solution to some odd Gnome 3.16 issues

I'm running Ubuntu Gnome 15.04 with the ppa's to bring me Gnome 3.16 (gnome3-team and gnome3-staging). After a bit of fiddling (removing some old extensions and packages), I got it to show me GDM. After getting into the desktop, there were some odd issues though. These issues also showed up on my laptop with Arch Linux installed, so apparently it wasn't Ubuntu specific.

First, it seemed a bit more sluggish than in 3.14. Also, shortcuts would randomly stop working, and themes would have odd issues, sometimes not wanting to apply at all. Also, logging out took quite a while, same as powering off. This all left me puzzled.

After fiddling around some more, I was left even more puzzled when I was switching around VTE's (or rather, TTY's) with ctrl+alt+Function keys and noticed that I had two GDM login screens. At last, a lead :)

I dove into Google some more, and found a setting for GDM to configure the TTY it should try to appear on first. I added this to /etc/gdm/custom.conf:

[daemon]
FirstVT = 7

as normally you would expect your graphical session to be launched in TTY 7 (go there by ctrl+alt+F7 or just alt+F7 when on a text prompt in another TTY).

I also tried the line WaylandEnable=false in the same section, but that didn't appear to have much effect.

Suddenly, it seems I have only one GDM again and things are running a lot better :) I do notice that GDM keeps showing its login screen on TTY 7 and just runs your logged in Gnome on TTY 8. Maybe it was doing so all along and it has to do with MultiSeat. Still, this appears to have helped with some issues.

  • Michiel Scholten
  • Home
  • 🕔

« Old rants