Simulating a slow network connection when testing on mobile devices

Mobile devices often have spotty network connectivity - rural areas, sitting in the subway or in a car are classic situations where the connection suffers. So mobile native or web apps need to take this into account and degrade gracefully when network requests time out or the response takes a long time to arrive. You can set network parameters in most emulators (see here for Android) or use a tool like the powerful Charles proxy. But on a physical device this is of no use. This is especially useful to test different devices and platforms under real-life conditions.

Using a wireless router we can use Linux traffic shaping to add delay, slow down the throughput and also randomly drop packets. For this example I used OpenWRT because I’m familiar with it and because it has a long list of supported routers, but DD-WRT might work too. Get a supported router and a snapshot image of the unstable Barrier Breaker release for the router. Flash it and set up your wifi. I ended up bridging the wifi to the WAN port since I did not need any routing:


Next, I created a shell script called qos.sh in /root:


# The bandwidth to simulate, here about 56kilobit per second. This is layer 2 bandwidth, so TCP/UDP and IP overhead will apply


# _Half_ the latency that we aim for. Since this applies to both the WAN port and Wi-Fi, the delay is applied twice, so this actually puts it at around 120+ms


# Chance of packet loss. Also applied to both interfaces, so it is 1%.


# The device name of your wifi device.


# The device name of your wan port


# Delete existing traffic control rules

tc qdisc del root dev $WIFI

tc qdisc del root dev $WAN

# Create a basic tc rule for wifi

tc qdisc add dev $WIFI root handle 1: htb default 12

# First apply the rate limiting through a HTC scheduler

tc class add dev $WIFI parent 1:1 classid 1:12 htb rate $BW ceil $BW

# Then apply the netem scheduler which handles delay and packet loss

tc qdisc add dev $WIFI parent 1:12 netem delay $LATENCY 10ms 25% loss $LOSS 

# The same for WAN

tc qdisc add dev $WAN root handle 2: htb default 12

tc class add dev $WAN parent 2:1 classid 2:12 htb rate $BW ceil $BW

tc qdisc add dev $WAN parent 2:12 netem delay $LATENCY 10ms 25% loss $LOSS 

You can download it from this gist. Mark it as executable with chmod a+x qos.sh and add the following to /etc/rc.local before the exit statement:


The delay and packet loss in one direction could probably be eliminated. Bandwidth limiting needs to be applied in both directions though. The script is based on this StackExchange answer. More info on netem can be found on this OpenWRT wiki page.


(Source: freezerfriday)


Mutable FragmentStatePagerAdapter or how to reorder pages in ViewPager or tabs

For our latest iteration of Guidants Mobile we wanted a carousel-like view of information panels. The user can reorder these, add new ones or delete the ones he doesn’t like. To this end I used ViewPager together with FragmentStatePagerAdapter and Fragments.

The problem here is that FragmentStatePagerAdapter restores its exact state when the ViewPager is restored, so that the original ordering of the Fragments is restored. There is a discussion of the cause and possible workarounds at this  Android issue. I took the code posted there, ported it to the latest version of the support library code and published it as a Gist.


Mysterious crash on OpenGL ES Surface closing on Galaxy S3 or Note 2

I was faced by a fairly ugly issue on Guidants Mobile these days. After the 4.3 update by Samsung our app crashed on the S3 and the Note 2 with a corrupted heap whenever the OpenGL ES Surface (in this case a TextureView) was closed. The crash didn’t occur on 4.1 or on other devices. The crash log might look something like this:

F/libc    (19140): Fatal signal 11 (SIGSEGV) at 0xffffffff (code=1), thread 19196 (Thread-215)

I/DEBUG   ( 2104): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

I/DEBUG   ( 2104): Build fingerprint: ‘samsung/m0xx/m0:4.3/JSS15J/I9300XXUGMJ9:user/release-keys’

I/DEBUG   ( 2104): Revision: ‘12’

