keys = fields.keys();
+
+ post.addFormDataPart("Content-Type", "text/plain");
+
+ while (keys.hasNext()) {
+ String key = keys.next();
+ post.addFormDataPart(key, fields.getString(key));
+ }
+
+ post.addFormDataPart("file", "file", RequestBody.create(MediaType.parse("text/plain"), paste));
+
+ Response postResponse = client.newCall(new Request.Builder().url(url).post(post.build()).build()).execute();
+
+ if (!postResponse.isSuccessful()) {
+ throw new IOException("Bad response: " + postResponse);
+ }
+
+ return API_ENDPOINT + "/" + item;
+ } catch (IOException | JSONException e) {
+ Log.w("ImageActivity", e);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(final String response) {
+ super.onPostExecute(response);
+
+ if (response != null)
+ handleShowSuccessDialog(response);
+ else {
+ Log.w(TAG, "Response was null from Gist API.");
+ Toast.makeText(getActivity(), R.string.log_submit_activity__network_failure, Toast.LENGTH_LONG).show();
+ }
+ }
+ }
+
+ private static long asMegs(long bytes) {
+ return bytes / 1048576L;
+ }
+
+ public static String getMemoryUsage(Context context) {
+ Runtime info = Runtime.getRuntime();
+ info.totalMemory();
+ return String.format(Locale.ENGLISH, "%dM (%.2f%% free, %dM max)",
+ asMegs(info.totalMemory()),
+ (float)info.freeMemory() / info.totalMemory() * 100f,
+ asMegs(info.maxMemory()));
+ }
+
+ @TargetApi(VERSION_CODES.KITKAT)
+ public static String getMemoryClass(Context context) {
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ String lowMem = "";
+
+ if (VERSION.SDK_INT >= VERSION_CODES.KITKAT && activityManager.isLowRamDevice()) {
+ lowMem = ", low-mem device";
+ }
+ return activityManager.getMemoryClass() + lowMem;
+ }
+
+ private static String buildDescription(Context context) {
+ final PackageManager pm = context.getPackageManager();
+ final StringBuilder builder = new StringBuilder();
+
+
+ builder.append("Device : ")
+ .append(Build.MANUFACTURER).append(" ")
+ .append(Build.MODEL).append(" (")
+ .append(Build.PRODUCT).append(")\n");
+ builder.append("Android : ").append(VERSION.RELEASE).append(" (")
+ .append(VERSION.INCREMENTAL).append(", ")
+ .append(Build.DISPLAY).append(")\n");
+ builder.append("Memory : ").append(getMemoryUsage(context)).append("\n");
+ builder.append("Memclass: ").append(getMemoryClass(context)).append("\n");
+ builder.append("OS Host : ").append(Build.HOST).append("\n");
+ builder.append("App : ");
+ try {
+ builder.append(pm.getApplicationLabel(pm.getApplicationInfo(context.getPackageName(), 0)))
+ .append(" ")
+ .append(pm.getPackageInfo(context.getPackageName(), 0).versionName)
+ .append("\n");
+ } catch (PackageManager.NameNotFoundException nnfe) {
+ builder.append("Unknown\n");
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * This interface must be implemented by activities that contain this
+ * fragment to allow an interaction in this fragment to be communicated
+ * to the activity and potentially other fragments contained in that
+ * activity.
+ *
+ * See the Android Training lesson Communicating with Other Fragments for more information.
+ */
+ public interface OnLogSubmittedListener {
+ public void onSuccess();
+ public void onFailure();
+ public void onCancel();
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java b/src/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java
new file mode 100644
index 0000000000..fd1e7a5d42
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 Open Whisper Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.thoughtcrime.securesms.logsubmit.util;
+
+import android.util.Log;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Scrub data for possibly sensitive information
+ */
+public class Scrubber {
+ private static final String TAG = Scrubber.class.getSimpleName();
+ private static final Pattern E164_PATTERN = Pattern.compile("\\+\\d{10,15}");
+
+ private static final Pattern[] DEFAULTS = new Pattern[] {
+ E164_PATTERN
+ };
+
+ private final Pattern[] patterns;
+ public Scrubber(Pattern... patterns) {
+ this.patterns = patterns;
+ }
+
+ public Scrubber() {
+ this(DEFAULTS);
+ }
+
+ public String scrub(final String in) {
+ Log.d(TAG, "scrubbing input");
+ String out = in;
+ for (Pattern pattern : patterns) {
+ Matcher matcher = pattern.matcher(out);
+ while (matcher.find()) {
+
+ StringBuilder builder = new StringBuilder(out.substring(0, matcher.start()));
+ final String censored = matcher.group().substring(0,1) +
+ new String(new char[matcher.group().length()-3]).replace("\0", "*") +
+ matcher.group().substring(matcher.group().length()-2);
+ builder.append(censored);
+ builder.append(out.substring(matcher.end()));
+ Log.i(TAG, "replacing a match on /" + pattern.toString() + "/ => " + censored);
+ out = builder.toString();
+ }
+ }
+ return out;
+ }
+}