Tuesday, January 17, 2012
Porting TouchWiz Apps for CM7
So hey, I'm Tortel. Recently, I've taken some time to port some of my favorite stock apps to CM7. In that time, I came up with a pretty decent process to remove all the TouchWiz dependencies from stock apps, and I would like to share what I have done. Check the thread on XDA for some downloads.
Here's the basic steps I took for removing the TouchWiz dependencies from the Memo, Calendar, and Task Manager apps
1. De-compile the app
I used apktool for this, use whatever you want
2. Remove the library dependence from the AndroidManifest.xml
The line looks like this:
<uses-library android:name="touchwiz" />
With that removed, it will install correctly. Might not work yet, but it will install.
Something else to look out for is alsong the lines of ‘com.device.samsung’
3. De-compile both the twframework.jar and twframework-res.apk files.
I used apktool again for this. We need the code for the stupidly re-written widgets, resources, and other shit.
4. Copy the twframework code into the app source.
With apktool, the directories to copy are in ‘twframework.jar.out/smali/’
Copy that entire directory tree into the app your de-TWing. Some directories will overlap, that’s normal.
The app your working on now contains both its own code, and all the needed TouchWiz code. There’s a small chance it might work if you recompile it now, but it probably also needs resources.
5. Update the resources
a. Add the needed files/parts
I found its easiest to search for any ‘@touchwiz:’ parts in any xml file under res/.
Next, you will need to merge everything under /res/ from the twframework-res.apk.
Copy over anything that doesn’t already exist. Files under /res/values/ (Except public.xml) will need to be merged, meaning insert all the values from the framework into the app, before the closing tag (Keep the XML valid). If your missing any resources, re-compiling the APK will fail and let you know vaguely what you need.
b. Remove the touchwiz references
Replace every occurrence of ‘@touchwiz:’ with just an ‘@’
In the Memo.apk, there were lots of references to ‘@touchwiz:color__’. find and sed are helpful
Don’t forget to remove the colon!
There are some calls to IDs in the 0x20 range, this is an issue because as far as I know, the 0x20 range can only be provided by the system somehow. For the Calendar app, I had to remove setIcon calls in a few activities to prevent ResourceNotFound exceptions.
If you remove them, then some things like images might not work. I also found that just removing them can cause random NullPointer errors.
Note: While working on the Task Manager, it became more complex. I had to update the old 0x20 references to the references within the new package.
After the resources are added, decompile it again, so the added resources show up in the /res/values/public.xml
Search for the old 0x20 value, and update it to the new value. If you include the /smali/touchwiz/ directory, then you can just search for the hex value and you will get the name of it from the TW R.smali files, and you can find the updated hex value in the /res/value/public.xml file
I used apktool again.
7. Sign the apk
Its a system app, so it will need one of two possible keys: The CM testkey, or the CM platform key, depending on its permissions.
These keys are found in ~/android/system/build/target/product/security/ as testkey.pk8 and testkey.x509.pem (Or platform)
To sign using these files, you need SignAPK (http://code.google.com/p/signapk/)
Usage: signapk testkey.x509.pem testkey.pk8 original.apk signed.apk
The Calendar and provider needed the testkey signature, but the Task Manager needed the platform signature. It depends on the permissions of the app. Check the log for any permission errors, and google them. Most apps will probably only need the testkey signature.
adb push /system/app/ ftw!
9. Run it, and have logcat open
Check for any exceptions, fix whats needed, and re-test.
Most likely, you’ll run into ResourceNotFound exceptions, and maybe NullPointer exceptions. This is the most fun part.
For ResourceNotFound, I grepped the source for the hex value. Then checked for the new value, and replaced all occurrences. (See 5b)
NullPointer exceptions seem to be from findResource calls. Check the smali for the class where the error occurs, and replace any 0x20x hex values with the updated value.
Keep testing until it actually works. Make sure you check all parts of the app, and the context menus. Samsung’s code isn’t the cleanest, so there are fun surprises hiding everywhere.
Once its running
Don’t forget to zipalign the final working apk, after its signed. Then it should be all set.