mirror of
https://github.com/whyorean/AuroraStore.git
synced 2026-06-16 03:31:02 -04:00
Rolled back ACRA and implemented an uncaught exception handler
This commit is contained in:
@@ -24,6 +24,5 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'ch.acra:acra:4.9.0'
|
||||
compile 'com.github.yeriomin:play-store-api:556e2bf'
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:name=".YalpStoreApplication"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true">
|
||||
|
||||
@@ -23,6 +23,12 @@ public class AboutActivity extends YalpStoreActivity {
|
||||
TextView gsfIdView = (TextView) findViewById(R.id.gsf_id);
|
||||
gsfIdView.setText(gsfId);
|
||||
gsfIdView.setOnClickListener(new CopyToClipboardListener());
|
||||
findViewById(R.id.developer_email).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new YalpStoreUncaughtExceptionHandler(AboutActivity.this).send(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class CopyToClipboardListener implements View.OnClickListener {
|
||||
|
||||
@@ -171,19 +171,19 @@ public class DetailsActivity extends YalpStoreActivity {
|
||||
if (null == versionName || versionName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String label = getString(R.string.details_versionName, versionName);
|
||||
if (app.isInstalled()) {
|
||||
try {
|
||||
PackageInfo info = getPackageManager().getPackageInfo(app.getPackageName(), 0);
|
||||
if (info.versionCode != app.getVersionCode()) {
|
||||
label = getString(R.string.details_versionName_updatable, info.versionName, versionName);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// We've checked for that already
|
||||
}
|
||||
}
|
||||
textView.setText(label);
|
||||
textView.setText(getString(R.string.details_versionName, versionName));
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
if (!app.isInstalled()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
PackageInfo info = getPackageManager().getPackageInfo(app.getPackageName(), 0);
|
||||
if (info.versionCode != app.getVersionCode()) {
|
||||
textView.setText(getString(R.string.details_versionName_updatable, info.versionName, versionName));
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// We've checked for that already
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDescription(App app) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.yeriomin.yalpstore;
|
||||
import android.content.Context;
|
||||
import android.content.pm.FeatureInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
@@ -22,24 +23,6 @@ public class NativeDeviceInfoProvider implements DeviceInfoProvider {
|
||||
|
||||
// Getting this requires a permission and google services to be installed
|
||||
static private final int GOOGLE_SERVICES_VERSION_CODE = 80711500;
|
||||
static private final String[] sharedLibraries = new String[] {
|
||||
"ConnectivityExt",
|
||||
"activation.jar",
|
||||
"android-support-v13.jar",
|
||||
"android-support-v4.jar",
|
||||
"android-support-v7-recyclerview.jar",
|
||||
"cloud-common.jar",
|
||||
"com.android.media.remotedisplay",
|
||||
"com.android.mediadrm.signer",
|
||||
"android.test.runner",
|
||||
"com.android.future.usb.accessory",
|
||||
"com.android.location.provider",
|
||||
"com.android.nfc_extras",
|
||||
"com.google.android.maps",
|
||||
"com.google.android.media.effects",
|
||||
"com.google.widevine.software.drm",
|
||||
"javax.obex"
|
||||
};
|
||||
static private final String[] glExtensions = new String[] {
|
||||
"GL_AMD_compressed_ATC_texture",
|
||||
"GL_AMD_performance_monitor",
|
||||
@@ -220,27 +203,43 @@ public class NativeDeviceInfoProvider implements DeviceInfoProvider {
|
||||
}
|
||||
|
||||
public DeviceConfigurationProto getDeviceConfigurationProto() {
|
||||
DisplayMetrics metrics = this.context.getResources().getDisplayMetrics();
|
||||
return DeviceConfigurationProto.newBuilder()
|
||||
.setTouchScreen(3)
|
||||
.setKeyboard(1)
|
||||
.setNavigation(1)
|
||||
.setScreenLayout(2)
|
||||
.setHasHardKeyboard(false)
|
||||
.setHasFiveWayNavigation(false)
|
||||
.setScreenDensity((int) (metrics.density * 160f))
|
||||
.setScreenWidth(metrics.widthPixels)
|
||||
.setScreenHeight(metrics.heightPixels)
|
||||
DeviceConfigurationProto.Builder builder = DeviceConfigurationProto.newBuilder();
|
||||
addDisplayMetrics(builder);
|
||||
addConfiguration(builder);
|
||||
return builder
|
||||
.addAllNativePlatform(getPlatforms())
|
||||
.addAllSystemSharedLibrary(Arrays.asList(sharedLibraries))
|
||||
.addAllSystemAvailableFeature(getFeatures())
|
||||
.addAllSystemSharedLibrary(getSharedLibraries(context))
|
||||
.addAllSystemAvailableFeature(getFeatures(context))
|
||||
.addAllSystemSupportedLocale(getLocales())
|
||||
.setGlEsVersion(196609) // Getting this and next list requires messing with ndk
|
||||
.addAllGlExtension(Arrays.asList(glExtensions))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<String> getPlatforms() {
|
||||
private DeviceConfigurationProto.Builder addDisplayMetrics(DeviceConfigurationProto.Builder builder) {
|
||||
DisplayMetrics metrics = this.context.getResources().getDisplayMetrics();
|
||||
builder
|
||||
.setScreenDensity((int) (metrics.density * 160f))
|
||||
.setScreenWidth(metrics.widthPixels)
|
||||
.setScreenHeight(metrics.heightPixels)
|
||||
;
|
||||
return builder;
|
||||
}
|
||||
|
||||
private DeviceConfigurationProto.Builder addConfiguration(DeviceConfigurationProto.Builder builder) {
|
||||
Configuration config = this.context.getResources().getConfiguration();
|
||||
builder
|
||||
.setTouchScreen(config.touchscreen)
|
||||
.setKeyboard(config.keyboard)
|
||||
.setNavigation(config.navigation)
|
||||
.setScreenLayout(config.screenLayout & 15)
|
||||
.setHasHardKeyboard(config.keyboard == Configuration.KEYBOARD_QWERTY)
|
||||
.setHasFiveWayNavigation(config.navigation == Configuration.NAVIGATIONHIDDEN_YES)
|
||||
;
|
||||
return builder;
|
||||
}
|
||||
|
||||
static public List<String> getPlatforms() {
|
||||
List<String> platforms = new ArrayList<>();
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
platforms = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||
@@ -255,8 +254,8 @@ public class NativeDeviceInfoProvider implements DeviceInfoProvider {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
private List<String> getFeatures() {
|
||||
PackageManager packageManager = this.context.getPackageManager();
|
||||
static public List<String> getFeatures(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
FeatureInfo[] featuresList = packageManager.getSystemAvailableFeatures();
|
||||
List<String> featureStringList = new ArrayList<>();
|
||||
for (FeatureInfo feature : featuresList) {
|
||||
@@ -267,7 +266,7 @@ public class NativeDeviceInfoProvider implements DeviceInfoProvider {
|
||||
return featureStringList;
|
||||
}
|
||||
|
||||
private List<String> getLocales() {
|
||||
static public List<String> getLocales() {
|
||||
List<String> localeStringList = new ArrayList<>();
|
||||
for (Locale locale : Locale.getAvailableLocales()) {
|
||||
String localeString = locale.toString();
|
||||
@@ -277,4 +276,8 @@ public class NativeDeviceInfoProvider implements DeviceInfoProvider {
|
||||
}
|
||||
return localeStringList;
|
||||
}
|
||||
|
||||
static public List<String> getSharedLibraries(Context context) {
|
||||
return Arrays.asList(context.getPackageManager().getSystemSharedLibraryNames());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ public abstract class YalpStoreActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
logout = false;
|
||||
ThemeManager.setTheme(this);
|
||||
Thread.setDefaultUncaughtExceptionHandler(new YalpStoreUncaughtExceptionHandler(this));
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.github.yeriomin.yalpstore;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.acra.ACRA;
|
||||
import org.acra.ReportField;
|
||||
import org.acra.ReportingInteractionMode;
|
||||
import org.acra.config.ACRAConfiguration;
|
||||
import org.acra.config.ACRAConfigurationException;
|
||||
import org.acra.config.ConfigurationBuilder;
|
||||
|
||||
public class YalpStoreApplication extends Application {
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context base) {
|
||||
super.attachBaseContext(base);
|
||||
|
||||
try {
|
||||
ACRAConfiguration config = new ConfigurationBuilder(this)
|
||||
.setMailTo(getString(R.string.about_developer_email))
|
||||
.setReportingInteractionMode(ReportingInteractionMode.DIALOG)
|
||||
.setResDialogText(R.string.application_crashed)
|
||||
.setCustomReportContent(
|
||||
ReportField.ANDROID_VERSION,
|
||||
ReportField.STACK_TRACE_HASH,
|
||||
ReportField.STACK_TRACE,
|
||||
ReportField.BUILD,
|
||||
ReportField.BUILD_CONFIG,
|
||||
ReportField.DISPLAY,
|
||||
ReportField.DEVICE_FEATURES
|
||||
)
|
||||
.build();
|
||||
ACRA.init(this, config);
|
||||
} catch (ACRAConfigurationException e) {
|
||||
Log.e(getClass().getName(), "Could not configure ACRA: " + e.getMessage());
|
||||
} catch (Throwable e) {
|
||||
Log.e(getClass().getName(), "Unknown problem with ACRA: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.github.yeriomin.yalpstore;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class YalpStoreUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
private Activity activity;
|
||||
|
||||
public YalpStoreUncaughtExceptionHandler(Activity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, final Throwable e) {
|
||||
e.printStackTrace();
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
showCrashDialog(e);
|
||||
Looper.loop();
|
||||
}
|
||||
};
|
||||
try {
|
||||
thread.start();
|
||||
} catch (Throwable ee) {
|
||||
Log.e(getClass().getName(), "Failed to process an uncaught exception: " + ee.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public AlertDialog showCrashDialog(final Throwable e) {
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setTitle(activity.getString(R.string.dialog_title_application_crashed))
|
||||
.setMessage(activity.getString(R.string.dialog_message_application_crashed))
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
System.exit(1);
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
send(e);
|
||||
dialog.dismiss();
|
||||
System.exit(1);
|
||||
}
|
||||
})
|
||||
.show()
|
||||
;
|
||||
}
|
||||
|
||||
public void send(Throwable e) {
|
||||
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
|
||||
emailIntent.setData(Uri.fromParts("mailto", activity.getString(R.string.about_developer_email), null));
|
||||
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getPackageName() + " Crash Report");
|
||||
emailIntent.putExtra(Intent.EXTRA_TEXT, buildBody(e));
|
||||
try {
|
||||
activity.startActivity(emailIntent);
|
||||
} catch (ActivityNotFoundException ee) {
|
||||
Log.e(getClass().getName(), ee.getClass().toString() + " " + ee.getMessage());
|
||||
((ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE)).setText(buildBody(e));
|
||||
}
|
||||
}
|
||||
|
||||
private String buildBody(Throwable e) {
|
||||
StringBuilder body = new StringBuilder();
|
||||
if (null != e) {
|
||||
body.append("\n\n").append(Log.getStackTraceString(e)).append("\n\n");
|
||||
}
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
values.putAll(getBuildValues());
|
||||
values.putAll(getConfigurationValues());
|
||||
values.putAll(getDisplayMetricsValues());
|
||||
values.putAll(getPackageManagerValues());
|
||||
for (String key : values.keySet()) {
|
||||
body.append(key).append(" = ").append(values.get(key)).append("\n");
|
||||
}
|
||||
return body.toString();
|
||||
}
|
||||
|
||||
private Map<String, String> getBuildValues() {
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
values.put("Build.FINGERPRINT", Build.FINGERPRINT);
|
||||
values.put("Build.HARDWARE", Build.HARDWARE);
|
||||
values.put("Build.BRAND", Build.BRAND);
|
||||
values.put("Build.RADIO", Build.RADIO);
|
||||
values.put("Build.BOOTLOADER", Build.BOOTLOADER);
|
||||
values.put("Build.DEVICE", Build.DEVICE);
|
||||
values.put("Build.VERSION.SDK_INT", Integer.toString(Build.VERSION.SDK_INT));
|
||||
values.put("Build.MODEL", Build.MODEL);
|
||||
values.put("Build.MANUFACTURER", Build.MANUFACTURER);
|
||||
values.put("Build.PRODUCT", Build.PRODUCT);
|
||||
return values;
|
||||
}
|
||||
|
||||
private Map<String, String> getConfigurationValues() {
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
Configuration config = activity.getResources().getConfiguration();
|
||||
values.put("TouchScreen", Integer.toString(config.touchscreen));
|
||||
values.put("Keyboard", Integer.toString(config.keyboard));
|
||||
values.put("Navigation", Integer.toString(config.navigation));
|
||||
values.put("ScreenLayout", Integer.toString(config.screenLayout & 15));
|
||||
values.put("HasHardKeyboard", Boolean.toString(config.keyboard == Configuration.KEYBOARD_QWERTY));
|
||||
values.put("HasFiveWayNavigation", Boolean.toString(config.navigation == Configuration.NAVIGATIONHIDDEN_YES));
|
||||
return values;
|
||||
}
|
||||
|
||||
private Map<String, String> getDisplayMetricsValues() {
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
|
||||
values.put("Screen.Density", Integer.toString((int) (metrics.density * 160f)));
|
||||
values.put("Screen.Width", Integer.toString(metrics.widthPixels));
|
||||
values.put("Screen.Height", Integer.toString(metrics.heightPixels));
|
||||
return values;
|
||||
}
|
||||
|
||||
private Map<String, String> getPackageManagerValues() {
|
||||
Map<String, String> values = new LinkedHashMap<>();
|
||||
values.put("Platforms", TextUtils.join(",", NativeDeviceInfoProvider.getPlatforms()));
|
||||
values.put("SharedLibraries", TextUtils.join(",", NativeDeviceInfoProvider.getSharedLibraries(activity)));
|
||||
values.put("Features", TextUtils.join(",", activity.getPackageManager().getSystemSharedLibraryNames()));
|
||||
values.put("Locales", TextUtils.join(",", NativeDeviceInfoProvider.getLocales()));
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@
|
||||
android:id="@+id/developer_email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="email"
|
||||
android:textColor="#5555ff"
|
||||
android:textSize="18sp"
|
||||
android:text="@string/about_developer_email" />
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="application_crashed">В Yalp Store произошёл сбой.\n\nВы можете помочь разработчику исправить это, отправив email с подробностями об ошибке. Нажмите OK чтобы открыть ваше email-приложение с письмом для разработчика, готовым к отправке.\n\nНикакой чувствительной и личной информации отправлено не будет, проверьте текст письма, если сомеваетесь.</string>
|
||||
<string name="about_developer_email_label">Почта разработчика:</string>
|
||||
<string name="about_logged_in">Ваш текущий аккаунт:</string>
|
||||
<string name="about_copied_to_clipboard">Скопировано в буфер обмена</string>
|
||||
@@ -9,6 +8,8 @@
|
||||
<string name="list_empty_updates">Обновлений нет</string>
|
||||
<string name="list_empty_search">Ничего не найдено</string>
|
||||
<string name="list_incompatible">несовместимо</string>
|
||||
<string name="dialog_title_application_crashed">В Yalp Store произошёл сбой</string>
|
||||
<string name="dialog_message_application_crashed">Вы можете помочь разработчику исправить это, отправив email с подробностями об ошибке. Нажмите OK чтобы открыть ваше email-приложение с письмом для разработчика, готовым к отправке.\n\nЕсли хотите, опишите проблему сами или добавьте любое другое сообщение.\n\nНикакой чувствительной и личной информации отправлено не будет, проверьте текст письма, если сомеваетесь.</string>
|
||||
<string name="dialog_two_factor_cancel">Позднее</string>
|
||||
<string name="dialog_two_factor_create_password">Создать пароль</string>
|
||||
<string name="dialog_title_two_factor">Двухэтапная аутентификация</string>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<string name="star_empty" translatable="false">☆</string>
|
||||
<string name="about_developer_email" translatable="false">yalp.store.dev@gmail.com</string>
|
||||
<string name="about_gsf_id" translatable="false">Google Services Framework id:</string>
|
||||
<string name="application_crashed">Sorry, Yalp Store crashed.\n\nYou can help fix this by sending error data to the developer. Clicking OK will take you to your default email app with a complete email ready to be sent to the developer.\n\nNo private or sensitive information is collected, please review the letter content if you doubt it.</string>
|
||||
<string name="about_developer_email_label">Developer\'s email:</string>
|
||||
<string name="about_logged_in">You are logged in as:</string>
|
||||
<string name="about_copied_to_clipboard">Copied to clipboard</string>
|
||||
@@ -24,6 +23,8 @@
|
||||
<string name="action_unwhitelist">Ignore updates</string>
|
||||
<string name="search_filter">All apps</string>
|
||||
<string name="search_title">Search applications</string>
|
||||
<string name="dialog_title_application_crashed">Sorry, Yalp Store crashed</string>
|
||||
<string name="dialog_message_application_crashed">You can help fix this by sending error data to the developer. Clicking OK will take you to your default email app with a complete email ready to be sent to the developer.\n\nFeel free to add your own description of the problem or any other message.\n\nNo private or sensitive information is collected, please review the letter content if you doubt it.</string>
|
||||
<string name="dialog_two_factor_cancel">Not now</string>
|
||||
<string name="dialog_two_factor_create_password">Create password</string>
|
||||
<string name="dialog_title_two_factor">2-Step Verification</string>
|
||||
|
||||
Reference in New Issue
Block a user