package com.mogujie.tt.imlib;
import java.util.ArrayList;
import java.util.List;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import com.mogujie.tt.config.SysConstant;
import com.mogujie.tt.imlib.common.ErrorCode;
import com.mogujie.tt.imlib.network.SocketThread;
import com.mogujie.tt.imlib.proto.HeartBeatPacket;
import com.mogujie.tt.log.Logger;
import com.mogujie.tt.ui.utils.IMServiceHelper;
import com.mogujie.tt.ui.utils.IMServiceHelper.OnIMServiceListner;
public class IMHeartBeatManager extends IMManager implements OnIMServiceListner {
// todo eric this is not a good way to keep heartbeat
private static IMHeartBeatManager inst;
public static IMHeartBeatManager instance() {
synchronized (IMContactManager.class) {
if (inst == null) {
inst = new IMHeartBeatManager();
}
return inst;
}
}
private Logger logger = Logger.getLogger(IMHeartBeatManager.class);
private IMServiceHelper imServiceHelper = new IMServiceHelper();
private PendingIntent pi;
//todo eric, ask luoning to support 4 minutes heartbeat
//right now, it will cost the battery really bad
// private final int HEARTBEAT_INTERVAL = 4 * 60 * 1000;
private final int HEARTBEAT_INTERVAL = 10 * 1000;
public void register() {
logger.d("heartbeat#regisgter");
List<String> actions = new ArrayList<String>();
actions.add(IMActions.ACTION_LOGIN_RESULT);
actions.add(IMActions.ACTION_SERVER_DISCONNECTED);
actions.add(IMActions.ACTION_SENDING_HEARTBEAT);
imServiceHelper.registerActions(ctx, actions, IMServiceHelper.INTENT_NO_PRIORITY, this);
}
private void reqSendHeartbeat() {
logger.i("heartbeat#reqSendHeartbeat");
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("contact#channel is null");
return;
}
channel.sendPacket(new HeartBeatPacket());
logger.i("heartbeat#send packet to server");
}
@Override
public void onAction(String action, Intent intent,
BroadcastReceiver broadcastReceiver) {
logger.d("heartbeat#onAction action:%s", action);
if (action.equals(IMActions.ACTION_LOGIN_RESULT)) {
handleLoginResultAction(intent);
} else if (action.equals(IMActions.ACTION_SERVER_DISCONNECTED)) {
handleDisconnectServerAction();
} else if (action.equals(IMActions.ACTION_SENDING_HEARTBEAT)) {
handleSendingHeartbeart();
}
}
private void handleSendingHeartbeart() {
logger.d("heartbeat#handleSendingHeartbeart");
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "teamtalk_heartbeat_wakelock");
wl.acquire();
try {
reqSendHeartbeat();
} catch (Exception e) {
logger.e("heartbeat#got exception");
} finally {
wl.release();
}
}
private void handleDisconnectServerAction() {
logger.d("heartbeat#handleDisconnectServerAction");
cancelHeartbeatTimer();
}
private void handleLoginResultAction(Intent intent) {
logger.d("heartbeat#handleLoginResultAction");
int errorCode = intent.getIntExtra(SysConstant.lOGIN_ERROR_CODE_KEY, -1);
if (errorCode == ErrorCode.S_OK) {
onLoginSuccess();
}
}
private void onLoginSuccess() {
logger.d("heartbeat#onLogin Successful");
scheduleHeartbeat(HEARTBEAT_INTERVAL);
}
private void scheduleHeartbeat(int seconds) {
logger.d("heartbeat#scheduleHeartbeat every %d seconds", seconds);
if (pi == null) {
logger.d("heartbeat#fill in pendingintent");
Intent intent = new Intent(IMActions.ACTION_SENDING_HEARTBEAT);
pi = PendingIntent.getBroadcast(ctx, 0, intent, 0);
if (pi == null) {
logger.e("heartbeat#pi is null");
return;
}
}
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + seconds, seconds, pi);
}
private void cancelHeartbeatTimer() {
logger.d("heartbeat#cancelHeartbeatTimer");
if (pi == null) {
logger.e("heartbeat#pi is null");
return;
}
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
@Override
public void onIMServiceConnected() {
// TODO Auto-generated method stub
}
}