aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/raw/bell.oggbin0 -> 5090 bytes
-rw-r--r--res/values/strings.xml14
-rw-r--r--res/xml/preferences.xml19
-rw-r--r--src/org/connectbot/HostListActivity.java3
-rw-r--r--src/org/connectbot/bean/HostBean.java17
-rw-r--r--src/org/connectbot/service/TerminalBridge.java17
-rw-r--r--src/org/connectbot/service/TerminalManager.java104
-rw-r--r--src/org/connectbot/util/PreferenceConstants.java4
8 files changed, 169 insertions, 9 deletions
diff --git a/res/raw/bell.ogg b/res/raw/bell.ogg
new file mode 100644
index 0000000..674f25d
--- /dev/null
+++ b/res/raw/bell.ogg
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index db0e720..666bf3c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -169,6 +169,17 @@
<!-- Summary for the haptic feedback (bumpy arrow) preference -->
<string name="pref_bumpyarrows_summary">Vibrate when sending arrow keys from trackball; useful for laggy connections</string>
+ <!-- Checkbox preference title for the audible terminal bell feature -->
+ <string name="pref_bell_title">Audible terminal bell</string>
+
+ <!-- Checkbox preference title for the vibrate on terminal bell feature -->
+ <string name="pref_bell_vibrate_title">Vibrate on terminal bell</string>
+
+ <!-- Checkbox preference title for the receive notifications on terminal bell feature -->
+ <string name="pref_bell_notification_title">Terminal bell notifications</string>
+ <!-- Brief summary of the feature that is enabled when the checkbox preference for the receive notifications on terminal bell feature is checked -->
+ <string name="pref_bell_notification_summary">Send notification when a terminal running in the background sounds a bell.</string>
+
<!-- Preference selection to indicate use of right side of keyboard for special shortcuts. -->
<string name="list_keymode_right">Use right-side keys</string>
<!-- Preference selection to indicate use of left side of keyboard for special shortcuts. -->
@@ -334,6 +345,9 @@
<string name="local_shell_unavailable">Failure! Local shell is unavailable on this phone.</string>
+ <!-- Text sent to the user to alert them that a Terminal Bell is received in a background session -->
+ <string name="notification_text">%1$s wants your attention.</string>
+
<!-- Dialog title when a new version of ConnectBot is detected. -->
<string name="upgrade">New version</string>
<!-- Button selection to upgrade to the latest ConnectBot when one is available. -->
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 5836d33..42f6b24 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -114,6 +114,25 @@
android:defaultValue="true"
/>
+ <CheckBoxPreference
+ android:key="bell"
+ android:title="@string/pref_bell_title"
+ android:defaultValue="true"
+ />
+
+ <CheckBoxPreference
+ android:key="bellVibrate"
+ android:title="@string/pref_bell_vibrate_title"
+ android:defaultValue="true"
+ />
+
+ <CheckBoxPreference
+ android:key="bellNotification"
+ android:title="@string/pref_bell_notification_title"
+ android:summary="@string/pref_bell_notification_summary"
+ android:defaultValue="false"
+ />
+
</PreferenceCategory>
</PreferenceScreen>
diff --git a/src/org/connectbot/HostListActivity.java b/src/org/connectbot/HostListActivity.java
index b9ac4c1..662da65 100644
--- a/src/org/connectbot/HostListActivity.java
+++ b/src/org/connectbot/HostListActivity.java
@@ -262,8 +262,7 @@ public class HostListActivity extends ListActivity {
hostdb.saveHost(host);
Intent intent = new Intent(HostListActivity.this, ConsoleActivity.class);
- intent.setData(Uri.parse(String.format("ssh://%s@%s:%d/#%s",
- Uri.encode(username), Uri.encode(hostname), port, Uri.encode(nickname))));
+ intent.setData(host.getUri());
HostListActivity.this.startActivity(intent);
// set list filter based on text
diff --git a/src/org/connectbot/bean/HostBean.java b/src/org/connectbot/bean/HostBean.java
index 3e06986..65e0450 100644
--- a/src/org/connectbot/bean/HostBean.java
+++ b/src/org/connectbot/bean/HostBean.java
@@ -20,6 +20,7 @@ package org.connectbot.bean;
import org.connectbot.util.HostDatabase;
import android.content.ContentValues;
+import android.net.Uri;
/**
* @author Kenny Root
@@ -240,4 +241,20 @@ public class HostBean extends AbstractBean {
return hash;
}
+ /**
+ * @return URI identifying this HostBean
+ */
+ public Uri getUri() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("ssh://")
+ .append(Uri.encode(username))
+ .append('@')
+ .append(Uri.encode(hostname))
+ .append(':')
+ .append(port)
+ .append("/#")
+ .append(nickname);
+ return Uri.parse(sb.toString());
+ }
+
}
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index c12eeeb..ab8a396 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -48,7 +48,6 @@ import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.FontMetrics;
-import android.os.Vibrator;
import android.text.ClipboardManager;
import android.util.Log;
import android.view.KeyCharacterMap;
@@ -353,6 +352,14 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
@Override
public void setWindowSize(int c, int r) {
}
+
+ @Override
+ public void beep() {
+ if (parent.isShown())
+ manager.playBeep();
+ else
+ manager.sendActivityNotification(host);
+ }
};
buffer.setBufferSize(scrollback);
@@ -756,9 +763,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
private boolean bumpyArrows = false;
- public Vibrator vibrator = null;
-
- public static final long VIBRATE_DURATION = 30;
/**
* Handle onKey() events coming down from a {@link TerminalView} above us.
@@ -1106,8 +1110,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
public synchronized void tryKeyVibrate() {
- if (bumpyArrows && vibrator != null)
- vibrator.vibrate(VIBRATE_DURATION);
+ if (bumpyArrows)
+ manager.vibrate();
}
/**
@@ -1170,7 +1174,6 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
int height = parent.getHeight();
bumpyArrows = manager.prefs.getBoolean(PreferenceConstants.BUMPY_ARROWS, true);
- vibrator = (Vibrator) parent.getContext().getSystemService(Context.VIBRATOR_SERVICE);
clipboard = (ClipboardManager) parent.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
if (!forcedSize) {
diff --git a/src/org/connectbot/service/TerminalManager.java b/src/org/connectbot/service/TerminalManager.java
index 4fdf0b5..bd3c413 100644
--- a/src/org/connectbot/service/TerminalManager.java
+++ b/src/org/connectbot/service/TerminalManager.java
@@ -27,6 +27,8 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
+import org.connectbot.ConsoleActivity;
+import org.connectbot.R;
import org.connectbot.bean.HostBean;
import org.connectbot.bean.PubkeyBean;
import org.connectbot.util.HostDatabase;
@@ -34,11 +36,18 @@ import org.connectbot.util.PreferenceConstants;
import org.connectbot.util.PubkeyDatabase;
import org.connectbot.util.PubkeyUtils;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnCompletionListener;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
@@ -47,6 +56,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -82,9 +92,18 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
private ConnectivityManager connectivityManager;
private WifiManager.WifiLock wifilock;
+ private MediaPlayer mediaPlayer;
+ private static final float BEEP_VOLUME = 0.15f;
+
private Timer idleTimer;
private final long IDLE_TIMEOUT = 300000; // 5 minutes
+ private Vibrator vibrator;
+ public static final long VIBRATE_DURATION = 30;
+
+ private NotificationManager notificationManager;
+ private static final int NOTIFICATION_ID = 1;
+
@Override
public void onCreate() {
Log.i(TAG, "Starting background service");
@@ -115,6 +134,12 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifilock = manager.createWifiLock(TAG);
+
+ vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+
+ enableMediaPlayer();
+
+ notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
@Override
@@ -142,6 +167,8 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
if (wifilock != null && wifilock.isHeld())
wifilock.release();
+
+ disableMediaPlayer();
}
/**
@@ -348,4 +375,81 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
TerminalManager.this.stopNow();
}
}
+
+ public void vibrate() {
+ if (vibrator != null)
+ vibrator.vibrate(VIBRATE_DURATION);
+ }
+
+ private void enableMediaPlayer() {
+ mediaPlayer = new MediaPlayer();
+
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
+ mediaPlayer.setOnCompletionListener(new BeepListener());
+
+ AssetFileDescriptor file = res.openRawResourceFd(R.raw.bell);
+ try {
+ mediaPlayer.setDataSource(file.getFileDescriptor(), file
+ .getStartOffset(), file.getLength());
+ file.close();
+ mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
+ mediaPlayer.prepare();
+ } catch (IOException e) {
+ Log.e(TAG, "Error setting up bell media player", e);
+ }
+ }
+
+ private void disableMediaPlayer() {
+ if (mediaPlayer != null) {
+ mediaPlayer.release();
+ mediaPlayer = null;
+ }
+ }
+
+ public void playBeep() {
+ if (prefs.getBoolean(PreferenceConstants.BELL, true))
+ if (mediaPlayer != null)
+ mediaPlayer.start();
+
+ if (prefs.getBoolean(PreferenceConstants.BELL_VIBRATE, true))
+ vibrate();
+ }
+
+ class BeepListener implements OnCompletionListener {
+ public void onCompletion(MediaPlayer mp) {
+ mp.seekTo(0);
+ }
+ }
+
+ /**
+ * Send system notification to user for a certain host. When user selects
+ * the notification, it will bring them directly to the ConsoleActivity
+ * displaying the host.
+ *
+ * @param host
+ */
+ public void sendActivityNotification(HostBean host) {
+ if (!prefs.getBoolean(PreferenceConstants.BELL_NOTIFICATION, false))
+ return;
+
+ String contentText = res.getString(
+ R.string.notification_text, host.getNickname());
+
+ Notification notification = new Notification(
+ R.drawable.notification_icon, contentText,
+ System.currentTimeMillis());
+ notification.flags |= Notification.FLAG_AUTO_CANCEL;
+
+ Context context = getApplicationContext();
+ Intent notificationIntent = new Intent(this, ConsoleActivity.class);
+ notificationIntent.setAction("android.intent.action.VIEW");
+ notificationIntent.setData(host.getUri());
+
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+ notificationIntent, 0);
+
+ notification.setLatestEventInfo(context, res.getString(R.string.app_name), contentText, contentIntent);
+
+ notificationManager.notify(NOTIFICATION_ID, notification);
+ }
}
diff --git a/src/org/connectbot/util/PreferenceConstants.java b/src/org/connectbot/util/PreferenceConstants.java
index fb2f49b..2ba8d6f 100644
--- a/src/org/connectbot/util/PreferenceConstants.java
+++ b/src/org/connectbot/util/PreferenceConstants.java
@@ -64,4 +64,8 @@ public class PreferenceConstants {
public static final String EULA = "eula";
public static final String SORT_BY_COLOR = "sortByColor";
+
+ public static final String BELL = "bell";
+ public static final String BELL_VIBRATE = "bellVibrate";
+ public static final String BELL_NOTIFICATION = "bellNotification";
}