Skip to content

Commit 648e2ae

Browse files
committed
Stamp: v2.1.4
fix: Joystick Fix#3
1 parent eda7087 commit 648e2ae

4 files changed

Lines changed: 175 additions & 79 deletions

File tree

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ android {
99
applicationId "com.github.thepiemonster.hidemocklocation"
1010
minSdk 29
1111
targetSdk 33
12-
versionCode 213
13-
versionName "2.1.3"
12+
versionCode 214
13+
versionName "2.1.4"
1414
}
1515

1616
signingConfigs {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
package com.github.thepiemonster.hidemocklocation;
22

3+
import android.annotation.SuppressLint;
4+
5+
import de.robv.android.xposed.callbacks.XC_LoadPackage;
6+
37
public class Common {
48
public static final String GMS_MOCK_KEY = "mockLocation"; // FusedLocationProviderApi.KEY_MOCK_LOCATION
9+
10+
11+
@SuppressLint("PrivateApi")
12+
public static Class<?> loadClassIfExist(XC_LoadPackage.LoadPackageParam lpparam, String name) {
13+
try {
14+
return lpparam.classLoader.loadClass(name);
15+
} catch (ClassNotFoundException e) {
16+
return null;
17+
}
18+
}
519
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package com.github.thepiemonster.hidemocklocation;
2+
3+
import static com.github.thepiemonster.hidemocklocation.Common.loadClassIfExist;
4+
5+
import android.app.Service;
6+
import android.location.LocationManager;
7+
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.lang.reflect.Method;
10+
import java.util.List;
11+
12+
import de.robv.android.xposed.XC_MethodHook;
13+
import de.robv.android.xposed.XposedBridge;
14+
import de.robv.android.xposed.XposedHelpers;
15+
import de.robv.android.xposed.callbacks.XC_LoadPackage;
16+
17+
public class GPSJoystickFixer {
18+
19+
// makes not kill process. but, joystick app uses for terminate threading.
20+
static boolean fixService(XC_LoadPackage.LoadPackageParam lpparam) {
21+
String packageName = lpparam.packageName;
22+
Class<?> joystick_MapOverlayService = loadClassIfExist(lpparam, packageName + ".service.MapOverlayService");
23+
Class<?> joystick_OverlayService = loadClassIfExist(lpparam, packageName + ".service.OverlayService");
24+
if (joystick_MapOverlayService != null && joystick_OverlayService != null) {
25+
Method joystick_MapOverlayService_onDestroy = XposedHelpers.findMethodExactIfExists(
26+
joystick_MapOverlayService,
27+
"onDestroy"
28+
);
29+
Method joystick_OverlayService_onDestroy = XposedHelpers.findMethodExactIfExists(
30+
joystick_OverlayService,
31+
"onDestroy"
32+
);
33+
if (joystick_MapOverlayService_onDestroy != null) {
34+
XposedBridge.hookMethod(joystick_MapOverlayService_onDestroy, new XC_MethodHook() {
35+
@Override
36+
protected void beforeHookedMethod(MethodHookParam param) {
37+
Service thisObject = (Service) param.thisObject;
38+
Method _internalDestroyMethod = XposedHelpers.findMethodExactIfExists(
39+
thisObject.getClass(),
40+
// 4.3.2
41+
"p"
42+
);
43+
if (_internalDestroyMethod != null) {
44+
try {
45+
_internalDestroyMethod.invoke(thisObject);
46+
param.setResult(null);
47+
} catch (IllegalAccessException | InvocationTargetException e) {
48+
// do nothing.
49+
}
50+
} else {
51+
XposedBridge.log("Failed to call internal destroy method(Joystick@MapOverlayService)");
52+
}
53+
}
54+
});
55+
}
56+
57+
if (joystick_OverlayService_onDestroy != null) {
58+
XposedBridge.hookMethod(joystick_OverlayService_onDestroy, new XC_MethodHook() {
59+
@Override
60+
protected void beforeHookedMethod(MethodHookParam param) {
61+
Service thisObject = (Service) param.thisObject;
62+
Method _internalDestroyMethod = XposedHelpers.findMethodExactIfExists(
63+
thisObject.getClass(),
64+
// 4.3.2
65+
"D"
66+
);
67+
if (_internalDestroyMethod != null) {
68+
try {
69+
_internalDestroyMethod.invoke(thisObject);
70+
param.setResult(null);
71+
} catch (IllegalAccessException | InvocationTargetException e) {
72+
// do nothing.
73+
}
74+
} else {
75+
XposedBridge.log("Failed to call internal destroy method(Joystick2OverlayService)");
76+
}
77+
}
78+
});
79+
}
80+
XposedBridge.log("fixService()");
81+
return true;
82+
}
83+
return false;
84+
}
85+
86+
static boolean fixTestProviderUpdates(XC_LoadPackage.LoadPackageParam lpparam) {
87+
String packageName = lpparam.packageName;
88+
Class<?> joystick_MockLocationManager = loadClassIfExist(lpparam, packageName + ".b.u");
89+
if (joystick_MockLocationManager != null) {
90+
Method updateLocationMethod = XposedHelpers.findMethodExactIfExists(joystick_MockLocationManager,
91+
"a",
92+
double.class, // d
93+
double.class, // d2
94+
double.class, // d3
95+
float.class, // f
96+
boolean.class, // z
97+
float.class, // f2
98+
float.class, // f3
99+
boolean.class // z2
100+
101+
);
102+
Method addTestProviderMethod = XposedHelpers.findMethodExactIfExists(joystick_MockLocationManager,
103+
"b"
104+
);
105+
106+
if (addTestProviderMethod != null) {
107+
XposedBridge.hookMethod(addTestProviderMethod, new XC_MethodHook() {
108+
@Override
109+
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
110+
super.beforeHookedMethod(param);
111+
112+
@SuppressWarnings("unchecked")
113+
List<String> providers = (List<String>) XposedHelpers.getObjectField(param.thisObject, "j");
114+
providers.clear();
115+
providers.add(LocationManager.GPS_PROVIDER);
116+
providers.add(LocationManager.NETWORK_PROVIDER);
117+
}
118+
});
119+
}
120+
if (updateLocationMethod != null) {
121+
XposedBridge.hookMethod(updateLocationMethod, new XC_MethodHook() {
122+
@Override
123+
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
124+
super.beforeHookedMethod(param);
125+
Object o = param.thisObject;
126+
127+
LocationManager locationManager = (LocationManager) XposedHelpers.getObjectField(o, "d");
128+
@SuppressWarnings("unchecked")
129+
List<String> providers = (List<String>) XposedHelpers.getObjectField(o, "j");
130+
131+
try {
132+
for (String next : providers) {
133+
if (!locationManager.isProviderEnabled(next)) {
134+
locationManager.setTestProviderEnabled(next, true);
135+
}
136+
137+
}
138+
} catch (Exception e) {
139+
// removeProviders
140+
XposedHelpers.callMethod(o, "c");
141+
// addProviders
142+
XposedHelpers.callMethod(o, "b");
143+
}
144+
}
145+
});
146+
return true;
147+
}
148+
}
149+
return false;
150+
}
151+
152+
static boolean tryFixJoystickApp(XC_LoadPackage.LoadPackageParam lpparam) {
153+
return fixTestProviderUpdates(lpparam);
154+
}
155+
}

