aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/org/connectbot/ConsoleActivity.java171
-rw-r--r--src/org/connectbot/HostListActivity.java117
-rw-r--r--src/org/connectbot/R.java4
-rw-r--r--src/org/connectbot/TerminalView.java2
-rw-r--r--src/org/connectbot/WizardActivity.java107
-rw-r--r--src/org/connectbot/service/TerminalBridge.java55
6 files changed, 277 insertions, 179 deletions
diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java
index 9417f65..450322e 100644
--- a/src/org/connectbot/ConsoleActivity.java
+++ b/src/org/connectbot/ConsoleActivity.java
@@ -30,7 +30,9 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.text.ClipboardManager;
import android.util.Log;
import android.view.GestureDetector;
@@ -40,11 +42,14 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.Window;
import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ViewFlipper;
@@ -88,6 +93,9 @@ public class ConsoleActivity extends Activity {
// create views for all bridges on this service
for(TerminalBridge bridge : bound.bridges) {
+ // let them know about our password services
+ bridge.passwordHandler = passwordHandler;
+
// inflate each terminal view
RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.item_terminal, flip, false);
@@ -112,6 +120,7 @@ public class ConsoleActivity extends Activity {
// show the requested bridge if found, also fade out overlay
flip.setDisplayedChild(requestedIndex);
flip.getCurrentView().findViewById(R.id.terminal_overlay).startAnimation(fade_out);
+ updatePasswordVisible();
}
@@ -122,7 +131,47 @@ public class ConsoleActivity extends Activity {
}
};
- protected Animation fade_out = null;
+ protected String getCurrentNickname() {
+ View view = findCurrentView(R.id.console_flip);
+ if(!(view instanceof TerminalView)) return null;
+ return ((TerminalView)view).bridge.nickname;
+ }
+
+
+ public Handler passwordHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ // someone below us requested to display a password dialog
+ // they are sending nickname and requested
+ String nickname = (String)msg.obj;
+
+ // if they are currently active, then obey request
+ if(nickname.equals(getCurrentNickname())) {
+ updatePasswordVisible();
+ }
+
+ }
+ };
+
+ protected void updatePasswordVisible() {
+ // check if our currently-visible terminalbridge is requesting password services
+ View view = findCurrentView(R.id.console_flip);
+ boolean requested = false;
+ if(view instanceof TerminalView)
+ requested = ((TerminalView)view).bridge.passwordRequested;
+
+ // handle showing/hiding password field and transferring focus
+ if(requested) {
+ this.password.setVisibility(View.VISIBLE);
+ this.password.setText("");
+ this.password.setHint(((TerminalView)view).bridge.passwordHint);
+ this.password.requestFocus();
+ } else {
+ this.password.setVisibility(View.GONE);
+ view.requestFocus();
+ }
+
+ }
/**
* Save the currently shown {@link TerminalView} as the default. This is
@@ -131,13 +180,14 @@ public class ConsoleActivity extends Activity {
*/
protected void updateDefault() {
// update the current default terminal
- TerminalView terminal = (TerminalView)flip.getCurrentView().findViewById(R.id.console_flip);
- if(bound == null || terminal == null) return;
+ 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 Uri requested;
-
@Override
public void onStart() {
super.onStart();
@@ -149,7 +199,7 @@ public class ConsoleActivity extends Activity {
}
@Override
- public void onStop() {
+ public void onStop() {
super.onStop();
this.unbindService(connection);
@@ -161,7 +211,12 @@ public class ConsoleActivity extends Activity {
return view.findViewById(id);
}
+ protected Uri requested;
protected ClipboardManager clipboard;
+
+ protected EditText password;
+
+ 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) {
@@ -176,17 +231,36 @@ public class ConsoleActivity extends Activity {
this.requested = this.getIntent().getData();
this.inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- this.flip = (ViewFlipper)this.findViewById(R.id.console_flip);
- this.fade_out = AnimationUtils.loadAnimation(this, R.anim.fade_out);
+ this.flip = (ViewFlipper)this.findViewById(R.id.console_flip);
+ this.password = (EditText)this.findViewById(R.id.console_password);
+ this.password.setOnKeyListener(new OnKeyListener() {
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if(keyCode != KeyEvent.KEYCODE_ENTER) return false;
+
+ // pass collected password down to current terminal
+ String value = password.getText().toString();
+
+ View view = findCurrentView(R.id.console_flip);
+ if(!(view instanceof TerminalView)) return true;
+ ((TerminalView)view).bridge.incomingPassword(value);
+
+ // finally clear password for next user
+ password.setText("");
+ return true;
+ }
+ });
+
// preload animations for terminal switching
- final Animation slide_left_in = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
- final Animation slide_left_out = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
- final Animation slide_right_in = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
- final Animation slide_right_out = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
- final Animation fade_stay_hidden = AnimationUtils.loadAnimation(this, R.anim.fade_stay_hidden);
+ this.slide_left_in = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
+ this.slide_left_out = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
+ this.slide_right_in = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
+ this.slide_right_out = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
+
+ this.fade_out = AnimationUtils.loadAnimation(this, R.anim.fade_out);
+ this.fade_stay_hidden = AnimationUtils.loadAnimation(this, R.anim.fade_stay_hidden);
// detect fling gestures to switch between terminals
final GestureDetector detect = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
@@ -202,7 +276,7 @@ public class ConsoleActivity extends Activity {
}
// activate consider if within x tolerance
- if(Math.abs(e1.getX() - e2.getX()) < 100) {
+ if(Math.abs(e1.getX() - e2.getX()) < ViewConfiguration.getTouchSlop() * 4) {
View flip = findCurrentView(R.id.console_flip);
if(flip == null) return false;
@@ -224,12 +298,10 @@ public class ConsoleActivity extends Activity {
} else {
// otherwise consume as pgup/pgdown for every 5 lines
if(moved > 5) {
- Log.d(this.getClass().toString(), "going pagedown");
((vt320)terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_DOWN, ' ', 0);
totalY = 0;
return true;
} else if(moved < -5) {
- Log.d(this.getClass().toString(), "going pageup");
((vt320)terminal.bridge.buffer).keyPressed(vt320.KEY_PAGE_UP, ' ', 0);
totalY = 0;
return true;
@@ -237,7 +309,6 @@ public class ConsoleActivity extends Activity {
}
-
}
return false;
@@ -256,36 +327,12 @@ public class ConsoleActivity extends Activity {
// make sure user kept a steady hand horizontally
if(Math.abs(disty) < 100) {
if(distx > goalwidth) {
-
- // 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);
+ shiftRight();
return true;
}
if(distx < -goalwidth) {
-
- // 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_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);
+ shiftLeft();
return true;
}
@@ -299,7 +346,6 @@ public class ConsoleActivity extends Activity {
});
-
flip.setLongClickable(true);
flip.setOnTouchListener(new OnTouchListener() {
@@ -310,9 +356,43 @@ public class ConsoleActivity extends Activity {
});
+ }
+
+ 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);
+
+ 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);
+
+ updatePasswordVisible();
+
+ }
+ 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);
+
+ updatePasswordVisible();
+
}
protected MenuItem copy, paste;
@@ -331,6 +411,7 @@ public class ConsoleActivity extends Activity {
TerminalView terminal = (TerminalView)view;
bound.disconnect(terminal.bridge);
flip.removeView(flip.getCurrentView());
+ shiftLeft();
return true;
}
});
@@ -338,7 +419,7 @@ public class ConsoleActivity extends Activity {
copy = menu.add("Copy");
copy.setIcon(android.R.drawable.ic_menu_set_as);
copy.setEnabled(false);
- // TODO: implement copy here :)
+ // TODO: freeze current console, allow selection, and set clipboard to contents
paste = menu.add("Paste");
diff --git a/src/org/connectbot/HostListActivity.java b/src/org/connectbot/HostListActivity.java
index 30ec5f9..9512d07 100644
--- a/src/org/connectbot/HostListActivity.java
+++ b/src/org/connectbot/HostListActivity.java
@@ -67,7 +67,7 @@ public class HostListActivity extends ListActivity {
}
};
- public TerminalManager bound = null;
+ protected TerminalManager bound = null;
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
@@ -83,11 +83,10 @@ public class HostListActivity extends ListActivity {
}
};
- public HostDatabase hostdb;
- public Cursor hosts;
- public ListView list;
+ protected HostDatabase hostdb;
+ protected Cursor hosts;
- public int COL_ID, COL_NICKNAME, COL_USERNAME, COL_HOSTNAME, COL_CONNECTED, COL_PORT;
+ protected int COL_ID, COL_NICKNAME, COL_USERNAME, COL_HOSTNAME, COL_CONNECTED, COL_PORT;
@Override
public void onStart() {
@@ -109,23 +108,34 @@ public class HostListActivity extends ListActivity {
public final static String EULA = "eula";
+
+ public final static int REQUEST_EDIT = 1;
+ public final static int REQUEST_EULA = 2;
+
protected SharedPreferences prefs = null;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if(resultCode == Activity.RESULT_OK) {
- // yay they agreed, so store that info
- Editor edit = prefs.edit();
- edit.putBoolean(EULA, true);
- edit.commit();
- } else {
- // user didnt agree, so close
- this.finish();
+ switch(requestCode) {
+ case REQUEST_EULA:
+ if(resultCode == Activity.RESULT_OK) {
+ // yay they agreed, so store that info
+ Editor edit = prefs.edit();
+ edit.putBoolean(EULA, true);
+ edit.commit();
+ } else {
+ // user didnt agree, so close
+ this.finish();
+ }
+ break;
+
+ case REQUEST_EDIT:
+ this.updateCursor();
+ break;
+
}
- this.updateCursor();
-
}
@@ -142,7 +152,7 @@ public class HostListActivity extends ListActivity {
boolean agreed = prefs.getBoolean(EULA, false);
if(!agreed) {
- this.startActivityForResult(new Intent(this, WizardActivity.class), 1);
+ this.startActivityForResult(new Intent(this, WizardActivity.class), REQUEST_EULA);
}
// start thread to check for new version
@@ -155,7 +165,7 @@ public class HostListActivity extends ListActivity {
// connect with hosts database and populate list
this.hostdb = new HostDatabase(this);
- this.list = this.getListView();
+ ListView list = this.getListView();
this.updateCursor();
//this.list.setSelector(R.drawable.highlight_disabled_pressed);
@@ -167,7 +177,7 @@ public class HostListActivity extends ListActivity {
this.COL_PORT = hosts.getColumnIndexOrThrow(HostDatabase.FIELD_HOST_PORT);
this.COL_CONNECTED = hosts.getColumnIndexOrThrow(HostDatabase.FIELD_HOST_LASTCONNECT);
- this.list.setOnItemClickListener(new OnItemClickListener() {
+ list.setOnItemClickListener(new OnItemClickListener() {
public synchronized void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -208,7 +218,7 @@ public class HostListActivity extends ListActivity {
});
- this.registerForContextMenu(this.list);
+ this.registerForContextMenu(list);
final Pattern hostmask = Pattern.compile(".+@.+(:\\d+)?");
final TextView text = (TextView) this.findViewById(R.id.front_quickconnect);
@@ -216,40 +226,38 @@ public class HostListActivity extends ListActivity {
public boolean onKey(View v, int keyCode, KeyEvent event) {
- if(keyCode == KeyEvent.KEYCODE_ENTER) {
-
- // make sure we follow pattern
- if (text.getText().length() < 3)
- return false;
-
- // show error if poorly formed
- if (!hostmask.matcher(text.getText().toString()).find()) {
- text.setError("Use the format 'username@hostname:port'");
- return false;
- }
-
- // create new host for entered string and then launch
- Uri uri = Uri.parse(String.format("ssh://%s", text.getText().toString()));
- String username = uri.getUserInfo();
- String hostname = uri.getHost();
- int port = uri.getPort();
- if(port == -1) port = 22;
+ if(keyCode != KeyEvent.KEYCODE_ENTER) return false;
- String nickname = String.format("%s@%s", username, hostname);
- hostdb.createHost(null, nickname, username, hostname, port, hostdb.COLOR_GRAY);
-
- Intent intent = new Intent(HostListActivity.this, ConsoleActivity.class);
- intent.setData(Uri.parse(String.format("ssh://%s@%s:%s/#%s", username, hostname, port, nickname)));
- HostListActivity.this.startActivity(intent);
-
+ // make sure we follow pattern
+ if (text.getText().length() < 3)
+ return false;
+
+ // show error if poorly formed
+ if (!hostmask.matcher(text.getText().toString()).find()) {
+ text.setError("Use the format 'username@hostname:port'");
+ return false;
}
+
+ // create new host for entered string and then launch
+ Uri uri = Uri.parse(String.format("ssh://%s", text.getText().toString()));
+ String username = uri.getUserInfo();
+ String hostname = uri.getHost();
+ int port = uri.getPort();
+ if(port == -1) port = 22;
+
+ String nickname = String.format("%s@%s", username, hostname);
+ hostdb.createHost(null, nickname, username, hostname, port, hostdb.COLOR_GRAY);
+
+ Intent intent = new Intent(HostListActivity.this, ConsoleActivity.class);
+ intent.setData(Uri.parse(String.format("ssh://%s@%s:%s/#%s", username, hostname, port, nickname)));
+ HostListActivity.this.startActivity(intent);
// set list filter based on text
// String filter = text.getText().toString();
// list.setTextFilterEnabled((filter.length() > 0));
// list.setFilterText(filter);
- return false;
+ return true;
}
});
@@ -259,7 +267,7 @@ public class HostListActivity extends ListActivity {
public MenuItem sortcolor, sortlast;
public boolean sortedByColor = false;
- public void updateCursor() {
+ protected void updateCursor() {
// refresh cursor because of possible sorting change
if(this.hosts != null)
@@ -267,12 +275,12 @@ public class HostListActivity extends ListActivity {
this.hosts = this.hostdb.allHosts(sortedByColor);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_host, this.hosts,
- new String[] { hostdb.FIELD_HOST_NICKNAME, hostdb.FIELD_HOST_LASTCONNECT, hostdb.FIELD_HOST_LASTCONNECT, hostdb.FIELD_HOST_COLOR },
+ new String[] { HostDatabase.FIELD_HOST_NICKNAME, HostDatabase.FIELD_HOST_LASTCONNECT, HostDatabase.FIELD_HOST_LASTCONNECT, HostDatabase.FIELD_HOST_COLOR },
new int[] { android.R.id.text1, android.R.id.text2, android.R.id.icon, android.R.id.content });
adapter.setViewBinder(new HostBinder(bound, this.getResources()));
//this.adapter = new HostAdapter(this, this.hosts);
- this.list.setAdapter(adapter);
+ this.setListAdapter(adapter);
}
@@ -293,14 +301,6 @@ public class HostListActivity extends ListActivity {
// add host, ssh keys, about
-// MenuItem add = menu.add(0, 0, Menu.NONE, "New host");
-// add.setIcon(android.R.drawable.ic_menu_add);
-// add.setOnMenuItemClickListener(new OnMenuItemClickListener() {
-// public boolean onMenuItemClick(MenuItem item) {
-// return true;
-// }
-// });
-
sortcolor = menu.add("Sort by color");
sortcolor.setIcon(android.R.drawable.ic_menu_share);
sortcolor.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@@ -337,9 +337,6 @@ public class HostListActivity extends ListActivity {
}
-
-
- public final static int REQUEST_EDIT = 1;
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
@@ -348,7 +345,7 @@ public class HostListActivity extends ListActivity {
// create menu to handle deleting and sharing lists
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- Cursor cursor = (Cursor) this.list.getItemAtPosition(info.position);
+ Cursor cursor = (Cursor) this.getListView().getItemAtPosition(info.position);
menu.setHeaderTitle(cursor.getString(COL_NICKNAME));
final int id = cursor.getInt(COL_ID);
diff --git a/src/org/connectbot/R.java b/src/org/connectbot/R.java
index 416addd..e82a6e1 100644
--- a/src/org/connectbot/R.java
+++ b/src/org/connectbot/R.java
@@ -41,10 +41,10 @@ public final class R {
public static final int action_next=0x7f090005;
public static final int action_prev=0x7f090004;
public static final int console_flip=0x7f090000;
- public static final int front_quickconnect=0x7f090001;
+ public static final int console_password=0x7f090001;
+ public static final int front_quickconnect=0x7f090002;
public static final int terminal_overlay=0x7f090006;
public static final int wizard_flipper=0x7f090003;
- public static final int wizard_scroll=0x7f090002;
}
public static final class layout {
public static final int act_console=0x7f030000;
diff --git a/src/org/connectbot/TerminalView.java b/src/org/connectbot/TerminalView.java
index 8e4c893..d94b84b 100644
--- a/src/org/connectbot/TerminalView.java
+++ b/src/org/connectbot/TerminalView.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelXorXfermode;
+import android.os.Handler;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@@ -59,6 +60,7 @@ public class TerminalView extends View {
// connect our view up to the bridge
this.setOnKeyListener(bridge);
+
}
public void destroy() {
diff --git a/src/org/connectbot/WizardActivity.java b/src/org/connectbot/WizardActivity.java
index 1d4c10f..48cba6b 100644
--- a/src/org/connectbot/WizardActivity.java
+++ b/src/org/connectbot/WizardActivity.java
@@ -34,51 +34,19 @@ import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.ViewFlipper;
+/**
+ * Show a series of wizard-like steps to the user, which might include an EULA,
+ * program credits, and helpful hints.
+ *
+ * @author jsharkey
+ */
public class WizardActivity extends Activity {
-
- public final static int ACTION_NEXT = +1, ACTION_PREV = -1;
-
- protected Handler actionHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
-
- switch(msg.what) {
- case ACTION_NEXT:
- if(flipper.getDisplayedChild() == flipper.getChildCount() - 1) {
- WizardActivity.this.setResult(Activity.RESULT_OK);
- WizardActivity.this.finish();
- } else {
- flipper.showNext();
- }
- break;
- case ACTION_PREV:
- if(flipper.getDisplayedChild() == 0) {
- WizardActivity.this.setResult(Activity.RESULT_CANCELED);
- WizardActivity.this.finish();
- } else {
- flipper.showPrevious();
- }
- break;
-
- }
-
- // scroll to top and hide all views except current
- scroll.scrollTo(0, 0);
-
- setButtons();
-
- }
- };
-
- protected void setButtons() {
- boolean eula = (flipper.getDisplayedChild() == 0);
-
- next.setText(eula ? "Agree" : "Next");
- prev.setText(eula ? "Cancel" : "Back");
-
- }
-
- protected ScrollView scroll = null;
+
+ /**
+ * In-order list of wizard steps to present to user. These are layout resource ids.
+ */
+ public final static int[] STEPS = new int[] { R.layout.wiz_eula, R.layout.wiz_features };
+
protected ViewFlipper flipper = null;
protected Button next, prev;
@@ -87,33 +55,62 @@ public class WizardActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_wizard);
- // let the user step through various parts of wizard
- // inflate all views to walk through
-
- LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- this.scroll = (ScrollView)this.findViewById(R.id.wizard_scroll);
this.flipper = (ViewFlipper)this.findViewById(R.id.wizard_flipper);
- this.flipper.addView(inflater.inflate(R.layout.wiz_eula, this.flipper, false));
- this.flipper.addView(inflater.inflate(R.layout.wiz_features, this.flipper, false));
+ // inflate the layouts for each step
+ LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ for(int layout : STEPS) {
+ View step = inflater.inflate(layout, this.flipper, false);
+ this.flipper.addView(step);
+ }
next = (Button)this.findViewById(R.id.action_next);
next.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
- actionHandler.sendEmptyMessage(ACTION_NEXT);
+ if(isLastDisplayed()) {
+ // user walked past end of wizard, so return okay
+ WizardActivity.this.setResult(Activity.RESULT_OK);
+ WizardActivity.this.finish();
+ } else {
+ // show next step and update buttons
+ flipper.showNext();
+ updateButtons();
+ }
}
});
prev = (Button)this.findViewById(R.id.action_prev);
prev.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
- actionHandler.sendEmptyMessage(ACTION_PREV);
+ if(isFirstDisplayed()) {
+ // user walked past beginning of wizard, so return that they cancelled
+ WizardActivity.this.setResult(Activity.RESULT_CANCELED);
+ WizardActivity.this.finish();
+ } else {
+ // show previous step and update buttons
+ flipper.showPrevious();
+ updateButtons();
+ }
}
});
- this.setButtons();
+ this.updateButtons();
+
+ }
+
+ protected boolean isFirstDisplayed() {
+ return (flipper.getDisplayedChild() == 0);
+ }
+
+ protected boolean isLastDisplayed() {
+ return (flipper.getDisplayedChild() == flipper.getChildCount() - 1);
+ }
+
+ protected void updateButtons() {
+ boolean eula = (flipper.getDisplayedChild() == 0);
+ next.setText(eula ? "Agree" : "Next");
+ prev.setText(eula ? "Cancel" : "Back");
}
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index 2a6f276..2cddb52 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -30,6 +30,8 @@ import android.graphics.PixelXorXfermode;
import android.graphics.Typeface;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.FontMetricsInt;
+import android.os.Handler;
+import android.os.Message;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -192,7 +194,11 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
outputLine("Trying to authenticate");
if(connection.isAuthMethodAvailable(username, AUTH_PASSWORD)) {
// show auth prompt in window
- promptPassword();
+ requestPasswordVisible(true, "Password");
+ //promptPassword();
+ } else {
+ outputLine("Looks like your host doesn't support 'password' authentication.");
+ outputLine("Other auth methods, such as interactive and publickey, are still being written.");
}
} catch (IOException e) {
Log.e(TAG, "Problem in SSH connection thread", e);
@@ -212,19 +218,33 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
this.redraw();
}
- protected void promptPassword() {
- this.outputLine("Password: ");
+// protected void promptPassword() {
+// this.outputLine("Password: ");
+// }
+
+ public boolean passwordRequested = false;
+ public Handler passwordHandler = null;
+ public String passwordHint = null;
+
+ protected void requestPasswordVisible(boolean visible, String hint) {
+ this.passwordRequested = visible;
+ this.passwordHint = hint;
+
+ // pass notification up to any attached gui
+ if(this.passwordHandler != null)
+ Message.obtain(this.passwordHandler, -1, this.nickname).sendToTarget();
}
/**
* Attempt to try password authentication using given string.
*/
- public void tryPassword(String password) {
+ public void incomingPassword(String password) {
try {
// try authenticating with given password
Log.d(TAG, "Attempting to try password authentication");
if(this.connection.authenticateWithPassword(this.username, password)) {
this.buffer.deleteArea(0, 0, this.buffer.getColumns(), this.buffer.getRows());
+ requestPasswordVisible(false, null);
finishConnection();
return;
}
@@ -232,7 +252,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
Log.e(TAG, "Problem while trying to authenticate with password", e);
}
this.outputLine("Permission denied, please try again.");
- this.promptPassword();
+// this.promptPassword();
}
/**
@@ -246,6 +266,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
// 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("screen", 0, 0, 0, 0, null);
this.session.startShell();
@@ -305,7 +326,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
* Buffer of collected characters, for example when prompted for password or
* accepting a hostkey.
*/
- protected StringBuffer collected = new StringBuffer();
+ //protected StringBuffer collected = new StringBuffer();
/**
* Handle onKey() events coming down from a {@link TerminalView} above us.
@@ -333,17 +354,17 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {
if(this.session == null) {
// check to see if we are collecting password information
- if(keyCode == KeyEvent.KEYCODE_ENTER) {
- this.tryPassword(collected.toString());
- collected = new StringBuffer();
- return true;
- } else if(printing) {
- collected.appendCodePoint(keymap.get(keyCode, event.getMetaState()));
- return true;
- } else if(keyCode == KeyEvent.KEYCODE_DEL && collected.length() > 0) {
- collected.deleteCharAt(collected.length() - 1);
- return true;
- }
+// if(keyCode == KeyEvent.KEYCODE_ENTER) {
+// this.incomingPassword(collected.toString());
+// collected = new StringBuffer();
+// return true;
+// } else if(printing) {
+// collected.appendCodePoint(keymap.get(keyCode, event.getMetaState()));
+// return true;
+// } else if(keyCode == KeyEvent.KEYCODE_DEL && collected.length() > 0) {
+// collected.deleteCharAt(collected.length() - 1);
+// return true;
+// }
} else {