CM: chromium doesn’t build with JDK 1.7

If you build Android or CyanogenMod and you run into issues with HashSet_jni.h you need the following changes to the chromium_org project:

diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index de865d5..d4a2324 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -555,18 +555,21 @@ class JNIFromJavaSource(object):
contents)
return JNIFromJavaSource(contents, fully_qualified_class)

+def MultipleReplace(string, rep_dict):
+ pattern = re.compile("|".join([re.escape(k) for k in rep_dict.keys()]), re.M)
+ return pattern.sub(lambda x: rep_dict[x.group(0)], string)

class InlHeaderFileGenerator(object):
"""Generates an inline header file for JNI integration."""

def __init__(self, namespace, fully_qualified_class, natives,
called_by_natives):
- self.namespace = namespace
- self.fully_qualified_class = fully_qualified_class
+ self.namespace = MultipleReplace(namespace, {'':''})
+ self.fully_qualified_class = MultipleReplace(fully_qualified_class, {'':''})
self.class_name = self.fully_qualified_class.split('/')[-1]
self.natives = natives
self.called_by_natives = called_by_natives
- self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
+ self.header_guard = MultipleReplace(fully_qualified_class, {'/':'_', '':''}) + '_JNI'

def GetContent(self):
"""Returns the content of the JNI binding file."""

In addition I needed to fix LinkNode in the Gallery app.

How to create a SuplRootCert for supl.google.com

Back to these bad GPS fixes for Android spread all over the net. This time I will describe how to find out which is the correct SSL root certificate you need and how to create it. So first we need know the root certificate the Google SUPL server has been signed. There are several ways but we use the easiest. Connect with the openssl binary to the SUPL server. This can be done by the following command:


$ openssl s_client -connect supl.google.com:7275

The output you will see will include the following relevant part at the beginning:


CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU = "(c) 2006 thawte, Inc. - For authorized use only", CN = thawte Primary Root CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=supl.google.com
i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
1 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
2 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
---

This means the server certificate of supl.google.com is signed by the “Thawte Premium Server CA” root certificate. So you need to go and find that. Each SSL certificate issuer has a site with all it root certificates available. You can find the root certificates for Thawte here:

https://www.thawte.com/roots/

UPDATE 2015: Google uses Root 2 – GeoTrust Global CA in the meantime. You can get it

Now download the “Root 2 Thawte Premium Server CA” certificate. You will get the certificate in the PEM format. The SuplRootCert file on Android is stored in the DER format so we need to convert it. This can be done with the following command:

openssl x509 -inform PEM -in thawte_Premium_Server_CA.pem -outform DER -out SuplRootCert

Now you have the correct SuplRootCert you can put in /system/etc and use with the gps.conf. If you have a SuplRootCert and you want to find out which root certificate it is you can do it with the following command:

openssl x509 -inform DER -in SuplRootCert -text

REMEMBER: This works only on vendor ROMs which provide SUPL TLS support. I didn’t see any CyanogenMod ROM with TLS SUPL support yet!!!

Android, CyanogenMod and the GPS fix

There are a lot of people around providing gps fixes for Android. Most of them don’t really help at all. I want to explain here what variables the code recognizes and what they do. The other thing is SuplCert which is the certificate to verify the ssl connection for the supl server. Most of the time poeple provide the wrong certificate.

gps.conf

There are two locations in the code which read the gps.conf file. GpsLocationProvider.java [1] GpsXtraDownloader.java [2] and loc_eng_cfg.cpp [3]. The GpsLocationProvider reads the following variables from the config:

    SUPL_HOST
    SUPL_PORT

    C2K_HOST
    C2K_PORT

GpsXtraDownloader.java

    XTRA_SERVER_1
    XTRA_SERVER_2
    XTRA_SERVER_3

