Bluetooth application in AOSP hardcodes strange constraint in form of whitelist of MIME types that are allowed to be received. Also LineageOS seems to have that code compiled for some reason. There is no other way to allow any file transfer than to make your own Bluetooth apk and install it. In this tutorial I will show how to recompile APK and install it in system.
Before I start I have to warn anybody trying to follow the tutorial: THERE IS NO WARRANTY THAT THIS METHOD WILL WORK, I am not responsible for bootloops, broken Bluetooth or any other harm made to your device. You, and only you are responsible for your device, so don’t do it, if you don’t know what you’re doing!
Preparing sources
Unfortunately, there is no easy way to compile just the Bluetooth app. To be able to make it, you have to have full copy of Android sources. For me it weighted 75 GiB overall, so be prepared for a lot of data and make sure you have broadband internet connection. Otherwise it may eat all mobile packet, you have!
Because I’m doing this for LineageOS, I am cloning LOS main repository. In theory this should apply to any other ROM, including AOSP. What is important is to have default.xml file in repo’s root, like in LOS. This way, you can tell it is the right repo. I’m checking out branch for LOS 16.0. Depth option could be used to limit required space a bit. However I haven’t tested how much you can earn by using it.
When ready, create new directory and inside it, execute following command:
repo init -u git://github.com/LineageOS/android.git -b lineage-16.0 --depth=2
It should prepare your repository for download. Cloning is started by running:
repo sync
This will take quite a while, because this is where all the download takes place and by the end, you should have several gigabytes of Android sources.
Patching Bluetooth app
Bluetooth app is located in directory packages/apps/Bluetooth
.
Here, you could go on of the two ways: you can patch the sources yourself or checkout my modified Bluetooth repository. I will show at first what is required to do it the hard way. If you just want it ready, skip to the next section.
The condition, which enforces the whitelist mechanism is in file src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
. It looks more or less like that:
262 // Reject anything outside the "whitelist" plus unspecified MIME Types. 263 if (mimeType == null || (!isWhitelisted && !Constants.mimeTypeMatches(mimeType, 264 Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))) { 265 if (D) { 266 Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer"); 267 } 268 return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE; 269 }
This can be safely commented out or removed. And that’s it. Easy.
Checking out Bluetooth repository
At first, make sure you are in packages/apps/Bluetooth
directory of android sources root. Then execute following command to checkout my repository, instead of default:
git fetch git@github.com:v3l0c1r4pt0r/android_packages_apps_Bluetooth.git lineage-16.0 && git checkout FETCH_HEAD
And you’re ready.
Building only single app
Despite having all the Android sources, I did not want to compile it all. It would take ages to complete. Instead, only single APK file can be generated. To do it, at first environment must be prepared (provided you are in repo root directory):
. build/envsetup.sh
Then get into Bluetooth repository:
cd packages/apps/Bluetooth
And build with:
mma
This is going to compile APK with all its dependencies. There exists a command to make only this project (mm
), but in my case it did not work. When finished, build system should print location of Bluetooth.apk. It should be out/target/product/generic/system/app/Bluetooth/Bluetooth.apk
. You also gonna need JNI library, as it is bundled together with APK itself. It can be found at out/target/product/generic/system/lib/libbluetooth_jni.so
.
Installation
You can push these two files, as usual with adb to some location, where shell user can write, like:
adb push out/target/product/generic/system/app/Bluetooth/Bluetooth.apk /storage/emulated/0/Bluetooth.apk adb push out/target/product/generic/system/lib/libbluetooth_jni.so /storage/emulated/0/libbluetooth_jni.so
Then, be sure to backup old APK and JNI, in case something goes wrong. You can ensure your directory structure is same as mine at the moment:
/system/app/Bluetooth ├── Bluetooth.apk └── lib └── arm └── libbluetooth_jni.so
If so, just remove it and reboot the device:
rm -fr /system/app/Bluetooth
After reboot, Bluetooth functionality should disappear. Don’t worry, it should show up again soon.
If app is really not there (check app list too), you can recreate the structure, you just removed:
mkdir -p /system/app/Bluetooth/lib/arm cp Bluetooth.apk /system/app/Bluetooth/ cp libbluetooth_jni.so /system/app/Bluetooth/lib/arm/ chmod +r /system/app/Bluetooth/ /system/app/Bluetooth/lib /system/app/Bluetooth/lib/arm /system/app/Bluetooth/lib/arm/libbluetooth_jni.so
Reboot system again and if everything went fine, Bluetooth should reappear on the app list.
DO NOT TURN IT ON YET!
By doing this, you would crash the app, or actually worse – the app would get into crash loop. It is crashing till it is fixed.
Before turning it on, it has to be given Contacts and Internal memory permissions. After that turn it on and try receiving some file that before was forbidden.
Final notes
My Bluetooth is not working as well, as before the hacking. I noticed that it is not appearing on the status bar anymore and there are some issues with listing nearby devices. However, I am not using it very extensively, so probably will ignore these problems. If you think it is too risky for you do not do it and find ROM on XDA-Developers that matches your needs.
Edit: it turned out that device detection is issue only with my other phone, so is likely unrelated and missing Bluetooth is “feature” of Android Pie. So the operation in fact was full success.