Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup #390

Merged
merged 9 commits into from
Mar 14, 2016
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
What is ACRA ?
==============

ACRA is a library enabling Android Application to automatically post their crash reports to a GoogleDoc form. It is targetted to android applications developers to help them get data from their applications when they crash or behave erroneously.
ACRA is a library enabling Android Application to automatically post their crash reports to a GoogleDoc form. It is targeted to android applications developers to help them get data from their applications when they crash or behave erroneously.

ACRA is used in 2.68% ([See AppBrain/stats](http://www.appbrain.com/stats/libraries/details/acra/acra)) of all apps on Google Play as of Feb 2016. That's over 53K **apps** using ACRA. And since the average US user has 41 apps installed on their phone that means there is a 70% chance that ACRA is running on any phone. That means ACRA is running on over a **billion devices**.

Expand All @@ -27,7 +27,7 @@ A crash reporting feature for android apps is native since Android 2.2 (FroYo) b

ACRA's notification systems are clean. If a crash occurs, your application does not add user notifications over existing system's crash notifications or reporting features. If you use the Toast, Status bar notification or direct dialog modes, the "force close" dialog is not displayed anymore and devices where the system native reporting feature is enabled do not offer the user to send an additional report.

The user is notified of an error only once, and you might enhance the percieved quality of your application by defining your own texts in the notifications/dialogs.
The user is notified of an error only once, and you might enhance the perceived quality of your application by defining your own texts in the notifications/dialogs.

Please do not hesitate to open defects/enhancements requests in [the issue tracker](http://github.com/ACRA/acra/issues).

Expand Down Expand Up @@ -57,7 +57,7 @@ ACRA v4.8
ACRA v4.7
===============================
- Support for Android M (6.0)
- Using HtttpUrlConnection instead of Apache Http
- Using HttpUrlConnection instead of Apache Http
- Using com.android.support:support-v4 to provide support fro removed Notification methods.
- Minimum Android version is Froyo (2.2). ACRA will disable itself for anything prior to that.
- Packaging as an AAR.
Expand Down
7 changes: 3 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ android {
minSdkVersion 8
targetSdkVersion 23
versionCode 1
versionName "1.0"
versionName "undefined"
}

buildTypes {
Expand All @@ -28,7 +28,6 @@ android {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:support-annotations:23.1.1'
compile 'com.android.support:support-v4:23.2.0'
compile 'com.android.support:support-annotations:23.2.0'
}
5 changes: 3 additions & 2 deletions src/main/java/org/acra/ACRA.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@
* @author Kevin Gaudin
*
*/
public class ACRA {
public final class ACRA {
private ACRA(){}

public static boolean DEV_LOGGING = false; // Should be false for release.
public static final boolean DEV_LOGGING = false; // Should be false for release.

public static final String LOG_TAG = ACRA.class.getSimpleName();

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/acra/ACRAConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* @since 4.3.0
*/
public final class ACRAConstants {
private ACRAConstants(){}

public static final String REPORTFILE_EXTENSION = ".stacktrace";

Expand Down Expand Up @@ -136,7 +137,7 @@ public final class ACRAConstants {
*
* @see org.acra.annotation.ReportsCrashes#mailTo()
*/
public final static ReportField[] DEFAULT_MAIL_REPORT_FIELDS = { USER_COMMENT, ANDROID_VERSION, APP_VERSION_NAME,
public static final ReportField[] DEFAULT_MAIL_REPORT_FIELDS = { USER_COMMENT, ANDROID_VERSION, APP_VERSION_NAME,
BRAND, PHONE_MODEL, CUSTOM_DATA, STACK_TRACE };

/**
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/acra/ReportField.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
*/
package org.acra;

import org.acra.annotation.ReportsCrashes;

import android.content.res.Configuration;

import org.acra.annotation.ReportsCrashes;

/**
* Specifies all the different fields available in a crash report.
*
Expand Down Expand Up @@ -293,7 +293,7 @@ public boolean containsKeyValuePairs() {
* Whether this field is a collection of key/value pairs.
*
* @return true if the field contains a string with a key/value pair on each
* line, key and value separated by an equal sugn
* line, key and value separated by an equal sign
*
*/
public boolean containsKeyValuePairs() {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/acra/annotation/ReportsCrashes.java
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@
* {@link Context#getFilesDir()}.
*
* @return a String containing the path/name of your application log file.
* If the string does not containt any path separator, the file is
* If the string does not contain any path separator, the file is
* assumed as being in {@link Context#getFilesDir()}.
*/
@NonNull String applicationLogFile() default ACRAConstants.DEFAULT_APPLICATION_LOGFILE;
Expand Down
80 changes: 32 additions & 48 deletions src/main/java/org/acra/builder/ReportExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import org.acra.ACRA;
import org.acra.ACRAConstants;
import org.acra.ReportingInteractionMode;
Expand Down Expand Up @@ -39,6 +40,8 @@
*/
public final class ReportExecutor {

private static final int THREAD_SLEEP_INTERVAL_MILLIS = 100;

private final Context context;
private final ACRAConfiguration config;
private final CrashReportDataFactory crashReportDataFactory;
Expand All @@ -52,10 +55,6 @@ public final class ReportExecutor {

private boolean enabled = false;

// This is used to wait for the crash toast to end it's display duration before killing the Application.
// TODO make this a local variable. Only here because it cannot be non-final and referenced within an anonymous class.
private boolean toastWaitEnded = true;

/**
* Used to create a new (non-cached) PendingIntent each time a new crash occurs.
*/
Expand Down Expand Up @@ -196,68 +195,53 @@ public void run() {
createNotification(reportFile, reportBuilder);
}

// This is used to wait for the crash toast to end it's display duration before killing the Application.
toastWaitEnded = true;
final boolean showDirectDialog = (reportingInteractionMode == ReportingInteractionMode.DIALOG)
&& !prefs.getBoolean(ACRA.PREF_ALWAYS_ACCEPT, false);

if (shouldDisplayToast) {
// A toast is being displayed, we have to wait for its end before doing anything else.
// The toastWaitEnded flag will be checked before any other operation.
toastWaitEnded = false;
new Thread() {

@Override
public void run() {
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Waiting for " + ACRAConstants.TOAST_WAIT_DURATION
+ " millis from " + sentToastTimeMillis.initialTimeMillis
+ " currentMillis=" + System.currentTimeMillis());
if (ACRA.DEV_LOGGING)
ACRA.log.d(LOG_TAG, "Waiting for " + ACRAConstants.TOAST_WAIT_DURATION
+ " millis from " + sentToastTimeMillis.initialTimeMillis
+ " currentMillis=" + System.currentTimeMillis());
while (sentToastTimeMillis.getElapsedTime() < ACRAConstants.TOAST_WAIT_DURATION) {
try {
// Wait a bit to let the user read the toast
Thread.sleep(100);
Thread.sleep(THREAD_SLEEP_INTERVAL_MILLIS);
} catch (InterruptedException e1) {
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Interrupted while waiting for Toast to end.", e1);
if (ACRA.DEV_LOGGING)
ACRA.log.d(LOG_TAG, "Interrupted while waiting for Toast to end.", e1);
}
}
toastWaitEnded = true;
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finished waiting for Toast");
dialogAndEnd(reportBuilder, reportFile, showDirectDialog);
}
}.start();
} else {
dialogAndEnd(reportBuilder, reportFile, showDirectDialog);
}
}

final boolean showDirectDialog = (reportingInteractionMode == ReportingInteractionMode.DIALOG)
&& !prefs.getBoolean(ACRA.PREF_ALWAYS_ACCEPT, false);

new Thread() {

@Override
public void run() {
// We have to wait for the toast display to be completed.
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Waiting for Toast");
while (!toastWaitEnded) {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Interrupted waiting for Toast");
}
}
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finished waiting for Toast");

if (showDirectDialog) {
// Create a new activity task with the confirmation dialog.
// This new task will be persisted on application restart
// right after its death.
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Creating CrashReportDialog for " + reportFile);
final Intent dialogIntent = createCrashReportDialogIntent(reportFile, reportBuilder);
dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dialogIntent);
}
private void dialogAndEnd(@NonNull ReportBuilder reportBuilder, @NonNull File reportFile, boolean shouldShowDialog) {
if (shouldShowDialog) {
// Create a new activity task with the confirmation dialog.
// This new task will be persisted on application restart
// right after its death.
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Creating CrashReportDialog for " + reportFile);
final Intent dialogIntent = createCrashReportDialogIntent(reportFile, reportBuilder);
dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dialogIntent);
}

if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Wait for Toast + worker ended. Kill Application ? " + reportBuilder.isEndApplication());
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Wait for Toast + worker ended. Kill Application ? " + reportBuilder.isEndApplication());

if (reportBuilder.isEndApplication()) {
endApplication(reportBuilder.getUncaughtExceptionThread(), reportBuilder.getException());
}
}
}.start();
if (reportBuilder.isEndApplication()) {
endApplication(reportBuilder.getUncaughtExceptionThread(), reportBuilder.getException());
}
}

/**
Expand Down Expand Up @@ -406,7 +390,7 @@ private void saveCrashReportFile(@NonNull File file, @NonNull CrashReportData cr
* @param reportBuilder ReportBuilder containing the details of the crash.
*/
@NonNull
private Intent createCrashReportDialogIntent(File reportFile, @NonNull ReportBuilder reportBuilder) {
private Intent createCrashReportDialogIntent(@NonNull File reportFile, @NonNull ReportBuilder reportBuilder) {
if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Creating DialogIntent for " + reportFile + " exception=" + reportBuilder.getException());
final Intent dialogIntent = new Intent(context, config.reportDialogClass());
dialogIntent.putExtra(ACRAConstants.EXTRA_REPORT_FILE, reportFile);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/acra/collector/CollectorUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.Reader;

public final class CollectorUtil {
private CollectorUtil(){}

/**
* Closes a Reader.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ private String getStackTraceHash(Throwable th) {
private Class<?> getBuildConfigClass() throws ClassNotFoundException {
final Class configuredBuildConfig = config.buildConfigClass();
if ((configuredBuildConfig != null) && !configuredBuildConfig.equals(Object.class)) {
// If set via annotations or programatically then it will have a real value,
// If set via annotations or programmatically then it will have a real value,
// otherwise it will be Object.class (annotation default) or null (explicit programmatic).
return configuredBuildConfig;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*
*/
final class DeviceFeaturesCollector {
private DeviceFeaturesCollector(){}

public static String getFeatures(@NonNull Context ctx) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
import java.lang.reflect.Field;

final class DisplayManagerCollector {
private DisplayManagerCollector(){}

final static SparseArray<String> mFlagsNames = new SparseArray<String>();
static final SparseArray<String> mFlagsNames = new SparseArray<String>();

public static String collectDisplays(@NonNull Context ctx) {
final Display[] displays;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/acra/collector/DumpSysCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
*
*/
final class DumpSysCollector {
private DumpSysCollector(){}

/**
* Collect results of the <code>dumpsys meminfo</code> command restricted to
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/acra/collector/LogFileCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private static BufferedReader getReader(@NonNull Context context, @NonNull Strin
// A file directly contained within the application files folder.
inputStream = context.openFileInput(fileName);
}
return new BufferedReader(new InputStreamReader(inputStream), 1024);
return new BufferedReader(new InputStreamReader(inputStream), 1024); //TODO: 1024 should be a constant. Use ACRAConstants.DEFAULT_BUFFER_SIZE_IN_BYTES ?
} catch (FileNotFoundException e) {
ACRA.log.e(LOG_TAG, "Cannot find application log file : '" + fileName + "'");
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[0])));
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/org/acra/collector/MediaCodecListCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package org.acra.collector;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
Expand All @@ -35,7 +34,8 @@
*
* @author Kevin Gaudin
*/
public class MediaCodecListCollector {
public final class MediaCodecListCollector {
private MediaCodecListCollector(){}
private enum CodecType {
AVC, H263, MPEG4, AAC

Expand Down Expand Up @@ -110,7 +110,6 @@ private enum CodecType {
* @return The media codecs information
*/
@NonNull
@SuppressLint("NewApi") //lint doesn't check complex NewApi blocks correctly
public static String collectMediaCodecList() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return "";
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/acra/collector/ReflectionCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
*
*/
final class ReflectionCollector {
private ReflectionCollector(){}

/**
* Retrieves key/value pairs from static fields of a class.
Expand Down
22 changes: 12 additions & 10 deletions src/main/java/org/acra/collector/SettingsCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
*/
final class SettingsCollector {

private static final String ERROR = "Error: ";

private final Context context;
private final ACRAConfiguration config;

Expand Down Expand Up @@ -73,9 +75,9 @@ public String collectSystemSettings() {
result.append(key.getName()).append("=").append(value).append("\n");
}
} catch (@NonNull IllegalArgumentException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull IllegalAccessException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
}
}
}
Expand All @@ -102,9 +104,9 @@ public String collectSecureSettings() {
result.append(key.getName()).append("=").append(value).append("\n");
}
} catch (@NonNull IllegalArgumentException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull IllegalAccessException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
}
}
}
Expand Down Expand Up @@ -139,17 +141,17 @@ public String collectGlobalSettings() {
}
}
} catch (@NonNull IllegalArgumentException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull InvocationTargetException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull NoSuchMethodException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull SecurityException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull ClassNotFoundException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
} catch (@NonNull IllegalAccessException e) {
ACRA.log.w(LOG_TAG, "Error : ", e);
ACRA.log.w(LOG_TAG, ERROR, e);
}

return result.toString();
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/acra/collector/ThreadCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
* @author Kevin Gaudin
*
*/
public class ThreadCollector {
public final class ThreadCollector {
private ThreadCollector(){}

/**
* Convenience method that collects some data identifying a Thread, usually the Thread which
Expand Down
Loading