mirror of
https://github.com/oxen-io/session-android.git
synced 2025-05-03 12:30:48 +00:00
clean up unused log submit
This commit is contained in:
parent
bb8e8a4e16
commit
690687064f
@ -307,16 +307,6 @@
|
|||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.TextSecure.DayNight.NoActionBar"
|
android:theme="@style/Theme.TextSecure.DayNight.NoActionBar"
|
||||||
android:windowSoftInputMode="stateHidden" />
|
android:windowSoftInputMode="stateHidden" />
|
||||||
<activity
|
|
||||||
android:name="org.thoughtcrime.securesms.stickers.StickerManagementActivity"
|
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
|
||||||
android:launchMode="singleTask"
|
|
||||||
android:windowSoftInputMode="stateUnchanged" />
|
|
||||||
<activity
|
|
||||||
android:name="org.thoughtcrime.securesms.LogSubmitActivity"
|
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
|
||||||
android:label="@string/AndroidManifest__log_submit"
|
|
||||||
android:windowSoftInputMode="stateHidden" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.thoughtcrime.securesms.MediaPreviewActivity"
|
android:name="org.thoughtcrime.securesms.MediaPreviewActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms;
|
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.session.libsignal.utilities.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.logsubmit.SubmitLogFragment;
|
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activity for submitting logcat logs to a pastebin service.
|
|
||||||
*/
|
|
||||||
public class LogSubmitActivity extends BaseActionBarActivity implements SubmitLogFragment.OnLogSubmittedListener {
|
|
||||||
|
|
||||||
private static final String TAG = LogSubmitActivity.class.getSimpleName();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle icicle) {
|
|
||||||
super.onCreate(icicle);
|
|
||||||
setContentView(R.layout.log_submit_activity);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
SubmitLogFragment fragment = SubmitLogFragment.newInstance();
|
|
||||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
|
||||||
transaction.replace(R.id.fragment_container, fragment);
|
|
||||||
transaction.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
switch (item.getItemId()) {
|
|
||||||
case android.R.id.home:
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess() {
|
|
||||||
Toast.makeText(getApplicationContext(), R.string.log_submit_activity__thanks, Toast.LENGTH_LONG).show();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure() {
|
|
||||||
Toast.makeText(getApplicationContext(), R.string.log_submit_activity__log_fetch_failed, Toast.LENGTH_LONG).show();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel() {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startActivity(Intent intent) {
|
|
||||||
try {
|
|
||||||
super.startActivity(intent);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
Toast.makeText(this, R.string.log_submit_activity__no_browser_installed, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* *
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
* /
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms.logsubmit;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rhodey
|
|
||||||
*/
|
|
||||||
public class ShareIntentListAdapter extends ArrayAdapter<ResolveInfo> {
|
|
||||||
|
|
||||||
public static ShareIntentListAdapter getAdapterForIntent(Context context, Intent shareIntent) {
|
|
||||||
List<ResolveInfo> activities = context.getPackageManager().queryIntentActivities(shareIntent, 0);
|
|
||||||
return new ShareIntentListAdapter(context, activities.toArray(new ResolveInfo[activities.size()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShareIntentListAdapter(Context context, ResolveInfo[] items) {
|
|
||||||
super(context, R.layout.share_intent_list, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
|
||||||
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
View rowView = inflater.inflate(R.layout.share_intent_row, parent, false);
|
|
||||||
ImageView intentImage = (ImageView) rowView.findViewById(R.id.share_intent_image);
|
|
||||||
TextView intentLabel = (TextView) rowView.findViewById(R.id.share_intent_label);
|
|
||||||
|
|
||||||
ApplicationInfo intentInfo = getItem(position).activityInfo.applicationInfo;
|
|
||||||
|
|
||||||
intentImage.setImageDrawable(intentInfo.loadIcon(getContext().getPackageManager()));
|
|
||||||
intentLabel.setText(intentInfo.loadLabel(getContext().getPackageManager()));
|
|
||||||
|
|
||||||
return rowView;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,614 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms.logsubmit;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Build.VERSION;
|
|
||||||
import android.os.Build.VERSION_CODES;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import android.text.ClipboardManager;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.text.method.LinkMovementMethod;
|
|
||||||
import android.text.util.Linkify;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
|
||||||
import network.loki.messenger.R;
|
|
||||||
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher;
|
|
||||||
import org.session.libsignal.utilities.logging.Log;
|
|
||||||
import org.thoughtcrime.securesms.logsubmit.util.Scrubber;
|
|
||||||
import org.session.libsession.utilities.Util;
|
|
||||||
import org.session.libsession.utilities.task.ProgressDialogAsyncTask;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
import okhttp3.MediaType;
|
|
||||||
import okhttp3.MultipartBody;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper {@link Fragment} to preview and submit logcat information to a public pastebin.
|
|
||||||
* Activities that contain this fragment must implement the
|
|
||||||
* {@link SubmitLogFragment.OnLogSubmittedListener} interface
|
|
||||||
* to handle interaction events.
|
|
||||||
* Use the {@link SubmitLogFragment#newInstance} factory method to
|
|
||||||
* create an instance of this fragment.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SubmitLogFragment extends Fragment {
|
|
||||||
|
|
||||||
private static final String TAG = SubmitLogFragment.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final String API_ENDPOINT = "https://debuglogs.org";
|
|
||||||
|
|
||||||
private static final String HEADER_SYSINFO = "========== SYSINFO ========";
|
|
||||||
private static final String HEADER_JOBS = "=========== JOBS =========";
|
|
||||||
private static final String HEADER_LOGCAT = "========== LOGCAT ========";
|
|
||||||
private static final String HEADER_LOGGER = "========== LOGGER ========";
|
|
||||||
|
|
||||||
private Button okButton;
|
|
||||||
private Button cancelButton;
|
|
||||||
private View scrollButton;
|
|
||||||
private String supportEmailAddress;
|
|
||||||
private String supportEmailSubject;
|
|
||||||
private String hackSavedLogUrl;
|
|
||||||
private boolean emailActivityWasStarted = false;
|
|
||||||
|
|
||||||
|
|
||||||
private RecyclerView logPreview;
|
|
||||||
private LogPreviewAdapter logPreviewAdapter;
|
|
||||||
private OnLogSubmittedListener mListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this factory method to create a new instance of
|
|
||||||
* this fragment using the provided parameters.
|
|
||||||
*
|
|
||||||
* @return A new instance of fragment SubmitLogFragment.
|
|
||||||
*/
|
|
||||||
public static SubmitLogFragment newInstance(String supportEmailAddress,
|
|
||||||
String supportEmailSubject)
|
|
||||||
{
|
|
||||||
SubmitLogFragment fragment = new SubmitLogFragment();
|
|
||||||
|
|
||||||
fragment.supportEmailAddress = supportEmailAddress;
|
|
||||||
fragment.supportEmailSubject = supportEmailSubject;
|
|
||||||
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SubmitLogFragment newInstance()
|
|
||||||
{
|
|
||||||
return newInstance(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubmitLogFragment() { }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
return inflater.inflate(R.layout.fragment_submit_log, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
initializeResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity) {
|
|
||||||
super.onAttach(activity);
|
|
||||||
try {
|
|
||||||
mListener = (OnLogSubmittedListener) activity;
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
if (emailActivityWasStarted && mListener != null)
|
|
||||||
mListener.onSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
super.onDetach();
|
|
||||||
mListener = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeResources() {
|
|
||||||
okButton = getView().findViewById(R.id.ok);
|
|
||||||
cancelButton = getView().findViewById(R.id.cancel);
|
|
||||||
logPreview = getView().findViewById(R.id.log_preview);
|
|
||||||
scrollButton = getView().findViewById(R.id.scroll_to_bottom_button);
|
|
||||||
|
|
||||||
okButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
new SubmitToPastebinAsyncTask(logPreviewAdapter.getText()).execute();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cancelButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
if (mListener != null) mListener.onCancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scrollButton.setOnClickListener(v -> logPreview.scrollToPosition(logPreviewAdapter.getItemCount() - 1));
|
|
||||||
|
|
||||||
logPreview.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
|
||||||
@Override
|
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
|
||||||
if (((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() < logPreviewAdapter.getItemCount() - 10) {
|
|
||||||
scrollButton.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
scrollButton.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
logPreviewAdapter = new LogPreviewAdapter();
|
|
||||||
|
|
||||||
logPreview.setLayoutManager(new LinearLayoutManager(getContext()));
|
|
||||||
logPreview.setAdapter(logPreviewAdapter);
|
|
||||||
|
|
||||||
new PopulateLogcatAsyncTask(getActivity()).execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String grabLogcat() {
|
|
||||||
try {
|
|
||||||
final Process process = Runtime.getRuntime().exec("logcat -d");
|
|
||||||
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
||||||
final StringBuilder log = new StringBuilder();
|
|
||||||
final String separator = System.getProperty("line.separator");
|
|
||||||
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
log.append(line);
|
|
||||||
log.append(separator);
|
|
||||||
}
|
|
||||||
return log.toString();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
Log.w(TAG, "IOException when trying to read logcat.", ioe);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intent getIntentForSupportEmail(String logUrl) {
|
|
||||||
Intent emailSendIntent = new Intent(Intent.ACTION_SEND);
|
|
||||||
|
|
||||||
emailSendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { supportEmailAddress });
|
|
||||||
emailSendIntent.putExtra(Intent.EXTRA_SUBJECT, supportEmailSubject);
|
|
||||||
emailSendIntent.putExtra(
|
|
||||||
Intent.EXTRA_TEXT,
|
|
||||||
getString(R.string.log_submit_activity__please_review_this_log_from_my_app, logUrl)
|
|
||||||
);
|
|
||||||
emailSendIntent.setType("message/rfc822");
|
|
||||||
|
|
||||||
return emailSendIntent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleShowChooserForIntent(final Intent intent, String chooserTitle) {
|
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
|
||||||
final ShareIntentListAdapter adapter = ShareIntentListAdapter.getAdapterForIntent(getActivity(), intent);
|
|
||||||
|
|
||||||
builder.setTitle(chooserTitle)
|
|
||||||
.setAdapter(adapter, new DialogInterface.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
ActivityInfo info = adapter.getItem(which).activityInfo;
|
|
||||||
intent.setClassName(info.packageName, info.name);
|
|
||||||
startActivity(intent);
|
|
||||||
|
|
||||||
emailActivityWasStarted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dialogInterface) {
|
|
||||||
if (hackSavedLogUrl != null)
|
|
||||||
handleShowSuccessDialog(hackSavedLogUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.create().show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView handleBuildSuccessTextView(final String logUrl) {
|
|
||||||
TextView showText = new TextView(getActivity());
|
|
||||||
|
|
||||||
showText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
|
|
||||||
showText.setPadding(15, 30, 15, 30);
|
|
||||||
showText.setText(getString(R.string.log_submit_activity__copy_this_url_and_add_it_to_your_issue, logUrl));
|
|
||||||
showText.setAutoLinkMask(Activity.RESULT_OK);
|
|
||||||
showText.setMovementMethod(LinkMovementMethod.getInstance());
|
|
||||||
showText.setOnLongClickListener(new View.OnLongClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(View v) {
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
ClipboardManager manager =
|
|
||||||
(ClipboardManager) getActivity().getSystemService(Activity.CLIPBOARD_SERVICE);
|
|
||||||
manager.setText(logUrl);
|
|
||||||
Toast.makeText(getActivity(),
|
|
||||||
R.string.log_submit_activity__copied_to_clipboard,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Linkify.addLinks(showText, Linkify.WEB_URLS);
|
|
||||||
return showText;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleShowSuccessDialog(final String logUrl) {
|
|
||||||
TextView showText = handleBuildSuccessTextView(logUrl);
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
|
||||||
|
|
||||||
builder.setTitle(R.string.log_submit_activity__success)
|
|
||||||
.setView(showText)
|
|
||||||
.setCancelable(false)
|
|
||||||
.setNeutralButton(R.string.log_submit_activity__button_got_it, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
dialogInterface.dismiss();
|
|
||||||
if (mListener != null) mListener.onSuccess();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (supportEmailAddress != null) {
|
|
||||||
builder.setPositiveButton(R.string.log_submit_activity__button_compose_email, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
handleShowChooserForIntent(
|
|
||||||
getIntentForSupportEmail(logUrl),
|
|
||||||
getString(R.string.log_submit_activity__choose_email_app)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.create().show();
|
|
||||||
hackSavedLogUrl = logUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PopulateLogcatAsyncTask extends AsyncTask<Void,Void,String> {
|
|
||||||
private WeakReference<Context> weakContext;
|
|
||||||
|
|
||||||
public PopulateLogcatAsyncTask(Context context) {
|
|
||||||
this.weakContext = new WeakReference<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(Void... voids) {
|
|
||||||
Context context = weakContext.get();
|
|
||||||
if (context == null) return null;
|
|
||||||
|
|
||||||
Scrubber scrubber = new Scrubber();
|
|
||||||
|
|
||||||
String newLogs;
|
|
||||||
try {
|
|
||||||
long t1 = System.currentTimeMillis();
|
|
||||||
String logs = ApplicationContext.getInstance(context).getPersistentLogger().getLogs().get();
|
|
||||||
Log.i(TAG, "Fetch our logs : " + (System.currentTimeMillis() - t1) + " ms");
|
|
||||||
|
|
||||||
long t2 = System.currentTimeMillis();
|
|
||||||
newLogs = scrubber.scrub(logs);
|
|
||||||
Log.i(TAG, "Scrub our logs: " + (System.currentTimeMillis() - t2) + " ms");
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
Log.w(TAG, "Failed to retrieve new logs.", e);
|
|
||||||
newLogs = "Failed to retrieve logs.";
|
|
||||||
}
|
|
||||||
|
|
||||||
long t3 = System.currentTimeMillis();
|
|
||||||
String logcat = grabLogcat();
|
|
||||||
Log.i(TAG, "Fetch logcat: " + (System.currentTimeMillis() - t3) + " ms");
|
|
||||||
|
|
||||||
long t4 = System.currentTimeMillis();
|
|
||||||
String scrubbedLogcat = scrubber.scrub(logcat);
|
|
||||||
Log.i(TAG, "Scrub logcat: " + (System.currentTimeMillis() - t4) + " ms");
|
|
||||||
|
|
||||||
return HEADER_SYSINFO + "\n\n" +
|
|
||||||
buildDescription(context) + "\n\n\n" +
|
|
||||||
HEADER_JOBS + "\n\n" +
|
|
||||||
scrubber.scrub(ApplicationContext.getInstance(context).getJobManager().getDebugInfo()) + "\n\n" +
|
|
||||||
HEADER_LOGCAT + "\n\n" +
|
|
||||||
scrubbedLogcat + "\n\n\n" +
|
|
||||||
HEADER_LOGGER + "\n\n" +
|
|
||||||
newLogs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
super.onPreExecute();
|
|
||||||
logPreviewAdapter.setText(getString(R.string.log_submit_activity__loading_logs));
|
|
||||||
okButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(String logcat) {
|
|
||||||
super.onPostExecute(logcat);
|
|
||||||
if (TextUtils.isEmpty(logcat)) {
|
|
||||||
if (mListener != null) mListener.onFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
logPreviewAdapter.setText(logcat);
|
|
||||||
okButton.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SubmitToPastebinAsyncTask extends ProgressDialogAsyncTask<Void,Void,String> {
|
|
||||||
private final String paste;
|
|
||||||
|
|
||||||
public SubmitToPastebinAsyncTask(String paste) {
|
|
||||||
super(getActivity(), R.string.log_submit_activity__submitting, R.string.log_submit_activity__uploading_logs);
|
|
||||||
this.paste = paste;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(Void... voids) {
|
|
||||||
try {
|
|
||||||
OkHttpClient client = new OkHttpClient.Builder().build();
|
|
||||||
Response response = client.newCall(new Request.Builder().url(API_ENDPOINT).get().build()).execute();
|
|
||||||
ResponseBody body = response.body();
|
|
||||||
|
|
||||||
if (!response.isSuccessful() || body == null) {
|
|
||||||
throw new IOException("Unsuccessful response: " + response);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSONObject json = new JSONObject(body.string());
|
|
||||||
String url = json.getString("url");
|
|
||||||
JSONObject fields = json.getJSONObject("fields");
|
|
||||||
String item = fields.getString("key");
|
|
||||||
MultipartBody.Builder post = new MultipartBody.Builder();
|
|
||||||
Iterator<String> 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("Time : ").append(System.currentTimeMillis()).append('\n');
|
|
||||||
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("ABIs : ").append(TextUtils.join(", ", getSupportedAbis())).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(" (")
|
|
||||||
.append(org.thoughtcrime.securesms.util.Util.getManifestApkVersion(context))
|
|
||||||
.append(")\n");
|
|
||||||
} catch (PackageManager.NameNotFoundException nnfe) {
|
|
||||||
builder.append("Unknown\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Iterable<String> getSupportedAbis() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
return Arrays.asList(Build.SUPPORTED_ABIS);
|
|
||||||
} else {
|
|
||||||
LinkedList<String> abis = new LinkedList<>();
|
|
||||||
abis.add(Build.CPU_ABI);
|
|
||||||
if (Build.CPU_ABI2 != null && !"unknown".equals(Build.CPU_ABI2)) {
|
|
||||||
abis.add(Build.CPU_ABI2);
|
|
||||||
}
|
|
||||||
return abis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* See the Android Training lesson <a href=
|
|
||||||
* "http://developer.android.com/training/basics/fragments/communicating.html"
|
|
||||||
* >Communicating with Other Fragments</a> for more information.
|
|
||||||
*/
|
|
||||||
public interface OnLogSubmittedListener {
|
|
||||||
public void onSuccess();
|
|
||||||
public void onFailure();
|
|
||||||
public void onCancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class LogPreviewAdapter extends RecyclerView.Adapter<LogPreviewViewHolder> {
|
|
||||||
|
|
||||||
private String[] lines = new String[0];
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LogPreviewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
||||||
return new LogPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_log_preview, parent, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(LogPreviewViewHolder holder, int position) {
|
|
||||||
holder.bind(lines, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewRecycled(LogPreviewViewHolder holder) {
|
|
||||||
holder.unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return lines.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setText(@NonNull String text) {
|
|
||||||
lines = text.split("\n");
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
String getText() {
|
|
||||||
return Util.join(lines, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class LogPreviewViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private EditText text;
|
|
||||||
private String[] lines;
|
|
||||||
private int index;
|
|
||||||
|
|
||||||
LogPreviewViewHolder(View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
text = (EditText) itemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(String[] lines, int index) {
|
|
||||||
this.lines = lines;
|
|
||||||
this.index = index;
|
|
||||||
|
|
||||||
text.setText(lines[index]);
|
|
||||||
text.addTextChangedListener(textWatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unbind() {
|
|
||||||
text.removeTextChangedListener(textWatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final SimpleTextWatcher textWatcher = new SimpleTextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(String text) {
|
|
||||||
if (lines != null) {
|
|
||||||
lines[index] = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms.logsubmit.util;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
String out = in;
|
|
||||||
for (Pattern pattern : patterns) {
|
|
||||||
Matcher matcher = pattern.matcher(out);
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
int lastEndingPos = 0;
|
|
||||||
|
|
||||||
while (matcher.find()) {
|
|
||||||
builder.append(out.substring(lastEndingPos, 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);
|
|
||||||
|
|
||||||
lastEndingPos = matcher.end();
|
|
||||||
}
|
|
||||||
builder.append(out.substring(lastEndingPos));
|
|
||||||
out = builder.toString();
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user