diff options
| author | Ben Murdoch <benm@google.com> | 2009-07-01 20:19:05 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2009-07-17 11:22:26 +0100 |
| commit | bff2d603c022691237c31d9a57ad8c217c6e7e11 (patch) | |
| tree | 3e29889b7e51881715cb3fbb32b197c81d877754 /src/com/android/browser/ErrorConsoleView.java | |
| parent | cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8a (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.java | 339 |
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; + } + } +} |
