[Android Software/Hacking General [Developers Only]] CosmicDan:
Note - I assume this question is better suited to here rather than Q&A, I am definitely not a newbie ;)

Hello people. I am attempting to develop a method for ROM developers/hackers to predefine (prebuild?) the settings.db for first bootup, and also to "lock" settings which could later be hidden from the GUI. Very useful for various hacks that we need to perform in ROM ports/kangs. This particular one is an attempt to automate the installation for "Hardware LED Fix" on the XPERIA X10. Here is my script so far, whether or not some of these commands are even needed doesn't matter as I have included it all for the sake of completion - as you can see some commands are conflicted but they are commented out, just showing what I've tried.

Behold:

# M&M's MIUI changes below
# ------------------------------------
# Force "Dim Level" to 20 for HW_LED fix
SETTINGSDB=/data/data/com.android.providers.settings/databases/settings.db
if [ ! -e $SETTINGSDB ];
then # First-boot, create database!
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /data # Is this needed?
echo "[M&M] Firstboot detected, creating Settings database..."
mkdir -p /data/data/com.android.providers.settings/databases/
sqlite3 -line $SETTINGSDB 'create table system (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT UNIQUE ON CONFLICT REPLACE,value TEXT);'
sqlite3 -line $SETTINGSDB 'INSERT INTO system VALUES (82,"light_sensor_custom",1);'
sqlite3 -line $SETTINGSDB 'INSERT INTO system VALUES (88,"light_screen_dim",20);'
sqlite3 -line $SETTINGSDB 'CREATE INDEX systemIndex1 ON system (name);'
# Set permissions
chown -R 1000.1000 /data
chmod 0755 /data
#find /data/data -type d -exec chmod -R 0771 {} \;
#find /data/data -type f -exec chmod -R 0644 {} \;
#find /data/data -type d -exec chmod -R 0755 {} \;
#find /data/data -type f -exec chmod -R 0660 {} \;
#chmod 0751 /data/data/com.android.providers.settings
#chmod 0660 $SETTINGSDB
echo "[M&M] OK, now fixing permissions..."
/sbin/fix_permissions
fi

if [ -e $SETTINGSDB ]
then
echo "[M&M] Verifying locked settings..."
# TODO: Conditional check for existing values saving unnecessary writes
sqlite3 -line $SETTINGSDB 'REPLACE INTO system VALUES (82,"light_sensor_custom",1);'
sqlite3 -line $SETTINGSDB 'REPLACE INTO system VALUES (88,"light_screen_dim",20);'
fi

# Kill servers to force refresh... needed?
killall sqlite3
killall system_server
echo "[M&M] Custom boot processing complete."

And yes, those last "killall" commands I have tried with and without.

That's the most complete/overkill init.d script for my task. FYI I had it originally in hw_config.sh but I am not sure if that is too soon in the boot process, or maybe this init.d script is too late (but I doubt it, it's right up the top of logcat from boot). Anywho, here is the snipped logcat for above script (from fresh boot i.e. after database creation, and yes I do have log.redirect-stdio set to true):

I/ActivityThread( 2164): Pub settings: com.android.providers.settings.SettingsProvider
I/Database( 2164): sqlite returned: error code = 1, msg = table system already exists
E/Database( 2164): Failure 1 (table system already exists) on 0x254790 when preparing 'CREATE TABLE system (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT UNIQUE ON CONFLICT REPLACE,value TEXT);'.
E/SQLiteOpenHelper( 2164): Couldn't open settings.db for writing (will try read-only):
E/SQLiteOpenHelper( 2164): android.database.sqlite.SQLiteException: table system already exists: CREATE TABLE system (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT UNIQUE ON CONFLICT REPLACE,value TEXT);
E/SQLiteOpenHelper( 2164): at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method)
E/SQLiteOpenHelper( 2164): at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1763)
E/SQLiteOpenHelper( 2164): at com.android.providers.settings.DatabaseHelper.onCreate(DatabaseHelper.java:91)
E/SQLiteOpenHelper( 2164): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:126)
E/SQLiteOpenHelper( 2164): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
E/SQLiteOpenHelper( 2164): at com.android.providers.settings.SettingsProvider.query(SettingsProvider.java:406)
E/SQLiteOpenHelper( 2164): at com.android.providers.settings.SettingsProvider.ensureAndroidIdIsSet(SettingsProvider.java:325)
E/SQLiteOpenHelper( 2164): at com.android.providers.settings.SettingsProvider.onCreate(SettingsProvider.java:261)
E/SQLiteOpenHelper( 2164): at android.content.ContentProvider.attachInfo(ContentProvider.java:806)
E/SQLiteOpenHelper( 2164): at android.app.ActivityThread.installProvider(ActivityThread.java:3574)
E/SQLiteOpenHelper( 2164): at android.app.ActivityThread.installContentProviders(ActivityThread.java:3329)
E/SQLiteOpenHelper( 2164): at android.app.ActivityThread.installSystemProviders(ActivityThread.java:3680)
E/SQLiteOpenHelper( 2164): at com.android.server.am.ActivityManagerService.installSystemProviders(ActivityManagerService.java:5822)
E/SQLiteOpenHelper( 2164): at com.android.server.ServerThread.run(SystemServer.java:174)
E/System ( 2164): Failure starting core service

It seems that the sql service is crashing out because the table already exists. FYI, 2164 is system_server here hence why I tried the killall command. My educated guesses are numerous here:

(a) A bug in Cyanogenmod/Android

(b) A security feature in cyanogenmod

(c) Some permissions/ownership issue somewhere or process locking.

(d) Or, more likely, I'm missing something.

Stuck on what to do about this bootloop. Any help is greatly appreciated and beneficial for all of us as this is an idea that nobody seems to have tried (or at least publicly spoken of) ;)

Cheers XDA'ers!

EDIT: I am currently downloading the entire CM7.2 sourcecode and will do a full find-in-files text search for "create table system" to investigate this further. I may yet answer my own question in time :P