/*
* Copyright (C) 2007-2008 Esmertec AG. Copyright (C) 2007-2008 The Android Open
* Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.awesomeapp.messenger.service;
import im.zom.messenger.R;
import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.Preferences;
import org.awesomeapp.messenger.RouterActivity;
import org.awesomeapp.messenger.model.Contact;
import org.awesomeapp.messenger.plugin.xmpp.XmppAddress;
import org.awesomeapp.messenger.provider.Imps;
import org.awesomeapp.messenger.ui.legacy.DatabaseUtils;
import org.awesomeapp.messenger.ui.widgets.RoundedAvatarDrawable;
import org.awesomeapp.messenger.util.SystemServices;
import java.util.HashMap;
import org.awesomeapp.messenger.MainActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
public class StatusBarNotifier {
private static final boolean DBG = false;
private static final long SUPPRESS_SOUND_INTERVAL_MS = 3000L;
static final long[] VIBRATE_PATTERN = new long[] { 0, 250, 250, 250 };
private Context mContext;
private NotificationManager mNotificationManager;
private Handler mHandler;
private HashMap<String, NotificationInfo> mNotificationInfos;
private long mLastSoundPlayedMs;
public StatusBarNotifier(Context context) {
mContext = context;
mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mHandler = new Handler();
mNotificationInfos = new HashMap<String, NotificationInfo>();
}
public void notifyChat(long providerId, long accountId, long chatId, String username,
String nickname, String msg, boolean lightWeightNotify) {
if (!Preferences.isNotificationEnabled()) {
if (DBG)
log("notification for chat " + username + " is not enabled");
return;
}
// msg = html2text(msg); // strip tags for html client inbound msgs
Bitmap avatar = null;
try { byte[] bdata = DatabaseUtils.getAvatarBytesFromAddress(mContext.getContentResolver(), XmppAddress.stripResource(username));
avatar = BitmapFactory.decodeByteArray(bdata, 0, bdata.length);
}
catch (Exception e){}
String title = nickname;
String snippet = mContext.getString(R.string.new_messages_notify) + ' ' + nickname;// + ": " + msg;
Intent intent = getDefaultIntent(accountId, providerId);//new Intent(Intent.ACTION_VIEW);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, chatId),Imps.Chats.CONTENT_ITEM_TYPE);
intent.addCategory(ImApp.IMPS_CATEGORY);
notify(username, title, snippet, msg, providerId, accountId, intent, lightWeightNotify, R.drawable.ic_discuss, avatar);
}
public void notifyError(String username, String error) {
Intent intent = getDefaultIntent(-1,-1);
notify(username, error, error, error, -1, -1, intent, true, R.drawable.alerts_and_states_error);
}
public void notifySubscriptionRequest(long providerId, long accountId, long contactId,
String username, String nickname) {
if (!Preferences.isNotificationEnabled()) {
if (DBG)
log("notification for subscription request " + username + " is not enabled");
return;
}
String title = nickname;
String message = mContext.getString(R.string.subscription_notify_text, nickname);
Intent intent = getDefaultIntent(accountId, providerId);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_FROM_ADDRESS, username);
intent.setType(Imps.Contacts.CONTENT_ITEM_TYPE);
intent.addCategory(ImApp.IMPS_CATEGORY);
notify(username, title, message, message, providerId, accountId, intent, false, R.drawable.ic_people_white_24dp);
}
public void notifySubscriptionApproved(Contact contact, long providerId, long accountId) {
if (!Preferences.isNotificationEnabled()) {
if (DBG)
log("notification for subscription approved is not enabled");
return;
}
String title = contact.getName();
String message = mContext.getString(R.string.invite_accepted);
Intent intent = getDefaultIntent(accountId, providerId);//new Intent(Intent.ACTION_VIEW);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_FROM_ADDRESS, contact.getAddress().getBareAddress());
intent.setType(Imps.Contacts.CONTENT_ITEM_TYPE);
intent.addCategory(ImApp.IMPS_CATEGORY);
notify(contact.getAddress().getAddress(), title, message, message, providerId, accountId, intent, false, R.drawable.ic_people_white_24dp);
}
public void notifyGroupInvitation(long providerId, long accountId, long invitationId,
String username) {
Intent intent = new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(
Imps.Invitation.CONTENT_URI, invitationId));
String title = mContext.getString(R.string.notify_groupchat_label);
String message = mContext.getString(R.string.group_chat_invite_notify_text, username);
notify(username, title, message, message, providerId, accountId, intent, false, R.drawable.group_chat);
}
public void notifyLoggedIn(long providerId, long accountId) {
Intent intent = new Intent(mContext, MainActivity.class);
;
String title = mContext.getString(R.string.app_name);
String message = mContext.getString(R.string.presence_available);
notify(message, title, message, message, providerId, accountId, intent, false, R.drawable.ic_discuss);
}
public void notifyLocked() {
Intent intent = new Intent(mContext, RouterActivity.class);
String title = mContext.getString(R.string.app_name);
String message = mContext.getString(R.string.account_setup_pers_now_title);
notify(message, title, message, message, -1, -1, intent, true, R.drawable.ic_lock_outline_black_18dp);
}
public void notifyDisconnected(long providerId, long accountId) {
Intent intent = new Intent(mContext, MainActivity.class);
;
String title = mContext.getString(R.string.app_name);
String message = mContext.getString(R.string.presence_offline);
notify(message, title, message, message, providerId, accountId, intent, false, R.drawable.alerts_and_states_error);
}
public void notifyFile(long providerId, long accountId, long id, String username,
String nickname, String path, Uri uri, String type, boolean b) {
String message = mContext.getString(R.string.file_notify_text);
Intent intent = SystemServices.Viewer.getViewIntent(uri, type);
notify(message, nickname, message, message, providerId, accountId, intent, false, R.drawable.ic_stat_status);
}
public void dismissNotifications(long providerId) {
synchronized (mNotificationInfos) {
NotificationInfo info = mNotificationInfos.get(providerId);
if (info != null) {
mNotificationManager.cancel(info.computeNotificationId());
mNotificationInfos.remove(providerId);
}
}
}
public void dismissChatNotification(long providerId, String username) {
NotificationInfo info;
boolean removed;
synchronized (mNotificationInfos) {
info = mNotificationInfos.get(username);
if (info == null) {
return;
}
removed = info.removeItem(username);
}
if (removed) {
if (info.getMessage() == null) {
if (DBG)
log("dismissChatNotification: removed notification for " + providerId);
mNotificationManager.cancel(info.computeNotificationId());
} else {
if (DBG) {
log("cancelNotify: new notification" + " mTitle=" + info.getTitle()
+ " mMessage=" + info.getMessage() + " mIntent=" + info.getIntent());
}
mNotificationManager.cancel(info.computeNotificationId());
}
}
}
public void notify(String title, String tickerText, String message,
Intent intent, boolean lightWeightNotify) {
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
NotificationInfo info;
info = new NotificationInfo(-1, -1);
info.addItem("", title, message, intent);
mNotificationManager.notify(info.computeNotificationId(),
info.createNotification(tickerText, lightWeightNotify, R.drawable.ic_stat_status, null, intent));
}
private void notify(String sender, String title, String tickerText, String message,
long providerId, long accountId, Intent intent, boolean lightWeightNotify, int iconSmall) {
notify(sender,title,tickerText,message,providerId,accountId,intent,lightWeightNotify,iconSmall,null);
}
private void notify(String sender, String title, String tickerText, String message,
long providerId, long accountId, Intent intent, boolean lightWeightNotify, int iconSmall, Bitmap iconLarge) {
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
NotificationInfo info;
synchronized (mNotificationInfos) {
info = mNotificationInfos.get(sender);
if (info == null) {
info = new NotificationInfo(providerId, accountId);
mNotificationInfos.put(sender, info);
}
info.addItem(sender, title, message, intent);
}
mNotificationManager.notify(info.computeNotificationId(),
info.createNotification(tickerText, lightWeightNotify, iconSmall, iconLarge, intent));
}
private Intent getDefaultIntent(long accountId, long providerId) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType(Imps.Contacts.CONTENT_TYPE);
intent.setClass(mContext, MainActivity.class);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, accountId);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, providerId);
return intent;
}
private void setRinger(long providerId, NotificationCompat.Builder builder) {
Uri ringtoneUri = Preferences.getNotificationRingtoneUri();
builder.setSound(ringtoneUri);
mLastSoundPlayedMs = SystemClock.elapsedRealtime();
if (DBG)
log("setRinger: notification.sound = " + ringtoneUri);
if (Preferences.getNotificationVibrate()) {
builder.setDefaults(Notification.DEFAULT_VIBRATE);
if (DBG)
log("setRinger: defaults |= vibrate");
}
}
private static int UNIQUE_INT_PER_CALL = 10000;
class NotificationInfo {
class Item {
String mTitle;
String mMessage;
Intent mIntent;
public Item(String title, String message, Intent intent) {
mTitle = title;
mMessage = message;
mIntent = intent;
}
}
// private HashMap<String, Item> mItems;
private Item lastItem;
private long mProviderId;
private long mAccountId;
public NotificationInfo(long providerId, long accountId) {
mProviderId = providerId;
mAccountId = accountId;
// mItems = new HashMap<String, Item>();
}
public int computeNotificationId() {
if (lastItem == null)
return (int)mProviderId;
return lastItem.mTitle.hashCode();
}
public synchronized void addItem(String sender, String title, String message, Intent intent) {
/*
Item item = mItems.get(sender);
if (item == null) {
item = new Item(title, message, intent);
mItems.put(sender, item);
} else {
item.mTitle = title;
item.mMessage = message;
item.mIntent = intent;
}*/
lastItem = new Item(title, message, intent);
}
public synchronized boolean removeItem(String sender) {
/*
Item item = mItems.remove(sender);
if (item != null) {
return true;
}*/
return true;
}
public Notification createNotification(String tickerText, boolean lightWeightNotify, int icon, Bitmap largeIcon, Intent intent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
// Intent intent = getDefaultIntent();
/**
if (lastItem.mIntent != null)
{
intent.setAction(lastItem.mIntent.getAction());
intent.setDataAndType(lastItem.mIntent.getData(), lastItem.mIntent.getType());
if (lastItem.mIntent.getExtras() != null)
intent.putExtras(lastItem.mIntent.getExtras());
intent.setFlags(lastItem.mIntent.getFlags());
}*/
builder
.setSmallIcon(icon)
.setTicker(lightWeightNotify ? null : tickerText)
.setWhen(System.currentTimeMillis())
.setLights(0xff00ff00, 300, 1000)
.setContentTitle(getTitle())
.setContentText(getMessage())
.setContentIntent(PendingIntent.getActivity(mContext, UNIQUE_INT_PER_CALL++, intent, PendingIntent.FLAG_UPDATE_CURRENT))
.setAutoCancel(true);
if (largeIcon != null)
builder.setLargeIcon(largeIcon);
if (!(lightWeightNotify || shouldSuppressSoundNotification())) {
setRinger(mProviderId, builder);
}
return builder.build();
}
private Intent getMultipleNotificationIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClass(mContext, MainActivity.class);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, mProviderId);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, mAccountId);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_SHOW_MULTIPLE, true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
public String getTitle() {
/*
int count = mItems.size();
if (count == 0) {
return null;
} else if (count == 1) {
Item item = mItems.values().iterator().next();
return item.mTitle;
} else {
return mContext.getString(R.string.newMessages_label, Imps.Provider
.getProviderNameForId(mContext.getContentResolver(), mProviderId));
}*/
return lastItem.mTitle;
}
public String getMessage() {
/*
int count = mItems.size();
if (count == 0) {
return null;
} else if (count == 1) {
Item item = mItems.values().iterator().next();
return item.mMessage;
} else {
return mContext.getString(R.string.num_unread_chats, count);
}*/
return lastItem.mMessage;
}
public Intent getIntent() {
/*
int count = mItems.size();
if (count == 0) {
return getDefaultIntent();
} else if (count == 1) {
Item item = mItems.values().iterator().next();
return item.mIntent;
} else {
return getMultipleNotificationIntent();
}*/
return lastItem.mIntent;
}
}
private static void log(String msg) {
RemoteImService.debug("[StatusBarNotify] " + msg);
}
private boolean shouldSuppressSoundNotification() {
return (SystemClock.elapsedRealtime() - mLastSoundPlayedMs < SUPPRESS_SOUND_INTERVAL_MS);
}
/**
public static String html2text(String html) {
return Jsoup.parse(html).text();
}**/
}