package cri.sanity.util;
import cri.sanity.*;
import com.android.internal.telephony.ITelephony;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public final class MobDataTracker extends PhoneStateListener
{
private static final int ACT_NONE = 0;
private static final int ACT_ENABLE = 1;
private static final int ACT_DISABLE = 2;
private static final int ENABLED = TelephonyManager.DATA_CONNECTED;
private static final int ENABLING = TelephonyManager.DATA_CONNECTING;
private static final int DISABLED = TelephonyManager.DATA_DISCONNECTED;
private static final int SUSPENDED = TelephonyManager.DATA_SUSPENDED;
private static final int TASK_ACTION = Task.idNew();
private int state;
private int action = ACT_NONE;
private boolean waiter = false;
private ITelephony itel;
private final Task taskAction = new Task() {
@Override
public void run() {
synchronized(MobDataTracker.this) {
try {
if( action == ACT_ENABLE ) itel. enableDataConnectivity();
else if(action == ACT_DISABLE) itel.disableDataConnectivity();
} catch(Exception e) {
action = ACT_NONE;
state = SUSPENDED;
}
}
}
};
public MobDataTracker()
{
itel = Dev.iTel();
if(itel == null)
state = SUSPENDED;
else {
state = ENABLED;
A.telMan().listen(this, LISTEN_DATA_CONNECTION_STATE);
}
}
public synchronized void shutdown()
{
try {
if(action != ACT_NONE) {
waiter = true;
wait(Conf.DEVS_MIN_RETRY * 2);
}
} catch(Exception e) {}
try { A.telMan().listen(this, LISTEN_NONE); } catch(Exception e) {}
}
//public boolean isOn() { return state==ENABLED || state==ENABLING; }
public synchronized boolean willOn() {
return (action==ACT_NONE && (state==ENABLED || state==ENABLING)) || (action==ACT_ENABLE && Task.has(TASK_ACTION));
}
@Override
public synchronized void onDataConnectionStateChanged(int state)
{
this.state = state;
if(action != ACT_NONE) enable(action == ACT_ENABLE);
if(waiter) notifyAll();
}
public synchronized void enable(boolean enable)
{
switch(state) {
case SUSPENDED:
break;
case ENABLING:
action = enable? ACT_ENABLE : ACT_DISABLE;
break;
case DISABLED:
if(!enable)
action = ACT_NONE;
else {
action = ACT_ENABLE;
if(!Task.has(TASK_ACTION)) taskAction.exec(TASK_ACTION, Conf.TRACKER_SWITCH_DELAY);
}
break;
case ENABLED:
if(enable)
action = ACT_NONE;
else {
action = ACT_DISABLE;
if(!Task.has(TASK_ACTION)) taskAction.exec(TASK_ACTION, Conf.TRACKER_SWITCH_DELAY);
}
break;
default:
if(!enable)
action = ACT_NONE;
else {
action = ACT_ENABLE;
if(!Task.has(TASK_ACTION)) taskAction.exec(TASK_ACTION, Conf.DEVS_MIN_RETRY);
}
}
//A.logd("after mobdata enable ("+enable+") : action="+action+", state="+state);
}
}