This is pretty obvious. It then calls a function from libloc_api called loc_eng_set_server() to set the agps server. libloc_api itself reads also the gps.conf to get the values for the following variables:

    INTERMEDIATE_POS (Turn on intermediate position)
    ACCURACY_THRES   (Turn-off  intermediate positions outside required accuracy)
    ENABLE_WIPER     (The code only reads this variable but it doesn't do anything)
    DEBUG_LEVEL      (0-5, default: 4)

SuplCert

In most of the flashable gps fixes you find a SuplCert. Most of them I looked at have the wrong certificate. They include a Verisign certificate but supl.google.com is signed by Thawte.

supl_google_com_request

This is a SSL encrypted supl request to supl.google.com on port 7275.

However as you can see above. There is no support for a TLS supl request in the code. It doesn’t make sense to add the host, port and certificate in CyanogenMod.

Supl Protocol

For supl you need to have a cell connection. You ask the radio for the cell parameters and send it to the supl server. The supl server will return the gps coordinates of the tower or an estimation of your location.

You can get the cell id information with the following AT commands:

       $ AT+COP?
       +COPS: 0,2,"24405",2
       OK
       $ AT+CREG=2
       OK
       $ AT+CREG?
       +CREG: 2,1,"59E2","31B0"
       OK
       $ AT+CREG=0
       OK

       This results in:

       MCC = 244     (Mobile Country Code)
       MCN = 05      (Mobile Country Network)
       LAC = 0x59e2  (Local Area Code)
       CI  = 0x31b0  (Cell Identifier)

Conclusion

The default gps.conf by CyanogenMod provides all needed variables to have supl support for a faster GPS fix.

With DEBUG_LEVEL=5 you normally see the following lines:

    D/libloc  (  169): loc_eng_init created client, id = 1
    D/libloc  (  169): loc_eng_ni_init: entered.
    D/libloc  (  169): loc_eng_set_server, type = 1, hostname = supl.google.com, port = 7276
    D/libloc  (  169): loc_eng_set_server, addr = supl.google.com:7276
    D/libloc  (  169): loc_eng_ioctl called: client = 1, ioctl_type = RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR
    D/RPC     (  169): 3000008c:00020002 call success.
    D/RPC     (  169): 3000008c:00020002 sending call (XID 2).
    D/RPC     (  169): 3000008c:00020002 received REPLY (XID 2), grabbing mutex to wake up client.

[1] frameworks/base/services/java/com/android/server/location/GpsLocationProvider.java
[2] frameworks/base/services/java/com/android/server/location/GpsXtraDownloader.java
[2] hardware/qcom/gps/loc_api/libloc_api/loc_eng_cfg.cpp

CyanogenMod 9 for HTC Wildfire S (ALPHA3)

Maybe you already know that I worked since January 2012 on porting CM9 to the HTC Wildfire S (Marvel). It took quite a while to figure out how Android is working and how to get the the OS correctly talking with the hardware. Today I’ve released ALPHA3 of my work which is a pretty stable version. The Wildfire S is not a supported Android 4.0 device, so you have to workaround a lot of things and use old binary blobs. This also means there will probably never be an official CM9 release for the Wildfire S. However most of the stuff is working pretty well and you can live with the known bugs.

Known bugs:

  • Camera isn’t fully working, you can take pictures without problems.
  • OMX codecs aren’t fully working cause they are too old. We asked Quallcom to release new OMX codecs for ARMv6 but they said it will not be possible to get it working with QDSP5.
  • The device reboots if you turn blootooth on sometimes and bluetooth drains the battery.

You can download ALPHA3 of the ROM here.

Have fun.

CM9 (Android 4.0 ICS) and deep sleep

I’ve had the problem that the device didn’t want to switch into deep sleep mode if radio was on. What is deep sleep? To make it simple we break it down. Your device has 3 modes. The fisrst is “Screen On and Awake”, “Awake” and “Deep Sleep”. If you use your device it you’re in the first mode and you need a obviously a lot of battery. The second “Awake” means it is doing some background work. Checking for calls, checking Emails, syncing contacts. The last one means it goes for some time into a mode were it uses almost no battery, and this is Deep Sleep. If you don’t do anything and your phone is in your pocket you want that it is in the Deep Sleep mode most of the time.

My HTC Wildfire S didn’t want to go into the “Deep Sleep” mode at all if radio was turned on. It worked with Airplane mode. I thought this has something todo with RIL but I was wrong. Actually it was a bluetooth wakelock. The wakelock “msm_serial_hs_dma” was held all the time. The problem is that the msm7227 platform doesn’t supports quick switch-on/off of the bluetooth module and you need to deactivate it with an overlay else ICS always tries to trigger it.

So adding

<bool name="config_bluetooth_adapter_quick_switch">false</bool>

to overlay/frameworks/base/core/res/res/values/config.xml fixed the problem and the wakelock was gone.

libhtc_ril.so and segfaults

If you try to get a new Android version, in this case CyanogenMod9, working on your old phone you have to deal with binary blobs. One of these blobs is the library talking to the radio, libhtc_ril.so.

I wanted to document what I learned about libhtc_ril.so. I’ve wanted to get the library version matching my baseband version working with cm9. This resulted it several segfaults. So I’ve started to strace the rild process to find what’s going wrong, which permissions are missing etc. The library doesn’t check return values so it segfaults. One of these segfaults was a missing kernel interface called usb_function_switch. The file should be in /sys/devices/platform/msm_hsusb/usb_function_switch. I’ve implemented that function in the kernel and it still segfaulted and I had no idea what to do now. Today I analyzed the RADIO logs and stumpled upon:

D/RILJ    (  328): [0100]> SCREEN_STATE: false
D/HTC_RIL ( 1360): ril_func_screen_state_notified():called
D/HTC_RIL ( 1360): ril_func_screen_state_notified():Not found 'ether:' in USB_STATE_PATH

As it segfaulted directly after closing /sys/devices/platform/msm_hsusb/usb_function_switch it smelled like it expeced to have something like:

ether:disable

I’ve dived into the code and found out that in my kernel tree it was called rndis and in the htc kernel tree it was called ether. So I’ve fixed that and added the other values of /sys/devices/platform/msm_hsusb/usb_function_switch it started to work just fine. I hope this post will help other developers with similar problems.

This is the full set of the usb_function_switch:

ether:disable
accessory:disable
usb_mass_storage:enable
adb:enable
cdc_ethernet:disable
diag:disable
modem:disable
serial:disable

CM9 on Marvel (HTC Wildfire S)

After Qualcom released new graphic blobs for ARMv6 I was able to get CyanogenMod 9 working on my HTC Wildfire S pretty well. There are still some problem which need to be fixed. GPS isn’t working, if you have GSM/3G turned on the battery drains pretty fast. I’m currently trying to get the camera working. There is also a wakelock bug with bluetooth in the kernel right now.

If you’re a developer working on a msm7x27 device and are interested to work together join #cyanogenmod-msm7x27 @ freenode.

You can find my work at http://git.cryptomilk.org/

CyanogenMod 9 for HTC Wildfire S

I’ve got a new gadget, a nice and small Android based smartphone, the HTC Wildfire S (WFS). The week before I got it alquez finished porting CyanogenMod 7 to the wfs. I’ve installed it and started to use it. After some time I was curios how to build the system. I’ve asked alquez how to set it up and I built it from source. Then I got interested in Android 4.0 and looked at CM9. After I managed to build it, it booted with the CM7 kernel and you could get a shell but that was it. So I’ve started to look into the Kernel and read CM9 code. Now after two weeks of work the device shows a UI. The questions if it will work in the end. Most of the stuff is Open Source but you rely on some binary libraries for OpenGL and maybe will not work out in the end. Android 4.0 relies on a lot of features of the 3.0 Kernel, new netfilter modules, updated graphics stuff etc.

If it will not work out in the end, at least I worked on the Kernel 😉