Skip to content
Merged

Dev #48

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 21 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

- **APK Checker:**

Analyse the APK package, give suggestions of reducing the APK size; Compare two APK and find out the most significant growth
Analyse the APK package, give suggestions of reducing the APK's size; Compare two APK and find out the most significant increment on size

- **Resource Canary:**

Expand All @@ -25,12 +25,12 @@

- **IO Canary:**

Detect the file IO issues, including performance of file io and closeable leak
Detect the file IO issues, including performance of file IO and closeable leak

## Features
### APK Checker

- **Easy-to-use.** Matrix provides a JAR tool, which is more convenient to apply to your integration systems.
- **Easy-to-use.** Matrix provides a JAR tool, which is more convenient to apply to your integration systems.
- **More features.** In addition to APK Analyzer, Matrix find out the R redundancies, the dynamic libraries statically linked STL, unused resources, and supports custom checking rules.
- **Visual Outputs.** supports HTML and JSON outputs.

Expand All @@ -42,38 +42,32 @@

### Trace Canary

- **High performance.** Dynamically modify bytecode at compile time, record function cost and stack with little performance loss.
- **Accurate stack of ui-block.** Provide informations such as stack, function cost, execution times to solve the problem of ui-block quickly.
- **High performance.** Dynamically modify bytecode at compile time, record function cost and call stack with little performance loss.
- **Accurate call stack of ui-block.** Provide informations such as call stack, function cost, execution times to solve the problem of ui-block quickly.
- **Non-hack.** High compatibility to Android versions.
- **More features.** Automatically covers multiple fluency indicators such as ui-block, startup time, activity switching, slow function detection.

### SQLite Lint

- **Easy-to-use.** No code intrusion.
- **Easy-to-use.** Non-invasive.
- **High applicability.** Regardless of the amount of data, you can discover SQLite performance problems during development and testing.
- **High standards.** Detection algorithms based on best practices, make the quality of SQLite statement high quality.
- **May support multi-platform.** C++ implementation make it possible to support multi-platform.
- **High standards.** Detection algorithms based on best practices, make SQLite statements to the highest quality.
- **May support multi-platform.** Implementing in C++ makes it possible to support multi-platform.

### IO Canary
- **Easy-to-use.** No code intrusion.
- **More feature.** Including performance of file io and closeable leak.
- **Easy-to-use.** Non-invasive.
- **More feature.** Including performance of file IO and closeable leak.
- **Compatible with Android P.**

## Getting Started

1. Configure Matrix version in gradle.properties.
1. Configure `MATRIX_VERSION` in gradle.properties.
``` gradle
MATRIX_VERSION=0.4.7
MATRIX_VERSION=0.4.10
```

2. Add matrix-gradle-plugin in your build.gradle:
2. Add `matrix-gradle-plugin` in your build.gradle:
``` gradle
repositories {
maven {
url "https://dl.bintray.com/matrix/maven/"
}
}

dependencies {
classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
}
Expand Down Expand Up @@ -102,7 +96,7 @@
}
```

4. Implement PluginListener to receive data processed by Matrix.
4. Implement `PluginListener` to receive data processed by Matrix.

``` java
public class TestPluginListener extends DefaultPluginListener {
Expand All @@ -122,7 +116,7 @@
}
```

5. Implement DynamicConfig to change parametes of Matrix.
5. Implement `DynamicConfig` to change parametes of Matrix.
``` java
public class DynamicConfigImplDemo implements IDynamicConfig {
public DynamicConfigImplDemo() {}
Expand Down Expand Up @@ -158,8 +152,8 @@
}
}

```
6. Init Matrix in the ```onCreate``` of your application.

``` java
Matrix.Builder builder = new Matrix.Builder(application); // build matrix
builder.patchListener(new TestPluginListener(this)); // add general pluginListener
Expand All @@ -185,7 +179,8 @@ You can get more about Matrix output at the wiki [The output of Matrix](https://

### APK Checker Usage

APK Checker can run independently in Jar ([matrix-apk-canary-0.4.10.jar](https://dl.bintray.com/matrix/maven/com/tencent/matrix/matrix-apk-canary/0.4.10/matrix-apk-canary-0.4.10.jar)) mode, usage:
APK Checker can run independently in Jar ([matrix-apk-canary-0.4.10.jar](https://jcenter.bintray.com/com/tencent/matrix/matrix-apk-canary/0.4.10/matrix-apk-canary-0.4.10.jar)) mode, usage:


```shell
java -jar matrix-apk-canary-0.4.10.jar
Expand Down Expand Up @@ -232,7 +227,7 @@ Any problem?

