Add additional info to support emails and debuglogs.

This commit is contained in:
Greyson Parrelli
2020-05-06 15:02:26 -04:00
committed by Alex Hart
parent b156e4a79a
commit 3fef58057e
7 changed files with 187 additions and 79 deletions

View File

@@ -0,0 +1,71 @@
package org.thoughtcrime.securesms.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.logging.Log;
import org.whispersystems.libsignal.util.guava.Optional;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public final class AppSignatureUtil {
private static final String TAG = Log.tag(AppSignatureUtil.class);
private static final String HASH_TYPE = "SHA-256";
private static final int HASH_LENGTH_BYTES = 9;
private static final int HASH_LENGTH_CHARS = 11;
private AppSignatureUtil() {}
/**
* Only intended to be used for logging.
*/
@SuppressLint("PackageManagerGetSignatures")
public static Optional<String> getAppSignature(@NonNull Context context) {
try {
String packageName = context.getPackageName();
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
if (signatures.length > 0) {
String hash = hash(packageName, signatures[0].toCharsString());
return Optional.fromNullable(hash);
}
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, e);
}
return Optional.absent();
}
private static String hash(String packageName, String signature) {
String appInfo = packageName + " " + signature;
try {
MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
byte[] hashSignature = messageDigest.digest();
hashSignature = Arrays.copyOfRange(hashSignature, 0, HASH_LENGTH_BYTES);
String base64Hash = Base64.encodeBytes(hashSignature);
base64Hash = base64Hash.substring(0, HASH_LENGTH_CHARS);
return base64Hash;
} catch (NoSuchAlgorithmException e) {
Log.w(TAG, e);
}
return null;
}
}

View File

@@ -0,0 +1,66 @@
package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.R;
import java.util.Locale;
public final class SupportEmailUtil {
private SupportEmailUtil() { }
public static @NonNull String getSupportEmailAddress(@NonNull Context context) {
return context.getString(R.string.SupportEmailUtil_support_email);
}
/**
* Generates a support email body with system info near the top.
*/
public static @NonNull String generateSupportEmailBody(@NonNull Context context,
@NonNull String subject,
@Nullable String prefix,
@Nullable String suffix)
{
prefix = Util.firstNonNull(prefix, "");
suffix = Util.firstNonNull(suffix, "");
return String.format("%s\n%s\n%s", prefix, buildSystemInfo(context, subject), suffix);
}
private static @NonNull String buildSystemInfo(@NonNull Context context, @NonNull String subject) {
return "--- " + context.getString(R.string.HelpFragment__support_info) + " ---" +
"\n" +
context.getString(R.string.SupportEmailUtil_subject) + " " + subject +
"\n" +
context.getString(R.string.SupportEmailUtil_device_info) + " " + getDeviceInfo() +
"\n" +
context.getString(R.string.SupportEmailUtil_android_version) + " " + getAndroidVersion() +
"\n" +
context.getString(R.string.SupportEmailUtil_signal_version) + " " + getSignalVersion() +
"\n" +
context.getString(R.string.SupportEmailUtil_signal_package) + " " + getSignalPackage(context) +
"\n" +
context.getString(R.string.SupportEmailUtil_locale) + " " + Locale.getDefault().toString();
}
private static CharSequence getDeviceInfo() {
return String.format("%s %s (%s)", Build.MANUFACTURER, Build.MODEL, Build.PRODUCT);
}
private static CharSequence getAndroidVersion() {
return String.format("%s (%s, %s)", Build.VERSION.RELEASE, Build.VERSION.INCREMENTAL, Build.DISPLAY);
}
private static CharSequence getSignalVersion() {
return BuildConfig.VERSION_NAME;
}
private static CharSequence getSignalPackage(@NonNull Context context) {
return String.format("%s (%s)", BuildConfig.APPLICATION_ID, AppSignatureUtil.getAppSignature(context).or("Unknown"));
}
}