I/DEBUG   ( 2104): pid: 19140, tid: 19196, name: Thread-215  »> ag.boersego.myrmecophaga «<

I/DEBUG   ( 2104): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr ffffffff

I/DEBUG   ( 2104):     r0 ffffffff  r1 4014ce00  r2 401142f1  r3 00000000

I/DEBUG   ( 2104):     r4 5d7effa0  r5 5d6b5c58  r6 00000001  r7 00000003

I/DEBUG   ( 2104):     r8 4014f538  r9 4014f2f0  sl 63d23dd0  fp 4014f2f0

I/DEBUG   ( 2104):     ip 60f54ea0  sp 63d23d50  lr 40110cdd  pc 60ebae24  cpsr a00e0010

I/DEBUG   ( 2104):     d0  0000000000000000  d1  0000000000000000

I/DEBUG   ( 2104):     d2  0000000000000000  d3  0000000000000000

I/DEBUG   ( 2104):     d4  0000000000000001  d5  0000000000000000

I/DEBUG   ( 2104):     d6  44340000000002d0  d7  00000000000002d0

I/DEBUG   ( 2104):     d8  0000000000000000  d9  0000000000000000

I/DEBUG   ( 2104):     d10 0000000000000000  d11 0000000000000000

I/DEBUG   ( 2104):     d12 0000000000000000  d13 0000000000000000

I/DEBUG   ( 2104):     d14 0000000000000000  d15 0000000000000000

I/DEBUG   ( 2104):     d16 0000000000000001  d17 0000000000000000

I/DEBUG   ( 2104):     d18 0000000000000000  d19 0000000000000001

I/DEBUG   ( 2104):     d20 0000000000004000  d21 0000000000000000

I/DEBUG   ( 2104):     d22 0000000000004000  d23 0000000000000001

I/DEBUG   ( 2104):     d24 0000000000000000  d25 3f67f26832c604c8

I/DEBUG   ( 2104):     d26 3c60000000000000  d27 4338000000000000

I/DEBUG   ( 2104):     d28 3fe45f306dc9c883  d29 4338000000000130

I/DEBUG   ( 2104):     d30 4073000000000000  d31 0000000000004000

I/DEBUG   ( 2104):     scr 20000013

I/DEBUG   ( 2104): 

I/DEBUG   ( 2104): backtrace:

I/DEBUG   ( 2104):     #00  pc 00053e24  /system/lib/libMali.so

I/DEBUG   ( 2104):     #01  pc 0000d71c  /system/lib/libc.so

I/DEBUG   ( 2104):     #02  pc 0000ee78  /system/lib/libc.so (pthread_exit+80)

I/DEBUG   ( 2104):     #03  pc 0000d3e0  /system/lib/libc.so (pthread_create+240)

I/DEBUG   ( 2104): 

I/DEBUG   ( 2104): stack:

I/DEBUG   ( 2104):          63d23d10  00000001  

I/DEBUG   ( 2104):          63d23d14  60eb5e5c  /system/lib/libMali.so

I/DEBUG   ( 2104):          63d23d18  00000001  

I/DEBUG   ( 2104):          63d23d1c  00000000  

I/DEBUG   ( 2104):          63d23d20  00000003  

I/DEBUG   ( 2104):          63d23d24  000030a0  

I/DEBUG   ( 2104):          63d23d28  401b847d  /system/lib/libbinder.so (android::IPCThreadState::threadDestructor(void*))

I/DEBUG   ( 2104):          63d23d2c  5d7effa0  

I/DEBUG   ( 2104):          63d23d30  4014d000  /system/lib/libc.so

I/DEBUG   ( 2104):          63d23d34  5d7effa0  

I/DEBUG   ( 2104):          63d23d38  5d6b5c58  

I/DEBUG   ( 2104):          63d23d3c  00000001  

I/DEBUG   ( 2104):          63d23d40  00000003  

