Skip to content

Commit 88fa984

Browse files
committed
fix vm incompatible
1 parent 6bebbee commit 88fa984

4 files changed

Lines changed: 120 additions & 23 deletions

File tree

project/Libraries/DroidPlugin/src/com/morgoo/droidplugin/pm/IPluginManagerImpl.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,11 @@ public int installPackage(String filepath, int flags) throws RemoteException {
858858
// Log.e(TAG, "reqFeature name=%s,flags=%s,glesVersion=%s", reqFeature.name, reqFeature.flags, reqFeature.getGlEsVersion());
859859
// }
860860
// }
861-
copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0));
861+
if (copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0)) < 0) {
862+
new File(apkfile).delete();
863+
return PackageManagerCompat.INSTALL_FAILED_NOT_SUPPORT_ABI;
864+
}
865+
862866
dexOpt(mContext, apkfile, parser);
863867
mPluginCache.put(parser.getPackageName(), parser);
864868
mActivityManagerService.onPkgInstalled(mPluginCache, parser, parser.getPackageName());
@@ -895,7 +899,11 @@ public int installPackage(String filepath, int flags) throws RemoteException {
895899
// }
896900
// }
897901

898-
copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0));
902+
if (copyNativeLibs(mContext, apkfile, parser.getApplicationInfo(0)) < 0) {
903+
new File(apkfile).delete();
904+
return PackageManagerCompat.INSTALL_FAILED_NOT_SUPPORT_ABI;
905+
}
906+
899907
dexOpt(mContext, apkfile, parser);
900908
mPluginCache.put(parser.getPackageName(), parser);
901909
mActivityManagerService.onPkgInstalled(mPluginCache, parser, parser.getPackageName());
@@ -978,9 +986,9 @@ private void sendUninstalledBroadcast(String packageName) {
978986
mContext.sendBroadcast(intent);
979987
}
980988

