|
23 | 23 | import android.content.pm.ActivityInfo;
|
24 | 24 | import android.content.pm.ApplicationInfo;
|
25 | 25 | import android.content.pm.PackageInfo;
|
26 |
| -import android.content.pm.PackageManager; |
27 | 26 | import android.content.pm.ServiceInfo;
|
28 |
| -import android.content.res.Configuration; |
29 | 27 | import android.content.res.Resources;
|
30 | 28 | import android.os.Build;
|
31 | 29 | import android.os.Bundle;
|
32 | 30 | import android.os.IBinder;
|
33 |
| -import android.support.annotation.Keep; |
34 | 31 | import android.text.TextUtils;
|
| 32 | +import android.util.Log; |
35 | 33 | import android.view.ContextThemeWrapper;
|
36 | 34 |
|
37 | 35 | import com.didi.virtualapk.PluginManager;
|
|
46 | 44 | import java.io.InputStream;
|
47 | 45 | import java.io.OutputStream;
|
48 | 46 | import java.util.Enumeration;
|
49 |
| -import java.util.HashMap; |
50 |
| -import java.util.List; |
51 |
| -import java.util.Locale; |
52 |
| -import java.util.Map; |
53 | 47 | import java.util.zip.ZipEntry;
|
54 | 48 | import java.util.zip.ZipFile;
|
55 | 49 |
|
@@ -186,68 +180,98 @@ public static IBinder getBinder(Bundle bundle, String key) {
|
186 | 180 | return null;
|
187 | 181 | }
|
188 | 182 | }
|
189 |
| - |
190 |
| - public static void copyNativeLib(File apk, Context context, PackageInfo packageInfo, File nativeLibDir) { |
| 183 | + |
| 184 | + public static void copyNativeLib(File apk, Context context, PackageInfo packageInfo, File nativeLibDir) throws Exception { |
| 185 | + long startTime = System.currentTimeMillis(); |
| 186 | + ZipFile zipfile = new ZipFile(apk.getAbsolutePath()); |
| 187 | + |
191 | 188 | try {
|
192 |
| - String cpuArch; |
193 | 189 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
194 |
| - cpuArch = Build.SUPPORTED_ABIS[0]; |
| 190 | + for (String cpuArch : Build.SUPPORTED_ABIS) { |
| 191 | + if (findAndCopyNativeLib(zipfile, context, cpuArch, packageInfo, nativeLibDir)) { |
| 192 | + return; |
| 193 | + } |
| 194 | + } |
| 195 | + |
195 | 196 | } else {
|
196 |
| - cpuArch = Build.CPU_ABI; |
197 |
| - } |
198 |
| - boolean findSo = false; |
199 |
| - |
200 |
| - ZipFile zipfile = new ZipFile(apk.getAbsolutePath()); |
201 |
| - ZipEntry entry; |
202 |
| - Enumeration e = zipfile.entries(); |
203 |
| - while (e.hasMoreElements()) { |
204 |
| - entry = (ZipEntry) e.nextElement(); |
205 |
| - if (entry.isDirectory()) |
206 |
| - continue; |
207 |
| - if(entry.getName().endsWith(".so") && entry.getName().contains("lib/" + cpuArch)){ |
208 |
| - findSo = true; |
209 |
| - break; |
| 197 | + if (findAndCopyNativeLib(zipfile, context, Build.CPU_ABI, packageInfo, nativeLibDir)) { |
| 198 | + return; |
210 | 199 | }
|
211 | 200 | }
|
212 |
| - e = zipfile.entries(); |
213 |
| - while (e.hasMoreElements()) { |
214 |
| - entry = (ZipEntry) e.nextElement(); |
215 |
| - if (entry.isDirectory() || !entry.getName().endsWith(".so")) |
| 201 | + |
| 202 | + findAndCopyNativeLib(zipfile, context, "armeabi", packageInfo, nativeLibDir); |
| 203 | + |
| 204 | + } finally { |
| 205 | + zipfile.close(); |
| 206 | + Log.d("NativeLib", "Done! +" + (System.currentTimeMillis() - startTime) + "ms"); |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + private static boolean findAndCopyNativeLib(ZipFile zipfile, Context context, String cpuArch, PackageInfo packageInfo, File nativeLibDir) throws Exception { |
| 211 | + Log.d("NativeLib", "Try to copy plugin's cup arch: " + cpuArch); |
| 212 | + boolean findLib = false; |
| 213 | + boolean findSo = false; |
| 214 | + byte buffer[] = null; |
| 215 | + String libPrefix = "lib/" + cpuArch + "/"; |
| 216 | + ZipEntry entry; |
| 217 | + Enumeration e = zipfile.entries(); |
| 218 | + |
| 219 | + while (e.hasMoreElements()) { |
| 220 | + entry = (ZipEntry) e.nextElement(); |
| 221 | + String entryName = entry.getName(); |
| 222 | + |
| 223 | + if (entryName.charAt(0) < 'l') { |
| 224 | + continue; |
| 225 | + } |
| 226 | + if (entryName.charAt(0) > 'l') { |
| 227 | + break; |
| 228 | + } |
| 229 | + if (!findLib && !entryName.startsWith("lib/")) { |
| 230 | + continue; |
| 231 | + } |
| 232 | + findLib = true; |
| 233 | + if (!entryName.endsWith(".so") || !entryName.startsWith(libPrefix)) { |
| 234 | + continue; |
| 235 | + } |
| 236 | + |
| 237 | + if (buffer == null) { |
| 238 | + findSo = true; |
| 239 | + Log.d("NativeLib", "Found plugin's cup arch dir: " + cpuArch); |
| 240 | + buffer = new byte[8192]; |
| 241 | + } |
| 242 | + |
| 243 | + String libName = entryName.substring(entryName.lastIndexOf('/') + 1); |
| 244 | + Log.d("NativeLib", "verify so " + libName); |
| 245 | + File libFile = new File(nativeLibDir, libName); |
| 246 | + String key = packageInfo.packageName + "_" + libName; |
| 247 | + if (libFile.exists()) { |
| 248 | + int VersionCode = Settings.getSoVersion(context, key); |
| 249 | + if (VersionCode == packageInfo.versionCode) { |
| 250 | + Log.d("NativeLib", "skip existing so : " + entry.getName()); |
216 | 251 | continue;
|
217 |
| - if((findSo && entry.getName().contains("lib/" + cpuArch)) || (!findSo && entry.getName().contains("lib/armeabi/"))){ |
218 |
| - String[] temp = entry.getName().split("/"); |
219 |
| - String libName = temp[temp.length - 1]; |
220 |
| - System.out.println("verify so " + libName); |
221 |
| - File libFile = new File(nativeLibDir.getAbsolutePath() + File.separator + libName); |
222 |
| - String key = packageInfo.packageName + "_" + libName; |
223 |
| - if (libFile.exists()) { |
224 |
| - int VersionCode = Settings.getSoVersion(context, key); |
225 |
| - if (VersionCode == packageInfo.versionCode) { |
226 |
| - System.out.println("skip existing so : " + entry.getName()); |
227 |
| - continue; |
228 |
| - } |
229 |
| - } |
230 |
| - FileOutputStream fos = new FileOutputStream(libFile); |
231 |
| - System.out.println("copy so " + entry.getName() + " of " + cpuArch); |
232 |
| - copySo(zipfile.getInputStream(entry), fos); |
233 |
| - Settings.setSoVersion(context, key, packageInfo.versionCode); |
234 | 252 | }
|
235 |
| - |
236 | 253 | }
|
237 |
| - |
238 |
| - zipfile.close(); |
239 |
| - } catch (IOException e) { |
240 |
| - e.printStackTrace(); |
| 254 | + FileOutputStream fos = new FileOutputStream(libFile); |
| 255 | + Log.d("NativeLib", "copy so " + entry.getName() + " of " + cpuArch); |
| 256 | + copySo(buffer, zipfile.getInputStream(entry), fos); |
| 257 | + Settings.setSoVersion(context, key, packageInfo.versionCode); |
241 | 258 | }
|
| 259 | + |
| 260 | + if (!findLib) { |
| 261 | + Log.d("NativeLib", "Fast skip all!"); |
| 262 | + return true; |
| 263 | + } |
| 264 | + |
| 265 | + return findSo; |
242 | 266 | }
|
243 |
| - |
244 |
| - private static void copySo(InputStream input, OutputStream output) throws IOException { |
| 267 | + |
| 268 | + private static void copySo(byte[] buffer, InputStream input, OutputStream output) throws IOException { |
245 | 269 | BufferedInputStream bufferedInput = new BufferedInputStream(input);
|
246 | 270 | BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
|
247 | 271 | int count;
|
248 |
| - byte data[] = new byte[8192]; |
249 |
| - while ((count = bufferedInput.read(data, 0, 8192)) != -1) { |
250 |
| - bufferedOutput.write(data, 0, count); |
| 272 | + |
| 273 | + while ((count = bufferedInput.read(buffer)) > 0) { |
| 274 | + bufferedOutput.write(buffer, 0, count); |
251 | 275 | }
|
252 | 276 | bufferedOutput.flush();
|
253 | 277 | bufferedOutput.close();
|
|
0 commit comments