summaryrefslogtreecommitdiff
path: root/src/com/android/browser/ErrorConsoleView.java
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-07-01 20:19:05 +0100
committerBen Murdoch <benm@google.com>2009-07-17 11:22:26 +0100
commitbff2d603c022691237c31d9a57ad8c217c6e7e11 (patch)
tree3e29889b7e51881715cb3fbb32b197c81d877754 /src/com/android/browser/ErrorConsoleView.java
parentcd11589fc3930906d4b9b7dd18aa52a9f1eb0c8a (diff)
Implement an error console. The console is displayed when the user has enabled debug in the browser (been to about:debug) and there are errors on the page. It can be toggled on/off in debug mode in the settings menu.
Diffstat (limited to 'src/com/android/browser/ErrorConsoleView.java')
-rw-r--r--src/com/android/browser/ErrorConsoleView.java339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/com/android/browser/ErrorConsoleView.java b/src/com/android/browser/ErrorConsoleView.java
new file mode 100644
index 00000000..56f663be
--- /dev/null
+++ b/src/com/android/browser/ErrorConsoleView.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2009 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.browser;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.webkit.WebView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.TwoLineListItem;
+
+import java.util.Vector;
+
+/* package */ class ErrorConsoleView extends LinearLayout {
+
+ /**
+ * Define some constants to describe the visibility of the error console.
+ */
+ public static final int SHOW_MINIMIZED = 0;
+ public static final int SHOW_MAXIMIZED = 1;
+ public static final int SHOW_NONE = 2;
+
+ private TextView mConsoleHeader;
+ private ErrorConsoleListView mErrorList;
+ private LinearLayout mEvalJsViewGroup;
+ private EditText mEvalEditText;
+ private Button mEvalButton;
+ private WebView mWebView;
+ private int mCurrentShowState = SHOW_NONE;
+
+ private boolean mSetupComplete = false;
+
+ // Before we've been asked to display the console, cache any messages that should
+ // be added to the console. Then when we do display the console, add them to the view
+ // then.
+ private Vector<ErrorConsoleMessage> mErrorMessageCache;
+
+ public ErrorConsoleView(Context context) {
+ super(context);
+ }
+
+ public ErrorConsoleView(Context context, AttributeSet attributes) {
+ super(context, attributes);
+ }
+
+ private void commonSetupIfNeeded() {
+ if (mSetupComplete) {
+ return;
+ }
+
+ LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.error_console, this);
+
+ // Get references to each ui element.
+ mConsoleHeader = (TextView) findViewById(R.id.error_console_header_id);
+ mErrorList = (ErrorConsoleListView) findViewById(R.id.error_console_list_id);
+ mEvalJsViewGroup = (LinearLayout) findViewById(R.id.error_console_eval_view_group_id);
+ mEvalEditText = (EditText) findViewById(R.id.error_console_eval_text_id);
+ mEvalButton = (Button) findViewById(R.id.error_console_eval_button_id);
+
+ mEvalButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ // Send the javascript to be evaluated to webkit as a javascript: url
+ // TODO: Can we expose access to webkit's JS interpreter here and evaluate it that
+ // way? Note that this is called on the UI thread so we will need to post a message
+ // to the WebCore thread to implement this.
+ if (mWebView != null) {
+ mWebView.loadUrl("javascript:" + mEvalEditText.getText());
+ }
+
+ mEvalEditText.setText("");
+ }
+ });
+
+ // Make clicking on the console title bar min/maximse it.
+ mConsoleHeader.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurrentShowState == SHOW_MINIMIZED) {
+ showConsole(SHOW_MAXIMIZED);
+ } else {
+ showConsole(SHOW_MINIMIZED);
+ }
+ }
+ });
+
+ // Add any cached messages to the list now that we've assembled the view.
+ if (mErrorMessageCache != null) {
+ for (ErrorConsoleMessage msg : mErrorMessageCache) {
+ mErrorList.addErrorMessage(msg.getMessage(), msg.getSourceID(), msg.getLineNumber());
+ }
+ mErrorMessageCache.clear();
+ }
+
+ mSetupComplete = true;
+ }
+
+ /**
+ * Adds a message to the set of messages the console uses.
+ */
+ public void addErrorMessage(String msg, String sourceId, int lineNumber) {
+ if (mSetupComplete) {
+ mErrorList.addErrorMessage(msg, sourceId, lineNumber);
+ } else {
+ if (mErrorMessageCache == null) {
+ mErrorMessageCache = new Vector<ErrorConsoleMessage>();
+ }
+ mErrorMessageCache.add(new ErrorConsoleMessage(msg, sourceId, lineNumber));
+ }
+ }
+
+ /**
+ * Removes all error messages from the console.
+ */
+ public void clearErrorMessages() {
+ if (mSetupComplete) {
+ mErrorList.clearErrorMessages();
+ } else if (mErrorMessageCache != null) {
+ mErrorMessageCache.clear();
+ }
+ }
+
+ /**
+ * Returns the current number of errors displayed in the console.
+ */
+ public int numberOfErrors() {
+ if (mSetupComplete) {
+ return mErrorList.getCount();
+ } else {
+ return (mErrorMessageCache == null) ? 0 : mErrorMessageCache.size();
+ }
+ }
+
+ /**
+ * Sets the webview that this console is associated with. Currently this is used so
+ * we can call into webkit to evaluate JS expressions in the console.
+ */
+ public void setWebView(WebView webview) {
+ mWebView = webview;
+ }
+
+ /**
+ * Sets the visibility state of the console.
+ */
+ public void showConsole(int show_state) {
+ commonSetupIfNeeded();
+ switch (show_state) {
+ case SHOW_MINIMIZED:
+ mConsoleHeader.setVisibility(View.VISIBLE);
+ mConsoleHeader.setText(R.string.error_console_header_text_minimized);
+ mErrorList.setVisibility(View.GONE);
+ mEvalJsViewGroup.setVisibility(View.GONE);
+ break;
+
+ case SHOW_MAXIMIZED:
+ mConsoleHeader.setVisibility(View.VISIBLE);
+ mConsoleHeader.setText(R.string.error_console_header_text_maximized);
+ mErrorList.setVisibility(View.VISIBLE);
+ mEvalJsViewGroup.setVisibility(View.VISIBLE);
+ break;
+
+ case SHOW_NONE:
+ mConsoleHeader.setVisibility(View.GONE);
+ mErrorList.setVisibility(View.GONE);
+ mEvalJsViewGroup.setVisibility(View.GONE);
+ break;
+ }
+ mCurrentShowState = show_state;
+ }
+
+ /**
+ * Returns the current visibility state of the console.
+ */
+ public int getShowState() {
+ if (mSetupComplete) {
+ return mCurrentShowState;
+ } else {
+ return SHOW_NONE;
+ }
+ }
+
+ /**
+ * This class extends ListView to implement the View that will actually display the set of
+ * errors encountered on the current page.
+ */
+ private static class ErrorConsoleListView extends ListView {
+ // An adapter for this View that contains a list of error messages.
+ private ErrorConsoleMessageList mConsoleMessages;
+
+ public ErrorConsoleListView(Context context, AttributeSet attributes) {
+ super(context, attributes);
+ mConsoleMessages = new ErrorConsoleMessageList(context);
+ setAdapter(mConsoleMessages);
+ }
+
+ public void addErrorMessage(String msg, String sourceId, int lineNumber) {
+ mConsoleMessages.add(msg, sourceId, lineNumber);
+ setSelection(mConsoleMessages.getCount());
+ }
+
+ public void clearErrorMessages() {
+ mConsoleMessages.clear();
+ }
+
+ /**
+ * This class is an adapter for ErrorConsoleListView that contains the error console
+ * message data.
+ */
+ private class ErrorConsoleMessageList extends android.widget.BaseAdapter
+ implements android.widget.ListAdapter {
+
+ private Vector<ErrorConsoleMessage> mMessages;
+ private LayoutInflater mInflater;
+
+ public ErrorConsoleMessageList(Context context) {
+ mMessages = new Vector<ErrorConsoleMessage>();
+ mInflater = (LayoutInflater)context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ /**
+ * Add a new message to the list and update the View.
+ */
+ public void add(String msg, String sourceID, int lineNumber) {
+ mMessages.add(new ErrorConsoleMessage(msg, sourceID, lineNumber));
+ notifyDataSetChanged();
+ }
+
+ /**
+ * Remove all messages from the list and update the view.
+ */
+ public void clear() {
+ mMessages.clear();
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return false;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public Object getItem(int position) {
+ return mMessages.get(position);
+ }
+
+ public int getCount() {
+ return mMessages.size();
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ /**
+ * Constructs a TwoLineListItem for the error at position.
+ */
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view;
+ ErrorConsoleMessage error = mMessages.get(position);
+
+ if (error == null) {
+ return null;
+ }
+
+ if (convertView == null) {
+ view = mInflater.inflate(android.R.layout.two_line_list_item, parent, false);
+ } else {
+ view = convertView;
+ }
+
+ TextView headline = (TextView) view.findViewById(android.R.id.text1);
+ TextView subText = (TextView) view.findViewById(android.R.id.text2);
+ headline.setText(error.getSourceID() + ":" + error.getLineNumber());
+ subText.setText(error.getMessage());
+ return view;
+ }
+
+ }
+ }
+
+ /**
+ * This class holds the data for a single error message in the console.
+ */
+ private static class ErrorConsoleMessage {
+ private String mMessage;
+ private String mSourceID;
+ private int mLineNumber;
+
+ public ErrorConsoleMessage(String msg, String sourceID, int lineNumber) {
+ mMessage = msg;
+ mSourceID = sourceID;
+ mLineNumber = lineNumber;
+ }
+
+ public String getMessage() {
+ return mMessage;
+ }
+
+ public String getSourceID() {
+ return mSourceID;
+ }
+
+ public int getLineNumber() {
+ return mLineNumber;
+ }
+ }
+}