diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 0b52046057..e763d471cb 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -67,6 +67,12 @@
android:name=".SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
+
+
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/BreakpadUploaderService.java b/android/app/src/main/java/io/highfidelity/hifiinterface/BreakpadUploaderService.java
new file mode 100644
index 0000000000..c8b337fb7e
--- /dev/null
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/BreakpadUploaderService.java
@@ -0,0 +1,169 @@
+package io.highfidelity.hifiinterface;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.FileObserver;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import javax.net.ssl.HttpsURLConnection;
+
+public class BreakpadUploaderService extends Service {
+
+ private static final String ANNOTATIONS_JSON = "annotations.json";
+ private static final String TAG = "Interface";
+ public static final String EXT_DMP = "dmp";
+
+ private FileObserver fileObserver;
+
+ public BreakpadUploaderService() {
+ super();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ URL baseUrl;
+
+ baseUrl = getUrl();
+
+ if (baseUrl == null) {
+ stopSelf();
+ return START_NOT_STICKY;
+ }
+
+ new Thread(() -> {
+ File[] matchingFiles = getFilesByExtension(getObbDir(), EXT_DMP);
+ for (File file : matchingFiles)
+ {
+ uploadDumpAndDelete(file, baseUrl);
+ }
+ }).start();
+
+ fileObserver = new FileObserver(getObbDir().getPath()) {
+ @Override
+ public void onEvent(int event, String path) {
+ if (path == null) {
+ return;
+ }
+ if (FileObserver.CREATE == event && EXT_DMP.equals(getExtension(path))) {
+ URL baseUrl = getUrl();
+ if (baseUrl != null) {
+ new Thread(() -> uploadDumpAndDelete(new File(path), baseUrl)).start();
+ }
+ }
+ }
+ };
+
+ fileObserver.startWatching();
+ return START_STICKY;
+ }
+
+ private URL getUrl() {
+ String parameters = getAnnotationsAsUrlEncodedParameters();
+ try {
+ return new URL(BuildConfig.BACKTRACE_URL+ "/post?format=minidump&token=" + BuildConfig.BACKTRACE_TOKEN + (parameters.isEmpty() ? "" : ("&" + parameters)));
+ } catch (MalformedURLException e) {
+ Log.e(TAG, "Could not initialize Breakpad URL", e);
+ }
+ return null;
+ }
+
+ private void uploadDumpAndDelete(File file, URL url) {
+ int size = (int) file.length();
+ byte[] bytes = new byte[size];
+ try {
+ BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
+ buf.read(bytes, 0, bytes.length);
+ buf.close();
+ HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
+ urlConnection.setRequestMethod("POST");
+ urlConnection.setDoOutput(true);
+ urlConnection.setChunkedStreamingMode(0);
+
+ OutputStream ostream = urlConnection.getOutputStream();
+
+ OutputStream out = new BufferedOutputStream(ostream);
+ out.write(bytes, 0, size);
+
+ InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ in.read();
+ if (urlConnection.getResponseCode() == 200) {
+ file.delete();
+ }
+ urlConnection.disconnect();
+ } catch (IOException e) {
+ Log.e(TAG, "Error uploading file " + file.getAbsolutePath(), e);
+ }
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private File[] getFilesByExtension(File dir, final String extension)
+ {
+ return dir.listFiles(pathName -> getExtension(pathName.getName()).equals(extension));
+ }
+
+ private String getExtension(String fileName)
+ {
+ String extension = "";
+
+ int i = fileName.lastIndexOf('.');
+ int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
+
+ if (i > p)
+ {
+ extension = fileName.substring(i+1);
+ }
+
+ return extension;
+ }
+
+
+ public String getAnnotationsAsUrlEncodedParameters() {
+ String parameters = "";
+ File annotationsFile = new File(getObbDir(), ANNOTATIONS_JSON);
+ if (annotationsFile.exists()) {
+ JsonParser parser = new JsonParser();
+ try {
+ JsonObject json = (JsonObject) parser.parse(new FileReader(annotationsFile));
+ for (String k: json.keySet()) {
+ if (!json.get(k).getAsString().isEmpty()) {
+ String key = k.contains("/") ? k.substring(k.indexOf("/") + 1) : k;
+ if (!parameters.isEmpty()) {
+ parameters += "&";
+ }
+ parameters += URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(json.get(k).getAsString(), "UTF-8");
+ }
+ }
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Error reading annotations file", e);
+ } catch (UnsupportedEncodingException e) {
+ Log.e(TAG, "Error reading annotations file", e);
+ }
+ }
+ return parameters;
+ }
+
+}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java b/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java
index 0d2d39db7d..10cfd85b50 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java
@@ -1,71 +1,54 @@
package io.highfidelity.hifiinterface;
import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.app.Activity;
-
-import android.content.DialogInterface;
-import android.app.AlertDialog;
import android.util.Log;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-
import org.json.JSONException;
import org.json.JSONObject;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
import java.io.Writer;
-import java.net.URL;
-import java.net.URLEncoder;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-
-import javax.net.ssl.HttpsURLConnection;
public class PermissionChecker extends Activity {
private static final int REQUEST_PERMISSIONS = 20;
private static final boolean CHOOSE_AVATAR_ON_STARTUP = false;
private static final String TAG = "Interface";
- private static final String ANNOTATIONS_JSON = "annotations.json";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Intent myIntent = new Intent(this, BreakpadUploaderService.class);
+ startService(myIntent);
if (CHOOSE_AVATAR_ON_STARTUP) {
showMenu();
}
- Thread networkThread = new Thread(new Runnable() {
- public void run() {
- UploadCrashReports();
- runOnUiThread(() -> requestAppPermissions(new
- String[]{
- Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Manifest.permission.RECORD_AUDIO,
- Manifest.permission.CAMERA}
- ,2,REQUEST_PERMISSIONS));
+ File obbDir = getObbDir();
+ if (!obbDir.exists()) {
+ if (obbDir.mkdirs()) {
+ Log.d(TAG, "Obb dir created");
}
- });
- networkThread.start();
+ }
+
+ requestAppPermissions(new
+ String[]{
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.RECORD_AUDIO,
+ Manifest.permission.CAMERA}
+ ,2,REQUEST_PERMISSIONS);
}
@@ -152,89 +135,4 @@ public class PermissionChecker extends Activity {
launchActivityWithPermissions();
}
}
-
- public void UploadCrashReports()
- {
- try
- {
- String parameters = getAnnotationsAsUrlEncodedParameters();
- URL url = new URL(BuildConfig.BACKTRACE_URL+ "/post?format=minidump&token=" + BuildConfig.BACKTRACE_TOKEN + (parameters.isEmpty() ? "" : ("&" + parameters)));
- // Check if a crash .dmp exists
- File[] matchingFiles = getFilesByExtension(getObbDir(), "dmp");
- for (File file : matchingFiles)
- {
- int size = (int) file.length();
- byte[] bytes = new byte[size];
- BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
- buf.read(bytes, 0, bytes.length);
- buf.close();
- HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
- urlConnection.setRequestMethod("POST");
- urlConnection.setDoOutput(true);
- urlConnection.setChunkedStreamingMode(0);
-
- OutputStream ostream = urlConnection.getOutputStream();
-
- OutputStream out = new BufferedOutputStream(ostream);
- out.write(bytes, 0, size);
-
- InputStream in = new BufferedInputStream(urlConnection.getInputStream());
- in.read();
- if (urlConnection.getResponseCode() == 200) {
- file.delete();
- }
- urlConnection.disconnect();
- }
- }
- catch (Exception e)
- {
- Log.e(TAG, "Error uploading breakpad dumps", e);
- }
- }
-
- private File[] getFilesByExtension(File dir, final String extension)
- {
- return dir.listFiles(pathName -> getExtension(pathName.getName()).equals(extension));
- }
-
- private String getExtension(String fileName)
- {
- String extension = "";
-
- int i = fileName.lastIndexOf('.');
- int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
-
- if (i > p)
- {
- extension = fileName.substring(i+1);
- }
-
- return extension;
- }
-
-
- public String getAnnotationsAsUrlEncodedParameters() {
- String parameters = "";
- File annotationsFile = new File(getObbDir(), ANNOTATIONS_JSON);
- if (annotationsFile.exists()) {
- JsonParser parser = new JsonParser();
- try {
- JsonObject json = (JsonObject) parser.parse(new FileReader(annotationsFile));
- for (String k: json.keySet()) {
- if (!json.get(k).getAsString().isEmpty()) {
- String key = k.contains("/") ? k.substring(k.indexOf("/") + 1) : k;
- if (!parameters.isEmpty()) {
- parameters += "&";
- }
- parameters += URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(json.get(k).getAsString(), "UTF-8");
- }
- }
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Error reading annotations file", e);
- } catch (UnsupportedEncodingException e) {
- Log.e(TAG, "Error reading annotations file", e);
- }
- }
- return parameters;
- }
}
diff --git a/interface/src/Breakpad.cpp b/interface/src/Breakpad.cpp
index 3d27eee29c..cb4785305a 100644
--- a/interface/src/Breakpad.cpp
+++ b/interface/src/Breakpad.cpp
@@ -14,7 +14,6 @@
#if defined(HAS_BREAKPAD)
#include
-#include
#include
#include
#include