Index: src/org/adblockplus/android/CrashReportDialog.java |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/src/org/adblockplus/android/CrashReportDialog.java |
@@ -0,0 +1,160 @@ |
+package org.adblockplus.android; |
+ |
+import java.io.IOException; |
+import java.io.StringWriter; |
+import java.util.regex.Pattern; |
+ |
+import org.apache.http.HttpResponse; |
+import org.apache.http.StatusLine; |
+import org.apache.http.client.ClientProtocolException; |
+import org.apache.http.client.HttpClient; |
+import org.apache.http.client.methods.HttpPost; |
+import org.apache.http.entity.StringEntity; |
+import org.apache.http.impl.client.DefaultHttpClient; |
+import org.apache.http.util.EntityUtils; |
+import org.xmlpull.v1.XmlSerializer; |
+ |
+import android.app.Activity; |
+import android.os.Bundle; |
+import android.text.TextUtils; |
+import android.util.Log; |
+import android.util.Xml; |
+import android.view.View; |
+import android.view.Window; |
+import android.widget.EditText; |
+import android.widget.Toast; |
+ |
+/** |
+ * Shows crash report dialog asking user to submit crash report together with comments. |
+ */ |
+public final class CrashReportDialog extends Activity |
+{ |
+ private final static String TAG = "CrashReportDialog"; |
+ private String report; |
+ |
+ @Override |
+ protected void onCreate(Bundle savedInstanceState) |
+ { |
+ super.onCreate(savedInstanceState); |
+ requestWindowFeature(Window.FEATURE_LEFT_ICON); |
+ setContentView(R.layout.crashreport); |
+ |
+ Bundle extras = getIntent().getExtras(); |
+ if (extras == null) |
+ { |
+ finish(); |
+ return; |
+ } |
+ report = extras.getString("report"); |
+ |
+ getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, android.R.drawable.ic_dialog_alert); |
+ } |
+ |
+ public void onOk(View v) |
+ { |
+ String comment = ((EditText) findViewById(R.id.comments)).getText().toString(); |
+ |
+ try |
+ { |
+ String[] reportLines = report.split(System.getProperty("line.separator")); |
+ int api = Integer.parseInt(reportLines[0]); |
+ int build = Integer.parseInt(reportLines[1]); |
+ |
+ XmlSerializer xmlSerializer = Xml.newSerializer(); |
+ StringWriter writer = new StringWriter(); |
+ |
+ xmlSerializer.setOutput(writer); |
+ xmlSerializer.startDocument("UTF-8", true); |
+ xmlSerializer.startTag("", "crashreport"); |
+ xmlSerializer.attribute("", "version", "1"); |
+ xmlSerializer.attribute("", "api", String.valueOf(api)); |
+ xmlSerializer.attribute("", "build", String.valueOf(build)); |
+ xmlSerializer.startTag("", "error"); |
+ xmlSerializer.attribute("", "type", reportLines[2]); |
+ xmlSerializer.startTag("", "message"); |
+ xmlSerializer.text(reportLines[3]); |
+ xmlSerializer.endTag("", "message"); |
+ xmlSerializer.startTag("", "stacktrace"); |
+ Pattern p = Pattern.compile("\\|"); |
+ boolean hasCause = false; |
+ int i = 4; |
+ while (i < reportLines.length) |
+ { |
+ if ("cause".equals(reportLines[i])) |
+ { |
+ xmlSerializer.endTag("", "stacktrace"); |
+ xmlSerializer.startTag("", "cause"); |
+ hasCause = true; |
+ i++; |
+ xmlSerializer.attribute("", "type", reportLines[i]); |
+ i++; |
+ xmlSerializer.startTag("", "message"); |
+ xmlSerializer.text(reportLines[i]); |
+ i++; |
+ xmlSerializer.endTag("", "message"); |
+ xmlSerializer.startTag("", "stacktrace"); |
+ continue; |
+ } |
+ Log.e(TAG, "Line: " + reportLines[i]); |
+ String[] element = TextUtils.split(reportLines[i], p); |
+ xmlSerializer.startTag("", "frame"); |
+ xmlSerializer.attribute("", "class", element[0]); |
+ xmlSerializer.attribute("", "method", element[1]); |
+ xmlSerializer.attribute("", "isnative", element[2]); |
+ xmlSerializer.attribute("", "file", element[3]); |
+ xmlSerializer.attribute("", "line", element[4]); |
+ xmlSerializer.endTag("", "frame"); |
+ i++; |
+ } |
+ xmlSerializer.endTag("", "stacktrace"); |
+ if (hasCause) |
+ xmlSerializer.endTag("", "cause"); |
+ xmlSerializer.endTag("", "error"); |
+ xmlSerializer.startTag("", "comment"); |
+ xmlSerializer.text(comment); |
+ xmlSerializer.endTag("", "comment"); |
+ xmlSerializer.endTag("", "crashreport"); |
+ xmlSerializer.endDocument(); |
+ |
+ String xml = writer.toString(); |
+ HttpClient httpclient = new DefaultHttpClient(); |
+ HttpPost httppost = new HttpPost(getString(R.string.crash_report_url)); |
+ httppost.setHeader("Content-Type", "text/xml; charset=UTF-8"); |
+ httppost.addHeader("X-Adblock-Plus", "yes"); |
+ httppost.setEntity(new StringEntity(xml)); |
+ HttpResponse httpresponse = httpclient.execute(httppost); |
+ StatusLine statusLine = httpresponse.getStatusLine(); |
+ Log.e(TAG, statusLine.getStatusCode() + " " + statusLine.getReasonPhrase()); |
+ Log.e(TAG, EntityUtils.toString(httpresponse.getEntity())); |
+ if (statusLine.getStatusCode() != 200) |
+ throw new ClientProtocolException(); |
+ String response = EntityUtils.toString(httpresponse.getEntity()); |
+ if (!"saved".equals(response)) |
+ throw new ClientProtocolException(); |
+ deleteFile(CrashHandler.REPORT_FILE); |
+ } |
+ catch (ClientProtocolException e) |
+ { |
+ Log.e(TAG, "Failed to submit a crash", e); |
+ Toast.makeText(this, R.string.msg_crash_submission_failure, Toast.LENGTH_LONG).show(); |
+ } |
+ catch (IOException e) |
+ { |
+ Log.e(TAG, "Failed to submit a crash", e); |
+ Toast.makeText(this, R.string.msg_crash_submission_failure, Toast.LENGTH_LONG).show(); |
+ } |
+ catch (Exception e) |
+ { |
+ Log.e(TAG, "Failed to create report", e); |
+ // Assuming corrupted report file, just silently deleting it |
+ deleteFile(CrashHandler.REPORT_FILE); |
+ } |
+ finish(); |
+ } |
+ |
+ public void onCancel(View v) |
+ { |
+ deleteFile(CrashHandler.REPORT_FILE); |
+ finish(); |
+ } |
+} |