Skip to content

Commit 5706ef2

Browse files
committed
optimize dex opt process, add more failure point check
1 parent 1fecaf2 commit 5706ef2

18 files changed

+764
-283
lines changed

amigo-lib/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/build
2+
/.externalNativeBuild

amigo-lib/CMakeLists.txt

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Sets the minimum version of CMake required to build the native
2+
# library. You should either keep the default value or only pass a
3+
# value of 3.4.0 or lower.
4+
5+
cmake_minimum_required(VERSION 3.4.1)
6+
7+
# Creates and names a library, sets it as either STATIC
8+
# or SHARED, and provides the relative paths to its source code.
9+
# You can define multiple libraries, and CMake builds it for you.
10+
# Gradle automatically packages shared libraries with your APK.
11+
12+
add_library( # Sets the name of the library.
13+
symbolic-link
14+
15+
# Sets the library as a shared library.
16+
SHARED
17+
18+
# Provides a relative path to your source file(s).
19+
# Associated headers in the same location as their source
20+
# file are automatically included.
21+
src/main/cpp/SymbolicLinkUtil.cpp)
22+
23+
# Searches for a specified prebuilt library and stores the path as a
24+
# variable. Because system libraries are included in the search path by
25+
# default, you only need to specify the name of the public NDK library
26+
# you want to add. CMake verifies that the library exists before
27+
# completing its build.
28+
29+
find_library( # Sets the name of the path variable.
30+
log-lib
31+
32+
# Specifies the name of the NDK library that
33+
# you want CMake to locate.
34+
log )
35+
36+
# Specifies libraries CMake should link to your target library. You
37+
# can link multiple libraries, such as libraries you define in the
38+
# build script, prebuilt third-party libraries, or system libraries.
39+
40+
target_link_libraries( # Specifies the target library.
41+
symbolic-link
42+
43+
# Links the target library to the log library
44+
# included in the NDK.
45+
$\{log-lib} )

amigo-lib/build.gradle

+16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,23 @@ android {
1212
versionCode 1
1313
versionName "1.0"
1414
consumerProguardFiles 'proguard-rules.txt'
15+
externalNativeBuild {
16+
cmake {
17+
cppFlags "-std=c++11"
18+
}
19+
}
20+
}
21+
22+
externalNativeBuild {
23+
cmake {
24+
path "CMakeLists.txt"
25+
}
26+
}
27+
28+
lintOptions {
29+
abortOnError false
1530
}
31+
1632
}
1733

