[Epic 4G Android Development] SenseiSimple:
First-Boot Install System​

I have searched Far and wide for something like this since i first put out SleeperROM in November and always come up empty.

So with the latest release, i decided it was finally time to do it myself.

All you have to do is, using the following package as a template either on its own or in your ROM, make sure your batch folder with the .apk's to install are in /data/.firstboot/

Why

Some apps like QuickPic, ConnectBot, TinyFlashlight, Flash, Google Goggles and others that rely on linked libs don't like to simply be copied to their install dir because many won't install their own libs unless the PackageManager does it and/or they won't add themselves to the packages list (like QuickPic). The old solution is to include the lib either in the /data/data/appdir/lib with the rom install OR in /system/lib but this is quite wasteful especially in the case of big apps like Flash where including the libs separately from the app effectively doubles the space taken up on the rom by that single app since the apk still contains the lib files within.

So the solution is to install on first boot by including the apps in a batch folder for the script to process.

How it works

What it does is run from the init scripts, as one of the last scripts to run, it waits until the Android core system is up (checks to be sure by waiting for the SystemUI process is running then waits for an additional 10 seconds)

Then runs /data/.firstboot.sh, which is where you should put your first boot routines. Included in this script is the batch app installer which looks for the apps in /data/.firstboot/ and stores temporary app backups in /cache/tmp -- so be mindful that on MTD roms, the cache partition is smaller so may have to modify the $tmp variable to wherever you want to store temporaries

After installing, it sleeps for a proportional number of seconds (5 seconds per app installed) to ensure there is no race condition between installs or the final permissions_fix, zipalign and tmp cleanup. The /data/.firstboot.sh script removes itself when everything is complete.

The remaining components are kept in there for additional use by the /etc/init.d/Y02firstboot script in the future, so then all that needs to be put on the phone is a new /data/.firstboot/ dir and replacement /data/.firstboot.sh to run a batch of updates.

The Apps MUST be named by their package name.

I.e. Titanium Backup MUST be named com.keramidas.TitaniumBackup.apk

the file name must correspond with the name of the data dir in /data/data/ the script is lazy in that way, i didn't feel like keeping a file manifest of installs, instead just like to drop in apps to install.

The installer

consists of the following components:

- /system/etc/init.d/Y02firstboot

- /system/xbin/rsync

- /system/xbin/fix_permissions

- /system/xbin/batch_zipalign

- /system/xbin/sleeperlog (echos, logcats, and writes a log of activity to /sdcard/sleeperlog.txt)

- /data/.firstboot.sh

- /data/.firstboot/ (batch app directory)

- NOT INCLUDED, there must be a busybox bin somewhere in $PATH - this is not a problem for most roms

See the package link for a ready to use first-boot installer [CWM] flashable. Just drop your apks into /fs/data/.firstboot/ for a batch app updater

Download the template/usable package

DOWNLOAD MOD_CWM-FirstBoot-20120112.zip

File size: 341.07 KB / MD5 23d88c349b8d2fa3cd2f9958ae99a1f6

​

THE MAIN COMPONENTS:

/system/etc/init.d/Y02firstboot

#!/system/bin/sh
# execute post-install script on First boot
# 01022012 SENSEISIMPLE
SLEEP=3
FBSCR="/data/.firstboot.sh"
BB="busybox"
pg () {
$BB ps | $BB grep "$@" | $BB grep -v "$( echo $BB grep $@ )"
}

if [ -f "$FBSCR" ]; then
#install apps on first boot after system services have started
sleeperlog "Found $FBLOC"
sleeperlog "Waiting for system"
$BB chmod 0755 $FBSCR
while : ; do
if pg systemui; then
$BB sleep 10
sleeperlog "system loaded."
log -p i -t boot "Executing $FBSCR script"
sleeperlog "Running FirstBoot init"
$FBSCR

break
fi
sleeperlog "WAITING FOR SYSTEM SERVICE: sleeping for $SLEEP s..."
$BB sleep $SLEEP

done
fi

/data/.firstboot.sh

#!/system/bin/sh
#
# 20120107 - SENSEISIMPLE
#
log -p i -t init:firstboot "INIT.firstboot BEGIN: USER SCRIPT $FBLOC.sh"
sleeperlog "FirstBoot Script OK TO RUN"

FBLOC="/data/.firstboot"
tmp="/cache/tmp/firstboot"
bak="$tmp/bak/data/data/"

BB="busybox"
RM="$BB rm"
CP="$BB cp"
MV="$BB mv"
MKDIR="$BB mkdir"
LS="$BB ls"
CHMOD="$BB chmod"
SLEEP="$BB sleep"
GREP="$BB grep"

pg () {
$BB ps | $BB grep "$@" | $BB grep -v "$( echo $BB grep $@ )"
}

$CHMOD 0777 /data

#install apps on first boot
if [ -d $FBLOC ]; then
sleeperlog "Found $FBLOC"

if [ "$($LS $FBLOC)" ]; then
cd $FBLOC
$MKDIR -p $bak
for pkg in *.apk; do
log -p i -t init:firstboot "INIT.firstboot INSTALLING: $pkg"
sleeperlog "PREPARING: $pkg"

pkgname=${pkg%.*}
sleeperlog "BACKING UP APP DATA - $pkgname"
#back up data, delete the original data dir to prevent install errors (pm isn't very good at what it does)
if [ -d /data/data/$pkgname ]; then
$CP -a /data/data/$pkgname $bak/$pkgname
$RM -rf /data/data/$pkgname
fi

#WAIT, then install, then WAIT SOME MORE
$SLEEP 2
sleeperlog "INSTALLING $pkgname"
pm install -r $FBLOC/$pkg &
$SLEEP 10

#REIntegrate application data
if [ -d "$bak/$pkgname" ]; then
sleeperlog "\nSYNCING APP DATA \n\n$(/system/xbin/rsync -auv --exclude=lib $bak/$pkgname/ /data/data/$pkgname/)\n"
fi
i=$((i+1))

#Move the install .apk to tmp
if $LS /data/app | $GREP "$pkgname"; then
sleeperlog "Package appears to have installed."
$MV "$pkg" $tmp/
fi
#If the firstboot batch dir is empty, delete it now
! [ "$($LS $FBLOC)" ] && $RM -rf $FBLOC
done

#WAIT for [#ofapps x 5 seconds each] to avoid a race condition
waitsecs=$(( i * 5 ))
sleeperlog "Waiting for ${waitsecs}s before Fixing Permissions"
$SLEEP $waitsecs
sleeperlog "Fixing Permissions $(/system/xbin/fix_permissions)"
sleeperlog "Running batch zipalign \n\n $(/system/xbin/zipalign)"
sleeperlog "Clearing tmp $tmp"

fi

fi

sleeperlog "FIRSTBOOT SCRIPT COMPLETE"

log -p i -t init:firstboot "INIT.firstboot SELF DESTRUCT FIRSTBOOTSCRIPT"
if ! [ "$($LS $FBLOC)" ]; then
$MV $0 $tmp/.firstboot
# COMMENT THIS OUT FOR DEBUGGING, TO NOT REMOVE THE TMP DIR
$RM -r $tmp
echo ""
fi
echo -e "#\n#COMPLETED ON $(date)\n#" >> $0
sleeperlog "FirstBoot Apoptosis"
log -p i -t init:firstboot "INIT.firstboot END: USER SCRIPT $FBLOC.sh"

THANKS

CyanogenMod team for the Fix_permissions script

DarkyROM for the Batch Zipalign script