981-
private void copyNativeLibs(Context context, String apkfile, ApplicationInfo applicationInfo) throws Exception {
989+
private int copyNativeLibs(Context context, String apkfile, ApplicationInfo applicationInfo) throws Exception {
982990
String nativeLibraryDir = PluginDirHelper.getPluginNativeLibraryDir(context, applicationInfo.packageName);
983-
NativeLibraryHelperCompat.copyNativeBinaries(new File(apkfile), new File(nativeLibraryDir));
991+
return NativeLibraryHelperCompat.copyNativeBinaries(new File(apkfile), new File(nativeLibraryDir));
984992
}
985993

986994

project/Libraries/DroidPlugin/src/com/morgoo/helper/compat/NativeLibraryHelperCompat.java

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22

33
import android.annotation.TargetApi;
44
import android.os.Build;
5+
6+
import com.morgoo.droidplugin.pm.PluginManager;
57
import com.morgoo.droidplugin.reflect.MethodUtils;
8+
import com.morgoo.helper.Log;
9+
610
import java.io.File;
711
import java.lang.reflect.InvocationTargetException;
12+
import java.util.Enumeration;
13+
import java.util.HashSet;
14+
import java.util.Set;
15+
import java.util.zip.ZipEntry;
16+
import java.util.zip.ZipFile;
817

918
public class NativeLibraryHelperCompat {
1019

20+
private static final String TAG = NativeLibraryHelperCompat.class.getSimpleName();
1121

1222
private static final Class nativeLibraryHelperClass() throws ClassNotFoundException {
1323
return Class.forName("com.android.internal.content.NativeLibraryHelper");
@@ -19,20 +29,19 @@ private static final Class handleClass() throws ClassNotFoundException {
1929

2030
public static final int copyNativeBinaries(File apkFile, File sharedLibraryDir) {
2131

22-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
23-
return copyNativeBinariesAfterM(apkFile, sharedLibraryDir);
32+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
33+
return copyNativeBinariesAfterL(apkFile, sharedLibraryDir);
2434
} else {
25-
return copyNativeBinariesBeforeM(apkFile, sharedLibraryDir);
35+
return copyNativeBinariesBeforeL(apkFile, sharedLibraryDir);
2636
}
2737

2838
}
2939

30-
private static int copyNativeBinariesBeforeM(File apkFile, File sharedLibraryDir) {
40+
private static int copyNativeBinariesBeforeL(File apkFile, File sharedLibraryDir) {
3141
try {
3242
Object[] args = new Object[2];
3343
args[0] = apkFile;
3444
args[1] = sharedLibraryDir;
35-
3645
return (int) MethodUtils.invokeStaticMethod(nativeLibraryHelperClass(), "copyNativeBinariesIfNeededLI", args);
3746
} catch (NoSuchMethodException e) {
3847
e.printStackTrace();
@@ -47,27 +56,44 @@ private static int copyNativeBinariesBeforeM(File apkFile, File sharedLibraryDir
4756
return -1;
4857
}
4958

50-
@TargetApi(Build.VERSION_CODES.M)
51-
private static int copyNativeBinariesAfterM(File apkFile, File sharedLibraryDir) {
52-
59+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
60+
private static int copyNativeBinariesAfterL(File apkFile, File sharedLibraryDir) {
5361
try {
5462
Object handleInstance = MethodUtils.invokeStaticMethod(handleClass(), "create", apkFile);
5563
if (handleInstance == null) {
5664
return -1;
5765
}
66+
5867
String abi = null;
59-
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
60-
int abiIndex = (int) MethodUtils.invokeStaticMethod(nativeLibraryHelperClass(), "findSupportedAbi", handleInstance, Build.SUPPORTED_32_BIT_ABIS);
61-
abi = Build.SUPPORTED_32_BIT_ABIS[abiIndex];
62-
}
6368

64-
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
65-
int abiIndex = (int) MethodUtils.invokeStaticMethod(nativeLibraryHelperClass(), "findSupportedAbi", handleInstance, Build.SUPPORTED_64_BIT_ABIS);
66-
if (abiIndex >= 0) {
67-
abi = Build.SUPPORTED_64_BIT_ABIS[abiIndex];
69+
if (isVM64()) {
70+
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
71+
Set<String> abis = getAbisFromApk(apkFile.getAbsolutePath());
72+
if (abis == null || abis.isEmpty()) {
73+
return 0;
74+
}
75+
int abiIndex = (int) MethodUtils.invokeStaticMethod(nativeLibraryHelperClass(), "findSupportedAbi", handleInstance, Build.SUPPORTED_64_BIT_ABIS);
76+
if (abiIndex >= 0) {
77+
abi = Build.SUPPORTED_64_BIT_ABIS[abiIndex];
78+
}
79+
}
80+
} else {
81+
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
82+
Set<String> abis = getAbisFromApk(apkFile.getAbsolutePath());
83+
if (abis == null || abis.isEmpty()) {
84+
return 0;
85+
}
86+
int abiIndex = (int) MethodUtils.invokeStaticMethod(nativeLibraryHelperClass(), "findSupportedAbi", handleInstance, Build.SUPPORTED_32_BIT_ABIS);
87+
if (abiIndex >= 0) {
88+
abi = Build.SUPPORTED_32_BIT_ABIS[abiIndex];
89+
}
6890
}
6991
}
7092

93+
if (abi == null) {
94+
return -1;
95+
}
96+
7197
Object[] args = new Object[3];
7298
args[0] = handleInstance;
7399
args[1] = sharedLibraryDir;
@@ -85,4 +111,53 @@ private static int copyNativeBinariesAfterM(File apkFile, File sharedLibraryDir)
85111

86112
return -1;
87113
}
114+
115+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
116+
private static boolean isVM64() {
117+
Set<String> supportedAbis = getAbisFromApk(getHostApk());
118+
if (Build.SUPPORTED_64_BIT_ABIS.length == 0) {
119+
return false;
120+
}
121+
122+
if (supportedAbis == null || supportedAbis.isEmpty()) {
123+
return true;
124+
}
125+
126+
for (String supportedAbi : supportedAbis) {
127+
if ("arm64-v8a".endsWith(supportedAbi) || "x86_64".equals(supportedAbi) || "mips64".equals(supportedAbi)) {
128+
return true;
129+
}
130+
}
131+
132+
return false;
133+
}
134+
135+
private static Set<String> getAbisFromApk(String apk) {
136+
try {
137+
ZipFile apkFile = new ZipFile(apk);
138+
Enumeration<? extends ZipEntry> entries = apkFile.entries();
139+
Set<String> supportedAbis = new HashSet<>();
140+
while (entries.hasMoreElements()) {
141+
ZipEntry entry = entries.nextElement();
142+
String name = entry.getName();
143+
if (name.contains("../")) {
144+
continue;
145+
}
146+
if (name.startsWith("lib/") && !entry.isDirectory() && name.endsWith(".so")) {
147+
String supportedAbi = name.substring(name.indexOf("/") + 1, name.lastIndexOf("/"));
148+
supportedAbis.add(supportedAbi);
149+
}
150+
}
151+
Log.d(TAG, "supportedAbis : %s", supportedAbis);
152+
return supportedAbis;
153+
} catch (Exception e) {
154+
Log.e(TAG, "get supportedAbis failure", e);
155+
}
156+
157+
return null;
158+
}
159+
160+
private static String getHostApk() {
161+
return PluginManager.getInstance().getHostContext().getApplicationInfo().sourceDir;
162+
}
88163
}

project/Libraries/DroidPlugin/src/com/morgoo/helper/compat/PackageManagerCompat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ public class PackageManagerCompat {
3333
public static final int INSTALL_FAILED_INVALID_APK = -2;
3434
public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
3535
public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
36-
}
36+
public static final int INSTALL_FAILED_NOT_SUPPORT_ABI = -3;}

project/TestPlugin/src/com/example/TestPlugin/ApkFragment.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@
2626
import android.widget.Toast;
2727

2828
import com.morgoo.droidplugin.pm.PluginManager;
29+
import com.morgoo.helper.compat.PackageManagerCompat;
2930

3031
import java.io.File;
3132
import java.util.ArrayList;
3233
import java.util.List;
3334

35+
import static com.morgoo.helper.compat.PackageManagerCompat.*;
36+
3437
public class ApkFragment extends ListFragment implements ServiceConnection {
3538
private ArrayAdapter<ApkItem> adapter;
3639
final Handler handler = new Handler();
@@ -290,8 +293,19 @@ public void run() {
290293
handler.post(new Runnable() {
291294
@Override
292295
public void run() {
293-
Toast.makeText(getActivity(), re == PluginManager.INSTALL_FAILED_NO_REQUESTEDPERMISSION ? "安装失败,文件请求的权限太多" : "安装完成", Toast.LENGTH_SHORT).show();
294-
adapter.notifyDataSetChanged();
296+
switch (re) {
297+
case PluginManager.INSTALL_FAILED_NO_REQUESTEDPERMISSION:
298+
Toast.makeText(getActivity(), "安装失败,文件请求的权限太多", Toast.LENGTH_SHORT).show();
299+
break;
300+
case INSTALL_FAILED_NOT_SUPPORT_ABI:
301+
Toast.makeText(getActivity(), "宿主不支持插件的abi环境,可能宿主运行时为64位,但插件只支持32位", Toast.LENGTH_SHORT).show();
302+
break;
303+
case INSTALL_SUCCEEDED:
304+
Toast.makeText(getActivity(), "安装完成", Toast.LENGTH_SHORT).show();
305+
adapter.notifyDataSetChanged();
306+
break;
307+
}
308+
295309
}
296310
});
297311
} catch (RemoteException e) {

0 commit comments

Comments
 (0)