I/DEBUG   ( 2104):          63d23d44  40110cdd  /system/lib/libc.so (free+12)

I/DEBUG   ( 2104):          63d23d48  00000001  

I/DEBUG   ( 2104):          63d23d4c  60ebae0c  /system/lib/libMali.so

I/DEBUG   ( 2104):     #00  63d23d50  5d7effa0  

I/DEBUG   ( 2104):          63d23d54  4014f348  /system/lib/libc.so

I/DEBUG   ( 2104):          63d23d58  0000001c  

I/DEBUG   ( 2104):          63d23d5c  4014f35c  /system/lib/libc.so

I/DEBUG   ( 2104):          63d23d60  60ebaf20  /system/lib/libMali.so

I/DEBUG   ( 2104):          63d23d64  40110720  /system/lib/libc.so

I/DEBUG   ( 2104):     #01  63d23d68  419775dc  /system/lib/libdvm.so

I/DEBUG   ( 2104):          63d23d6c  5d7effa0  

I/DEBUG   ( 2104):          63d23d70  00000004  

I/DEBUG   ( 2104):          63d23d74  4014f2f0  /system/lib/libc.so

I/DEBUG   ( 2104):          63d23d78  00000001  

I/DEBUG   ( 2104):          63d23d7c  5f1166d0  

I/DEBUG   ( 2104):          63d23d80  00000000  

I/DEBUG   ( 2104):          63d23d84  00000000  

I/DEBUG   ( 2104):          63d23d88  000fe000  

I/DEBUG   ( 2104):          63d23d8c  63c26000  

I/DEBUG   ( 2104):          63d23d90  63d23dd0  

I/DEBUG   ( 2104):          63d23d94  bedd0574  [stack]

I/DEBUG   ( 2104):          63d23d98  00000000  

I/DEBUG   ( 2104):          63d23d9c  40111e7c  /system/lib/libc.so (pthread_exit+84)

I/DEBUG   ( 2104):     #02  63d23da0  63d23dd0  

I/DEBUG   ( 2104):          63d23da4  5f1166d0  

I/DEBUG   ( 2104):          63d23da8  4191b6f5  /system/lib/libdvm.so

I/DEBUG   ( 2104):          63d23dac  5f116278  

I/DEBUG   ( 2104):          63d23db0  4191b6f5  /system/lib/libdvm.so

I/DEBUG   ( 2104):          63d23db4  5f1166d0  

I/DEBUG   ( 2104):          63d23db8  400fff2c  /system/bin/linker

I/DEBUG   ( 2104):          63d23dbc  0000000b  

I/DEBUG   ( 2104):          63d23dc0  00000078  

I/DEBUG   ( 2104):          63d23dc4  4191b6f5  /system/lib/libdvm.so

I/DEBUG   ( 2104):          63d23dc8  bedd0574  [stack]

I/DEBUG   ( 2104):          63d23dcc  401103e4  /system/lib/libc.so (pthread_create+244)

It might complain about a corrupt heap on free or dlmalloc, and every now and then libMali.so might crop up in the stack trace. I started instrumenting all my native code for heap debugging (hint: This android dev post or this SO post are quite helpful for that). It didn’t appear that I had any stray memset or memcpy calls, so I started the good old divide-and-conquer commenting out of code.

It turned out that after you’re done with an EGL context, you can’t just call eglDestroyContext on it with the latest Sammy GL libs. You need to use eglMakeCurrent first to make another context (or none at all) the current context, something that all other EGL implementations do for you. So the code to destroy the context should look something like:


mEgl.eglDestroyContext(mEglDisplay, mEglContext);

mEgl.eglDestroySurface(mEglDisplay, mEglSurface);

mEglSurface = null;

mEglContext = null;

Tags: android opengl


Also ich hab mir in letzter Zeit einige Image-Filme angeschaut, hauptsächlich von Universitäten und ich muss sagen: Der Fremdschäm-Faktor war meist relativ hoch (bis zur Unerträglichkeit). Einzige Ausnahme bisher ist die Universität Vechta, der Film war so herzlich und hat mir gute Laune gemacht. 

