Skip to content

Commit 5cf316c

Browse files
committed
Remove unused code, debug xposed hot reload
1 parent 821340b commit 5cf316c

File tree

1 file changed

+5
-183
lines changed

1 file changed

+5
-183
lines changed
Lines changed: 5 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
package com.surcumference.fingerprint.xposed.loader;
22

33
import android.content.Context;
4-
import android.content.pm.ApplicationInfo;
5-
import android.content.pm.PackageManager;
6-
import android.database.Cursor;
7-
import android.net.Uri;
84

9-
import com.surcumference.fingerprint.BuildConfig;
10-
import com.surcumference.fingerprint.util.ReflectionUtils;
11-
import com.surcumference.fingerprint.util.log.L;
12-
13-
import java.io.File;
14-
import java.io.IOException;
15-
import java.lang.reflect.Field;
165
import java.lang.reflect.InvocationTargetException;
176
import java.lang.reflect.Method;
18-
import java.util.ArrayList;
19-
import java.util.Enumeration;
207
import java.util.HashMap;
21-
import java.util.List;
228
import java.util.Map;
239

24-
import dalvik.system.BaseDexClassLoader;
25-
import dalvik.system.DexFile;
2610
import de.robv.android.xposed.callbacks.XC_LoadPackage;
2711

2812
/**
@@ -31,160 +15,21 @@
3115

3216
public class XposedPluginLoader {
3317

34-
//TODO 受Xposed機制影響 這玩意好像是廢的, 待檢查
3518
private static Map<Class, Object> sPluginCache = new HashMap<>();
3619

3720
public static void load(Class pluginClz, Context context, XC_LoadPackage.LoadPackageParam lpparam) throws Exception {
3821
Object pluginObj;
39-
if (BuildConfig.DEBUG) {
40-
pluginObj = loadFromDex(context, pluginClz);
41-
} else {
42-
if ((pluginObj = sPluginCache.get(pluginClz)) == null) {
43-
synchronized (pluginClz) {
44-
if ((pluginObj = sPluginCache.get(pluginClz)) == null) {
45-
pluginObj = loadFromLocal(pluginClz);
46-
sPluginCache.put(pluginClz, pluginObj);
47-
}
22+
if ((pluginObj = sPluginCache.get(pluginClz)) == null) {
23+
synchronized (pluginClz) {
24+
if ((pluginObj = sPluginCache.get(pluginClz)) == null) {
25+
pluginObj = loadFromLocal(pluginClz);
26+
sPluginCache.put(pluginClz, pluginObj);
4827
}
4928
}
5029
}
5130
callPluginMain(pluginObj, context, lpparam);
5231
}
5332

54-
private static Object loadFromDex(Context context, Class pluginClz) throws Exception {
55-
File apkFile = getModuleApkFile(context);
56-
File odexDir = context.getCacheDir();
57-
ClassLoader xposedClassLoader = XposedPluginLoader.class.getClassLoader();
58-
hijackDexElements(xposedClassLoader, apkFile, odexDir);
59-
Method findClzMethod = BaseDexClassLoader.class.getDeclaredMethod("findClass", String.class);
60-
findClzMethod.setAccessible(true);
61-
Class<?> clz = (Class<?>) findClzMethod.invoke(xposedClassLoader, pluginClz.getName());
62-
return clz.newInstance();
63-
}
64-
65-
private static File getModuleApkFile(Context context) {
66-
try {
67-
ApplicationInfo info = context.getApplicationContext().getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0);
68-
return new File(info.sourceDir);
69-
} catch (PackageManager.NameNotFoundException e) {
70-
L.e(e);
71-
}
72-
return new File("/data/local/tmp/" + BuildConfig.APPLICATION_ID + ".apk");
73-
}
74-
75-
public static final String COLUMN_KEY = "key";
76-
public static final String COLUMN_TYPE = "type";
77-
public static final String COLUMN_VALUE = "value";
78-
79-
private static Map<String, Object> queryAll(Uri baseUri, Context context) {
80-
Uri uri = baseUri.buildUpon().appendPath("").build();
81-
String[] columns = {COLUMN_KEY, COLUMN_TYPE, COLUMN_VALUE};
82-
Cursor cursor = query(context, uri, columns);
83-
try {
84-
HashMap<String, Object> map = new HashMap<String, Object>();
85-
if (cursor == null) {
86-
return map;
87-
}
88-
while (cursor.moveToNext()) {
89-
String name = cursor.getString(0);
90-
map.put(name, getValue(cursor, 1, 2));
91-
}
92-
return map;
93-
} finally {
94-
if (cursor != null) {
95-
cursor.close();
96-
}
97-
}
98-
}
99-
100-
private static Object getValue(Cursor cursor, int typeCol, int valueCol) {
101-
int expectedType = cursor.getInt(typeCol);
102-
switch (expectedType) {
103-
case RemoteContract.TYPE_STRING:
104-
return cursor.getString(valueCol);
105-
case RemoteContract.TYPE_STRING_SET:
106-
return cursor.getString(valueCol);
107-
case RemoteContract.TYPE_INT:
108-
return cursor.getInt(valueCol);
109-
case RemoteContract.TYPE_LONG:
110-
return cursor.getLong(valueCol);
111-
case RemoteContract.TYPE_FLOAT:
112-
return cursor.getFloat(valueCol);
113-
case RemoteContract.TYPE_BOOLEAN:
114-
return cursor.getInt(valueCol) != 0;
115-
default:
116-
throw new AssertionError("Invalid expected type: " + expectedType);
117-
}
118-
}
119-
public static class RemoteContract {
120-
public static final String COLUMN_KEY = "key";
121-
public static final String COLUMN_TYPE = "type";
122-
public static final String COLUMN_VALUE = "value";
123-
public static final String[] COLUMN_ALL = {
124-
RemoteContract.COLUMN_KEY,
125-
RemoteContract.COLUMN_TYPE,
126-
RemoteContract.COLUMN_VALUE
127-
};
128-
129-
public static final int TYPE_NULL = 0;
130-
public static final int TYPE_STRING = 1;
131-
public static final int TYPE_STRING_SET = 2;
132-
public static final int TYPE_INT = 3;
133-
public static final int TYPE_LONG = 4;
134-
public static final int TYPE_FLOAT = 5;
135-
public static final int TYPE_BOOLEAN = 6;
136-
}
137-
138-
139-
140-
private static Cursor query(Context context, Uri uri, String[] columns) {
141-
Cursor cursor = null;
142-
try {
143-
cursor = context.getContentResolver().query(uri, columns, null, null, null);
144-
} catch (Exception e) {
145-
L.e(e);
146-
}
147-
return cursor;
148-
}
149-
private static void hijackDexElements(ClassLoader classLoader, File apkFile, File odexFile) {
150-
try {
151-
Field pathListField = BaseDexClassLoader.class.getDeclaredField("pathList");
152-
pathListField.setAccessible(true);
153-
Object pathList = pathListField.get(classLoader);
154-
Class DexPathListClass = pathList.getClass();
155-
Field dexElementsField = DexPathListClass.getDeclaredField("dexElements");
156-
dexElementsField.setAccessible(true);
157-
Object[] dexElements = (Object[])dexElementsField.get(pathList);
158-
for (Object dexElement : dexElements) {
159-
L.d("dexElement", dexElement);
160-
}
161-
ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();
162-
ArrayList<File> apkFileList = new ArrayList<>();
163-
apkFileList.add(apkFile);
164-
Object[] apkDexElements = makePathElements(pathList, apkFileList, odexFile, suppressedExceptions);
165-
if (suppressedExceptions.size() > 0) {
166-
for (IOException e : suppressedExceptions) {
167-
L.e("Exception in makePathElements", e);
168-
}
169-
}
170-
dexElementsField.set(pathList, apkDexElements);
171-
} catch (Exception e){
172-
L.e(e);
173-
}
174-
}
175-
176-
private static Object[] makePathElements(
177-
Object dexPathList, ArrayList<File> files, File optimizedDirectory,
178-
ArrayList<IOException> suppressedExceptions)
179-
throws IllegalAccessException, InvocationTargetException,
180-
NoSuchMethodException {
181-
Method makeDexElements =
182-
ReflectionUtils.findMethod(dexPathList, "makePathElements", List.class, File.class,
183-
List.class);
184-
return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory,
185-
suppressedExceptions);
186-
}
187-
18833
private static Object loadFromLocal(Class pluginClz) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
18934
return pluginClz.newInstance();
19035
}
@@ -194,27 +39,4 @@ private static void callPluginMain(Object pluginObj, Context context, XC_LoadPac
19439
method.invoke(pluginObj, context, lpparam);
19540
}
19641

197-
private static boolean forceClassLoaderReloadClasses(ClassLoader classLoader, String packageNameStartWith, String apkPath) {
198-
try {
199-
Method findClzMethod = BaseDexClassLoader.class.getDeclaredMethod("findClass", String.class);
200-
findClzMethod.setAccessible(true);
201-
packageNameStartWith = packageNameStartWith + ".";
202-
DexFile dexFile = new DexFile(apkPath);
203-
Enumeration<String> classNames = dexFile.entries();
204-
while (classNames.hasMoreElements()) {
205-
String className = classNames.nextElement();
206-
if (className.startsWith(packageNameStartWith)) {
207-
try {
208-
findClzMethod.invoke(classLoader, className);
209-
} catch (Exception e) {
210-
L.d(e);
211-
}
212-
}
213-
}
214-
return true;
215-
} catch (Exception e) {
216-
L.e(e);
217-
}
218-
return false;
219-
}
22042
}

0 commit comments

Comments
 (0)