package com.sibext.android.activity;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.sibext.android.manager.CrashCatcherManager;
import com.sibext.android.tools.CrashCatcherError;
import com.sibext.android.tools.KeyboardHelper;
import com.sibext.android.tools.ReportHelper;
import com.sibext.crashcatcher.R;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
/**
* Created by santaev on 3/10/15.
*/
public abstract class NewDesignActivity extends Activity{
public static enum ErrorType{
CRASH(R.string.error_type_crash, 0),
LOGIC_BUG(R.string.error_type_logic_bug, 0),
UI_BUG(R.string.error_type_ui_bug, 0),
FEEDBACK(R.string.error_type_feedback, 0);
private int nameId;
private int code;
ErrorType(int name, int code){
this.nameId = name;
this.code = code;
}
public int getName(){
return nameId;
}
public static ErrorType fromCode(int code){
for (int i = 0; i < ErrorType.values().length; i++) {
if (ErrorType.values()[i].code == code){
return ErrorType.values()[i];
}
}
throw new RuntimeException("Unknown Error Type code " + code);
}
}
private ImageView sliderArrow;
private SlidingUpPanelLayout slidingUpPanelLayout;
private Spinner spinner;
private TextView privacyText;
private View logo;
private View sliderContent;
private View header;
private ArrayAdapter spinnerAdapter;
private static final String TAG = "[CCL] CrashCatcherActivity";
private static final String DEFAULT_CRASH_SUBJECT = "Crash report";
private static final String DEFAULT_SUBJECT = "MANUAL Report";
public static final String TRACE_INFO = "TRACE_INFO";
public static final String RESULT_EXTRA_TEXT = "RESULT_EXTRA_TEXT";
private final static String STORAGE_DIRECTORY = Environment.getExternalStorageDirectory()
.toString();
private final static String SETTINGS_DIR_PROJECT = STORAGE_DIRECTORY + "/.settings";
final static String SETTINGS_DIR_LOG = STORAGE_DIRECTORY + "/.logcat";
private final static String PATH_TO_LOG = SETTINGS_DIR_LOG + "/logcat.txt";
private final static String PATH_TO_RESULT = SETTINGS_DIR_PROJECT + "/result.jpg";
private View yes;
private TextView yesText;
private View no;
private EditText note;
protected String currentReportId;
private boolean isManual;
private boolean isOpened = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: start");
setContentView(R.layout.new_activity);
TextView titleText = (TextView) findViewById(R.id.titleText);
sliderArrow = (ImageView) findViewById(R.id.slider_circle_arrow);
slidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
spinner = (Spinner) findViewById(R.id.spinner);
privacyText = (TextView) findViewById(R.id.privacy);
logo = findViewById(R.id.logo);
sliderContent = findViewById(R.id.slider_content);
header = findViewById(R.id.header);
slidingUpPanelLayout.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float v) {
}
@Override
public void onPanelCollapsed(View view) {
sliderArrow.setImageResource(R.drawable.circle_arrow_up);
}
@Override
public void onPanelExpanded(View view) {
sliderArrow.setImageResource(R.drawable.circle_arrow);
}
@Override
public void onPanelAnchored(View view) {
}
@Override
public void onPanelHidden(View view) {
}
});
ErrorType[] values = ErrorType.values();
String[] items = new String[values.length];
for (int i = 0; i < values.length; i++){
items[i] = getString(values[i].getName());
}
spinnerAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, items);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
yes = findViewById(R.id.button_yes);
yesText = (TextView) findViewById(R.id.button_yes_text);
no = findViewById(R.id.button_no);
note = (EditText)findViewById(R.id.editTextComment);
isManual = getIntent().getBooleanExtra(CrashCatcherManager.MANUAL_FLAG_KEY, false);
titleText.setText(isManual ? R.string.manual_report_message : R.string.crash_message);
note.setHint(isManual ? R.string.com_sibext_crashcatcher_manual_message_hint
: R.string.com_sibext_crashcatcher_message_hint);
no.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
KeyboardHelper.hide(v.getContext());
finish();
}
});
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
KeyboardHelper.hide(v.getContext());
yes.setClickable(false);
no.setClickable(false);
note.setEnabled(false);
spinner.setEnabled(false);
new CrashSendTask(isManual).execute();
}
});
Log.d(TAG, "onCreate: finish");
setListenerToRootView();
privacyText.setPaintFlags(privacyText.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy:");
no.setOnClickListener(null);
yes.setOnClickListener(null);
}
abstract protected boolean onReportReadyForSend(String title, StringBuilder body, String resultPath, boolean isManual, ErrorType errorType);
protected void onReportSent() {
onReportSent(getString(R.string.com_sibext_crashcatcher_status, currentReportId));
}
protected void onReportSent(final String status) {
note.post(new Runnable() {
@Override
public void run() {
note.setVisibility(View.INVISIBLE);
no.setVisibility(View.INVISIBLE);
yesText.setText(R.string.com_sibext_crashcatcher_exit);
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
yes.setClickable(true);
}
});
}
protected void onReportUnSent() {
onReportUnSent(getString(R.string.com_sibext_crashcatcher_error));
}
protected void onReportUnSent(final String reason) {
note.post(new Runnable() {
@Override
public void run() {
yes.setClickable(true);
no.setClickable(true);
note.setEnabled(true);
Toast.makeText(NewDesignActivity.this, reason, Toast.LENGTH_LONG).show();
}
});
}
protected String getNotes() {
return note.getText().toString();
}
protected boolean hasNotes() {
return getNotes().trim().length() != 0;
}
private String getPathResult() {
return PATH_TO_RESULT;
}
private String getSubject() {
return DEFAULT_SUBJECT;
}
private String getCrashSubject() {
return DEFAULT_CRASH_SUBJECT;
}
private String getPathLog() {
return PATH_TO_LOG;
}
private String getPathDirLog() {
return SETTINGS_DIR_LOG;
}
private void captureLog() {
final StringBuilder log = ReportHelper.getLog();
saveLogToFile(log);
}
private void saveLogToFile(StringBuilder builder) {
File outputFile = new File(getPathLog());
if ( outputFile.exists() ) {
outputFile.delete();
}
Writer writer = null;
try {
writer = new BufferedWriter(new FileWriter(outputFile));
writer.write(builder.toString());
} catch (Exception e) {
Log.e(TAG, "saveLogToFile failed", e);
throw new CrashCatcherError("Error writing file on device");
} finally {
try {
writer.close();
} catch (Exception e) {
}
}
}
private String getFinalSubject(boolean isManuallyMode) {
currentReportId = ReportHelper.generateReportID();
try {
String versionName = getPackageManager()
.getPackageInfo(getPackageName(), 0).versionName;
return "[" + getPackageName() + " v" + versionName + "] " + ( isManuallyMode ? getSubject() : getCrashSubject() ) + " " + currentReportId;
} catch (Exception e) {
return "[" + getPackageName() + " NO VERSION] " + getSubject() + " " + currentReportId;
}
}
private String getExtraText() {
return getIntent().getStringExtra(RESULT_EXTRA_TEXT);
}
private boolean hasExtraText() {
return getIntent().getStringExtra(RESULT_EXTRA_TEXT) != null;
}
private class CrashSendTask extends AsyncTask<Void, Void, Boolean> {
private final boolean isManuallyMode;
private StringBuilder body = new StringBuilder("");
public CrashSendTask(boolean isManuallyMode) {
this.isManuallyMode = isManuallyMode;
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Log.i(TAG, "Capture log...");
captureLog();
} catch (CrashCatcherError e) {
Log.e(TAG, "ERROR when capture log!");
body.append(e.getMessage()).append("\n");
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean success) {
if ( isCancelled() ) {
return;
}
if ( hasExtraText() ) {
body.append(getExtraText());
}
body.append("\n");
if ( !isManuallyMode ) {
body.append(" Error: ").append(getIntent().getStringExtra(TRACE_INFO));
} else {
body.append("Note: Manually sending");
}
final String title = getFinalSubject(isManuallyMode);
ErrorType[] values = ErrorType.values();
if ( onReportReadyForSend(title, body, getPathLog(), isManuallyMode, values[spinner.getSelectedItemPosition()]) ) {
finish();
}
}
}
public void setListenerToRootView(){
final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > 100 ) { // 99% of the time the height diff will be due to a keyboard.
//sliderContent.setVisibility(View.GONE);
if(!isOpened){
//Do two things, make the view top visible and the editText smaller
logo.setVisibility(View.GONE);
header.setVisibility(View.GONE);
privacyText.setVisibility(View.GONE);
slidingUpPanelLayout.setPanelHeight(0);
}
isOpened = true;
}else if(isOpened){
isOpened = false;
logo.setVisibility(View.VISIBLE);
header.setVisibility(View.VISIBLE);
slidingUpPanelLayout.setPanelHeight((int) getResources().getDimension(R.dimen.slider_header_closed_height));
privacyText.setVisibility(View.VISIBLE);
//sliderContent.setVisibility(View.VISIBLE);
}
}
});
}
}