Sunday, November 29, 2009

Recovering access to Google services on Android 1.6

Still very impressed by my Android phone. Have the latest Cyanogenmod v4.2.5 installed.  A few days ago the phone randomly crashed/reboot and after that Gmail, the Market and other inbuilt google services stopped working (crashed with force-close). 

Given i couldnt find any similar issues on the internet, i'll post my investigation and the solution that worked for me.  Most importantly i wanted to avoid having to do a factory reset. The "adb" application for accessing the phone over USB is part of the Android SDK here.

First checking the logs while opening the Gmail program (typed commands are in bold:

$ /opt/android-sdk/tools/adb logcat
W/dalvikvm(16474): threadid=23: thread exiting with uncaught exception (group=0x4001e1c0)
E/AndroidRuntime(16474): Uncaught handler: thread Thread-13 exiting due to uncaught exception
D/Gmail (17064): ConversationHeaderCursorAdapter.cursorStatusChanged: LOADING
E/AndroidRuntime(16474): android.database.sqlite.SQLiteDatabaseCorruptException: error code 11: database disk image is malformed
E/AndroidRuntime(16474): at android.database.sqlite.SQLiteStatement.native_1x1_string(Native Method)
E/AndroidRuntime(16474): at android.database.sqlite.SQLiteStatement.simpleQueryForString(SQLiteStatement.java:154)
E/AndroidRuntime(16474): at com.google.android.googleapps.GoogleLoginService$GlsImplementation.readAuthToken(GoogleLoginService.java:1226)
E/AndroidRuntime(16474): at com.google.android.googleapps.GoogleLoginService$GlsImplementation.blockingGetCredentials(GoogleLoginService.java:799)
E/AndroidRuntime(16474): at com.google.android.googleapps.IGoogleLoginService$Stub.onTransact(IGoogleLoginService.java:107)
E/AndroidRuntime(16474): at android.os.Binder.transact(Binder.java:248)
E/AndroidRuntime(16474): at com.google.android.googleapps.IGoogleLoginService$Stub$Proxy.blockingGetCredentials(IGoogleLoginService.java:516)
E/AndroidRuntime(16474): at com.google.android.googlelogin.GoogleLoginServiceBlockingHelper.getCredentials(GoogleLoginServiceBlockingHelper.java:503)
E/AndroidRuntime(16474): at com.google.android.googlelogin.GoogleLoginServiceBlockingHelper.getAuthToken(GoogleLoginServiceBlockingHelper.java:456)
E/AndroidRuntime(16474): at com.google.android.providers.gmail.MailEngine.runHttpRequestInternal(MailEngine.java:1101)
E/AndroidRuntime(16474): at com.google.android.providers.gmail.MailEngine.runHttpRequest(MailEngine.java:1080)
E/AndroidRuntime(16474): at com.google.android.providers.gmail.MailEngine.runSyncLoop(MailEngine.java:1003)
E/AndroidRuntime(16474): at com.google.android.providers.gmail.MailEngine.access$1800(MailEngine.java:92)
E/AndroidRuntime(16474): at com.google.android.providers.gmail.MailEngine$NetworkCursorLogic.run(MailEngine.java:2567)
E/AndroidRuntime(16474): at java.lang.Thread.run(Thread.java:1060)
I/Process (16213): Sending signal. PID: 16474 SIG: 3
I/dalvikvm(16474): threadid=7: reacting to signal 3
I/dalvikvm(16474): Wrote stack trace to '/data/anr/traces.txt'

The exception spells it out pretty clearly "SQLiteDatabaseCorruptException: error code 11: database disk image is malformed". Having used SQL lite before, I knew that meant i had to find the right ".db" file on the phone. Using the root shell and after a bit of searching:

# /opt/android-sdk/tools/adb shell
# find /data | grep googleapps
...
/data/com.google.android.googleapps/databases/accounts.db

At a guess that looked like the right SQLite database file. Checking the filesystems:

# mount | grep /data

/dev/block/mtdblock5 on /data type yaffs2 (rw,nodev)

As expected the /data folder is mounted read/write. Temporarily moving the file so it can't be found by the google login service:

# cd /data/data/com.google.android.googleapps/databases
# mv accounts.db accounts.db~

Then exit adb and watch the logs again:

# exit

$ /opt/android-sdk/tools/adb logcat

The gmail program still didn't work, however at the home screen going Settings > Data Synchronization caused the Google account signup sequence to be started (same as on a factory reset phone).

A few minutes after relogging in, all Gmail/Calendar data was resynchronised and the phone back to normal. Hope this helps someone!

No comments:

Post a Comment