mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #13331 from gcalero/breakpad_android
Breakpad integration for android Interface
This commit is contained in:
commit
9c488ff05e
18 changed files with 397 additions and 81 deletions
|
@ -27,7 +27,8 @@ android {
|
|||
'-DRELEASE_TYPE=' + RELEASE_TYPE,
|
||||
'-DSTABLE_BUILD=' + STABLE_BUILD,
|
||||
'-DDISABLE_QML=OFF',
|
||||
'-DDISABLE_KTX_CACHE=OFF'
|
||||
'-DDISABLE_KTX_CACHE=OFF',
|
||||
'-DUSE_BREAKPAD=' + (project.hasProperty("BACKTRACE_URL") && project.hasProperty("BACKTRACE_TOKEN") ? 'ON' : 'OFF');
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
|
@ -46,6 +47,10 @@ android {
|
|||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
buildConfigField "String", "BACKTRACE_URL", "\"" + (project.hasProperty("BACKTRACE_URL") ? BACKTRACE_URL : '') + "\""
|
||||
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (project.hasProperty("BACKTRACE_TOKEN") ? BACKTRACE_TOKEN : '') + "\""
|
||||
}
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
|
@ -53,6 +58,8 @@ android {
|
|||
project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") &&
|
||||
project.hasProperty("HIFI_ANDROID_KEY_ALIAS") &&
|
||||
project.hasProperty("HIFI_ANDROID_KEY_PASSWORD")? signingConfigs.release : null
|
||||
buildConfigField "String", "BACKTRACE_URL", "\"" + (project.hasProperty("BACKTRACE_URL") ? BACKTRACE_URL : '') + "\""
|
||||
buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (project.hasProperty("BACKTRACE_TOKEN") ? BACKTRACE_TOKEN : '') + "\""
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,12 @@
|
|||
android:name=".SplashActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Translucent.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".BreakpadUploaderService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:process=":breakpad_uploader"/>
|
||||
</application>
|
||||
|
||||
<uses-feature android:name="android.software.vr.mode" android:required="true"/>
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
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 java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
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 static final long DUMP_DELAY = 5000;
|
||||
|
||||
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 Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
uploadDumpAndDelete(new File(getObbDir(), path), baseUrl);
|
||||
}
|
||||
}, DUMP_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
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 org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -24,20 +24,31 @@ 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";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Intent myIntent = new Intent(this, BreakpadUploaderService.class);
|
||||
startService(myIntent);
|
||||
if (CHOOSE_AVATAR_ON_STARTUP) {
|
||||
showMenu();
|
||||
}
|
||||
this.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");
|
||||
}
|
||||
}
|
||||
|
||||
requestAppPermissions(new
|
||||
String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.CAMERA}
|
||||
,2,REQUEST_PERMISSIONS);
|
||||
|
||||
}
|
||||
|
||||
|
@ -124,6 +135,4 @@ public class PermissionChecker extends Activity {
|
|||
launchActivityWithPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -149,6 +149,13 @@ def packages = [
|
|||
file: 'etc2comp-patched-armv8-libcpp.tgz',
|
||||
versionId: 'bHhGECRAQR1vkpshBcK6ByNc1BQIM8gU',
|
||||
checksum: '14b02795d774457a33bbc60e00a786bc'
|
||||
],
|
||||
breakpad: [
|
||||
file: 'breakpad.zip',
|
||||
versionId: '2OwvCCZrF171wnte5T44AnjTYFhhJsGJ',
|
||||
checksum: 'a46062a3167dfedd4fb4916136e204d2',
|
||||
sharedLibFolder: 'lib',
|
||||
includeLibs: ['libbreakpad_client.a','libbreakpad.a']
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -367,6 +374,7 @@ task verifyPolyvox(type: Verify) { def p = packages['polyvox']; src new File(bas
|
|||
task verifyTBB(type: Verify) { def p = packages['tbb']; src new File(baseFolder, p['file']); checksum p['checksum'] }
|
||||
task verifyHifiAC(type: Verify) { def p = packages['hifiAC']; src new File(baseFolder, p['file']); checksum p['checksum'] }
|
||||
task verifyEtc2Comp(type: Verify) { def p = packages['etc2comp']; src new File(baseFolder, p['file']); checksum p['checksum'] }
|
||||
task verifyBreakpad(type: Verify) { def p = packages['breakpad']; src new File(baseFolder, p['file']); checksum p['checksum'] }
|
||||
|
||||
task verifyDependencyDownloads(dependsOn: downloadDependencies) { }
|
||||
verifyDependencyDownloads.dependsOn verifyQt
|
||||
|
@ -378,6 +386,7 @@ verifyDependencyDownloads.dependsOn verifyPolyvox
|
|||
verifyDependencyDownloads.dependsOn verifyTBB
|
||||
verifyDependencyDownloads.dependsOn verifyHifiAC
|
||||
verifyDependencyDownloads.dependsOn verifyEtc2Comp
|
||||
verifyDependencyDownloads.dependsOn verifyBreakpad
|
||||
|
||||
task extractDependencies(dependsOn: verifyDependencyDownloads) {
|
||||
doLast {
|
||||
|
@ -615,4 +624,4 @@ task testElf (dependsOn: 'externalNativeBuildDebug') {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
22
cmake/macros/TargetBreakpad.cmake
Normal file
22
cmake/macros/TargetBreakpad.cmake
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Copyright 2018 High Fidelity, Inc.
|
||||
# Created by Gabriel Calero & Cristian Duarte on 2018/03/13
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_BREAKPAD)
|
||||
if (ANDROID)
|
||||
set(INSTALL_DIR ${HIFI_ANDROID_PRECOMPILED}/breakpad)
|
||||
set(BREAKPAD_INCLUDE_DIRS "${INSTALL_DIR}/include" CACHE TYPE INTERNAL)
|
||||
set(LIB_DIR ${INSTALL_DIR}/lib)
|
||||
list(APPEND BREAKPAD_LIBRARIES ${LIB_DIR}/libbreakpad_client.a)
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BREAKPAD_INCLUDE_DIRS})
|
||||
if (USE_BREAKPAD)
|
||||
add_definitions(-DHAS_BREAKPAD)
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${TARGET_NAME} ${BREAKPAD_LIBRARIES})
|
||||
endmacro()
|
||||
|
||||
|
|
@ -226,6 +226,7 @@ target_openssl()
|
|||
target_bullet()
|
||||
target_opengl()
|
||||
add_crashpad()
|
||||
target_breakpad()
|
||||
|
||||
# perform standard include and linking for found externals
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
|
|
|
@ -150,8 +150,8 @@
|
|||
#include "audio/AudioScope.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
#include "avatar/MyHead.h"
|
||||
#include "CrashRecoveryHandler.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "Crashpad.h"
|
||||
#include "devices/DdeFaceTracker.h"
|
||||
#include "DiscoverabilityManager.h"
|
||||
#include "GLCanvas.h"
|
||||
|
@ -791,7 +791,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
|
||||
bool previousSessionCrashed { false };
|
||||
if (!inTestMode) {
|
||||
previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt);
|
||||
previousSessionCrashed = CrashRecoveryHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt);
|
||||
}
|
||||
|
||||
// get dir to use for cache
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// CrashHandler.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by David Rowe on 24 Aug 2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
// Created by Clement Brisset on 01/19/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -12,22 +12,10 @@
|
|||
#ifndef hifi_CrashHandler_h
|
||||
#define hifi_CrashHandler_h
|
||||
|
||||
#include <QString>
|
||||
#include <string>
|
||||
|
||||
class CrashHandler {
|
||||
bool startCrashHandler();
|
||||
void setCrashAnnotation(std::string name, std::string value);
|
||||
|
||||
public:
|
||||
static bool checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt = false);
|
||||
|
||||
private:
|
||||
enum Action {
|
||||
DELETE_INTERFACE_INI,
|
||||
RETAIN_IMPORTANT_INFO,
|
||||
DO_NOTHING
|
||||
};
|
||||
|
||||
static Action promptUserForAction(bool showCrashMessage);
|
||||
static void handleCrash(Action action);
|
||||
};
|
||||
|
||||
#endif // hifi_CrashHandler_h
|
||||
#endif
|
70
interface/src/CrashHandler_Breakpad.cpp
Normal file
70
interface/src/CrashHandler_Breakpad.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// CrashHandler_Breakpad.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 01/19/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "CrashHandler.h"
|
||||
|
||||
#if HAS_BREAKPAD
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <client/linux/handler/exception_handler.h>
|
||||
#include <client/linux/handler/minidump_descriptor.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMap>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtAndroidExtras/QAndroidJniObject>
|
||||
|
||||
#include <SettingHelpers.h>
|
||||
|
||||
google_breakpad::ExceptionHandler* gBreakpadHandler;
|
||||
|
||||
std::mutex annotationMutex;
|
||||
QMap<QString, QString> annotations;
|
||||
|
||||
static bool breakpad_dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) {
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
QString obbDir() {
|
||||
QAndroidJniObject mediaDir = QAndroidJniObject::callStaticObjectMethod("android/os/Environment", "getExternalStorageDirectory", "()Ljava/io/File;");
|
||||
QAndroidJniObject mediaPath = mediaDir.callObjectMethod( "getAbsolutePath", "()Ljava/lang/String;" );
|
||||
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
|
||||
QAndroidJniObject package = activity.callObjectMethod("getPackageName", "()Ljava/lang/String;");
|
||||
QString dataAbsPath = mediaPath.toString()+"/Android/obb/" + package.toString();
|
||||
return dataAbsPath;
|
||||
}
|
||||
|
||||
bool startCrashHandler() {
|
||||
|
||||
gBreakpadHandler = new google_breakpad::ExceptionHandler(
|
||||
google_breakpad::MinidumpDescriptor(obbDir().toStdString()),
|
||||
nullptr, breakpad_dumpCallback, nullptr, true, -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void setCrashAnnotation(std::string name, std::string value) {
|
||||
std::lock_guard<std::mutex> guard(annotationMutex);
|
||||
QString qName = QString::fromStdString(name);
|
||||
QString qValue = QString::fromStdString(value);
|
||||
annotations[qName] = qValue;
|
||||
|
||||
QSettings settings(obbDir() + "/annotations.json", JSON_FORMAT);
|
||||
settings.clear();
|
||||
settings.beginGroup("Annotations");
|
||||
for (auto k : annotations.keys()) {
|
||||
settings.setValue(k, annotations.value(k));
|
||||
}
|
||||
settings.endGroup();
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Crashpad.cpp
|
||||
// CrashHandler_Crashpad.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 01/19/18.
|
||||
|
@ -9,7 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Crashpad.h"
|
||||
#include "CrashHandler.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -117,14 +117,4 @@ void setCrashAnnotation(std::string name, std::string value) {
|
|||
crashpadAnnotations->SetKeyValue(name, value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool startCrashHandler() {
|
||||
qDebug() << "No crash handler available.";
|
||||
return false;
|
||||
}
|
||||
|
||||
void setCrashAnnotation(std::string name, std::string value) {
|
||||
}
|
||||
|
||||
#endif
|
27
interface/src/CrashHandler_None.cpp
Normal file
27
interface/src/CrashHandler_None.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// CrashHandler_None.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 01/19/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "CrashHandler.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <QDebug>
|
||||
|
||||
#if !defined(HAS_CRASHPAD) && !defined(HAS_BREAKPAD)
|
||||
|
||||
bool startCrashHandler() {
|
||||
qDebug() << "No crash handler available.";
|
||||
return false;
|
||||
}
|
||||
|
||||
void setCrashAnnotation(std::string name, std::string value) {
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// CrashHandler.cpp
|
||||
// CrashRecoveryHandler.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by David Rowe on 24 Aug 2015.
|
||||
|
@ -9,7 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "CrashHandler.h"
|
||||
#include "CrashRecoveryHandler.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDialog>
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include <SettingHelpers.h>
|
||||
|
||||
|
||||
bool CrashHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) {
|
||||
bool CrashRecoveryHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) {
|
||||
QSettings::setDefaultFormat(JSON_FORMAT);
|
||||
QSettings settings;
|
||||
settings.beginGroup("Developer");
|
||||
|
@ -59,7 +59,7 @@ bool CrashHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPromp
|
|||
return wasLikelyCrash;
|
||||
}
|
||||
|
||||
CrashHandler::Action CrashHandler::promptUserForAction(bool showCrashMessage) {
|
||||
CrashRecoveryHandler::Action CrashRecoveryHandler::promptUserForAction(bool showCrashMessage) {
|
||||
QDialog crashDialog;
|
||||
QLabel* label;
|
||||
if (showCrashMessage) {
|
||||
|
@ -94,20 +94,20 @@ CrashHandler::Action CrashHandler::promptUserForAction(bool showCrashMessage) {
|
|||
|
||||
if (result == QDialog::Accepted) {
|
||||
if (option1->isChecked()) {
|
||||
return CrashHandler::DELETE_INTERFACE_INI;
|
||||
return CrashRecoveryHandler::DELETE_INTERFACE_INI;
|
||||
}
|
||||
if (option2->isChecked()) {
|
||||
return CrashHandler::RETAIN_IMPORTANT_INFO;
|
||||
return CrashRecoveryHandler::RETAIN_IMPORTANT_INFO;
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog cancelled or "do nothing" option chosen
|
||||
return CrashHandler::DO_NOTHING;
|
||||
return CrashRecoveryHandler::DO_NOTHING;
|
||||
}
|
||||
|
||||
void CrashHandler::handleCrash(CrashHandler::Action action) {
|
||||
if (action != CrashHandler::DELETE_INTERFACE_INI && action != CrashHandler::RETAIN_IMPORTANT_INFO) {
|
||||
// CrashHandler::DO_NOTHING or unexpected value
|
||||
void CrashRecoveryHandler::handleCrash(CrashRecoveryHandler::Action action) {
|
||||
if (action != CrashRecoveryHandler::DELETE_INTERFACE_INI && action != CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) {
|
||||
// CrashRecoveryHandler::DO_NOTHING or unexpected value
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ void CrashHandler::handleCrash(CrashHandler::Action action) {
|
|||
QUrl address;
|
||||
bool tutorialComplete = false;
|
||||
|
||||
if (action == CrashHandler::RETAIN_IMPORTANT_INFO) {
|
||||
if (action == CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) {
|
||||
// Read avatar info
|
||||
|
||||
// Location and orientation
|
||||
|
@ -151,7 +151,7 @@ void CrashHandler::handleCrash(CrashHandler::Action action) {
|
|||
settingsFile.remove();
|
||||
}
|
||||
|
||||
if (action == CrashHandler::RETAIN_IMPORTANT_INFO) {
|
||||
if (action == CrashRecoveryHandler::RETAIN_IMPORTANT_INFO) {
|
||||
// Write avatar info
|
||||
|
||||
// Location and orientation
|
33
interface/src/CrashRecoveryHandler.h
Normal file
33
interface/src/CrashRecoveryHandler.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// CrashRecoveryHandler.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by David Rowe on 24 Aug 2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_CrashRecoveryHandler_h
|
||||
#define hifi_CrashRecoveryHandler_h
|
||||
|
||||
#include <QString>
|
||||
|
||||
class CrashRecoveryHandler {
|
||||
|
||||
public:
|
||||
static bool checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt = false);
|
||||
|
||||
private:
|
||||
enum Action {
|
||||
DELETE_INTERFACE_INI,
|
||||
RETAIN_IMPORTANT_INFO,
|
||||
DO_NOTHING
|
||||
};
|
||||
|
||||
static Action promptUserForAction(bool showCrashMessage);
|
||||
static void handleCrash(Action action);
|
||||
};
|
||||
|
||||
#endif // hifi_CrashRecoveryHandler_h
|
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// Crashpad.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 01/19/18.
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Crashpad_h
|
||||
#define hifi_Crashpad_h
|
||||
|
||||
#include <string>
|
||||
|
||||
bool startCrashHandler();
|
||||
void setCrashAnnotation(std::string name, std::string value);
|
||||
|
||||
#endif // hifi_Crashpad_h
|
|
@ -23,7 +23,7 @@
|
|||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Crashpad.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "Menu.h"
|
||||
|
||||
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Connections;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "AddressManager.h"
|
||||
#include "Application.h"
|
||||
#include "Crashpad.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "UserActivityLogger.h"
|
||||
#include "MainWindow.h"
|
||||
|
|
|
@ -46,6 +46,7 @@ function init() {
|
|||
|
||||
function onMuteClicked() {
|
||||
Audio.muted = !Audio.muted;
|
||||
Menu.triggerOption("Out of Bounds Vector Access");
|
||||
}
|
||||
|
||||
function onMutePressed() {
|
||||
|
|
Loading…
Reference in a new issue