app/src/main/java/com/github/thepiemonster/hidemocklocation/XposedModule.java

Lines changed: 4 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.github.thepiemonster.hidemocklocation;
22

3+
import static com.github.thepiemonster.hidemocklocation.Common.loadClassIfExist;
4+
35
import android.annotation.SuppressLint;
4-
import android.app.Service;
56
import android.location.Location;
67
import android.os.Build;
78
import android.os.Bundle;
89

9-
import java.lang.reflect.InvocationTargetException;
1010
import java.lang.reflect.Method;
1111

1212
import de.robv.android.xposed.IXposedHookLoadPackage;
1313
import de.robv.android.xposed.IXposedHookZygoteInit;
1414
import de.robv.android.xposed.XC_MethodHook;
15-
import de.robv.android.xposed.XC_MethodReplacement;
1615
import de.robv.android.xposed.XposedBridge;
1716
import de.robv.android.xposed.XposedHelpers;
1817
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@@ -23,16 +22,6 @@ public class XposedModule implements IXposedHookZygoteInit, IXposedHookLoadPacka
2322
public XC_MethodHook hideMockProviderHook;
2423
public XC_MethodHook hideMockGooglePlayServicesHook;
2524

26-
27-
@SuppressLint("PrivateApi")
28-
private Class<?> loadClassIfExist(XC_LoadPackage.LoadPackageParam lpparam, String name) {
29-
try {
30-
return lpparam.classLoader.loadClass(name);
31-
} catch (ClassNotFoundException e) {
32-
return null;
33-
}
34-
}
35-
3625
@Override
3726
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
3827
if (lpparam == null) {
@@ -86,70 +75,8 @@ protected void beforeHookedMethod(MethodHookParam param) {
8675
});
8776
}
8877
}
89-
} else {
90-
// GPS Joystick (Samsung devices) bug fix
91-
String packageName = lpparam.packageName;
92-
Class<?> joystick_MapOverlayService = loadClassIfExist(lpparam, packageName + ".service.MapOverlayService");
93-
Class<?> joystick_OverlayService = loadClassIfExist(lpparam, packageName + ".service.OverlayService");
94-
if (joystick_MapOverlayService != null && joystick_OverlayService != null) {
95-
Method joystick_MapOverlayService_onDestroy = XposedHelpers.findMethodExactIfExists(
96-
joystick_MapOverlayService,
97-
"onDestroy"
98-
);
99-
Method joystick_OverlayService_onDestroy = XposedHelpers.findMethodExactIfExists(
100-
joystick_OverlayService,
101-
"onDestroy"
102-
);
103-
if (joystick_MapOverlayService_onDestroy != null) {
104-
XposedBridge.hookMethod(joystick_MapOverlayService_onDestroy, new XC_MethodHook() {
105-
@Override
106-
protected void beforeHookedMethod(MethodHookParam param) {
107-
Service thisObject = (Service) param.thisObject;
108-
Method _internalDestroyMethod = XposedHelpers.findMethodExactIfExists(
109-
thisObject.getClass(),
110-
// 4.3.2
111-
"p"
112-
);
113-
if (_internalDestroyMethod != null) {
114-
try {
115-
_internalDestroyMethod.invoke(thisObject);
116-
param.setResult(null);
117-
} catch (IllegalAccessException | InvocationTargetException e) {
118-
// do nothing.
119-
}
120-
} else {
121-
XposedBridge.log("Failed to call internal destroy method(Joystick@MapOverlayService)");
122-
}
123-
}
124-
});
125-
}
126-
127-
if (joystick_OverlayService_onDestroy != null) {
128-
XposedBridge.hookMethod(joystick_OverlayService_onDestroy, new XC_MethodHook() {
129-
@Override
130-
protected void beforeHookedMethod(MethodHookParam param) {
131-
Service thisObject = (Service) param.thisObject;
132-
Method _internalDestroyMethod = XposedHelpers.findMethodExactIfExists(
133-
thisObject.getClass(),
134-
// 4.3.2
135-
"D"
136-
);
137-
if (_internalDestroyMethod != null) {
138-
try {
139-
_internalDestroyMethod.invoke(thisObject);
140-
param.setResult(null);
141-
} catch (IllegalAccessException | InvocationTargetException e) {
142-
// do nothing.
143-
}
144-
} else {
145-
XposedBridge.log("Failed to call internal destroy method(Joystick2OverlayService)");
146-
}
147-
}
148-
});
149-
}
150-
} else {
151-
handleLoadPackageForApps(lpparam);
152-
}
78+
} else if (!GPSJoystickFixer.tryFixJoystickApp(lpparam)) {
79+
handleLoadPackageForApps(lpparam);
15380
}
15481
}
15582

0 commit comments

Comments
 (0)