1. Learn more from [Sample](https://github.com/Tencent/matrix/tree/master/samples/sample-android)
2. [Source Code](https://github.com/Tencent/matrix/tree/master)
3. [Wiki](https://github.com/Tencent/matrix/wiki) 或 [FAQ](https://github.com/Tencent/Matrix/wiki/Matrix-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
3. [Wiki](https://github.com/Tencent/matrix/wiki) & [FAQ](https://github.com/Tencent/Matrix/wiki/Matrix-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
4. Contact us for help

## Contributing
Expand Down Expand Up @@ -303,17 +298,11 @@ Matrix 当前监控范围包括:应用安装包大小,帧率变化,启动

1. 在你项目根目录下的 gradle.properties 中配置要依赖的 Matrix 版本号,如:
``` gradle
MATRIX_VERSION=0.4.7
MATRIX_VERSION=0.4.10
```

2. 在你项目根目录下的 build.gradle 文件添加 Matrix 依赖,如:
``` gradle
repositories {
maven {
url "https://dl.bintray.com/matrix/maven/"
}
}

dependencies {
classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
}
Expand Down Expand Up @@ -423,7 +412,7 @@ Matrix 分析后的输出字段的含义请查看 [Matrix 输出内容的含义

### APK Checker

APK Check 以独立的 jar 包提供 ([matrix-apk-canary-0.4.10.jar](https://dl.bintray.com/matrix/maven/com/tencent/matrix/matrix-apk-canary/0.4.10/matrix-apk-canary-0.4.10.jar)),你可以运行:
APK Check 以独立的 jar 包提供 ([matrix-apk-canary-0.4.10.jar](https://jcenter.bintray.com/com/tencent/matrix/matrix-apk-canary/0.4.10/matrix-apk-canary-0.4.10.jar)),你可以运行:

```cmd
java -jar matrix-apk-canary-0.4.10.jar
Expand Down
5 changes: 5 additions & 0 deletions codecc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cd /home/android/hudson/workspace/open-check/build/repositories/matrix-android/matrix/matrix-android
./gradlew clean compileDebugJavaWithJavac -PforCoverity --no-daemon
./gradlew :matrix-io-canary:build
./gradlew :matrix-sqlite-lint:build

2 changes: 1 addition & 1 deletion matrix/matrix-android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Tue Jun 20 10:24:33 CST 2017
VERSION_NAME_PREFIX=0.4.7
VERSION_NAME_PREFIX=0.4.8
VERSION_NAME_SUFFIX=
2 changes: 1 addition & 1 deletion matrix/matrix-android/gradle/android-publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ android.libraryVariants.all { variant ->

from components.findByName("android${variant.name.capitalize()}")

// artifact sourcesJar
artifact sourcesJar
artifact javadocJar
artifact jniSymbolsJar

Expand Down
2 changes: 1 addition & 1 deletion matrix/matrix-android/gradle/java-publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ publishing {
artifactId = POM_ARTIFACT_ID
version = version

// artifact sourcesJar
artifact sourcesJar
artifact javadocJar

// append additional configurations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,12 @@ public void run() throws Exception {
ApkTask unzipTask = TaskFactory.factory(TaskFactory.TASK_TYPE_UNZIP, jobConfig, new HashMap<String, String>());
preTasks.add(unzipTask);
for (String format : jobConfig.getOutputFormatList()) {
jobResults.add(JobResultFactory.factory(format, jobConfig));
JobResult result = JobResultFactory.factory(format, jobConfig);
if (result != null) {
jobResults.add(result);
} else {
Log.w(TAG, "Unknown output format name '%s' !", format);
}
}
execute();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public TaskResult call() throws TaskExecuteException {
RandomAccessFile dexFile = dexFileList.get(i);
DexData dexData = new DexData(dexFile);
dexData.load();
dexFile.close();
ClassRef[] defClassRefs = dexData.getInternalReferences();
Set<String> classNameSet = new HashSet<>();
for (ClassRef classRef : defClassRefs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public TaskResult call() throws TaskExecuteException {
for (RandomAccessFile dexFile : dexFileList) {
DexData dexData = new DexData(dexFile);
dexData.load();
dexFile.close();
ClassRef[] defClassRefs = dexData.getInternalReferences();
for (ClassRef classRef : defClassRefs) {
String className = ApkUtil.getNormalClassName(classRef.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ public TaskResult call() throws TaskExecuteException {
for (int i = 0; i < dexFileList.size(); i++) {
RandomAccessFile dexFile = dexFileList.get(i);
countDex(dexFile);
dexFile.close();
int totalInternalMethods = sumOfValue(classInternalMethod);
int totalExternalMethods = sumOfValue(classExternalMethod);
JsonObject jsonObject = new JsonObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.iface.ClassDef;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand All @@ -56,7 +54,6 @@ public class UnusedAssetsTask extends ApkTask {

private File inputFile;
private final List<String> dexFileNameList;
private final List<RandomAccessFile> dexFileList;
private final Set<String> ignoreSet;
private final Set<String> assetsPathSet;
private final Set<String> assetRefSet;
Expand All @@ -66,7 +63,6 @@ public UnusedAssetsTask(JobConfig config, Map<String, String> params) {
type = TaskFactory.TASK_TYPE_UNUSED_ASSETS;
dexFileNameList = new ArrayList<>();
ignoreSet = new HashSet<>();
dexFileList = new ArrayList<>();
assetsPathSet = new HashSet<>();
assetRefSet = new HashSet<>();
}
Expand Down Expand Up @@ -94,18 +90,12 @@ public void init() throws TaskInitException {
}

File[] files = inputFile.listFiles();
try {
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(ApkConstants.DEX_FILE_SUFFIX)) {
dexFileNameList.add(file.getName());
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
dexFileList.add(randomAccessFile);
}
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(ApkConstants.DEX_FILE_SUFFIX)) {
dexFileNameList.add(file.getName());
}
}
} catch (FileNotFoundException e) {
throw new TaskInitException(e.getMessage(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -67,7 +65,6 @@ public class UnusedResourcesTask extends ApkTask {
private File mappingTxt;
private File resMappingTxt;
private final List<String> dexFileNameList;
private final List<RandomAccessFile> dexFileList;
private final Map<String, String> rclassProguardMap;
private final Map<String, String> resourceDefMap;
private final Map<String, Set<String>> styleableMap;
Expand All @@ -81,7 +78,6 @@ public UnusedResourcesTask(JobConfig config, Map<String, String> params) {
type = TaskFactory.TASK_TYPE_UNUSED_RESOURCES;
dexFileNameList = new ArrayList<>();
ignoreSet = new HashSet<>();
dexFileList = new ArrayList<>();
rclassProguardMap = new HashMap<>();
resourceDefMap = new HashMap<>();
styleableMap = new HashMap<>();
Expand Down Expand Up @@ -131,19 +127,14 @@ public void init() throws TaskInitException {
}

File[] files = inputFile.listFiles();
try {
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(ApkConstants.DEX_FILE_SUFFIX)) {
dexFileNameList.add(file.getName());
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
dexFileList.add(randomAccessFile);
}
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(ApkConstants.DEX_FILE_SUFFIX)) {
dexFileNameList.add(file.getName());
}
}
} catch (FileNotFoundException e) {
throw new TaskInitException(e.getMessage(), e);
}

}

private String parseResourceId(String resId) {
Expand Down
2 changes: 1 addition & 1 deletion matrix/matrix-android/matrix-io-canary/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ android {
cppFlags "-std=gnu++11 -frtti -fexceptions"
}
ndk {
abiFilters "armeabi"
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ namespace iocanary {
__android_log_print(ANDROID_LOG_WARN, kTag, "doHook hook read failed, try __read_chk");
if (!elfhook_replace(soinfo, "__read_chk", (void*)ProxyRead, (void**)&original_read)) {
__android_log_print(ANDROID_LOG_WARN, kTag, "doHook hook failed: __read_chk");
elfhook_close(soinfo);
return false;
}
}
Expand All @@ -317,6 +318,7 @@ namespace iocanary {
__android_log_print(ANDROID_LOG_WARN, kTag, "doHook hook write failed, try __write_chk");
if (!elfhook_replace(soinfo, "__write_chk", (void*)ProxyWrite, (void**)&original_write)) {
__android_log_print(ANDROID_LOG_WARN, kTag, "doHook hook failed: __write_chk");
elfhook_close(soinfo);
return false;
}
}
Expand Down Expand Up @@ -346,6 +348,8 @@ namespace iocanary {
elfhook_replace(soinfo, "__read_chk", (void*) original_read, nullptr);
elfhook_replace(soinfo, "__write_chk", (void*) original_write, nullptr);
elfhook_replace(soinfo, "close", (void*) original_close, nullptr);

elfhook_close(soinfo);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ android {
arguments "-Dplatform=android"
}
ndk {
abiFilters "armeabi", "armeabi-v7a"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ namespace sqlitelint {
}
if (!elfhook_replace(soinfo, "sqlite3_profile", (void*)hooked_sqlite3_profile, (void**)&original_sqlite3_profile)) {
LOGW("Failure to hook sqlite3_profile");
elfhook_close(soinfo);
soinfo = nullptr;
return false;
}
elfhook_close(soinfo);
Expand Down
2 changes: 1 addition & 1 deletion samples/sample-android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

ndk {
abiFilters 'armeabi'
abiFilters 'armeabi', 'armeabi-v7a', 'x86'
}
}

Expand Down
2 changes: 1 addition & 1 deletion samples/sample-android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Wed Jun 28 12:25:50 AWST 2017
MATRIX_VERSION=0.4.7
MATRIX_VERSION=0.4.8