Aber dieser Image-Film hier ist etwas anderes. Er handelt von Obstverkäufer Didi, an dessen Stand ich auch ein paar Mal die Woche vorbei gehe. Zwar esse ich einfach kein Obst, aber dennoch sehen wir uns an und jedes Mal grüßt er mich herzlich, einfach nur, weil ich seit ein paar Jahren bei ihm vorbei komme. Ein sehr nettes Video :)


Just wow.

Just wow.

(Source: nicholasius)


An iOS Developer Takes on Android


Recently, we released the Android version of Meridian, our platform for building location-based apps.

We didn’t use one of these “Cross Platform!” tools like Titanium. We wrote it, from scratch, in Java, like you do in Android.

We decided it was important to keep the native stuff native, and to respect each platform’s conventions as much as possible. Some conventions are easy to follow, like putting our tabs on the top. Other conventions go deep into the Android Way, like handling Intents, closing old Activities, implementing Search Providers, and being strict about references to help the garbage collector.

Now, our platform leverages HTML5 (buzzword, sorry) in many places for branding and content display, so we got a fair amount of UI for free. But there was much platform code written in Objective-C that needed translation into Java, such as map navigation, directions, and location switching.

So, we rolled up our sleeves, downloaded the Android SDK, and got to work.

Read More


Postmodern society and Wikileaks

In his fascinating book "In search of Power", the sociologist Zygmunt Bauman puts forth the theory that in pre-postmodern times, or solidly modern times as he puts it, society in general was divided into three parts:

Whereas the family kept privacy (in the classic sense) in the oikos, in the agora the ecclesia (the powers-that-be) and the citizens came to forge policy and to make decisions. Classically, the ecclesia would have more influence in the agora than the citizens, so that private needs would adapt to the public.

In postmodernism, Bauman explains, this balance has changed. An alternate place of power has established itself outside of the ecclesia. Here, unshackled by the need to reach a compromise with the public, powerful entities reach decisions and enact these with little interference by the other sides. The ease of international telecommunication, cheap travel and harmonization of laws world-wide grant these powers the ability to circumvent restrictions that have the ecclesia more control over events. The consequence is that the citizens grow mistrustful of the ecclesia, the ecclesia desperately grapple with this new enemy without really having the tools for this fight, and the agora is emptied of decision-making. This void is filled by what once was private; petty scandals, reality TV and the dismantling of the boundaries of the oikos.

I wondered: How does an organization like Wikileaks fit in with this theory? Wikileaks is certainly not in itself of the Oikos in Baumans sense, as it does not demand privacy (quite the contrary). It is the mutual enemy of the ecclesia. By leaking a lot of sensitive data from industries and corporations that, in my opinion, can be fitted into Baumanns idea of the new, invisible power, they are also an enemy of said power.

Wikileaks and the idea behind it then stand for a new, fourth entity in this game. My gut feeling is that they will fight with the other two powers. Opposition against either is not new. But the technique used is new: Transparency against invisibility. Where this leads is anyones guess. It might just open up the agora for discussion again.


Can’t chown or chmod on OSX?

Had a bunch of files that couldn’t be chown’ed or chmod’ed even by root:

$ svn switch —relocate http://my.svn.url/

svn: Can’t remove file ‘lib/.svn/all-wcprops’: Operation not permitted

$ ls -ltra lib/.svn/all-wcprops

-r—r—r—  1 kread  staff  260 Apr 25  2010 all-wcprops

$ chmod -R u+w .

chmod: Unable to change file mode on ./.svn/all-wcprops: Operation not permitted

OSX introduces file-level flags on HFS+ that can flag files as immutable. Try

sudo chflags nouchg FILENAME

Things should be good now. More info in man chflags

Tags: osx