1834
dependencies {

amigo-lib/src/main/aidl/android/app/IAmigoService.aidl

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// Created by wwm on 3/10/17.
3+
//
4+
5+
#include <unistd.h>
6+
#include <stdio.h>
7+
#include <errno.h>
8+
#include "SymbolicLinkUtil.h"
9+
10+
jint throwException(JNIEnv *env, const char *message) {
11+
jclass exClass;
12+
const char *className = "java/io/IOException";
13+
exClass = env->FindClass(className);
14+
15+
if(!exClass) {
16+
return -1; // ignore
17+
}
18+
19+
return env->ThrowNew(exClass, message);
20+
}
21+
22+
23+
JNIEXPORT jint JNICALL Java_me_ele_amigo_utils_SymbolicLinkUtil_makeSymbolicLink
24+
(JNIEnv *env, jclass clazz, jstring linkPath, jstring targetFilePath) {
25+
const char *inputFilePathC = env->GetStringUTFChars(targetFilePath, 0);
26+
const char *inputSymLinkPathC = env->GetStringUTFChars(linkPath, 0);
27+
28+
int result = symlink(inputFilePathC, inputSymLinkPathC);
29+
30+
//release resources when done
31+
env->ReleaseStringUTFChars(targetFilePath, inputFilePathC);
32+
env->ReleaseStringUTFChars(linkPath, inputSymLinkPathC);
33+
34+
if (result == -1) {
35+
char errorStr[100];
36+
sprintf(errorStr, "failed to create link, errno=%d", errno);
37+
throwException(env, errorStr);
38+
}
39+
40+
return result;
41+
}

amigo-lib/src/main/cpp/SymbolicLinkUtil.h

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amigo-lib/src/main/java/me/ele/amigo/Amigo.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@
66
import android.content.pm.ApplicationInfo;
77
import android.content.pm.PackageInfo;
88
import android.os.Handler;
9-
import android.os.SystemClock;
109
import android.text.TextUtils;
1110
import android.util.Log;
12-
1311
import java.io.File;
1412
import java.lang.ref.WeakReference;
1513
import java.lang.reflect.Field;
1614
import java.util.Map;
17-
1815
import me.ele.amigo.exceptions.LoadPatchApkException;
1916
import me.ele.amigo.hook.HookFactory;
2017
import me.ele.amigo.reflect.FieldUtils;
@@ -399,7 +396,7 @@ public static void workLaterWithoutCheckingSignature(Context context, File patch
399396
}
400397

401398
public interface WorkLaterCallback {
402-
void onPatchApkReleased();
399+
void onPatchApkReleased(boolean success);
403400
}
404401

405402
private static void workLater(Context context, File patchFile, boolean checkSignature,

amigo-lib/src/main/java/me/ele/amigo/AmigoClassLoader.java

+28-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package me.ele.amigo;
22

33
import android.content.Context;
4+
import android.os.Build;
45
import android.util.Log;
56

67
import java.io.File;
@@ -11,7 +12,6 @@
1112

1213
import dalvik.system.DexClassLoader;
1314

14-
1515
public class AmigoClassLoader extends DexClassLoader {
1616
private static final String TAG = AmigoClassLoader.class.getName();
1717

@@ -38,6 +38,33 @@ public static AmigoClassLoader newInstance(Context context, String checksum) {
3838
AmigoClassLoader.class.getClassLoader().getParent());
3939
}
4040

41+
private static String getLibraryPath(Context context, String checksum) {
42+
return AmigoDirs.getInstance(context).libDir(checksum).getAbsolutePath();
43+
}
44+
45+
private static String joinPath(File folder) {
46+
StringBuilder path = new StringBuilder();
47+
File[] libFiles = folder.listFiles();
48+
if (libFiles == null || libFiles.length == 0) {
49+
return null;
50+
}
51+
52+
for (File libFile : libFiles) {
53+
path.append(File.pathSeparatorChar);
54+
path.append(libFile.getAbsolutePath());
55+
}
56+
return path.toString();
57+
}
58+
59+
private static String getDexPath(Context context, String checksum) {
60+
if (Build.VERSION.SDK_INT >= 21) {
61+
return PatchApks.getInstance(context).patchPath(checksum);
62+
}
63+
64+
String dexPath = joinPath(AmigoDirs.getInstance(context).dexDir(checksum));
65+
return dexPath != null ? dexPath : PatchApks.getInstance(context).patchPath(checksum);
66+
}
67+
4168
@Override
4269
protected URL findResource(String name) {
4370
if ((zipFile == null) || (zipFile.getEntry(name) == null)) {
@@ -71,32 +98,4 @@ public Class<?> loadClass(String name) throws ClassNotFoundException {
7198
return AmigoClassLoader.class.getClassLoader().loadClass(name);
7299
}
73100
}
74-
75-
private static String getLibraryPath(Context context, String checksum) {
76-
return AmigoDirs.getInstance(context).libDir(checksum).getAbsolutePath();
77-
}
78-
79-
private static String joinPath(File folder) {
80-
StringBuilder path = new StringBuilder();
81-
File[] libFiles = folder.listFiles();
82-
if (libFiles == null || libFiles.length == 0) {
83-
return null;
84-
}
85-
86-
for (File libFile : libFiles) {
87-
path.append(File.pathSeparatorChar);
88-
path.append(libFile.getAbsolutePath());
89-
}
90-
return path.toString();
91-
}
92-
93-
private static String getDexPath(Context context, String checksum) {
94-
String dexPath = joinPath(AmigoDirs.getInstance(context).dexDir(checksum));
95-
if (dexPath == null) {
96-
throw new RuntimeException("Amigo: no patch dex available for checksum[" + checksum +
97-
"]");
98-
}
99-
return dexPath;
100-
}
101-
102101
}

amigo-lib/src/main/java/me/ele/amigo/AmigoDirs.java

+25-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@
22

33
import android.content.Context;
44
import android.content.pm.ApplicationInfo;
5+
import android.os.Build;
56
import android.util.Log;
6-
77
import java.io.File;
8-
import java.util.Arrays;
98
import java.util.HashMap;
109
import java.util.Map;
11-
12-
import me.ele.amigo.reflect.FieldUtils;
1310
import me.ele.amigo.utils.CommonUtils;
1411
import me.ele.amigo.utils.FileUtils;
1512

@@ -141,7 +138,29 @@ private void ensurePatchDirs(String checksum) {
141138

142139
public boolean isOptedDexExists(String checksum) {
143140
File[] odexes = dexOptDir(checksum).listFiles();
144-
return odexes != null && odexes.length > 0;
141+
int odexFilesLength;
142+
if (odexes == null
143+
|| (odexFilesLength = odexes.length) == 0) {
144+
return false;
145+
}
146+
147+
if (Build.VERSION.SDK_INT >= 21) {
148+
return odexFilesLength == 1 && odexes[0].exists();
149+
}
150+
151+
File[] dexFiles = dexDir(checksum).listFiles();
152+
int dexFilesLength;
153+
if (dexFiles == null || (dexFilesLength = dexFiles.length) != odexFilesLength) {
154+
return false;
155+
}
156+
157+
for (int i = 0; i < dexFilesLength; i++) {
158+
if (!dexFiles[i].exists() || !odexes[i].exists()) {
159+
return false;
160+
}
161+
}
162+
163+
return true;
145164
}
146165

147166
// delete dex, odex, so files of a patch and also clear unused patches
@@ -170,6 +189,7 @@ private void clearAmigoDir(File excludeFile) {
170189
return;
171190
}
172191

192+
//always keep amigo.json
173193
File patchInfoFile = patchInfoFile();
174194
for (File subFile : subFiles) {
175195
if (!subFile.equals(patchInfoFile) && !subFile.equals(excludeFile)) {

0 commit comments

Comments
 (0)