aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2008-11-18 19:51:00 +0000
committerKenny Root <kenny@the-b.org>2008-11-18 19:51:00 +0000
commit2066c47a3624c05979ee84822043d62bd2983bc6 (patch)
treebe909730c792f6fa6de9b8765a6b995efce90708
parent047edeadfc88bd9d7add4d6383f7cfce253a1f9a (diff)
downloadconnectbot-2066c47a3624c05979ee84822043d62bd2983bc6.tar.gz
connectbot-2066c47a3624c05979ee84822043d62bd2983bc6.tar.bz2
connectbot-2066c47a3624c05979ee84822043d62bd2983bc6.zip
* Refactor a bit of the help screen
* Don't close view when host disconnects (user must explicitly close now)
-rw-r--r--res/layout/act_help_topic.xml2
-rw-r--r--res/values/strings.xml1
-rw-r--r--src/org/connectbot/ConsoleActivity.java474
-rw-r--r--src/org/connectbot/WizardActivity.java3
-rw-r--r--src/org/connectbot/service/PromptHelper.java2
-rw-r--r--src/org/connectbot/service/TerminalBridge.java308
-rw-r--r--src/org/connectbot/util/HelpTopicView.java28
7 files changed, 439 insertions, 379 deletions
diff --git a/res/layout/act_help_topic.xml b/res/layout/act_help_topic.xml
index 1b59589..052bede 100644
--- a/res/layout/act_help_topic.xml
+++ b/res/layout/act_help_topic.xml
@@ -23,7 +23,7 @@
android:layout_height="fill_parent"
>
- <HelpTopicView
+ <org.connectbot.util.HelpTopicView
android:id="@+id/topic_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f08d7a5..b12dfda 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -110,6 +110,7 @@
<string name="console_copy_start">Touch and drag to select area to copy</string>
<string name="console_menu_disconnect">Disconnect</string>
+ <string name="console_menu_close">Close</string>
<string name="console_menu_copy">Copy</string>
<string name="console_menu_paste">Paste</string>
<string name="console_menu_portforwards">Port Forwards</string>
diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java
index 53cecfc..9015c35 100644
--- a/src/org/connectbot/ConsoleActivity.java
+++ b/src/org/connectbot/ConsoleActivity.java
@@ -75,7 +75,33 @@ public class ConsoleActivity extends Activity {
protected TerminalManager bound = null;
protected LayoutInflater inflater = null;
- private ServiceConnection connection = new ServiceConnection() {
+ protected SharedPreferences prefs = null;
+
+ protected PowerManager.WakeLock wakelock = null;
+
+ protected String PREF_KEEPALIVE = null;
+
+ protected Uri requested;
+
+ protected ClipboardManager clipboard;
+ protected EditText stringPrompt;
+
+ protected TextView booleanPrompt;
+
+ protected Button booleanYes, booleanNo;
+
+ protected TextView empty;
+
+ protected Animation slide_left_in, slide_left_out, slide_right_in, slide_right_out, fade_stay_hidden, fade_out;
+
+ protected MenuItem disconnect, copy, paste, portForward, resize;
+
+ protected boolean requestedDisconnect = false;
+
+ protected boolean copying = false;
+ protected TerminalView copySource = null;
+
+ private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
bound = ((TerminalManager.TerminalBinder) service).getService();
@@ -95,8 +121,8 @@ public class ConsoleActivity extends Activity {
if(bridge.host.getNickname().equals(requestedNickname))
found = true;
}
-
- // if we didnt find the requested connection, try opening it
+
+ // If we didn't find the requested connection, try opening it
if(!found) {
try {
Log.d(TAG, String.format("We couldnt find an existing bridge with URI=%s, so creating one now", requested.toString()));
@@ -105,7 +131,7 @@ public class ConsoleActivity extends Activity {
Log.e(TAG, "Problem while trying to create new requested bridge from URI", e);
}
}
-
+
// create views for all bridges on this service
for(TerminalBridge bridge : bound.bridges) {
@@ -115,11 +141,11 @@ public class ConsoleActivity extends Activity {
// inflate each terminal view
RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.item_terminal, flip, false);
-
+
// set the terminal overlay text
TextView overlay = (TextView)view.findViewById(R.id.terminal_overlay);
overlay.setText(bridge.host.getNickname());
-
+
// and add our terminal view control, using index to place behind overlay
TerminalView terminal = new TerminalView(ConsoleActivity.this, bridge);
terminal.setId(R.id.console_flip);
@@ -146,7 +172,7 @@ public class ConsoleActivity extends Activity {
updateEmptyVisible();
}
-
+
public void onServiceDisconnected(ComponentName className) {
// tell each bridge to forget about our prompt handler
for(TerminalBridge bridge : bound.bridges)
@@ -158,160 +184,93 @@ public class ConsoleActivity extends Activity {
}
};
-
- protected HostBean getCurrentHost() {
- View view = findCurrentView(R.id.console_flip);
- if(!(view instanceof TerminalView)) return null;
- return ((TerminalView)view).bridge.host;
- }
-
+
public Handler promptHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// someone below us requested to display a prompt
updatePromptVisible();
-
}
};
-
+
public Handler disconnectHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
+ Log.d(TAG, "Someone sending HANDLE_DISCONNECT to parentHandler");
+
// someone below us requested to display a password dialog
// they are sending nickname and requested
TerminalBridge bridge = (TerminalBridge)msg.obj;
- // remove this bridge becase its been disconnected
- Log.d(TAG, "Someone sending HANDLE_DISCONNECT to parentHandler");
- for(int i = 0; i < flip.getChildCount(); i++) {
- View view = flip.getChildAt(i).findViewById(R.id.console_flip);
- if(!(view instanceof TerminalView)) continue;
- TerminalView terminal = (TerminalView)view;
- if(terminal.bridge.equals(bridge)) {
- // weve found the terminal to remove
- // shift something into its place if currently visible
- if(flip.getDisplayedChild() == i) {
- shiftLeft();
- }
- flip.removeViewAt(i);
- updateEmptyVisible();
- break;
- }
- }
-
+ if (bridge.isAwaitingClose())
+ closeBridge(bridge);
}
};
-
- protected void hideAllPrompts() {
- this.stringPrompt.setVisibility(View.GONE);
- this.booleanPrompt.setVisibility(View.GONE);
- this.booleanYes.setVisibility(View.GONE);
- this.booleanNo.setVisibility(View.GONE);
-
- }
-
+
/**
- * Show any prompts requested by the currently visible {@link TerminalView}.
+ * @param bridge
*/
- protected void updatePromptVisible() {
- // check if our currently-visible terminalbridge is requesting any prompt services
- View view = findCurrentView(R.id.console_flip);
- if(!(view instanceof TerminalView)) {
- // we dont have an active view, so hide any prompts
- this.hideAllPrompts();
- return;
- }
-
- PromptHelper prompt = ((TerminalView)view).bridge.promptHelper;
- if(String.class.equals(prompt.promptRequested)) {
- this.stringPrompt.setVisibility(View.VISIBLE);
- this.stringPrompt.setText("");
- this.stringPrompt.setHint(prompt.promptHint);
- this.stringPrompt.requestFocus();
+ private void closeBridge(TerminalBridge bridge) {
+ for(int i = 0; i < flip.getChildCount(); i++) {
+ View child = flip.getChildAt(i).findViewById(R.id.console_flip);
- } else if(Boolean.class.equals(prompt.promptRequested)) {
- this.booleanPrompt.setVisibility(View.VISIBLE);
- this.booleanPrompt.setText(prompt.promptHint);
- this.booleanYes.setVisibility(View.VISIBLE);
- this.booleanYes.requestFocus();
- this.booleanNo.setVisibility(View.VISIBLE);
+ if (!(child instanceof TerminalView)) continue;
- } else {
- this.hideAllPrompts();
- view.requestFocus();
+ TerminalView terminal = (TerminalView) child;
+ if (terminal.bridge.equals(bridge)) {
+ // we've found the terminal to remove
+ // shift something into its place if currently visible
+ if(flip.getDisplayedChild() == i)
+ shiftLeft();
+ flip.removeViewAt(i);
+ updateEmptyVisible();
+ break;
+ }
}
-
}
- /**
- * Save the currently shown {@link TerminalView} as the default. This is
- * saved back down into {@link TerminalManager} where we can read it again
- * later.
- */
- protected void updateDefault() {
- // update the current default terminal
- View view = findCurrentView(R.id.console_flip);
- if(!(view instanceof TerminalView)) return;
-
- TerminalView terminal = (TerminalView)view;
- if(bound == null) return;
- bound.defaultBridge = terminal.bridge;
- }
-
- protected SharedPreferences prefs = null;
- protected PowerManager.WakeLock wakelock = null;
-
- protected String PREF_KEEPALIVE = null;
-
- @Override
- public void onStart() {
- super.onStart();
-
- // connect with manager service to find all bridges
- // when connected it will insert all views
- this.bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE);
-
- // make sure we dont let the screen fall asleep
- // this also keeps the wifi chipset from disconnecting us
- if(this.wakelock != null && prefs.getBoolean(PREF_KEEPALIVE, true))
- wakelock.acquire();
-
- }
-
- @Override
- public void onStop() {
- super.onStop();
- this.unbindService(connection);
+ protected void createPortForward(TerminalView target, String nickname, String type, String source, String dest) {
+ String summary = getString(R.string.portforward_problem);
+ try {
+ long hostId = target.bridge.host.getId();
- // allow the screen to dim and fall asleep
- if(this.wakelock != null && this.wakelock.isHeld())
- wakelock.release();
+ PortForwardBean pfb = new PortForwardBean(hostId, nickname, type, source, dest);
+
+ target.bridge.addPortForward(pfb);
+ if (target.bridge.enablePortForward(pfb)) {
+ summary = getString(R.string.portforward_done);
+ }
+ } catch(Exception e) {
+ Log.e(TAG, "Problem trying to create portForward", e);
+ }
+ Toast.makeText(ConsoleActivity.this, summary, Toast.LENGTH_LONG).show();
}
-
protected View findCurrentView(int id) {
View view = this.flip.getCurrentView();
if(view == null) return null;
return view.findViewById(id);
}
+ protected HostBean getCurrentHost() {
+ View view = findCurrentView(R.id.console_flip);
+ if(!(view instanceof TerminalView)) return null;
+ return ((TerminalView)view).bridge.host;
+ }
+
protected PromptHelper getCurrentPromptHelper() {
View view = findCurrentView(R.id.console_flip);
if(!(view instanceof TerminalView)) return null;
return ((TerminalView)view).bridge.promptHelper;
+ }
+
+ protected void hideAllPrompts() {
+ this.stringPrompt.setVisibility(View.GONE);
+ this.booleanPrompt.setVisibility(View.GONE);
+ this.booleanYes.setVisibility(View.GONE);
+ this.booleanNo.setVisibility(View.GONE);
}
-
- protected Uri requested;
- protected ClipboardManager clipboard;
-
- protected EditText stringPrompt;
- protected TextView booleanPrompt;
- protected Button booleanYes, booleanNo;
-
- protected TextView empty;
-
- protected Animation slide_left_in, slide_left_out, slide_right_in, slide_right_out, fade_stay_hidden, fade_out;
@Override
public void onCreate(Bundle icicle) {
@@ -409,6 +368,32 @@ public class ConsoleActivity extends Activity {
public float totalY = 0;
@Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+
+ float distx = e2.getRawX() - e1.getRawX();
+ float disty = e2.getRawY() - e1.getRawY();
+ int goalwidth = flip.getWidth() / 2;
+
+ // need to slide across half of display to trigger console change
+ // make sure user kept a steady hand horizontally
+ if(Math.abs(disty) < 100) {
+ if(distx > goalwidth) {
+ shiftRight();
+ return true;
+ }
+
+ if(distx < -goalwidth) {
+ shiftLeft();
+ return true;
+ }
+
+ }
+
+ return false;
+ }
+
+
+ @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// if copying, then ignore
@@ -457,34 +442,6 @@ public class ConsoleActivity extends Activity {
return false;
}
-
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-
- float distx = e2.getRawX() - e1.getRawX();
- float disty = e2.getRawY() - e1.getRawY();
- int goalwidth = flip.getWidth() / 2;
-
- // need to slide across half of display to trigger console change
- // make sure user kept a steady hand horizontally
- if(Math.abs(disty) < 100) {
- if(distx > goalwidth) {
- shiftRight();
- return true;
- }
-
- if(distx < -goalwidth) {
- shiftLeft();
- return true;
- }
-
- }
-
-
-
- return false;
- }
});
@@ -564,81 +521,39 @@ public class ConsoleActivity extends Activity {
});
}
-
- protected void updateEmptyVisible() {
- // update visibility of empty status message
- this.empty.setVisibility((flip.getChildCount() == 0) ? View.VISIBLE : View.GONE);
- }
-
-
- protected void shiftLeft() {
- // keep current overlay from popping up again
- View overlay = findCurrentView(R.id.terminal_overlay);
- if(overlay != null) overlay.startAnimation(fade_stay_hidden);
-
- // Only show animation if there is something else to go to.
- if (flip.getChildCount() > 1)
- flip.setInAnimation(slide_left_in);
-
- flip.setOutAnimation(slide_left_out);
- flip.showNext();
- ConsoleActivity.this.updateDefault();
-
- // show overlay on new slide and start fade
- overlay = findCurrentView(R.id.terminal_overlay);
- if(overlay != null) overlay.startAnimation(fade_out);
-
- updatePromptVisible();
- }
- protected void shiftRight() {
-
- // keep current overlay from popping up again
- View overlay = findCurrentView(R.id.terminal_overlay);
- if(overlay != null) overlay.startAnimation(fade_stay_hidden);
-
- flip.setInAnimation(slide_right_in);
- flip.setOutAnimation(slide_right_out);
- flip.showPrevious();
- ConsoleActivity.this.updateDefault();
-
- // show overlay on new slide and start fade
- overlay = findCurrentView(R.id.terminal_overlay);
- if(overlay != null) overlay.startAnimation(fade_out);
- updatePromptVisible();
-
- }
-
- protected MenuItem disconnect, copy, paste, portForward, resize;
-
- protected boolean copying = false;
- protected TerminalView copySource = null;
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
final View view = findCurrentView(R.id.console_flip);
- boolean activeTerminal = (view instanceof TerminalView);
+ final boolean activeTerminal = (view instanceof TerminalView);
boolean authenticated = false;
boolean sessionOpen = false;
- if(activeTerminal) {
+
+ if (activeTerminal) {
authenticated = ((TerminalView) view).bridge.isAuthenticated();
sessionOpen = ((TerminalView) view).bridge.isSessionOpen();
}
+
disconnect = menu.add(R.string.console_menu_disconnect);
+ if (!sessionOpen)
+ disconnect.setTitle(R.string.console_menu_close);
disconnect.setEnabled(activeTerminal);
disconnect.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
disconnect.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
- // close the currently visible session
- TerminalView terminal = (TerminalView)view;
- terminal.bridge.dispatchDisconnect();
- // movement should now be happening over in onDisconnect() handler
- //flip.removeView(flip.getCurrentView());
- //shiftLeft();
+ // disconnect or close the currently visible session
+ TerminalBridge bridge = ((TerminalView)view).bridge;
+ if (bridge.isSessionOpen()) {
+ requestedDisconnect = true;
+ bridge.dispatchDisconnect();
+ } else {
+ // remove this bridge because it's been explicitly closed.
+ closeBridge(bridge);
+ }
return true;
}
});
@@ -714,25 +629,7 @@ public class ConsoleActivity extends Activity {
return true;
}
- protected void createPortForward(TerminalView target, String nickname, String type, String source, String dest) {
- String summary = getString(R.string.portforward_problem);
- try {
- long hostId = target.bridge.host.getId();
-
- PortForwardBean pfb = new PortForwardBean(hostId, nickname, type, source, dest);
-
- target.bridge.addPortForward(pfb);
- if (target.bridge.enablePortForward(pfb)) {
- summary = getString(R.string.portforward_done);
- }
- } catch(Exception e) {
- Log.e(TAG, "Problem trying to create portForward", e);
- }
-
- Toast.makeText(ConsoleActivity.this, summary, Toast.LENGTH_LONG).show();
- }
-
- @Override
+ @Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
@@ -746,6 +643,10 @@ public class ConsoleActivity extends Activity {
}
disconnect.setEnabled(activeTerminal);
+ if (sessionOpen)
+ disconnect.setTitle(R.string.console_menu_disconnect);
+ else
+ disconnect.setTitle(R.string.console_menu_close);
copy.setEnabled(activeTerminal);
paste.setEnabled(clipboard.hasText() && activeTerminal && sessionOpen);
portForward.setEnabled(activeTerminal && authenticated);
@@ -753,5 +654,124 @@ public class ConsoleActivity extends Activity {
return true;
}
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ // connect with manager service to find all bridges
+ // when connected it will insert all views
+ this.bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE);
+
+ // make sure we dont let the screen fall asleep
+ // this also keeps the wifi chipset from disconnecting us
+ if(this.wakelock != null && prefs.getBoolean(PREF_KEEPALIVE, true))
+ wakelock.acquire();
+
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ this.unbindService(connection);
+
+ // allow the screen to dim and fall asleep
+ if(this.wakelock != null && this.wakelock.isHeld())
+ wakelock.release();
+
+ }
+
+ protected void shiftLeft() {
+ // keep current overlay from popping up again
+ View overlay = findCurrentView(R.id.terminal_overlay);
+ if(overlay != null) overlay.startAnimation(fade_stay_hidden);
+
+ // Only show animation if there is something else to go to.
+ if (flip.getChildCount() > 1)
+ flip.setInAnimation(slide_left_in);
+
+ flip.setOutAnimation(slide_left_out);
+ flip.showNext();
+ ConsoleActivity.this.updateDefault();
+
+ // show overlay on new slide and start fade
+ overlay = findCurrentView(R.id.terminal_overlay);
+ if(overlay != null) overlay.startAnimation(fade_out);
+
+ updatePromptVisible();
+ }
+
+ protected void shiftRight() {
+
+ // keep current overlay from popping up again
+ View overlay = findCurrentView(R.id.terminal_overlay);
+ if(overlay != null) overlay.startAnimation(fade_stay_hidden);
+
+ flip.setInAnimation(slide_right_in);
+ flip.setOutAnimation(slide_right_out);
+ flip.showPrevious();
+ ConsoleActivity.this.updateDefault();
+
+ // show overlay on new slide and start fade
+ overlay = findCurrentView(R.id.terminal_overlay);
+ if(overlay != null) overlay.startAnimation(fade_out);
+
+ updatePromptVisible();
+
+ }
+
+ /**
+ * Save the currently shown {@link TerminalView} as the default. This is
+ * saved back down into {@link TerminalManager} where we can read it again
+ * later.
+ */
+ protected void updateDefault() {
+ // update the current default terminal
+ View view = findCurrentView(R.id.console_flip);
+ if(!(view instanceof TerminalView)) return;
+
+ TerminalView terminal = (TerminalView)view;
+ if(bound == null) return;
+ bound.defaultBridge = terminal.bridge;
+ }
+
+ protected void updateEmptyVisible() {
+ // update visibility of empty status message
+ this.empty.setVisibility((flip.getChildCount() == 0) ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * Show any prompts requested by the currently visible {@link TerminalView}.
+ */
+ protected void updatePromptVisible() {
+ // check if our currently-visible terminalbridge is requesting any prompt services
+ View view = findCurrentView(R.id.console_flip);
+ if(!(view instanceof TerminalView)) {
+ // we dont have an active view, so hide any prompts
+ this.hideAllPrompts();
+ return;
+ }
+
+ PromptHelper prompt = ((TerminalView)view).bridge.promptHelper;
+ if(String.class.equals(prompt.promptRequested)) {
+ this.stringPrompt.setVisibility(View.VISIBLE);
+ this.stringPrompt.setText("");
+ this.stringPrompt.setHint(prompt.promptHint);
+ this.stringPrompt.requestFocus();
+
+ } else if(Boolean.class.equals(prompt.promptRequested)) {
+ this.booleanPrompt.setVisibility(View.VISIBLE);
+ this.booleanPrompt.setText(prompt.promptHint);
+ this.booleanYes.setVisibility(View.VISIBLE);
+ this.booleanYes.requestFocus();
+ this.booleanNo.setVisibility(View.VISIBLE);
+
+ } else {
+ this.hideAllPrompts();
+ view.requestFocus();
+
+ }
+
+ }
}
diff --git a/src/org/connectbot/WizardActivity.java b/src/org/connectbot/WizardActivity.java
index 12941e6..871e6ca 100644
--- a/src/org/connectbot/WizardActivity.java
+++ b/src/org/connectbot/WizardActivity.java
@@ -53,8 +53,7 @@ public class WizardActivity extends Activity {
// Add a view for each help topic we want the user to see.
String[] topics = getResources().getStringArray(R.array.list_wizard_topics);
for (String topic : topics) {
- View step = new HelpTopicView(this, topic);
- flipper.addView(step);
+ flipper.addView(new HelpTopicView(this).setTopic(topic));
}
next = (Button)this.findViewById(R.id.action_next);
diff --git a/src/org/connectbot/service/PromptHelper.java b/src/org/connectbot/service/PromptHelper.java
index 37d12be..7732e2e 100644
--- a/src/org/connectbot/service/PromptHelper.java
+++ b/src/org/connectbot/service/PromptHelper.java
@@ -97,6 +97,4 @@ public class PromptHelper {
}
return value;
}
-
-
}
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index 729be57..ad60450 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -50,6 +50,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
+import com.trilead.ssh2.ChannelCondition;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.ConnectionMonitor;
import com.trilead.ssh2.DynamicPortForwarder;
@@ -110,11 +111,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
protected final TerminalManager manager;
public HostBean host;
- //public final String nickname;
- //protected final String username;
- //public String postlogin = null;
- //private boolean wantSession = true;
- //private boolean compression = false;
public final Connection connection;
protected Session session;
@@ -124,6 +120,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
protected OutputStream stdin;
protected InputStream stdout;
+ private InputStream stderr;
+
protected Thread relay;
protected final String emulation;
@@ -142,10 +140,9 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
private boolean pubkeysExhausted = false;
private boolean authenticated = false;
-
private boolean sessionOpen = false;
-
protected boolean disconnectFlag = false;
+ private boolean awaitingClose = false;
private boolean forcedSize = false;
private int termWidth;
@@ -215,29 +212,29 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
this.manager = manager;
this.host = host;
- this.emulation = manager.getEmulation();
- this.scrollback = manager.getScrollback();
+ emulation = manager.getEmulation();
+ scrollback = manager.getScrollback();
// create prompt helper to relay password and hostkey requests up to gui
- this.promptHelper = new PromptHelper(this);
+ promptHelper = new PromptHelper(this);
// create our default paint
- this.defaultPaint = new Paint();
- this.defaultPaint.setAntiAlias(true);
- this.defaultPaint.setTypeface(Typeface.MONOSPACE);
+ defaultPaint = new Paint();
+ defaultPaint.setAntiAlias(true);
+ defaultPaint.setTypeface(Typeface.MONOSPACE);
- this.setFontSize(DEFAULT_FONT_SIZE);
+ setFontSize(DEFAULT_FONT_SIZE);
// prepare our "darker" colors
for(int i = 0; i < color.length; i++)
- this.darkerColor[i] = darken(color[i]);
+ darkerColor[i] = darken(color[i]);
// create terminal buffer and handle outgoing data
// this is probably status reply information
- this.buffer = new vt320() {
+ buffer = new vt320() {
public void write(byte[] b) {
try {
- TerminalBridge.this.stdin.write(b);
+ stdin.write(b);
} catch (IOException e) {
Log.e(TAG, "Problem handling incoming data in vt320() thread", e);
} catch (NullPointerException npe) {
@@ -253,20 +250,20 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
};
- this.buffer.setScreenSize(TERM_WIDTH_CHARS, TERM_HEIGHT_CHARS, true);
- this.buffer.setBufferSize(scrollback);
- this.buffer.setDisplay(this);
- this.buffer.setCursorPosition(0, 0);
+ buffer.setScreenSize(TERM_WIDTH_CHARS, TERM_HEIGHT_CHARS, true);
+ buffer.setBufferSize(scrollback);
+ buffer.setDisplay(this);
+ buffer.setCursorPosition(0, 0);
// TODO Change this when hosts are beans as well
- this.portForwards = manager.hostdb.getPortForwardsForHost(host);
+ portForwards = manager.hostdb.getPortForwardsForHost(host);
// prepare the ssh connection for opening
// we perform the actual connection later in startConnection()
- this.outputLine(String.format("Connecting to %s:%d", host.getHostname(), host.getPort()));
- this.connection = new Connection(host.getHostname(), host.getPort());
- this.connection.addConnectionMonitor(this);
- this.connection.setCompression(host.getCompression());
+ outputLine(String.format("Connecting to %s:%d", host.getHostname(), host.getPort()));
+ connection = new Connection(host.getHostname(), host.getPort());
+ connection.addConnectionMonitor(this);
+ connection.setCompression(host.getCompression());
}
/**
@@ -466,9 +463,9 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* Convenience method for writing a line into the underlying MUD buffer.
*/
protected void outputLine(String line) {
- this.buffer.putString(0, this.buffer.getCursorRow(), line);
- this.buffer.setCursorPosition(0, this.buffer.getCursorRow() + 1);
- this.redraw();
+ buffer.putString(0, buffer.getCursorRow(), line);
+ buffer.setCursorPosition(0, buffer.getCursorRow() + 1);
+ redraw();
}
/**
@@ -511,31 +508,50 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
try {
- this.session = connection.openSession();
- buffer.deleteArea(0, 0, TerminalBridge.this.buffer.getColumns(), TerminalBridge.this.buffer.getRows());
+ session = connection.openSession();
+ buffer.deleteArea(0, 0, buffer.getColumns(), buffer.getRows());
// previously tried vt100 and xterm for emulation modes
// "screen" works the best for color and escape codes
// TODO: pull this value from the preferences
- this.session.requestPTY(emulation, termWidth, termHeight, 0, 0, null);
- this.session.startShell();
+ session.requestPTY(emulation, termWidth, termHeight, 0, 0, null);
+ session.startShell();
+
+ new Thread(new Runnable() {
+ public void run() {
+ session.waitForCondition(ChannelCondition.CLOSED, 0);
+ }
+ }).start();
// grab stdin/out from newly formed session
- this.stdin = this.session.getStdin();
- this.stdout = this.session.getStdout();
+ stdin = session.getStdin();
+ stdout = session.getStdout();
+ stderr = session.getStderr();
// create thread to relay incoming connection data to buffer
- this.relay = new Thread(new Runnable() {
+ relay = new Thread(new Runnable() {
public void run() {
- byte[] b = new byte[256];
+ byte[] b = new byte[4096];
int n = 0;
- while(n >= 0) {
+ int conditions = ChannelCondition.STDOUT_DATA
+ | ChannelCondition.STDERR_DATA
+ | ChannelCondition.CLOSED;
+ int newConditions = 0;
+ while((newConditions & ChannelCondition.CLOSED) == 0) {
try {
- n = TerminalBridge.this.stdout.read(b);
- if(n > 0) {
- // pass along data to buffer, then redraw any results
- ((vt320)TerminalBridge.this.buffer).putString(new String(b, 0, n, ENCODING));
- TerminalBridge.this.redraw();
+ newConditions = session.waitForCondition(conditions, 0);
+ if ((newConditions & ChannelCondition.STDOUT_DATA) == ChannelCondition.STDOUT_DATA) {
+ n = stdout.read(b);
+ if (n > 0) {
+ ((vt320)buffer).putString(new String(b, 0, n, ENCODING));
+ redraw();
+ }
+ }
+
+ if ((newConditions & ChannelCondition.STDERR_DATA) == ChannelCondition.STDERR_DATA) {
+ n = stderr.read(b);
+ /* I don't know.. do we want this? */
+ Log.d(TAG, String.format("Read data from stderr: %s", new String(b, 0, n, ENCODING)));
}
} catch (IOException e) {
Log.e(TAG, "Problem while handling incoming data in relay thread", e);
@@ -547,9 +563,9 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
relay.start();
// force font-size to make sure we resizePTY as needed
- setFontSize(this.fontSize);
+ setFontSize(fontSize);
- setSessionOpen(true);
+ sessionOpen = true;
// finally send any post-login string, if requested
injectString(host.getPostLogin());
@@ -559,16 +575,9 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
}
-
- /**
- * @param sessionOpen the sessionOpen to set
- */
- public void setSessionOpen(boolean sessionOpen) {
- this.sessionOpen = sessionOpen;
- }
/**
- * @return the sessionOpen
+ * @return whether a session is open or not
*/
public boolean isSessionOpen() {
return sessionOpen;
@@ -584,6 +593,10 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* Force disconnection of this terminal bridge.
*/
public void dispatchDisconnect() {
+ // We don't need to do this multiple times.
+ if (disconnectFlag)
+ return;
+
// disconnection request hangs if we havent really connected to a host yet
// temporary fix is to just spawn disconnection into a thread
new Thread(new Runnable() {
@@ -594,21 +607,30 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
}).start();
- this.disconnectFlag = true;
- this.authenticated = false;
- this.sessionOpen = false;
+ disconnectFlag = true;
+ authenticated = false;
+ sessionOpen = false;
// pass notification back up to terminal manager
// the manager will do any gui notification if applicable
- if(this.disconnectListener != null)
- this.disconnectListener.onDisconnected(this);
+ if(disconnectListener != null)
+ disconnectListener.onDisconnected(this);
+ new Thread(new Runnable() {
+ public void run() {
+ boolean result = promptHelper.requestBooleanPrompt("Host has disconnected.\nClose session?");
+ if (result) {
+ awaitingClose = true;
+ disconnectListener.onDisconnected(TerminalBridge.this);
+ }
+ }
+ }).start();
}
public String keymode = null;
public void refreshKeymode() {
- this.keymode = this.manager.getKeyMode();
+ keymode = manager.getKeyMode();
}
public KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
@@ -619,28 +641,28 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* or passwords, but otherwise we pass them directly over to the SSH host.
*/
public boolean onKey(View v, int keyCode, KeyEvent event) {
- // pass through any keystrokes to output stream
-
// ignore any key-up events
- if(event.getAction() == KeyEvent.ACTION_UP) return false;
+ if(event.getAction() == KeyEvent.ACTION_UP)
+ return false;
try {
// check for terminal resizing keys
// TODO: see if there is a way to make sure we dont "blip"
if(keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
- this.forcedSize = false;
- this.setFontSize(this.fontSize + 2);
+ forcedSize = false;
+ setFontSize(fontSize + 2);
return true;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
- this.forcedSize = false;
- this.setFontSize(this.fontSize - 2);
+ forcedSize = false;
+ setFontSize(fontSize - 2);
return true;
}
boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE);
- // skip keys if we arent connected yet
- if(this.session == null) return false;
+ // skip keys if we aren't connected yet or have been disconnected
+ if(disconnectFlag || session == null)
+ return false;
// otherwise pass through to existing session
// print normal keys
@@ -688,24 +710,24 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
}
- this.stdin.write(key);
+ stdin.write(key);
return true;
}
// try handling keymode shortcuts
- if("Use right-side keys".equals(this.keymode)) {
+ if("Use right-side keys".equals(keymode)) {
switch(keyCode) {
- case KeyEvent.KEYCODE_ALT_RIGHT: this.stdin.write('/'); return true;
- case KeyEvent.KEYCODE_SHIFT_RIGHT: this.stdin.write(0x09); return true;
- case KeyEvent.KEYCODE_SHIFT_LEFT: this.shiftPressed = true; return true;
- case KeyEvent.KEYCODE_ALT_LEFT: this.altPressed = true; return true;
+ case KeyEvent.KEYCODE_ALT_RIGHT: stdin.write('/'); return true;
+ case KeyEvent.KEYCODE_SHIFT_RIGHT: stdin.write(0x09); return true;
+ case KeyEvent.KEYCODE_SHIFT_LEFT: shiftPressed = true; return true;
+ case KeyEvent.KEYCODE_ALT_LEFT: altPressed = true; return true;
}
- } else if("Use left-side keys".equals(this.keymode)) {
+ } else if("Use left-side keys".equals(keymode)) {
switch(keyCode) {
- case KeyEvent.KEYCODE_ALT_LEFT: this.stdin.write('/'); return true;
- case KeyEvent.KEYCODE_SHIFT_LEFT: this.stdin.write(0x09); return true;
- case KeyEvent.KEYCODE_SHIFT_RIGHT: this.shiftPressed = true; return true;
- case KeyEvent.KEYCODE_ALT_RIGHT: this.altPressed = true; return true;
+ case KeyEvent.KEYCODE_ALT_LEFT: stdin.write('/'); return true;
+ case KeyEvent.KEYCODE_SHIFT_LEFT: stdin.write(0x09); return true;
+ case KeyEvent.KEYCODE_SHIFT_RIGHT: shiftPressed = true; return true;
+ case KeyEvent.KEYCODE_ALT_RIGHT: altPressed = true; return true;
}
}
@@ -716,11 +738,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// check to see which shortcut the camera button triggers
String camera = manager.prefs.getString(manager.res.getString(R.string.pref_camera), manager.res.getString(R.string.list_camera_ctrlaspace));
if(manager.res.getString(R.string.list_camera_ctrlaspace).equals(camera)) {
- this.stdin.write(0x01);
- this.stdin.write(' ');
+ stdin.write(0x01);
+ stdin.write(' ');
} else if(manager.res.getString(R.string.list_camera_ctrla).equals(camera)) {
- this.stdin.write(0x01);
+ stdin.write(0x01);
} else if(manager.res.getString(R.string.list_camera_esc).equals(camera)) {
((vt320)buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0);
@@ -749,6 +771,13 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
} catch (IOException e) {
Log.e(TAG, "Problem while trying to handle an onKey() event", e);
+ try {
+ stdin.flush();
+ } catch (IOException ioe) {
+ // Our stdin got blown away, so we must be closed.
+ Log.d(TAG, "Our stdin was closed, dispatching disconnect event");
+ dispatchDisconnect();
+ }
}
return false;
}
@@ -765,21 +794,21 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* sure we resize PTY if needed.
*/
protected void setFontSize(float size) {
- this.defaultPaint.setTextSize(size);
- this.fontSize = size;
+ defaultPaint.setTextSize(size);
+ fontSize = size;
// read new metrics to get exact pixel dimensions
- FontMetricsInt fm = this.defaultPaint.getFontMetricsInt();
- this.charDescent = fm.descent;
+ FontMetricsInt fm = defaultPaint.getFontMetricsInt();
+ charDescent = fm.descent;
float[] widths = new float[1];
- this.defaultPaint.getTextWidths("X", widths);
- this.charWidth = (int)widths[0];
- this.charHeight = Math.abs(fm.top) + Math.abs(fm.descent) + 1;
+ defaultPaint.getTextWidths("X", widths);
+ charWidth = (int)widths[0];
+ charHeight = Math.abs(fm.top) + Math.abs(fm.descent) + 1;
// refresh any bitmap with new font size
- if(this.parent != null)
- this.parentChanged(this.parent);
+ if(parent != null)
+ parentChanged(parent);
}
/**
@@ -798,7 +827,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
int width = parent.getWidth();
int height = parent.getHeight();
- if (!this.forcedSize) {
+ if (!forcedSize) {
// recalculate buffer size
int newTermWidth, newTermHeight;
@@ -815,30 +844,30 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
// reallocate new bitmap if needed
- boolean newBitmap = (this.bitmap == null);
- if(this.bitmap != null)
- newBitmap = (this.bitmap.getWidth() != width || this.bitmap.getHeight() != height);
+ boolean newBitmap = (bitmap == null);
+ if(bitmap != null)
+ newBitmap = (bitmap.getWidth() != width || bitmap.getHeight() != height);
if(newBitmap) {
- this.bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
- this.canvas.setBitmap(this.bitmap);
+ bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
+ canvas.setBitmap(bitmap);
}
// clear out any old buffer information
- this.defaultPaint.setColor(Color.BLACK);
- this.canvas.drawRect(0, 0, width, height, this.defaultPaint);
+ defaultPaint.setColor(Color.BLACK);
+ canvas.drawRect(0, 0, width, height, defaultPaint);
// Stroke the border of the terminal if the size is being forced;
- if (this.forcedSize) {
+ if (forcedSize) {
int borderX = (termWidth * charWidth) + 1;
int borderY = (termHeight * charHeight) + 1;
- this.defaultPaint.setColor(Color.GRAY);
- this.defaultPaint.setStrokeWidth(0.0f);
+ defaultPaint.setColor(Color.GRAY);
+ defaultPaint.setStrokeWidth(0.0f);
if (width >= borderX)
- this.canvas.drawLine(borderX, 0, borderX, borderY + 1, defaultPaint);
+ canvas.drawLine(borderX, 0, borderX, borderY + 1, defaultPaint);
if (height >= borderY)
- this.canvas.drawLine(0, borderY, borderX + 1, borderY, defaultPaint);
+ canvas.drawLine(0, borderY, borderX + 1, borderY, defaultPaint);
}
try {
@@ -851,8 +880,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
// force full redraw with new buffer size
- this.fullRedraw = true;
- this.redraw();
+ fullRedraw = true;
+ redraw();
this.parent.notifyUser(String.format("%d x %d", termWidth, termHeight));
@@ -864,11 +893,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* to redraw anywhere, and we can recycle our internal bitmap.
*/
public synchronized void parentDestroyed() {
- this.parent = null;
- if(this.bitmap != null)
- this.bitmap.recycle();
- this.bitmap = null;
- this.canvas.setBitmap(null);
+ parent = null;
+ if(bitmap != null)
+ bitmap.recycle();
+ bitmap = null;
+ canvas.setBitmap(null);
}
public void setVDUBuffer(VDUBuffer buffer) {
@@ -884,12 +913,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public synchronized void redraw() {
// render our buffer only if we have a surface
- if(this.parent == null) return;
+ if(parent == null) return;
int lines = 0;
int fg, bg;
- boolean entireDirty = buffer.update[0] || this.fullRedraw;
+ boolean entireDirty = buffer.update[0] || fullRedraw;
// walk through all lines in the buffer
for(int l = 0; l < buffer.height; l++) {
@@ -931,8 +960,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
fg = Color.GRAY;
// correctly set bold and underlined attributes if requested
- this.defaultPaint.setFakeBoldText((currAttr & VDUBuffer.BOLD) != 0);
- this.defaultPaint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0);
+ defaultPaint.setFakeBoldText((currAttr & VDUBuffer.BOLD) != 0);
+ defaultPaint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0);
// determine the amount of continuous characters with the same settings and print them all at once
while(c + addr < buffer.width && buffer.charAttributes[buffer.windowBase + l][c + addr] == currAttr) {
@@ -940,15 +969,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
// clear this dirty area with background color
- this.defaultPaint.setColor(bg);
- canvas.drawRect(c * charWidth, (l * charHeight) - 1, (c + addr) * charWidth, (l + 1) * charHeight, this.defaultPaint);
+ defaultPaint.setColor(bg);
+ canvas.drawRect(c * charWidth, (l * charHeight) - 1, (c + addr) * charWidth, (l + 1) * charHeight, defaultPaint);
// write the text string starting at 'c' for 'addr' number of characters
- this.defaultPaint.setColor(fg);
+ defaultPaint.setColor(fg);
if((currAttr & VDUBuffer.INVISIBLE) == 0)
canvas.drawText(buffer.charArray[buffer.windowBase + l], c,
addr, c * charWidth, ((l + 1) * charHeight) - charDescent - 2,
- this.defaultPaint);
+ defaultPaint);
// advance to the next text block with different characteristics
c += addr - 1;
@@ -957,9 +986,9 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// reset entire-buffer flags
buffer.update[0] = false;
- this.fullRedraw = false;
+ fullRedraw = false;
- this.parent.postInvalidate();
+ parent.postInvalidate();
}
@@ -969,7 +998,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public void connectionLost(Throwable reason) {
// weve lost our ssh connection, so pass along to manager and gui
Log.e(TAG, "Somehow our underlying SSH socket died", reason);
- this.dispatchDisconnect();
+ dispatchDisconnect();
}
/**
@@ -1010,19 +1039,19 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
if (direction > 0)
size -= step;
- this.forcedSize = true;
- this.termWidth = cols;
- this.termHeight = rows;
+ forcedSize = true;
+ termWidth = cols;
+ termHeight = rows;
setFontSize(size);
}
private int fontSizeCompare(float size, int cols, int rows, int width, int height) {
// read new metrics to get exact pixel dimensions
- this.defaultPaint.setTextSize(size);
- FontMetricsInt fm = this.defaultPaint.getFontMetricsInt();
+ defaultPaint.setTextSize(size);
+ FontMetricsInt fm = defaultPaint.getFontMetricsInt();
float[] widths = new float[1];
- this.defaultPaint.getTextWidths("X", widths);
+ defaultPaint.getTextWidths("X", widths);
int termWidth = (int)widths[0] * cols;
int termHeight = (Math.abs(fm.top) + Math.abs(fm.descent) + 1) * rows;
@@ -1044,7 +1073,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* @return true on successful addition
*/
public boolean addPortForward(PortForwardBean portForward) {
- return this.portForwards.add(portForward);
+ return portForwards.add(portForward);
}
/**
@@ -1056,7 +1085,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// Make sure we don't have a phantom forwarder.
disablePortForward(portForward);
- return this.portForwards.remove(portForward);
+ return portForwards.remove(portForward);
}
/**
@@ -1073,7 +1102,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* @return true on successful port forward setup
*/
public boolean enablePortForward(PortForwardBean portForward) {
- if (!this.portForwards.contains(portForward)) {
+ if (!portForwards.contains(portForward)) {
Log.e(TAG, "Attempt to enable port forward not in list");
return false;
}
@@ -1081,7 +1110,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
if (HostDatabase.PORTFORWARD_LOCAL.equals(portForward.getType())) {
LocalPortForwarder lpf = null;
try {
- lpf = this.connection.createLocalPortForwarder(portForward.getSourcePort(), portForward.getDestAddr(), portForward.getDestPort());
+ lpf = connection.createLocalPortForwarder(portForward.getSourcePort(), portForward.getDestAddr(), portForward.getDestPort());
} catch (IOException e) {
Log.e(TAG, "Could not create local port forward", e);
return false;
@@ -1097,7 +1126,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
return true;
} else if (HostDatabase.PORTFORWARD_REMOTE.equals(portForward.getType())) {
try {
- this.connection.requestRemotePortForwarding("", portForward.getSourcePort(), portForward.getDestAddr(), portForward.getDestPort());
+ connection.requestRemotePortForwarding("", portForward.getSourcePort(), portForward.getDestAddr(), portForward.getDestPort());
} catch (IOException e) {
Log.e(TAG, "Could not create remote port forward", e);
return false;
@@ -1109,7 +1138,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
DynamicPortForwarder dpf = null;
try {
- dpf = this.connection.createDynamicPortForwarder(portForward.getSourcePort());
+ dpf = connection.createDynamicPortForwarder(portForward.getSourcePort());
} catch (IOException e) {
Log.e(TAG, "Could not create dynamic port forward", e);
return false;
@@ -1132,7 +1161,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
* @return true on successful port forward tear-down
*/
public boolean disablePortForward(PortForwardBean portForward) {
- if (!this.portForwards.contains(portForward)) {
+ if (!portForwards.contains(portForward)) {
Log.e(TAG, "Attempt to disable port forward not in list");
return false;
}
@@ -1160,7 +1189,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
portForward.setEnabled(false);
try {
- this.connection.cancelRemotePortForwarding(portForward.getSourcePort());
+ connection.cancelRemotePortForwarding(portForward.getSourcePort());
} catch (IOException e) {
Log.e(TAG, "Could not stop remote port forwarding, setting enabled to false", e);
return false;
@@ -1206,4 +1235,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public boolean isAuthenticated() {
return authenticated;
}
+
+ /**
+ * @return whether the TerminalBridge should close
+ */
+ public boolean isAwaitingClose() {
+ return awaitingClose;
+ }
}
diff --git a/src/org/connectbot/util/HelpTopicView.java b/src/org/connectbot/util/HelpTopicView.java
index 2a163cc..84216ae 100644
--- a/src/org/connectbot/util/HelpTopicView.java
+++ b/src/org/connectbot/util/HelpTopicView.java
@@ -20,6 +20,7 @@ package org.connectbot.util;
import org.connectbot.HelpActivity;
import android.content.Context;
+import android.util.AttributeSet;
import android.webkit.WebSettings;
import android.webkit.WebView;
@@ -28,29 +29,34 @@ import android.webkit.WebView;
*
*/
public class HelpTopicView extends WebView {
+ public HelpTopicView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initialize();
+ }
+
+ public HelpTopicView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize();
+ }
- /**
- * @param context
- */
public HelpTopicView(Context context) {
super(context);
-
+ initialize();
+ }
+
+ private void initialize() {
WebSettings wSet = getSettings();
wSet.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
wSet.setUseWideViewPort(false);
}
- public HelpTopicView(Context context, String topic) {
- this(context);
-
- this.setTopic(topic);
- }
-
- public void setTopic(String topic) {
+ public HelpTopicView setTopic(String topic) {
String path = String.format("file:///android_asset/%s/%s%s",
HelpActivity.HELPDIR, topic, HelpActivity.SUFFIX);
loadUrl(path);
computeScroll();
+
+ return this;
}
}