在GsmDataConnectiontracker构造方法中
p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
p.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
mSST是GsmServiceStateTrack。
void registerForGprsDetached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
gprsDetachedRegistrants.add(r);
if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) {
r.notifyRegistrant();
}
}
在mGsmServiceStateTrack中,当收到底层上来的PS注册状态时,执行:
case EVENT_POLL_STATE_GPRS:
states = (String[])ar.result;
int type = 0;
regState = -1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
// states[3] (if present) is the current radio technology
if (states.length >= 4 && states[3] != null) {
type = Integer.parseInt(states[3]);
}
} catch (NumberFormatException ex) {
Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
}
}
newGPRSState = regCodeToServiceState(regState);
mDataRoaming = regCodeIsRoaming(regState);
newNetworkType = type;
newSS.setRadioTechnology(type);
break;
然后调用pollStateDone(),方法中:
if (hasGprsAttached) {
gprsAttachedRegistrants.notifyRegistrants();
}
if (hasGprsDetached) {
gprsDetachedRegistrants.notifyRegistrants();
}
然后调用在GsmDataConnectiontracker的方法:
public void handleMessage (Message msg) {
if (DBG) Log.d(LOG_TAG,"GSMDataConnTrack handleMessage "+msg);
if (!mGsmPhone.mIsTheCurrentActivePhone) {
Log.d(LOG_TAG, "Ignore GSM msgs since GSM phone is inactive");
return;
}
switch (msg.what) {
case EVENT_RECORDS_LOADED:
onRecordsLoaded();
break;
case EVENT_GPRS_DETACHED:
onGprsDetached();
break;
case EVENT_GPRS_ATTACHED:
onGprsAttached();
break;
}
private void onGprsAttached() {
if (state == State.CONNECTED) {
startNetStatPoll();
phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
mRetryMgr.resetRetryCount();
}
trySetupData(Phone.REASON_GPRS_ATTACHED);
}
}
protected void startNetStatPoll() {
if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) {
Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
resetPollStats();
netStatPollEnabled = true;
mPollNetStat.run();
}
}
private Runnable mPollNetStat = new Runnable()
{
public void run() {
long sent, received;
long preTxPkts = -1, preRxPkts = -1;
Activity newActivity;
preTxPkts = txPkts;
preRxPkts = rxPkts;
txPkts = TrafficStats.getMobileTxPackets();
rxPkts = TrafficStats.getMobileRxPackets();setupData
//Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
sent = txPkts - preTxPkts;
received = rxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
sentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
mPdpResetCount = 0;
} else if (sent > 0 && received == 0) {
if (phone.getState() == Phone.State.IDLE) {
sentSinceLastRecv += sent;
} else {
sentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
sentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
mPdpResetCount = 0;
} else if (sent == 0 && received == 0) {
newActivity = Activity.NONE;
} else {
sentSinceLastRecv = 0;
newActivity = Activity.NONE;
}
if (activity != newActivity && mIsScreenOn) {
activity = newActivity;
phone.notifyDataActivity();
}
}
PhoneBase中:
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
DefaultPhoneNotifier:
public void notifyDataActivity(Phone sender) {
try {
mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState()));
} catch (RemoteException ex) {
// system process is dead
}
}
GsmPhone:
public DataActivityState getDataActivityState() {
DataActivityState ret = DataActivityState.NONE;
if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
switch (mDataConnection.getActivity()) {
case DATAIN:
ret = DataActivityState.DATAIN;
break;
case DATAOUT:
ret = DataActivityState.DATAOUT;
break;
case DATAINANDOUT:
ret = DataActivityState.DATAINANDOUT;
break;
}
}
return ret;
}
调用DefaultPhoneNotifier:
public static int convertDataActivityState(Phone.DataActivityState state) {
switch (state) {
case DATAIN:
return TelephonyManager.DATA_ACTIVITY_IN;
case DATAOUT:
return TelephonyManager.DATA_ACTIVITY_OUT;
case DATAINANDOUT:
return TelephonyManager.DATA_ACTIVITY_INOUT;
case DORMANT:
return TelephonyManager.DATA_ACTIVITY_DORMANT;
default:
return TelephonyManager.DATA_ACTIVITY_NONE;
}
}
调用TelephonyRegister:
public void notifyDataActivity(int state) {
369 if (!checkNotifyPermission("notifyDataActivity()" )) {
370 return;
371 }
372 synchronized (mRecords) {
373 mDataActivity = state;
374 for (int i = mRecords.size() - 1; i >= 0; i--) {
375 Record r = mRecords.get(i);
376 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
377 try {
378 r.callback.onDataActivity(state);
379 } catch (RemoteException ex) {
380 remove(r.binder);
381 }
382 }
383 }
384 }
385 }
StatusBarPolicy中:
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onDataActivity(int direction) {
mDataActivity = direction;
updateDataIcon();
}
};
private final void updateDataIcon() {
int iconId;
boolean visible = true;
if (!isCdma()) {
// GSM case, we have to check also the sim state
if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
if (hasPsService() && mDataState == TelephonyManager.DATA_CONNECTED) {
switch (mDataActivity) {
case TelephonyManager.DATA_ACTIVITY_IN:
iconId = mDataIconList[1];
break;
case TelephonyManager.DATA_ACTIVITY_OUT:
iconId = mDataIconList[2];
break;
case TelephonyManager.DATA_ACTIVITY_INOUT:
iconId = mDataIconList[3];
break;
default:
iconId = mDataIconList[0];
break;
}
mService.setIcon("data_connection", iconId, 0);
} else {
visible = false;
}
} else {
iconId = R.drawable.stat_sys_no_sim;
mService.setIcon("data_connection", iconId, 0);
}
}
}
p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
p.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
mSST是GsmServiceStateTrack。
void registerForGprsDetached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
gprsDetachedRegistrants.add(r);
if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) {
r.notifyRegistrant();
}
}
在mGsmServiceStateTrack中,当收到底层上来的PS注册状态时,执行:
case EVENT_POLL_STATE_GPRS:
states = (String[])ar.result;
int type = 0;
regState = -1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
// states[3] (if present) is the current radio technology
if (states.length >= 4 && states[3] != null) {
type = Integer.parseInt(states[3]);
}
} catch (NumberFormatException ex) {
Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
}
}
newGPRSState = regCodeToServiceState(regState);
mDataRoaming = regCodeIsRoaming(regState);
newNetworkType = type;
newSS.setRadioTechnology(type);
break;
然后调用pollStateDone(),方法中:
if (hasGprsAttached) {
gprsAttachedRegistrants.notifyRegistrants();
}
if (hasGprsDetached) {
gprsDetachedRegistrants.notifyRegistrants();
}
然后调用在GsmDataConnectiontracker的方法:
public void handleMessage (Message msg) {
if (DBG) Log.d(LOG_TAG,"GSMDataConnTrack handleMessage "+msg);
if (!mGsmPhone.mIsTheCurrentActivePhone) {
Log.d(LOG_TAG, "Ignore GSM msgs since GSM phone is inactive");
return;
}
switch (msg.what) {
case EVENT_RECORDS_LOADED:
onRecordsLoaded();
break;
case EVENT_GPRS_DETACHED:
onGprsDetached();
break;
case EVENT_GPRS_ATTACHED:
onGprsAttached();
break;
}
private void onGprsAttached() {
if (state == State.CONNECTED) {
startNetStatPoll();
phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
mRetryMgr.resetRetryCount();
}
trySetupData(Phone.REASON_GPRS_ATTACHED);
}
}
protected void startNetStatPoll() {
if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) {
Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
resetPollStats();
netStatPollEnabled = true;
mPollNetStat.run();
}
}
private Runnable mPollNetStat = new Runnable()
{
public void run() {
long sent, received;
long preTxPkts = -1, preRxPkts = -1;
Activity newActivity;
preTxPkts = txPkts;
preRxPkts = rxPkts;
txPkts = TrafficStats.getMobileTxPackets();
rxPkts = TrafficStats.getMobileRxPackets();setupData
//Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
sent = txPkts - preTxPkts;
received = rxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
sentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
mPdpResetCount = 0;
} else if (sent > 0 && received == 0) {
if (phone.getState() == Phone.State.IDLE) {
sentSinceLastRecv += sent;
} else {
sentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
sentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
mPdpResetCount = 0;
} else if (sent == 0 && received == 0) {
newActivity = Activity.NONE;
} else {
sentSinceLastRecv = 0;
newActivity = Activity.NONE;
}
if (activity != newActivity && mIsScreenOn) {
activity = newActivity;
phone.notifyDataActivity();
}
}
PhoneBase中:
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
DefaultPhoneNotifier:
public void notifyDataActivity(Phone sender) {
try {
mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState()));
} catch (RemoteException ex) {
// system process is dead
}
}
GsmPhone:
public DataActivityState getDataActivityState() {
DataActivityState ret = DataActivityState.NONE;
if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
switch (mDataConnection.getActivity()) {
case DATAIN:
ret = DataActivityState.DATAIN;
break;
case DATAOUT:
ret = DataActivityState.DATAOUT;
break;
case DATAINANDOUT:
ret = DataActivityState.DATAINANDOUT;
break;
}
}
return ret;
}
调用DefaultPhoneNotifier:
public static int convertDataActivityState(Phone.DataActivityState state) {
switch (state) {
case DATAIN:
return TelephonyManager.DATA_ACTIVITY_IN;
case DATAOUT:
return TelephonyManager.DATA_ACTIVITY_OUT;
case DATAINANDOUT:
return TelephonyManager.DATA_ACTIVITY_INOUT;
case DORMANT:
return TelephonyManager.DATA_ACTIVITY_DORMANT;
default:
return TelephonyManager.DATA_ACTIVITY_NONE;
}
}
调用TelephonyRegister:
public void notifyDataActivity(int state) {
369 if (!checkNotifyPermission("notifyDataActivity()" )) {
370 return;
371 }
372 synchronized (mRecords) {
373 mDataActivity = state;
374 for (int i = mRecords.size() - 1; i >= 0; i--) {
375 Record r = mRecords.get(i);
376 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
377 try {
378 r.callback.onDataActivity(state);
379 } catch (RemoteException ex) {
380 remove(r.binder);
381 }
382 }
383 }
384 }
385 }
StatusBarPolicy中:
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onDataActivity(int direction) {
mDataActivity = direction;
updateDataIcon();
}
};
private final void updateDataIcon() {
int iconId;
boolean visible = true;
if (!isCdma()) {
// GSM case, we have to check also the sim state
if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
if (hasPsService() && mDataState == TelephonyManager.DATA_CONNECTED) {
switch (mDataActivity) {
case TelephonyManager.DATA_ACTIVITY_IN:
iconId = mDataIconList[1];
break;
case TelephonyManager.DATA_ACTIVITY_OUT:
iconId = mDataIconList[2];
break;
case TelephonyManager.DATA_ACTIVITY_INOUT:
iconId = mDataIconList[3];
break;
default:
iconId = mDataIconList[0];
break;
}
mService.setIcon("data_connection", iconId, 0);
} else {
visible = false;
}
} else {
iconId = R.drawable.stat_sys_no_sim;
mService.setIcon("data_connection", iconId, 0);
}
}
}