Ievgenii Nazaruk deserves a lot of the credit for figuring out most of this (http://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/). I am simply updating his instructions for a Nexus 7 (2013) tablet running Android 4.3, and for the latest version of the ADT Plugin for Eclipse.
To get started:
Make sure that you have Eclipse with the latest ADT Plugin installed as well as the latest Android SDK. At the time of this writing, the latest Android SDK version is 22.3.
Tip for Mac users: Homebrew has a package for the Android SDK that can be installed with:
brew install android-sdk
In Eclipse, open the Android SDK Manager and install the Android 4.3 (API 18) SDK Platform. Also install the Android Support Library under "Extras".
- Attach the Android 4.3 device to your computer using the USB cable and set up USB debugging if you have not already done so. Verify that
adb
sees your device by running:
adb devices
- Install
smali
and baksmali
. At the time of this writing, the current version of smali
/baksmali
is 2.0.2.
- Install
dex2jar
. Homebrew users: brew install dex2jar
- Install
bbe
. Homebrew users: brew install bbe
In what follows, I use $ANDROID_HOME
to refer to the location of the Android SDK.
Accessing Android's internal/hidden APIs
The android.jar
in $ANDROID_HOME/platforms/android-18/
is stripped of all internal Android classes and hidden APIs, some of which are needed to build the Browser. We will be following along Ievgenii Nazaruk's instructions to create a custom Android SDK platform which contains all of the internal/hidden APIs.
Create a temporary folder and cd
into it.
Create a framework
folder within the temporary folder and copy bouncycastle.odex
, core-junit.odex
, core.odex
, ext.odex
, and framework.odex
from your device's /system/framework
folder:
mkdir framework && cd framework
adb pull /system/framework/bouncycastle.odex
adb pull /system/framework/core-junit.odex
adb pull /system/framework/core.odex
adb pull /system/framework/ext.odex
adb pull /system/framework/framework.odex
cd ..
Use baksmali
to extract core.odex
, ext.odex
, and framework.odex
:
baksmali -a 18 -x framework/core.odex -d framework
baksmali -a 18 -x framework/ext.odex -d framework
baksmali -a 18 -x framework/framework.odex -d framework
These commands will create an out/
folder within the temporary folder.
We will use smali
to create a DEX file, but first we need to delete some of the generated SMALI files in the out/
directory because there are too many for smali to process ("UNEXPECTED TOP-LEVEL EXCEPTION: org.jf.util.ExceptionWithContext: Unsigned short value out of range"):
rm -rf out/java out/javax/net out/javax/security out/javax/sql out/javax/xml
smali -a 18 -o android.dex out
Use dex2jar
to convert android.dex
to a JAR:
d2j-dex2jar android.dex
Now we want to create our custom Android 4.3 platform's android.jar
. To do this, we'll need some files from the real Android 4.3 platform's android.jar
:
mkdir android_jar && cd android_jar
unzip $ANDROID_HOME/platforms/android-18/android.jar resources.arsc
unzip $ANDROID_HOME/platforms/android-18/android.jar 'com/google/common/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'java/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'javax/net/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'javax/security/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'javax/sql/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'javax/xml/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'org/apache/http/*'
unzip $ANDROID_HOME/platforms/android-18/android.jar 'res/*'
unzip ../android-dex2jar.jar
To create our custom Android 4.3 platform, we start by copying $ANDROID_HOME/platforms/android-18
:
cp -R $ANDROID_HOME/platforms/android-18 $ANDROID_HOME/platforms/android-18-custom
unlink $ANDROID_HOME/platforms/android-18-custom/android.jar
jar cf $ANDROID_HOME/platforms/android-18-custom/android.jar *
Open $ANDROID_HOME/platforms/android-18-custom/build.prop
in a text editor. You need to change two lines:
ro.build.version.sdk=-18
ro.build.version.release=4.3-custom
The reason for using ro.build.version.sdk = -18 is because this must be a number and it must be different for each Android SDK platform.
Checking out the source code
Clone the git repo for the Browser source code on GitHub:
git clone https://github.com/android/platform_packages_apps_browser.git
There are several "android-4.3" tags, but all refer to the same commit: 84e92b9a43097a1252d7311204d2c4ce00c5a78a
Create a local branch from that commit:
git checkout -b Nexus_7_2013 tags/android-4.3.1_r1
Import the project in Eclipse. See How to import existing Android project into Eclipse?
You'll need to add three missing files, add a <uses-sdk> tag to AndroidManifest.xml
, rename the authority URLs of the Browser's ContentProviders, and comment out references to com.google.common.annotations.VisibleForTesting
. Alternatively, I have a git repo set up which contains these changes: https://github.com/dtrebbien/platform_packages_apps_browser/tree/Nexus_7_2013
Add the v4 and v13 Android Support Libraries to the build path. See http://developer.android.com/tools/support-library/setup.html and Updated SDK version, getting ClassNotFoundException: android.support.v4.view.ViewPager
Switch to the custom Android 4.3 platform. Right click on the project in Eclipse and select Properties. Select Android on the left. Check the box next to the "Android 4.3" target having API level -18. That's our custom Android SDK platform that we created in the previous section.
Removing ADT Plugin's "Forbidden: com/android/internal/**" restriction
I basically followed Ievgenii Nazaruk's instructions in Part 4, but I found that the modified AndroidClasspathContainerInitializer.class
file would not work if I added an 'x'. Instead, I changed the 'i' of "internal/**" to a capital 'I'. I also used bbe
instead of Notepad++:
unzip com.android.ide.eclipse.adt_*.jar
mv com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.class com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.class.bak
bbe -e 's~internal/**~Internal/**~' -o com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.class com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.class.bak
jar uf com.android.ide.eclipse.adt_*.jar com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.class
Running
Now for the fun part. Clean the project first, and then Run As -> Android Application. You should now have a fully-functional stock Browser app on your Android 4.3 device!