processErrorList = am.getProcessesInErrorState();
if (processErrorList != null) {
+ XCrash.getLogger().e(Util.TAG, "processErrorList is NOT null !!!!" + ", i = " + i);
for (ActivityManager.ProcessErrorStateInfo errorStateInfo : processErrorList) {
+ XCrash.getLogger().e(Util.TAG, "errorStateInfo.pid = " + errorStateInfo.pid + ", my pid = " + pid + ", errorStateInfo.condition = " + errorStateInfo.condition);
if (errorStateInfo.pid == pid && errorStateInfo.condition == ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING) {
return true;
}
}
+ } else {
+ XCrash.getLogger().e(Util.TAG, "processErrorList is null !!!!" + " poll = " + poll + ", i = " + i);
}
try {
@@ -296,7 +335,7 @@ static String getLogHeader(Date startTime, Date crashTime, String crashType, Str
+ "ABI list: '" + Util.getAbiList() + "'\n"
+ "Manufacturer: '" + Build.MANUFACTURER + "'\n"
+ "Brand: '" + Build.BRAND + "'\n"
- + "Model: '" + Build.MODEL + "'\n"
+ + "Model: '" + Util.getMobileModel() + "'\n"
+ "Build fingerprint: '" + Build.FINGERPRINT + "'\n";
}
@@ -363,11 +402,15 @@ public boolean accept(File dir, String name) {
for (File fd : fds) {
String path = null;
try {
- path = fd.getCanonicalPath();
+ if (Build.VERSION.SDK_INT >= 21) {
+ path = Os.readlink(fd.getAbsolutePath());
+ } else {
+ path = fd.getCanonicalPath();
+ }
} catch (Exception ignored) {
}
sb.append(" fd ").append(fd.getName()).append(": ")
- .append(TextUtils.isEmpty(path) ? "???" : path).append('\n');
+ .append(TextUtils.isEmpty(path) ? "???" : path.trim()).append('\n');
count++;
if (count > 1024) {
@@ -457,4 +500,171 @@ private static void getLogcatByBufferName(int pid, StringBuilder sb, String buff
}
}
}
+
+
+ public static String getSystemProperty(String key, String defaultValue) {
+ try {
+ Class> clz = Class.forName("android.os.SystemProperties");
+ Method get = clz.getMethod("get", String.class, String.class);
+ return (String) get.invoke(clz, key, defaultValue);
+ } catch (NoSuchMethodException var4) {
+ var4.printStackTrace();
+ } catch (IllegalAccessException var5) {
+ var5.printStackTrace();
+ } catch (InvocationTargetException var6) {
+ var6.printStackTrace();
+ } catch (ClassNotFoundException var7) {
+ var7.printStackTrace();
+ }
+
+ return defaultValue;
+ }
+
+ public static String getMobileModel() {
+ String mobileModel = null;
+ if (Rom.isMiui()) {
+ String deviceName = "";
+
+ try {
+ Class systemProperties = Class.forName("android.os.SystemProperties");
+ Method get = systemProperties.getDeclaredMethod("get", String.class, String.class);
+ deviceName = (String) get.invoke(systemProperties, "ro.product.marketname", "");
+ if (TextUtils.isEmpty(deviceName)) {
+ deviceName = (String) get.invoke(systemProperties, "ro.product.model", "");
+ }
+ } catch (InvocationTargetException var3) {
+ var3.printStackTrace();
+ } catch (NoSuchMethodException var4) {
+ var4.printStackTrace();
+ } catch (IllegalAccessException var5) {
+ var5.printStackTrace();
+ } catch (ClassNotFoundException var6) {
+ var6.printStackTrace();
+ }
+
+ mobileModel = deviceName;
+ } else {
+ mobileModel = Build.MODEL;
+ }
+
+ if (mobileModel == null) {
+ mobileModel = "";
+ }
+
+ return mobileModel;
+ }
+
+
+ public static class Rom {
+ private static final String TAG = "Rom";
+
+ public static final String ROM_MIUI = "MIUI";
+ public static final String ROM_EMUI = "EMUI";
+ public static final String ROM_FLYME = "FLYME";
+ public static final String ROM_OPPO = "OPPO";
+ public static final String ROM_SMARTISAN = "SMARTISAN";
+ public static final String ROM_VIVO = "VIVO";
+ public static final String ROM_QIKU = "QIKU";
+
+ private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
+ private static final String KEY_VERSION_EMUI = "ro.build.version.emui";
+ private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
+ private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";
+ private static final String KEY_VERSION_VIVO = "ro.vivo.os.version";
+
+ private static String sName;
+ private static String sVersion;
+
+ public static boolean isEmui() {
+ return check(ROM_EMUI);
+ }
+
+ public static boolean isMiui() {
+ return check(ROM_MIUI);
+ }
+
+ public static boolean isVivo() {
+ return check(ROM_VIVO);
+ }
+
+ public static boolean isOppo() {
+ return check(ROM_OPPO);
+ }
+
+ public static boolean isFlyme() {
+ return check(ROM_FLYME);
+ }
+
+ public static boolean is360() {
+ return check(ROM_QIKU) || check("360");
+ }
+
+ public static boolean isSmartisan() {
+ return check(ROM_SMARTISAN);
+ }
+
+ public static String getName() {
+ if (sName == null) {
+ check("");
+ }
+ return sName;
+ }
+
+ public static String getVersion() {
+ if (sVersion == null) {
+ check("");
+ }
+ return sVersion;
+ }
+
+ public static boolean check(String rom) {
+ if (sName != null) {
+ return sName.equals(rom);
+ }
+
+ if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) {
+ sName = ROM_MIUI;
+ } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) {
+ sName = ROM_EMUI;
+ } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) {
+ sName = ROM_OPPO;
+ } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) {
+ sName = ROM_VIVO;
+ } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) {
+ sName = ROM_SMARTISAN;
+ } else {
+ sVersion = Build.DISPLAY;
+ if (sVersion.toUpperCase().contains(ROM_FLYME)) {
+ sName = ROM_FLYME;
+ } else {
+ sVersion = Build.UNKNOWN;
+ sName = Build.MANUFACTURER.toUpperCase();
+ }
+ }
+ return sName.equals(rom);
+ }
+
+ public static String getProp(String name) {
+ String line = null;
+ BufferedReader input = null;
+ try {
+ Process p = Runtime.getRuntime().exec("getprop " + name);
+ input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
+ line = input.readLine();
+ input.close();
+ } catch (IOException ex) {
+ Log.e(TAG, "Unable to read prop " + name, ex);
+ return null;
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return line;
+ }
+ }
}
diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java b/xcrash_lib/src/main/java/xcrash/Version.java
similarity index 96%
rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java
rename to xcrash_lib/src/main/java/xcrash/Version.java
index eecdb0e..afcb82e 100644
--- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/Version.java
+++ b/xcrash_lib/src/main/java/xcrash/Version.java
@@ -27,6 +27,6 @@ class Version {
private Version() {
}
- static final String version = "2.4.8";
+ static final String version = "3.1.0";
static final String fullVersion = "xCrash " + version;
}
diff --git a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java b/xcrash_lib/src/main/java/xcrash/XCrash.java
similarity index 96%
rename from src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java
rename to xcrash_lib/src/main/java/xcrash/XCrash.java
index b5943d1..73821b0 100644
--- a/src/java/xcrash/xcrash_lib/src/main/java/xcrash/XCrash.java
+++ b/xcrash_lib/src/main/java/xcrash/XCrash.java
@@ -38,6 +38,7 @@ public final class XCrash {
private static String appVersion = null;
private static String logDir = null;
private static ILogger logger = new DefaultLogger();
+ public static String nativeLibDir = null;
private XCrash() {
}
@@ -69,6 +70,7 @@ public static synchronized int init(Context ctx, InitParameters params) {
if (XCrash.initialized) {
return Errno.OK;
}
+
XCrash.initialized = true;
if (ctx == null) {
@@ -104,6 +106,8 @@ public static synchronized int init(Context ctx, InitParameters params) {
}
XCrash.appVersion = params.appVersion;
+ XCrash.nativeLibDir = ctx.getApplicationInfo().nativeLibraryDir;
+
//save log dir
if (TextUtils.isEmpty(params.logDir)) {
params.logDir = ctx.getFilesDir() + "/tombstones";
@@ -175,7 +179,8 @@ public static synchronized int init(Context ctx, InitParameters params) {
params.anrLogcatMainLines,
params.anrDumpFds,
params.anrDumpNetworkInfo,
- params.anrCallback);
+ params.anrCallback,
+ params.anrFastCallback);
}
//init native crash handler / ANR handler (API level >= 21)
@@ -208,7 +213,8 @@ public static synchronized int init(Context ctx, InitParameters params) {
params.anrLogcatMainLines,
params.anrDumpFds,
params.anrDumpNetworkInfo,
- params.anrCallback);
+ params.anrCallback,
+ params.anrFastCallback);
}
//maintain tombstone and placeholder files in a background thread with some delay
@@ -712,6 +718,7 @@ public InitParameters setNativeCallback(ICrashCallback callback) {
boolean anrDumpFds = true;
boolean anrDumpNetworkInfo = true;
ICrashCallback anrCallback = null;
+ ICrashCallback anrFastCallback = null;
/**
* Enable the ANR capture feature. (Default: enable)
@@ -755,7 +762,7 @@ public InitParameters setAnrRethrow(boolean rethrow) {
/**
* Set whether the process error state (from "ActivityManager#getProcessesInErrorState()") is a necessary condition for ANR. (Default: true)
*
- * Note: On some Android TV box devices, the ANR is not reflected by process error state. In this case, set this option to false.
+ *
Note: On some Android TV box devices and on most Oppo phones, the ANR is not reflected by process error state. In this case, set this option to false.
*
* @param checkProcessState If true, process state error will be a necessary condition for ANR.
* @return The InitParameters object.
@@ -849,6 +856,20 @@ public InitParameters setAnrCallback(ICrashCallback callback) {
this.anrCallback = callback;
return this;
}
+
+ /**
+ * Set a fast callback to be executed when an ANR occurred.
+ * This callback is called before ANR trace dump
+ * (If not set, nothing will be happened.)
+ *
+ * @param fastCallback An instance of {@link xcrash.ICrashCallback}.
+ * @return The InitParameters object.
+ */
+ @SuppressWarnings("unused")
+ public InitParameters setAnrFastCallback(ICrashCallback fastCallback) {
+ this.anrFastCallback = fastCallback;
+ return this;
+ }
}
static String getAppId() {
@@ -859,7 +880,7 @@ static String getAppVersion() {
return appVersion;
}
- static String getLogDir() {
+ public static String getLogDir() {
return logDir;
}
diff --git a/src/java/xcrash/xcrash_sample/.gitignore b/xcrash_sample/.gitignore
similarity index 100%
rename from src/java/xcrash/xcrash_sample/.gitignore
rename to xcrash_sample/.gitignore
diff --git a/src/java/xcrash/xcrash_sample/build.gradle b/xcrash_sample/build.gradle
similarity index 74%
rename from src/java/xcrash/xcrash_sample/build.gradle
rename to xcrash_sample/build.gradle
index 35ba618..e578f86 100644
--- a/src/java/xcrash/xcrash_sample/build.gradle
+++ b/xcrash_sample/build.gradle
@@ -3,6 +3,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
+ ndkVersion rootProject.ext.ndkVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
@@ -10,7 +11,7 @@ android {
versionCode 1
versionName "1.0"
ndk {
- abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
+ abiFilters rootProject.ext.abiFilters.split(",")
}
}
compileOptions {
@@ -31,8 +32,10 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- //implementation 'com.iqiyi.xcrash:xcrash-android-lib:2.4.8'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+// implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.1.0'
implementation project(':xcrash_lib')
}
+
+apply from: rootProject.file('gradle/sanitizer.gradle')
diff --git a/src/java/xcrash/xcrash_sample/proguard-rules.pro b/xcrash_sample/proguard-rules.pro
similarity index 100%
rename from src/java/xcrash/xcrash_sample/proguard-rules.pro
rename to xcrash_sample/proguard-rules.pro
diff --git a/src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml b/xcrash_sample/src/main/AndroidManifest.xml
similarity index 85%
rename from src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml
rename to xcrash_sample/src/main/AndroidManifest.xml
index e25f77e..7e70e04 100644
--- a/src/java/xcrash/xcrash_sample/src/main/AndroidManifest.xml
+++ b/xcrash_sample/src/main/AndroidManifest.xml
@@ -13,7 +13,8 @@
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
-
+
@@ -21,7 +22,8 @@
-
+