mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-31 07:36:09 +00:00
Add additional info to support emails and debuglogs.
This commit is contained in:
committed by
Alex Hart
parent
b156e4a79a
commit
3fef58057e
@@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.help;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@@ -27,8 +28,10 @@ import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiImageView;
|
||||
import org.thoughtcrime.securesms.util.AppSignatureUtil;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.text.AfterTextChanged;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -150,70 +153,36 @@ public class HelpFragment extends Fragment {
|
||||
.findFirst().orElse(null);
|
||||
|
||||
CommunicationActions.openEmail(requireContext(),
|
||||
getString(R.string.RegistrationActivity_support_email),
|
||||
SupportEmailUtil.getSupportEmailAddress(requireContext()),
|
||||
getEmailSubject(),
|
||||
getEmailBody(debugLog, feeling).toString());
|
||||
getEmailBody(debugLog, feeling));
|
||||
}
|
||||
|
||||
private String getEmailSubject() {
|
||||
return getString(R.string.HelpFragment__signal_android_support_request);
|
||||
}
|
||||
|
||||
private Spanned getEmailBody(@Nullable String debugLog, @Nullable Feeling feeling) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
|
||||
builder.append(problem.getText().toString());
|
||||
builder.append("\n\n");
|
||||
builder.append("--- ");
|
||||
builder.append(getString(R.string.HelpFragment__support_info));
|
||||
builder.append(" ---\n");
|
||||
builder.append(getString(R.string.HelpFragment__subject));
|
||||
builder.append(" ");
|
||||
builder.append(getString(R.string.HelpFragment__signal_android_support_request));
|
||||
builder.append("\n");
|
||||
builder.append(getString(R.string.HelpFragment__device_info));
|
||||
builder.append(" ");
|
||||
builder.append(getDeviceInfo());
|
||||
builder.append("\n");
|
||||
builder.append(getString(R.string.HelpFragment__android_version));
|
||||
builder.append(" ");
|
||||
builder.append(getAndroidVersion());
|
||||
builder.append("\n");
|
||||
builder.append(getString(R.string.HelpFragment__signal_version));
|
||||
builder.append(" ");
|
||||
builder.append(getSignalVersion());
|
||||
builder.append("\n");
|
||||
builder.append(getString(R.string.HelpFragment__locale));
|
||||
builder.append(" ");
|
||||
builder.append(Locale.getDefault().toString());
|
||||
private String getEmailBody(@Nullable String debugLog, @Nullable Feeling feeling) {
|
||||
StringBuilder suffix = new StringBuilder();
|
||||
|
||||
if (debugLog != null) {
|
||||
builder.append("\n");
|
||||
builder.append(getString(R.string.HelpFragment__debug_log));
|
||||
builder.append(" ");
|
||||
builder.append(debugLog);
|
||||
suffix.append("\n");
|
||||
suffix.append(getString(R.string.HelpFragment__debug_log));
|
||||
suffix.append(" ");
|
||||
suffix.append(debugLog);
|
||||
}
|
||||
|
||||
if (feeling != null) {
|
||||
builder.append("\n\n");
|
||||
builder.append(feeling.getEmojiCode());
|
||||
builder.append("\n");
|
||||
builder.append(getString(feeling.getStringId()));
|
||||
suffix.append("\n\n");
|
||||
suffix.append(feeling.getEmojiCode());
|
||||
suffix.append("\n");
|
||||
suffix.append(getString(feeling.getStringId()));
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
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;
|
||||
return SupportEmailUtil.generateSupportEmailBody(requireContext(),
|
||||
getString(R.string.HelpFragment__signal_android_support_request),
|
||||
problem.getText().toString() + "\n\n",
|
||||
suffix.toString());
|
||||
}
|
||||
|
||||
private static void setSpinning(@Nullable CircularProgressButton button) {
|
||||
|
||||
@@ -10,6 +10,8 @@ import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.util.AppSignatureUtil;
|
||||
import org.thoughtcrime.securesms.util.ByteUnit;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -60,6 +62,7 @@ public class LogSectionSystemInfo implements LogSection {
|
||||
} catch (PackageManager.NameNotFoundException nnfe) {
|
||||
builder.append("Unknown\n");
|
||||
}
|
||||
builder.append("Package : ").append(BuildConfig.APPLICATION_ID).append(" (").append(getSigningString(context)).append(")");
|
||||
|
||||
return builder;
|
||||
}
|
||||
@@ -134,4 +137,8 @@ public class LogSectionSystemInfo implements LogSection {
|
||||
private static @NonNull String getScreenRefreshRate(@NonNull Context context) {
|
||||
return String.format(Locale.ENGLISH, "%.2f hz", ServiceUtil.getWindowManager(context).getDefaultDisplay().getRefreshRate());
|
||||
}
|
||||
|
||||
private static String getSigningString(@NonNull Context context) {
|
||||
return AppSignatureUtil.getAppSignature(context).or("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.registration.RegistrationUtil;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
@@ -195,14 +196,14 @@ public class PinRestoreEntryFragment extends Fragment {
|
||||
.setMessage(getString(R.string.PinRestoreEntryFragment_your_pin_is_a_d_digit_code, KbsConstants.MINIMUM_PIN_LENGTH))
|
||||
.setPositiveButton(R.string.PinRestoreEntryFragment_create_new_pin, null)
|
||||
.setNeutralButton(R.string.PinRestoreEntryFragment_contact_support, (dialog, which) -> {
|
||||
String body = SupportEmailUtil.generateSupportEmailBody(requireContext(),
|
||||
getString(R.string.PinRestoreEntryFragment_signal_registration_need_help_with_pin),
|
||||
null,
|
||||
null);
|
||||
CommunicationActions.openEmail(requireContext(),
|
||||
getString(R.string.PinRestoreEntryFragment_support_email),
|
||||
SupportEmailUtil.getSupportEmailAddress(requireContext()),
|
||||
getString(R.string.PinRestoreEntryFragment_signal_registration_need_help_with_pin),
|
||||
getString(R.string.PinRestoreEntryFragment_subject_signal_registration,
|
||||
getDevice(),
|
||||
getAndroidVersion(),
|
||||
BuildConfig.VERSION_NAME,
|
||||
Locale.getDefault()));
|
||||
body);
|
||||
})
|
||||
.setNegativeButton(R.string.PinRestoreEntryFragment_cancel, null)
|
||||
.show();
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.registration.service.RegistrationCodeRequest;
|
||||
import org.thoughtcrime.securesms.registration.service.RegistrationService;
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.RegistrationViewModel;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.SupportEmailUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
|
||||
import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse;
|
||||
|
||||
@@ -306,21 +307,13 @@ public final class EnterCodeFragment extends BaseRegistrationFragment {
|
||||
}
|
||||
|
||||
private void sendEmailToSupport() {
|
||||
String body = SupportEmailUtil.generateSupportEmailBody(requireContext(),
|
||||
getString(R.string.RegistrationActivity_code_support_subject),
|
||||
null,
|
||||
null);
|
||||
CommunicationActions.openEmail(requireContext(),
|
||||
getString(R.string.RegistrationActivity_support_email),
|
||||
SupportEmailUtil.getSupportEmailAddress(requireContext()),
|
||||
getString(R.string.RegistrationActivity_code_support_subject),
|
||||
getString(R.string.RegistrationActivity_code_support_body,
|
||||
getDevice(),
|
||||
getAndroidVersion(),
|
||||
BuildConfig.VERSION_NAME,
|
||||
Locale.getDefault()));
|
||||
}
|
||||
|
||||
private static String getDevice() {
|
||||
return String.format("%s %s (%s)", Build.MANUFACTURER, Build.MODEL, Build.PRODUCT);
|
||||
}
|
||||
|
||||
private static String getAndroidVersion() {
|
||||
return String.format("%s (%s, %s)", Build.VERSION.RELEASE, Build.VERSION.INCREMENTAL, Build.DISPLAY);
|
||||
body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user