Android emulator and the SIM card serial number

After publishing the post about changing the IMEI number, I was asked about modifying the SIM card serial number. Yes, it is perfectly possible, but requires a bit more investigation.

In general, the mechanism used is the same (i.e. AT commands sent to the emulated GSM modem). The telephony subsystem sends the following command to the emulated modem to retrieve the SIM card serial number (use any GSM modem manual for reference):

AT+CRSM=176,12258,0,0,10

The first numerical parameter denotes a command to execute on the SIM card, 176 stands for READ BINARY. Second parameter is the field identifier – Integrated Circuit Card identification, that is the SIM card serial number (for the full list of fields, called Elementary Files, refer to 3GPP TS 51.011 specification). Emulated modem responds with the following hard-coded response:

+CRSM: 144,0,98101430121181157002

The string of digits following the second comma is what we’re looking for, however, with every pair of digits swapped. All the SIM card commands and responses can be found in external/qemu/telephony/sim_card.c.

Changing the emulated SIM card serial number is now as easy changing the IMEI. To change the SIM card serial to e.g. 12345678901234567890, one has to:

  • backup the emulator binary 😉
  • open the binary in the hex editor
  • search for 98101430121181157002
  • replace it with 21436587092143658709 (remember about swapping)
Posted in Android. Tags: , . 2 Comments »

Android’s HTTPS implementation slow under debugger

Update: I’ve just discovered that the problem described below only affects Android 1.5 (which is the target platform for my project). Thus another solution is to use AVD configured with Android 1.6 or higher for debugging, and use version 1.5 otherwise to ensure compatibility.

The project I’m working on now communicates with server via custom protocol on top of HTTP and HTTPS (using org.apache.http.client.HttpClient as a HTTP/HTTPS implementation provider). Recently I’ve observed interesting problem of HTTPS requests taking ages to complete if application is executing under debugger control. It makes debugging the code quite frustrating.

To investigate the problem let’s use the following code snippet:

		HttpResponse response = null;
		HttpClient httpClient = new DefaultHttpClient();
		HttpContext localContext = new BasicHttpContext();

		Log.d("--------", "1. Sending http request");
		try {
			response = httpClient.execute(new HttpGet("http://www.apache-ssl.org/"), localContext);
		} catch (Exception e) {
			Log.d("--------", "Request failed", e);
		}
		Log.d("--------", "2. Request finished, status = " + response.getStatusLine().getStatusCode());

		Log.d("--------", "3. Sending https request");
		try {
			response = httpClient.execute(new HttpGet("https://www.apache-ssl.org/"), localContext);
		} catch (Exception e) {
			Log.d("--------", "Request failed", e);
		}
		Log.d("--------", "4. Request finished, status = " + response.getStatusLine().getStatusCode());

This code snippet has been executed on Android emulator (I’ve no device at hand at the moment to try it), platform version 1.5, running on Windows Vista. To make results more dependable the code has been executed five times and average times have been calculated. Sure, it’s not a serious benchmark of any kind, but we only want to have a rough idea what’s going on, right?

A bit of log post-processing reveals the following average times:

  • HTTP, no debugger: 0.80s
  • HTTPS, no debugger: 3.32s
  • HTTP, with debugger: 3.15s
  • HTTPS, with debugger: 142.16s

HTTPS request takes ~45 times longer to complete compared to HTTP, with debugger attached. Without debugger the factor is ~4, which is acceptable.

For the time being I have no explanation for such a big difference. Looking at the stack trace of the thread paused while performing the HTTPS request shows a lot of classes from Bouncy Castle project, as well as classes from org.apache.harmony.xnet.provider.jsse package – JNI interface to OpenSSL library. Some profiling would be necessary…

In case of my application (which always connects to the same, HTTPS-only server) I’ve decided to use the good old stunnel running on my Linux box. It is enough to change the URL in the example above to http://linuxbox:8888 and start stunnel as follows:

czajnik@czajnik:~$ sudo stunnel -c -d 8888 -r www.apache-ssl.org:443

However, it only works for hosts that accept Host: HTTP header value different from actual host name. Ideally, we should be able to leave the original URL and only redirect the socket connection to a different IP and port. And in fact we are, using HttpClient’s proxy settings:

		HttpParams params = httpClient.getParams();
		params.setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost("linuxbox", 8888));

With this setting HttpClient connects to our stunnel process, but still uses original URL – exactly what we need. Of course, URL has to be changed from https:// to http://, as the connection between HttpClient and stunnel is obviously not encrypted. Also, resist the temptation to use localhost 😉

First Android platform build

After playing with Android SDK for a while, now it’s time to try to build the platform. Unfortunately, Android documentation is not the best one I’ve ever seen, and some research is needed. Do they try to promote their web search engine this way? 😉

