/*
* ConnectBot: simple, powerful, open-source SSH client for Android
* Copyright 2010 Kenny Root, Jeffrey Sharkey
*
* 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 org.connectbot.service;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.connectbot.ConsoleActivity;
import org.connectbot.HostListActivity;
import org.connectbot.R;
import org.connectbot.bean.HostBean;
import org.connectbot.util.HostDatabase;
import org.connectbot.util.PreferenceConstants;
import android.annotation.TargetApi;
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.res.Resources;
import android.graphics.Color;
import android.support.v4.app.NotificationCompat;
/**
* @author Kenny Root
*
* Based on the concept from jasta's blog post.
*/
public abstract class ConnectionNotifier {
private static final int ONLINE_NOTIFICATION = 1;
private static final int ACTIVITY_NOTIFICATION = 2;
private static final int ONLINE_DISCONNECT_NOTIFICATION = 3;
public static ConnectionNotifier getInstance() {
if (PreferenceConstants.PRE_ECLAIR)
return PreEclair.Holder.sInstance;
else
return EclairAndBeyond.Holder.sInstance;
}
protected NotificationManager getNotificationManager(Context context) {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
protected NotificationCompat.Builder newNotificationBuilder(Context context) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.notification_icon)
.setWhen(System.currentTimeMillis());
return builder;
}
protected Notification newActivityNotification(Context context, HostBean host) {
NotificationCompat.Builder builder = newNotificationBuilder(context);
Resources res = context.getResources();
String contentText = res.getString(
R.string.notification_text, host.getNickname());
Intent notificationIntent = new Intent(context, ConsoleActivity.class);
notificationIntent.setAction("android.intent.action.VIEW");
notificationIntent.setData(host.getUri());
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
builder.setContentTitle(res.getString(R.string.app_name))
.setContentText(contentText)
.setContentIntent(contentIntent);
builder.setAutoCancel(true);
int ledOnMS = 300;
int ledOffMS = 1000;
builder.setDefaults(Notification.DEFAULT_LIGHTS);
if (HostDatabase.COLOR_RED.equals(host.getColor()))
builder.setLights(Color.RED, ledOnMS, ledOffMS);
else if (HostDatabase.COLOR_GREEN.equals(host.getColor()))
builder.setLights(Color.GREEN, ledOnMS, ledOffMS);
else if (HostDatabase.COLOR_BLUE.equals(host.getColor()))
builder.setLights(Color.BLUE, ledOnMS, ledOffMS);
else
builder.setLights(Color.WHITE, ledOnMS, ledOffMS);
return builder.build();
}
protected Notification newRunningNotification(Context context) {
NotificationCompat.Builder builder = newNotificationBuilder(context);
builder.setOngoing(true);
builder.setWhen(0);
builder.setContentIntent(PendingIntent.getActivity(context,
ONLINE_NOTIFICATION,
new Intent(context, ConsoleActivity.class), 0));
Resources res = context.getResources();
builder.setContentTitle(res.getString(R.string.app_name));
builder.setContentText(res.getString(R.string.app_is_running));
Intent disconnectIntent = new Intent(context, HostListActivity.class);
disconnectIntent.setAction(HostListActivity.DISCONNECT_ACTION);
builder.addAction(
android.R.drawable.ic_menu_close_clear_cancel,
res.getString(R.string.list_host_disconnect),
PendingIntent.getActivity(
context,
ONLINE_DISCONNECT_NOTIFICATION,
disconnectIntent,
0));
return builder.build();
}
public void showActivityNotification(Service context, HostBean host) {
getNotificationManager(context).notify(ACTIVITY_NOTIFICATION, newActivityNotification(context, host));
}
public void hideActivityNotification(Service context) {
getNotificationManager(context).cancel(ACTIVITY_NOTIFICATION);
}
public abstract void showRunningNotification(Service context);
public abstract void hideRunningNotification(Service context);
private static class PreEclair extends ConnectionNotifier {
private static final Class<?>[] setForegroundSignature = new Class[] {boolean.class};
private Method setForeground = null;
private static class Holder {
private static final PreEclair sInstance = new PreEclair();
}
public PreEclair() {
try {
setForeground = Service.class.getMethod("setForeground", setForegroundSignature);
} catch (Exception e) {
}
}
@Override
public void showRunningNotification(Service context) {
if (setForeground != null) {
Object[] setForegroundArgs = new Object[1];
setForegroundArgs[0] = Boolean.TRUE;
try {
setForeground.invoke(context, setForegroundArgs);
} catch (InvocationTargetException e) {
} catch (IllegalAccessException e) {
}
getNotificationManager(context).notify(ONLINE_NOTIFICATION, newRunningNotification(context));
}
}
@Override
public void hideRunningNotification(Service context) {
if (setForeground != null) {
Object[] setForegroundArgs = new Object[1];
setForegroundArgs[0] = Boolean.FALSE;
try {
setForeground.invoke(context, setForegroundArgs);
} catch (InvocationTargetException e) {
} catch (IllegalAccessException e) {
}
getNotificationManager(context).cancel(ONLINE_NOTIFICATION);
}
}
}
@TargetApi(5)
private static class EclairAndBeyond extends ConnectionNotifier {
private static class Holder {
private static final EclairAndBeyond sInstance = new EclairAndBeyond();
}
@Override
public void showRunningNotification(Service context) {
context.startForeground(ONLINE_NOTIFICATION, newRunningNotification(context));
}
@Override
public void hideRunningNotification(Service context) {
context.stopForeground(true);
}
}
}