11package de.binarynoise.betterBluetoothDeviceSort
22
3- import android.bluetooth.BluetoothAdapter
43import android.bluetooth.BluetoothDevice
4+ import de.binarynoise.logger.Logger.log
5+ import de.binarynoise.reflection.cast
56import de.robv.android.xposed.IXposedHookLoadPackage
67import de.robv.android.xposed.XposedHelpers
78import de.robv.android.xposed.callbacks.XC_LoadPackage
@@ -10,13 +11,36 @@ import de.robv.android.xposed.XC_MethodHook as MethodHook
1011class Hook : IXposedHookLoadPackage {
1112
1213 override fun handleLoadPackage (lpparam : XC_LoadPackage .LoadPackageParam ) {
13- XposedHelpers .findAndHookMethod(BluetoothAdapter ::class .java, " getMostRecentlyConnectedDevices" , object : MethodHook () {
14- override fun afterHookedMethod (param : MethodHookParam ) {
15- with (param) {
16- @Suppress(" UNCHECKED_CAST" ) val unsorted = result as MutableList <BluetoothDevice >
17- unsorted.sortBy { a -> a.alias ? : a.name }
14+
15+ XposedHelpers .findAndHookMethod(
16+ " com.android.bluetooth.btservice.storage.DatabaseManager" , lpparam.classLoader, " getMostRecentlyConnectedDevices" ,
17+ object : MethodHook () {
18+ override fun afterHookedMethod (param : MethodHookParam ) {
19+ log(" called getMostRecentlyConnectedDevices" )
20+ with (param) {
21+ if (throwable != null || result == null ) return
22+ @Suppress(" UNCHECKED_CAST" ) val unsorted = result as MutableList <BluetoothDevice >
23+ log(" ${unsorted.size} devices" )
24+
25+ val mAdapterService = XposedHelpers .getObjectField(param.thisObject, " mAdapterService" )
26+ val mRemoteDevices = XposedHelpers .getObjectField(mAdapterService, " mRemoteDevices" )
27+ val map = unsorted.associateWith { XposedHelpers .callMethod(mRemoteDevices, " getDeviceProperties" , it) }
28+
29+ val mMetadataCache = XposedHelpers .getObjectField(param.thisObject, " mMetadataCache" ).cast<Map <String , * >>()
30+ val (bonded, others) = unsorted.partition { mMetadataCache.containsKey(it.address) }
31+ log(" ${bonded.size} bonded, ${others.size} others" )
32+
33+ val comparator = Comparator .comparing<BluetoothDevice , String >({
34+ val properties = map[it] ? : return @comparing null
35+ (XposedHelpers .getObjectField(properties, " mAlias" ) ? : XposedHelpers .getObjectField(properties, " mName" )).cast<String ?>()
36+ }, Comparator .nullsLast(Comparator .naturalOrder<String >()))
37+
38+ result = bonded.toSortedSet(comparator).toMutableList() + others
39+ }
1840 }
19- }
20- })
41+ },
42+ )
43+
44+ log(" Hooked getMostRecentlyConnectedDevices" )
2145 }
2246}
0 commit comments