Fist step is to clone the repository, as described in this guide (I’m going to use donut branch). It goes smoothly, but takes a lot of time (my Internet link goes up to 120kB/s only):

czajnik@czajnik:~/mydroid$ repo init -u git://android.git.kernel.org/platform/manifest.git -bdonut
czajnik@czajnik:~/mydroid$ time repo sync

Next step would be to select the JDK version (android seem to require JDK 1.5), and set basic environment by sourcing one of the shell scripts:

czajnik@czajnik:~$ export JAVA_HOME=/usr/share/jdk1.5.0_22/
czajnik@czajnik:~$ export ANDROID_JAVA_HOME=$JAVA_HOME
czajnik@czajnik:~$ export PATH=/usr/share/jdk1.5.0_22/bin/:$PATH
czajnik@czajnik:~$ cd mydroid
czajnik@czajnik:~/mydroid$ . build/envsetup.sh
including vendor/aosp/vendorsetup.sh
czajnik@czajnik:~/mydroid$

Now we need to select a particular build configuration to be used. On this page (which is a must-read anyway) they mention choosecombo, let’s use it to select generic device debug build (there is also a tool called lunch which allows to select one of the common build types, call it without any parameters to get the list of possibilities and select one interactively):

czajnik@czajnik:~/mydroid$ choosecombo
Build for the simulator or the device?
     1. Device
     2. Simulator

Which would you like? [1]


Build type choices are:
     1. release
     2. debug

Which would you like? [1] 2


Which product would you like? [generic]


Variant choices are:
     1. user
     2. userdebug
     3. eng
Which would you like? [eng]

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=1.6
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=debug
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=Donut
============================================

Finally we reached the point where we can start actual build by issuing make -j2. First attempt fails with the following error message:

development/emulator/qtools/trace_reader.cpp: In function ‘char* ExtractDexPathFromMmap(const char*)’:
development/emulator/qtools/trace_reader.cpp:1012: error: invalid conversion from ‘const char*’ to ‘char*’
development/emulator/qtools/trace_reader.cpp:1015: error: invalid conversion from ‘const char*’ to ‘char*’

It’s time for a first useful hint – if you want to see the exact commands executed, invoke make showcommands. Armed with this weapon it’s pretty easy to track the problem. It seems that trace_reader.cpp is expecting C-like string function prototypes in string.h, while string.h on my system exports a C++-compatible declaration. In this particular case:

// C way
char *rindex(const char *s, int c);
// C++ way (overload)
char *rindex (char *s, int c);
const char *rindex (const char *s, int c);

My Linux distribution (Kubuntu 9.10) has switched from glibc to eglibc, included /usr/include/string.h file uses the second type of declaration if used inside a C++ source file, causing the compilation failure. Look at this fragment of string.h:

/* Tell the caller that we provide correct C++ prototypes.  */
#if defined __cplusplus && __GNUC_PREREQ (4, 4)
# define __CORRECT_ISO_CPP_STRING_H_PROTO
#endif

Obviously, there are at least the following solutions:

  • fix Android code (it’s a C++ file, it should expect C++ prototypes)
  • use a system that uses regular glibc
  • use GCC compiler version lower than 4.4
  • comment out #define line above

Of course, I’ve chosen the last option. And that was enough, after almost 80 minutes I’ve got my first own Android image. Now it’s time to hack it a bit – stay tuned!

Posted in Android. Tags: . 2 Comments »

Android 1.5 and ListView’s choiceMode

I’ve just discovered that setting the choiceMode attribute of the ListView element in the XML layout doesn’t work on Android 1.5. Comparing ListView.java from 1.5 and 1.6 releases reveals the following difference (among others):

@@ -166,6 +174,8 @@
             setDividerHeight(dividerHeight);
         }

+        setChoiceMode(a.getInt(R.styleable.ListView_choiceMode, CHOICE_MODE_NONE));
+        
         mHeaderDividersEnabled = a.getBoolean(R.styleable.ListView_headerDividersEnabled, true);
         mFooterDividersEnabled = a.getBoolean(R.styleable.ListView_footerDividersEnabled, true);

The change is inside ListView‘s constructor. Looks like someone has forgotten to add the code to retrieve the choiceMode attribute, and that was fixed in 1.6. I’ve found no ticket for that in the Android tracker, however.

Anyway, if you want your code to be 1.5-compatible, you’d rather call setChoiceMode() explicitly in your code.

Posted in Android. Tags: , . 2 Comments »

Android platform guide

After playing with Android SDK for some time, now I’m trying to make my own platform build and hack around a bit. Recently I’ve found the Android Platform Developer’s Guide site. It contains some very useful hints, but the site doesn’t seem referenced from neither http://developer.android.com/ nor http://source.android.com/. Serious oversight, isn’t it? Or did I overlook something?