@Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (VDBG) { mMdst.log("MdstHandler connected"); } mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj; } else { if (VDBG) { mMdst.log("MdstHandler %s NOT connected error=" + msg.arg1); } } break; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: if (VDBG) mMdst.log("Disconnected from DataStateTracker"); mMdst.mDataConnectionTrackerAc = null; break; default: { if (VDBG) mMdst.log("Ignorning unknown message=" + msg); break; } } }
/** * enable or disable interface by apn type * * @param apnType the type of APN to be enabled or disabled (e.g., mms) * @param enable {@code true} to enable the specified APN type, {@code false} to disable it. * @param radioNum 0:sim1, 1:sim2 * @return an integer value representing the outcome of the request. */ private int setEnableApnGemini(String apnType, boolean enable, int radioNum) { getPhoneService(false); /* * If the phone process has crashed in the past, we'll get a * RemoteException and need to re-reference the service. */ for (int retry = 0; retry < 2; retry++) { if (mPhoneService == null) { log("Ignoring feature request because could not acquire PhoneService"); break; } try { if (enable) { log( "gemini before enableApnTypeGemini() and mApnType is " + mApnType + " ,radioNum is " + radioNum); return mPhoneService.enableApnTypeGemini(apnType, radioNum); } else { return mPhoneService.disableApnTypeGemini(apnType, radioNum); } } catch (RemoteException e) { if (retry == 0) getPhoneService(true); } } log("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\""); return PhoneConstants.APN_REQUEST_FAILED; }
public void setInternalDataEnable(boolean enabled) { if (DBG) log("setInternalDataEnable: E enabled=" + enabled); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { channel.sendMessage( DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE, enabled ? DctConstants.ENABLED : DctConstants.DISABLED); } if (VDBG) log("setInternalDataEnable: X enabled=" + enabled); }
@Override public void setUserDataEnable(boolean enabled) { if (DBG) log("setUserDataEnable: E enabled=" + enabled); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { channel.sendMessage(CMD_SET_USER_DATA_ENABLE, enabled ? ENABLED : DISABLED); mUserDataEnabled = enabled; } if (VDBG) log("setUserDataEnable: X enabled=" + enabled); }
/** * carrier dependency is met/unmet * * @param met */ public void setDependencyMet(boolean met) { Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType); try { if (DBG) log("setDependencyMet: E met=" + met); Message msg = Message.obtain(); msg.what = DctConstants.CMD_SET_DEPENDENCY_MET; msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED); msg.setData(bundle); mDataConnectionTrackerAc.sendMessage(msg); if (VDBG) log("setDependencyMet: X met=" + met); } catch (NullPointerException e) { loge("setDependencyMet: X mAc was null" + e); } }
/** * Record the detailed state of a network, and if it is a change from the previous state, send a * notification to any listeners. * * @param state the new @{code DetailedState} * @param reason a {@code String} indicating a reason for the state change, if one was supplied. * May be {@code null}. * @param extraInfo optional {@code String} providing extra information about the state change * @param simId 0 for sim1 and 1 for sim2 */ public void setDetailedStateGemini( NetworkInfo.DetailedState state, String reason, String extraInfo, int simId) { if (DBG) log( "setDetailed state, old =" + mNetworkInfo.getDetailedState() + " and new state=" + state + " simId is " + simId); if (state != mNetworkInfo.getDetailedState()) { boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING); String lastReason = mNetworkInfo.getReason(); /* * If a reason was supplied when the CONNECTING state was entered, and no * reason was supplied for entering the CONNECTED state, then retain the * reason that was supplied when going to CONNECTING. */ if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null && lastReason != null) reason = lastReason; mNetworkInfo.setDetailedStateGemini(state, reason, extraInfo, simId); Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); msg.sendToTarget(); } else if (reason != null && (reason.equals(PhoneConstants.REASON_NO_SUCH_PDP) || reason.equals(Phone.REASON_APN_FAILED)) && state == DetailedState.DISCONNECTED) { mNetworkInfo.setDetailedStateGemini(state, reason, extraInfo, simId); Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); msg.sendToTarget(); } }
public NetworkInfo getNetworkInfo() { if (FeatureOption.MTK_GEMINI_SUPPORT) { getPhoneService(true); /* * If the phone process has crashed in the past, we'll get a * RemoteException and need to re-reference the service. */ for (int retry = 0; retry < 2; retry++) { if (mPhoneService == null) { loge("Ignoring feature request because could not acquire PhoneService"); break; } try { /** * M: update availabe info due to it may not correct when we received from * ACTION_ANY_DATA_CONNECTION_STATE_CHANGED */ mNetworkInfo.setIsAvailable(mPhoneService.isDataConnectivityPossible()); log("getNetworkInfo: updated IsAvailable=" + mNetworkInfo.isAvailable()); } catch (RemoteException e) { if (retry == 0) getPhoneService(true); } } } return mNetworkInfo; }
/** * Eanble/disable FailFast * * @param enabled is DctConstants.ENABLED/DISABLED */ public void setEnableFailFastMobileData(int enabled) { if (DBG) log("setEnableFailFastMobileData(enabled=" + enabled + ")"); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { channel.sendMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled); } }
@Override public void setPolicyDataEnable(boolean enabled) { if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")"); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { channel.sendMessage(CMD_SET_POLICY_DATA_ENABLE, enabled ? ENABLED : DISABLED); mPolicyDataEnabled = enabled; } }
/** Inform DCT mobile provisioning has started, it ends when provisioning completes. */ public void enableMobileProvisioning(String url) { if (DBG) log("enableMobileProvisioning(url=" + url + ")"); final AsyncChannel channel = mDataConnectionTrackerAc; if (channel != null) { Message msg = Message.obtain(); msg.what = DctConstants.CMD_ENABLE_MOBILE_PROVISIONING; msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, url)); channel.sendMessage(msg); } }
/** * Return if this network is the provisioning network. Valid only if connected. * * @param met */ public boolean isProvisioningNetwork() { boolean retVal; try { Message msg = Message.obtain(); msg.what = DctConstants.CMD_IS_PROVISIONING_APN; msg.setData(Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType)); Message result = mDataConnectionTrackerAc.sendMessageSynchronously(msg); retVal = result.arg1 == DctConstants.ENABLED; } catch (NullPointerException e) { loge("isProvisioningNetwork: X " + e); retVal = false; } if (DBG) log("isProvisioningNetwork: retVal=" + retVal); return retVal; }
/** * Record the detailed state of a network, and if it is a change from the previous state, send a * notification to any listeners. * * @param state the new @{code DetailedState} * @param reason a {@code String} indicating a reason for the state change, if one was supplied. * May be {@code null}. * @param extraInfo optional {@code String} providing extra information about the state change */ private void setDetailedState(NetworkInfo.DetailedState state, String reason, String extraInfo) { if (DBG) log("setDetailed state, old =" + mNetworkInfo.getDetailedState() + " and new state=" + state); if (state != mNetworkInfo.getDetailedState()) { boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING); String lastReason = mNetworkInfo.getReason(); /* * If a reason was supplied when the CONNECTING state was entered, and no * reason was supplied for entering the CONNECTED state, then retain the * reason that was supplied when going to CONNECTING. */ if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null && lastReason != null) reason = lastReason; mNetworkInfo.setDetailedState(state, reason, extraInfo); Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, new NetworkInfo(mNetworkInfo)); msg.sendToTarget(); } }
@Override public void onReceive(Context context, Intent intent) { if (intent .getAction() .equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED_MOBILE)) { String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY); MobileDataStateTracker tracker = mTrackerMap.get(apnType); if (tracker == null) { return; } int slot = 0; int curSlot = 0; if (FeatureOption.MTK_GEMINI_SUPPORT) { slot = intent.getIntExtra(PhoneConstants.GEMINI_SIM_ID_KEY, PhoneConstants.GEMINI_SIM_1); curSlot = tracker.mNetworkInfo.getSimId(); } if (tracker.mMobileDataState == PhoneConstants.DataState.CONNECTED) { if (slot != curSlot) { tracker.log("Receive peer SIM data state.ignor!"); return; } } if (VDBG) Slog.d( TAG, "MobileDataStateReceiver received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED_MOBILE [" + apnType + "]"); tracker.log( "Intent from SIM " + slot + ", current SIM " + curSlot + ", current DataState " + tracker.mMobileDataState); int oldSubtype = tracker.mNetworkInfo.getSubtype(); int newSubType = TelephonyManager.NETWORK_TYPE_UNKNOWN; String subTypeName; if (FeatureOption.MTK_GEMINI_SUPPORT) { newSubType = TelephonyManager.getDefault().getNetworkTypeGemini(tracker.mNetworkInfo.getSimId()); subTypeName = TelephonyManager.getDefault() .getNetworkTypeNameGemini(tracker.mNetworkInfo.getSimId()); } else { newSubType = TelephonyManager.getDefault().getNetworkType(); subTypeName = TelephonyManager.getDefault().getNetworkTypeName(); } tracker.mNetworkInfo.setSubtype(newSubType, subTypeName); if (newSubType != oldSubtype && tracker.mNetworkInfo.isConnected()) { Message msg = tracker.mTarget.obtainMessage( EVENT_NETWORK_SUBTYPE_CHANGED, oldSubtype, 0, tracker.mNetworkInfo); msg.sendToTarget(); } PhoneConstants.DataState state = Enum.valueOf( PhoneConstants.DataState.class, intent.getStringExtra(PhoneConstants.STATE_KEY)); String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY); String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY); tracker.mNetworkInfo.setRoaming( intent.getBooleanExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, false)); if (VDBG) { tracker.log( tracker.mApnType + " setting isAvailable to " + !intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, false)); } tracker.mNetworkInfo.setIsAvailable( !intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, false)); if (DBG) { tracker.log( "Received state=" + state + ", old=" + tracker.mMobileDataState + ", reason=" + (reason == null ? "(unspecified)" : reason)); } if (tracker.mMobileDataState != state) { tracker.mMobileDataState = state; switch (state) { case DISCONNECTED: if (tracker.isTeardownRequested()) { tracker.setTeardownRequested(false); } if (FeatureOption.MTK_GEMINI_SUPPORT) { tracker.setDetailedStateGemini(DetailedState.DISCONNECTED, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.DISCONNECTED, reason, apnName); } // can't do this here - ConnectivityService needs it to clear stuff // it's ok though - just leave it to be refreshed next time // we connect. // if (DBG) log("clearing mInterfaceName for "+ mApnType + // " as it DISCONNECTED"); // mInterfaceName = null; break; case CONNECTING: if (FeatureOption.MTK_GEMINI_SUPPORT) { tracker.setDetailedStateGemini(DetailedState.CONNECTING, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.CONNECTING, reason, apnName); } break; case SUSPENDED: if (FeatureOption.MTK_GEMINI_SUPPORT) { tracker.setDetailedStateGemini(DetailedState.SUSPENDED, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.SUSPENDED, reason, apnName); } break; case CONNECTED: tracker.mLinkProperties = intent.getParcelableExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY); if (tracker.mLinkProperties == null) { tracker.loge("CONNECTED event did not supply link properties."); tracker.mLinkProperties = new LinkProperties(); } tracker.mLinkCapabilities = intent.getParcelableExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY); if (tracker.mLinkCapabilities == null) { tracker.loge("CONNECTED event did not supply link capabilities."); tracker.mLinkCapabilities = new LinkCapabilities(); } if (FeatureOption.MTK_GEMINI_SUPPORT) { tracker.setDetailedStateGemini(DetailedState.CONNECTED, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.CONNECTED, reason, apnName); } break; } } else { // There was no state change. Check if LinkProperties has been updated. if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) { tracker.mLinkProperties = intent.getParcelableExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY); if (tracker.mLinkProperties == null) { tracker.loge("No link property in LINK_PROPERTIES change event."); tracker.mLinkProperties = new LinkProperties(); } // Just update reason field in this NetworkInfo tracker.mNetworkInfo.setDetailedState( tracker.mNetworkInfo.getDetailedState(), reason, tracker.mNetworkInfo.getExtraInfo()); Message msg = tracker.mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED, tracker.mNetworkInfo); msg.sendToTarget(); } if (reason != null && (reason.equals(Phone.REASON_APN_FAILED) || reason.equals(PhoneConstants.REASON_NO_SUCH_PDP)) && apnType != null && !apnType.equals(PhoneConstants.APN_TYPE_DEFAULT)) { tracker.log( "Handle PhoneConstants.REASON_APN_FAILED OR PhoneConstants.REASON_NO_SUCH_PDP from GeminiDataSubUtil"); if (state == PhoneConstants.DataState.DISCONNECTED) { if (tracker.isTeardownRequested()) { tracker.setTeardownRequested(false); } if (FeatureOption.MTK_GEMINI_SUPPORT) { tracker.setDetailedStateGemini(DetailedState.DISCONNECTED, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.DISCONNECTED, reason, apnName); } } } } } else if (intent.getAction().equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) { String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY); MobileDataStateTracker tracker = mTrackerMap.get(apnType); if (tracker == null) { return; } if (DBG) Slog.d( TAG, "MobileDataStateReceiver received: ACTION_ANY_DATA_CONNECTION_FAILED ignore [" + apnType + "]"); int slot = 0; String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY); String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY); if (DBG) { tracker.log( "Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); } if (FeatureOption.MTK_GEMINI_SUPPORT) { slot = intent.getIntExtra(PhoneConstants.GEMINI_SIM_ID_KEY, PhoneConstants.GEMINI_SIM_1); tracker.setDetailedStateGemini(DetailedState.FAILED, reason, apnName, slot); } else { tracker.setDetailedState(DetailedState.FAILED, reason, apnName); } } else if (intent.getAction().equals(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) { if (VDBG) Slog.d(TAG, "MobileDataStateReceiver received: ACTION_DATA_CONNECTION_TRACKER_MESSENGER"); Messenger messenger = intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER); Collection<MobileDataStateTracker> collection = mTrackerMap.values(); Iterator<MobileDataStateTracker> iter = collection.iterator(); while (iter.hasNext()) { MobileDataStateTracker tracker = iter.next(); tracker.mMessenger = messenger; AsyncChannel ac = new AsyncChannel(); ac.connect(tracker.mContext, tracker.mHandler, tracker.mMessenger); } } else { if (DBG) Slog.d(TAG, "MobileDataStateReceiver received: ignore " + intent.getAction()); } }
public void supplyMessenger(Messenger messenger) { if (VDBG) log(mApnType + " got supplyMessenger"); AsyncChannel ac = new AsyncChannel(); ac.connect(mContext, MobileDataStateTracker.this.mHandler, messenger); }