Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Commit

Permalink
Merge branch 'develop' into feature/remove-deprecated-API
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Scholtysik (Reimold) authored Oct 5, 2017
2 parents 1310a72 + 238b962 commit 612e30a
Show file tree
Hide file tree
Showing 37 changed files with 156 additions and 96 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
Expand All @@ -13,6 +14,7 @@ buildscript {
allprojects {
repositories {
jcenter()
google()
}

tasks.withType(Javadoc) {
Expand Down
9 changes: 3 additions & 6 deletions hockeysdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ publish {

dependencies {
// Mocking
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.crittercism.dexmaker:dexmaker:1.4'
androidTestCompile 'com.crittercism.dexmaker:dexmaker-dx:1.4'
androidTestCompile 'com.crittercism.dexmaker:dexmaker-mockito:1.4'
androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'

testCompile 'org.powermock:powermock-api-mockito:1.6.6'
testCompile 'org.powermock:powermock-module-junit4:1.6.6'
Expand All @@ -64,6 +61,6 @@ dependencies {
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'junit:junit:4.12'

androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test:runner:1.0.1'
androidTestCompile 'com.android.support.test:rules:1.0.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,40 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import junit.framework.TestCase;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* <h3>Description</h3>
*
* This class provides testing for the environment features, such as the SDK wide constants.
*/
@RunWith(AndroidJUnit4.class)
public class EnvironmentTest extends TestCase {
public class EnvironmentTest {

/*
* This test is disabled since it is always failing on emulators with API under 18. The problem
* is that emulators start with external storage being in removed state and necessary directory
* can not be created.
*
* TODO: Uncomment test in case emulators with API under 18 start supporting external storage
*/
/**
* Test to verify basic creation of the external storage directory works.
*/
@Test
//@Test
public void basicStorageDirTest() {
File storageDir = Constants.getHockeyAppStorageDir(InstrumentationRegistry.getTargetContext());

assertNotNull(storageDir);
assertTrue(storageDir.exists());
}

@Test
public void dummyTestMethod() {}
}
2 changes: 1 addition & 1 deletion hockeysdk/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<application>
<application android:supportsRtl="true">

<activity android:name=".UpdateActivity" />
<activity android:name=".FeedbackActivity" android:windowSoftInputMode="adjustResize|stateVisible" />
Expand Down
2 changes: 2 additions & 0 deletions hockeysdk/src/main/java/net/hockeyapp/android/Constants.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.hockeyapp.android;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
Expand Down Expand Up @@ -185,6 +186,7 @@ private static int loadBuildNumber(Context context, PackageManager packageManage
*
* @param context the context to use. Usually your Activity object.
*/
@SuppressLint("StaticFieldLeak")
private static void loadIdentifiers(final Context context) {
if (Constants.DEVICE_IDENTIFIER != null) {
return;
Expand Down
83 changes: 61 additions & 22 deletions hockeysdk/src/main/java/net/hockeyapp/android/CrashManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.hockeyapp.android;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
Expand Down Expand Up @@ -27,6 +28,7 @@
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -77,10 +79,22 @@ public class CrashManager {
private static final String PREFERENCES_NAME = "HockeySDK";
private static final String CONFIRMED_FILENAMES_KEY = "ConfirmedFilenames";

/**
* Maximum number of files with saved crashes.
*/
static final int MAX_NUMBER_OF_CRASHFILES = 100;

private static final int STACK_TRACES_FOUND_NONE = 0;
private static final int STACK_TRACES_FOUND_NEW = 1;
private static final int STACK_TRACES_FOUND_CONFIRMED = 2;

private static final FilenameFilter STACK_TRACES_FILTER = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith(".stacktrace");
}
};

/**
* Registers new crash manager and handles existing crash logs.
* HockeyApp App Identifier is read from configuration values in AndroidManifest.xml
Expand Down Expand Up @@ -191,6 +205,7 @@ public static void initialize(Context context, String urlString, String appIdent
* @param context The context to use. Usually your Activity object.
* @param listener Implement for callback functions.
*/
@SuppressLint("StaticFieldLeak")
public static void execute(Context context, final CrashManagerListener listener) {
final WeakReference<Context> weakContext = new WeakReference<>(context);
AsyncTaskUtils.execute(new AsyncTask<Void, Object, Integer>() {
Expand Down Expand Up @@ -313,12 +328,7 @@ public CrashDetails call() throws Exception {
if (dir == null) {
return null;
}
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith(".stacktrace");
}
});
File[] files = dir.listFiles(STACK_TRACES_FILTER);

long lastModification = 0;
File lastModifiedFile = null;
Expand Down Expand Up @@ -366,6 +376,13 @@ public static synchronized void submitStackTraces(final WeakReference<Context> w
String[] list = searchForStackTraces(weakContext);
if (list != null && list.length > 0) {
HockeyLog.debug("Found " + list.length + " stacktrace(s).");
if (list.length > MAX_NUMBER_OF_CRASHFILES) {
deleteRedundantStackTraces(weakContext);
list = searchForStackTraces(weakContext);
if (list == null) {
return;
}
}
for (String file : list) {
submitStackTrace(weakContext, file, listener, crashMetaData);
}
Expand Down Expand Up @@ -461,18 +478,11 @@ public static void deleteStackTraces(final WeakReference<Context> weakContext) {
String[] list = searchForStackTraces(weakContext);
if (list != null && list.length > 0) {
HockeyLog.debug("Found " + list.length + " stacktrace(s).");

for (String file : list) {
try {
Context context;
if (weakContext != null) {
HockeyLog.debug("Delete stacktrace " + file + ".");
deleteStackTrace(weakContext, file);

context = weakContext.get();
if (context != null) {
context.deleteFile(file);
}
}
} catch (Exception e) {
HockeyLog.error("Failed to delete stacktrace", e);
Expand All @@ -495,6 +505,7 @@ public static void deleteStackTraces(final WeakReference<Context> weakContext) {
* @see CrashMetaData
* @see CrashManagerListener
*/
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("WeakerAccess")
public static boolean handleUserInput(final CrashManagerUserInput userInput,
final CrashMetaData userProvidedMetaData, final CrashManagerListener listener,
Expand Down Expand Up @@ -626,6 +637,7 @@ private static String getAlertTitle(Context context) {
* Starts thread to send crashes to HockeyApp, then registers the exception
* handler.
*/
@SuppressLint("StaticFieldLeak")
private static void sendCrashes(final WeakReference<Context> weakContext, final CrashManagerListener listener, final boolean ignoreDefaultHandler, final CrashMetaData crashMetaData) {
registerHandler(listener, ignoreDefaultHandler);
Context context = weakContext != null ? weakContext.get() : null;
Expand All @@ -639,8 +651,16 @@ private static void sendCrashes(final WeakReference<Context> weakContext, final
AsyncTaskUtils.execute(new AsyncTask<Void, Object, Object>() {
@Override
protected Object doInBackground(Void... voids) {
final String[] list = searchForStackTraces(weakContext);
if (list != null) {
String[] list = searchForStackTraces(weakContext);
if (list != null && list.length > 0) {
HockeyLog.debug("Found " + list.length + " stacktrace(s).");
if (list.length > MAX_NUMBER_OF_CRASHFILES) {
deleteRedundantStackTraces(weakContext);
list = searchForStackTraces(weakContext);
if (list == null) {
return null;
}
}
saveConfirmedStackTraces(weakContext, list);
if (isConnectedToNetwork) {
for (String file : list) {
Expand Down Expand Up @@ -793,7 +813,7 @@ private static void saveConfirmedStackTraces(final WeakReference<Context> weakCo
/**
* Searches .stacktrace files and returns them as array.
*/
protected static String[] searchForStackTraces(final WeakReference<Context> weakContext) {
static String[] searchForStackTraces(final WeakReference<Context> weakContext) {
Context context = weakContext != null ? weakContext.get() : null;
if (context != null) {
File dir = context.getFilesDir();
Expand All @@ -804,19 +824,38 @@ protected static String[] searchForStackTraces(final WeakReference<Context> weak
}

// Filter for ".stacktrace" files
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".stacktrace");
}
};
return dir.list(filter);
return dir.list(STACK_TRACES_FILTER);
} else {
HockeyLog.debug("Can't search for exception as file path is null.");
}
}
return null;
}

private static void deleteRedundantStackTraces(final WeakReference<Context> weakContext) {
Context context = weakContext != null ? weakContext.get() : null;
if (context != null) {
File dir = context.getFilesDir();
if (dir == null || !dir.exists()) {
return;
}
File[] files = dir.listFiles(STACK_TRACES_FILTER);
if (files.length <= MAX_NUMBER_OF_CRASHFILES) {
return;
}
HockeyLog.debug("Delete " + (files.length - MAX_NUMBER_OF_CRASHFILES) + " redundant stacktrace(s).");
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return Long.valueOf(file1.lastModified()).compareTo(file2.lastModified());
}
});
for (int i = 0; i < files.length - MAX_NUMBER_OF_CRASHFILES; i++) {
deleteStackTrace(weakContext, files[i].getName());
}
}
}

@SuppressWarnings("WeakerAccess")
public static long getInitializeTimestamp() {
return initializeTimestamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
*
**/
public class ExceptionHandler implements UncaughtExceptionHandler {
private static final int MAX_NUMBER_OF_CRASHFILES = 100;
private boolean mIgnoreDefaultHandler = false;
private CrashManagerListener mCrashManagerListener;
private UncaughtExceptionHandler mDefaultExceptionHandler;
Expand Down Expand Up @@ -63,11 +62,13 @@ public static void saveException(Throwable exception, Thread thread, CrashManage

// Check for number of crashes on disk and don't save the crash in case we reached the defined limit.
final String[] list = CrashManager.searchForStackTraces(CrashManager.weakContext);
final int number = list.length;
HockeyLog.debug("ExceptionHandler: Found " + number + " stacktrace(s).");
if(number >= MAX_NUMBER_OF_CRASHFILES) {
HockeyLog.warn("ExceptionHandler: HockeyApp will not save this exception as there are already " + MAX_NUMBER_OF_CRASHFILES + " or more unsent exceptions on disk");
return;
if (list != null) {
HockeyLog.debug("ExceptionHandler: Found " + list.length + " stacktrace(s).");
if (list.length >= CrashManager.MAX_NUMBER_OF_CRASHFILES) {
HockeyLog.warn("ExceptionHandler: HockeyApp will not save this exception as there are already " +
CrashManager.MAX_NUMBER_OF_CRASHFILES + " or more unsent exceptions on disk");
return;
}
}

String filename = UUID.randomUUID().toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ private void loadFeedbackMessages(final FeedbackResponse feedbackResponse) {
}
}

@SuppressLint("StaticFieldLeak")
private void resetFeedbackView() {
mToken = null;
AsyncTaskUtils.execute(new AsyncTask<Void, Object, Object>() {
Expand All @@ -722,6 +723,7 @@ protected Object doInBackground(Void... voids) {
/**
* Send feedback to HockeyApp.
*/
@SuppressLint("StaticFieldLeak")
private void sendFeedback() {
if (!Util.isConnectedToNetwork(this)) {
Toast errorToast = Toast.makeText(this, R.string.hockeyapp_error_no_network_message, Toast.LENGTH_LONG);
Expand Down Expand Up @@ -873,6 +875,7 @@ private static class ParseFeedbackHandler extends Handler {
mWeakFeedbackActivity = new WeakReference<>(feedbackActivity);
}

@SuppressLint("StaticFieldLeak")
@Override
public void handleMessage(Message msg) {
boolean success = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.hockeyapp.android;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
Expand Down Expand Up @@ -198,6 +199,7 @@ public static void showFeedbackActivity(Context context, Uri... attachments) {
* @param attachments the optional attachment {@link Uri}s
* @param extras a bundle to be added to the Intent that starts the FeedbackActivity instance
*/
@SuppressLint("StaticFieldLeak")
public static void showFeedbackActivity(final Context context, final Bundle extras, final Uri... attachments) {
if (context != null) {
final Class<?> activityClass = lastListener != null ? lastListener.getFeedbackActivityClass() : null;
Expand Down Expand Up @@ -281,6 +283,7 @@ public boolean accept(File dir, String name) {
*
* @param context the context to use
*/
@SuppressLint("StaticFieldLeak")
public static void checkForAnswersAndNotify(final Context context) {
String token = PrefsUtil.getInstance().getFeedbackTokenFromPrefs(context);
if (token == null) {
Expand Down Expand Up @@ -417,6 +420,7 @@ public static void unsetCurrentActivityForScreenshot(Activity activity) {
*
* @param context toast messages will be displayed using this context
*/
@SuppressLint("StaticFieldLeak")
public static void takeScreenshot(final Context context) {
final Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.hockeyapp.android;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -175,6 +176,7 @@ public static void register(final Context context, String appIdentifier, String
* @param context The activity from which this method is called.
* @param intent The intent that the activity has been created with.
*/
@SuppressLint("StaticFieldLeak")
public static void verifyLogin(final Activity context, Intent intent) {
//Don't verify anything if we're in LOGIN_MODE_ANONYMOUS
if (context == null || mode == LOGIN_MODE_ANONYMOUS) {
Expand Down
Loading

0 comments on commit 612e30a

Please sign in to comment.