blob: 63270aab58bcf0170587b5edd92d330b6d209082 [file] [log] [blame]
/*
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package com.android.development;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.ContentObserver;
import android.database.DataSetObserver;
import android.graphics.Typeface;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Checkin;
import android.server.data.CrashData;
import android.server.data.ThrowableData;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.KeyEvent;
import android.widget.*;
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
/**
*
*
*/
public class ExceptionBrowser extends ListActivity {
/** Logging identifier. */
private static final String TAG = "ExceptionBrowser";
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Cursor cursor = getContentResolver().query(
Checkin.Crashes.CONTENT_URI,
new String[] { Checkin.Crashes._ID, Checkin.Crashes.DATA },
null, null, null);
if (cursor != null) {
startManagingCursor(cursor);
setListAdapter(new CursorAdapter(this, cursor, true) {
public View newView(Context context, Cursor c, ViewGroup v) {
return new CrashListItem(context);
}
public void bindView(View view, Context c, Cursor cursor) {
CrashListItem item = (CrashListItem) view;
try {
String data = cursor.getString(1);
CrashData crash = new CrashData(
new DataInputStream(
new ByteArrayInputStream(
Base64.decodeBase64(data.getBytes()))));
ThrowableData exc = crash.getThrowableData();
item.setText(exc.getType() + ": " + exc.getMessage());
item.setCrashData(crash);
} catch (IOException e) {
item.setText("Invalid crash: " + e);
Log.e(TAG, "Invalid crash", e);
}
}
});
} else {
// No database, no exceptions, empty list.
setListAdapter(new BaseAdapter() {
public int getCount() {
return 0;
}
public Object getItem(int position) {
throw new AssertionError();
}
public long getItemId(int position) {
throw new AssertionError();
}
public View getView(int position, View convertView,
ViewGroup parent) {
throw new AssertionError();
}
});
}
}
private static final int UPLOAD_ID = Menu.FIRST;
private static final int CLEAR_ID = Menu.FIRST + 1;
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, UPLOAD_ID, 0, R.string.menu_upload_exceptions);
menu.add(0, CLEAR_ID, 0, R.string.menu_clear_exceptions);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle all of the possible menu actions.
switch (item.getItemId()) {
case UPLOAD_ID:
sendBroadcast(new Intent(Checkin.TriggerIntent.ACTION));
break;
case CLEAR_ID:
getContentResolver().delete(
Checkin.Crashes.CONTENT_URI, null, null);
break;
}
return super.onOptionsItemSelected(item);
}
static class CrashListItem extends TextView {
CrashData crashData = null;
public CrashListItem(Context context) {
super(context);
setTextSize(10);
setTypeface(Typeface.MONOSPACE);
}
public CrashData getCrashData() {
return crashData;
}
public void setCrashData(CrashData crashData) {
this.crashData = crashData;
}
}
@Override
protected void onListItemClick(ListView l, View view, int pos, long id) {
// TODO: Use a generic VIEW action on the crash's content URI.
CrashData crash = ((CrashListItem) view).getCrashData();
if (crash != null) {
Intent intent = new Intent();
intent.setClass(this, StacktraceViewer.class);
intent.putExtra(
CrashData.class.getName(),
crash.getThrowableData().toString());
startActivity(intent);
}
}
}