[Android Software/Hacking General [Developers Only]] mikeoswego:
Thanks for that link and explanation, I thought that Motorola had just left out the functionality of the duplicate apps in data cleanup. I started trying to figure this out a couple weeks ago so it's interesting this has come up independently! Normally, using TK Gapps, they would be flashed from recovery and in the past, if the user had upgraded through the play store, the app in data would be removed on the next boot leaving the same/newer version in /system. Since we don't have write access to /system but can flash a modified /system image. I mount /system on my Linux box and update the apps from GApps with a modified version of the TK Gapps installer script or by hand as they are updated from the play store on my phone (and updated Moto/Verzion apps as well) and then distribute that modified /system image for others to flash onto their device. Of course, there is no point in going to that effort if the apps are going to remain in /data reducing space available in /sdcard unless the user doesn't update through play store. I've not tried waiting for a play store update to be older than a version in an update system image so I don't know if it will do the clean up then.

I tried to solve this problem by creating a /system/etc/applist file in my image using aapt while mounted to my Linux box with this rough script:

#!/bin/bash
cd /home/mike/mofo
echo
ready=$(df | grep system)
if [ "$ready" == "" ]; then
echo System is not mounted
echo
exit
fi
echo
sudo echo "# Apps in this build" > /system/etc/applist
tmp=$(sudo ls -a1 /system/app)
tmplines=$(sudo ls -a1 /system/app | wc -l)
let tmplines=tmplines+1
counter=3
while [ $counter -lt $tmplines ]; do
work=$(echo $tmp | cut -d " " -f $counter)
apkname=$(sudo ls -a1 /system/app/$work/*.apk)
appinfo=$(/home/mike/bin/aapt d badging $apkname | grep 'pack')
packagename=$( echo $appinfo | cut -d "'" -f2)
packagever=$( echo $appinfo | cut -d "'" -f4)
echo $packagename\"$packagever >> /system/etc/applist
let counter=counter+1
done

tmp=$(sudo ls -a1 /system/priv-app)
tmplines=$(sudo ls -a1 /system/priv-app | wc -l)
let tmplines=tmplines+1
counter=3
while [ $counter -lt $tmplines ]; do
work=$(echo $tmp | cut -d " " -f $counter)
apkname=$(sudo ls -a1 /system/priv-app/$work/*.apk)
appinfo=$(/home/mike/bin/aapt d badging $apkname | grep 'pack')
packagename=$( echo $appinfo | cut -d "'" -f2)
packagever=$( echo $appinfo | cut -d "'" -f4)
echo $packagename\"$packagever >> /system/etc/applist
let counter=counter+1
done
echo >> /system/etc/applist

echo
echo Done
echo

exit

Then on the phone, there doesn't seem to be any init.d support but there is an init.qcom.post_boot.sh script that runs late in the boot process and I've tacked the following onto the end of it:

# Hack to clean up apps in data after image upgrade
#
tmp=$(grep "\<updated-package name" /data/system/packages.xml)
tmpline=$(echo "$tmp" | grep -c \>)
let tmpline=tmpline+1
counter=1
while [ $counter -lt $tmpline ]; do
appname=$(echo $tmp | cut -d \> -f $counter | cut -d \" -f2)
poscounter=1
position=empty
datainfo=$(grep "\<package name=\"$appname\"" /data/system/packages.xml)
poscounter=1
until [ "$position" == " version=" ]; do
position=$(echo "$datainfo" | cut -d \" -f $poscounter)
if [ "$position" == " version=" ]; then
let poscounter=poscounter+1
dataversion=$(echo "$datainfo" | cut -d \" -f $poscounter)
fi
let poscounter=poscounter+2
done
sysversion=$( grep "$appname\"" /system/etc/applist | cut -d \" -f2)
if [ "$sysversion" == "" ]; then
sysversion=0
fi
if [ $sysversion -ge $dataversion ] ; then
pm uninstall -k $appname
fi
position=empty
let counter=counter+1
done
#
#End clean up hack

What that does is go through /data/system/packages.xml, find the apps marked as updated, finds the version of the app in /data, compares it to the version in the list made when creating the system image, and if equal or newer uses "pm uninstall -k $appname" to uninstall the older/equal versions in /data. It does this silently but does not save user settings, the app appears to be new when run; it also just fails on play games. I'm also experimenting with

am start -n "com.android.packageinstaller/.UninstallerActivity" -d "package:$apkname"

but this generates a dialog for each app and also fails on play services due to device administrator permissions requiring the user to disable that, etc. etc.

Today, I tried compiling a CM rom reverting the </<= change to that line in the pm source and then putting the CM /system/framework/pm.jar and /system/app/PackageInstaller.apk into the Moto rom; there was no dramatic failure but there was also no clean up performed on the equal versions of apps in /data. At this point, I think the only way to fix this would be find a stock script that runs earlier in the boot process and manipulate the packages.xml file directly but my returns for effort expended are getting pretty slim at this point..

I'm not expecting a resolution from you but you did ask what I was doing so I thought I'd share; thanks for all the stuff you do!