
private View.OnClickListener mDataEnabledListener = new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mBinding) return;final boolean dataEnabled = !mDataEnabled.isChecked();final String currentTab = mCurrentTab;if (TAB_MOBILE.equals(currentTab) || currentTab.startsWith(TAB_SIM)) {if (dataEnabled) {setMobileDataEnabled(true);if (mPolicyEditor.getPolicyWarningBytes(mTemplate) == WARNING_DISABLED) {mPolicyEditor.setPolicyWarningBytes(mTemplate, 2 * GB_IN_BYTES);}} else {// disabling data; show confirmation dialog which eventually// calls setMobileDataEnabled() once user confirms.ConfirmDataDisableFragment.show(DataUsageSummary.this);}}updatePolicy(false);}};
/*** Dialog to request user confirmation before disabling data.*/public static class ConfirmDataDisableFragment extends DialogFragment {public static void show(DataUsageSummary parent) {if (!parent.isAdded()) return;final ConfirmDataDisableFragment dialog = new ConfirmDataDisableFragment();dialog.setTargetFragment(parent, 0);dialog.show(parent.getFragmentManager(), TAG_CONFIRM_DATA_DISABLE);}@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {final Context context = getActivity();final AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setMessage(R.string.data_usage_disable_mobile);builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {final DataUsageSummary target = (DataUsageSummary) getTargetFragment();if (target != null) {// TODO: extend to modify policy enabled flag.target.setMobileDataEnabled(false);}}});builder.setNegativeButton(android.R.string.cancel, null);return builder.create();}}
private void setMobileDataEnabled(boolean enabled) {if (LOGD) Log.d(TAG, "setMobileDataEnabled()");// How about exposing sub based API like TelephonyManager.setDataEnabled(int subId);if (mCurrentTab.startsWith(TAB_SIM)) {int phoneId = multiSimGetCurrentSub();// as per phone, set the individual flagandroid.provider.Settings.Global.putInt(getActivity().getContentResolver(),android.provider.Settings.Global.MOBILE_DATA + phoneId, enabled ? 1 : 0);int[] subId = SubscriptionManager.getSubId(phoneId);mTelephonyManager.setDataEnabled(subId[0], enabled);} else {mTelephonyManager.setDataEnabled(enabled);mMobileDataEnabled = enabled;}updatePolicy(false);}
/** @hide */@SystemApipublic void setDataEnabled(int subId, boolean enable) {try {AppOpsManager appOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);if (enable) {if (appOps.noteOp(AppOpsManager.OP_DATA_CONNECT_CHANGE) != AppOpsManager.MODE_ALLOWED) {Log.w(TAG, "Permission denied by user.");return;}}Log.d(TAG, "setDataEnabled: enabled=" + enable);getITelephony().setDataEnabled(subId, enable);} catch (RemoteException e) {Log.e(TAG, "Error calling setDataEnabled", e);}}
/*** Set mobile data enabled* Used by the user through settings etc to turn on/off mobile data** @param enable {@code true} turn turn data on, else {@code false}*/@Overridepublic void setDataEnabled(int subId, boolean enable) {enforceModifyPermission();int phoneId = mSubscriptionController.getPhoneId(subId);log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);Phone phone = PhoneFactory.getPhone(phoneId);if (phone != null) {log("setDataEnabled: subId=" + subId + " enable=" + enable);phone.setDataEnabled(enable);} else {loge("setDataEnabled: no phone for subId=" + subId);}}
@Overridepublic void setDataEnabled(boolean enable) {mDcTracker.setDataEnabled(enable);}
/*** Modify {@link android.provider.Settings.Global#MOBILE_DATA} value.*/public void setDataEnabled(boolean enable) {Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);msg.arg1 = enable ? 1 : 0;sendMessage(msg);}
@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {log("DISCONNECTED_CONNECTED: msg=" + msg);DcAsyncChannel dcac = (DcAsyncChannel) msg.obj;mDataConnectionAcHashMap.remove(dcac.getDataConnectionIdSync());dcac.disconnected();break;}...case DctConstants.CMD_SET_USER_DATA_ENABLE: {final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);onSetUserDataEnabled(enabled);break;}...
protected void onSetUserDataEnabled(boolean enabled) {synchronized (mDataEnabledLock) {if (mUserDataEnabled != enabled) {mUserDataEnabled = enabled;Settings.Global.putInt(mPhone.getContext().getContentResolver(),Settings.Global.MOBILE_DATA + mPhone.getPhoneId(), enabled ? 1 : 0);if (getDataOnRoamingEnabled() == false &&mPhone.getServiceState().getRoaming() == true) {if (enabled) {notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);} else {notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);}}if (enabled) {onTrySetupData(Phone.REASON_DATA_ENABLED);} else {onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);//1}}}}
/*** Cleanup all connections.** TODO: Cleanup only a specified connection passed as a parameter.* Also, make sure when you clean up a conn, if it is last apply* logic as though it is cleanupAllConnections** @param cause for the clean up.*/@Overrideprotected void onCleanUpAllConnections(String cause) {cleanUpAllConnections(true, cause);}
/*** If tearDown is true, this only tears down a CONNECTED session. Presently,* there is no mechanism for abandoning an CONNECTING session,* but would likely involve cancelling pending async requests or* setting a flag or new state to ignore them when they came in* @param tearDown true if the underlying DataConnection should be* disconnected.* @param reason reason for the clean up.* @return boolean - true if we did cleanup any connections, false if they* were already all disconnected.*/protected boolean cleanUpAllConnections(boolean tearDown, String reason) {if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);boolean didDisconnect = false;boolean specificdisable = false;if (!TextUtils.isEmpty(reason)) {specificdisable = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED);}for (ApnContext apnContext : mApnContexts.values()) {if (apnContext.isDisconnected() == false) didDisconnect = true;if (specificdisable) {if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) {if (DBG) log("ApnConextType: " + apnContext.getApnType());apnContext.setReason(reason);cleanUpConnection(tearDown, apnContext);//2}} else {// TODO - only do cleanup if not disconnectedapnContext.setReason(reason);cleanUpConnection(tearDown, apnContext);}}stopNetStatPoll();stopDataStallAlarm();// TODO: Do we need mRequestedApnType?mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);if (tearDown && mDisconnectPendingCount == 0) {notifyDataDisconnectComplete();notifyAllDataDisconnected();}return didDisconnect;}
protected void cleanUpConnection(boolean tearDown, ApnContext apnContext) {if (apnContext == null) {if (DBG) log("cleanUpConnection: apn context is null");return;}DcAsyncChannel dcac = apnContext.getDcAc();if (DBG) {log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +" apnContext=" + apnContext);}if (tearDown) {//3if (apnContext.isDisconnected()) {// The request is tearDown and but ApnContext is not connected.// If apnContext is not enabled anymore, break the linkage to the DCAC/DC.apnContext.setState(DctConstants.State.IDLE);if (!apnContext.isReady()) {if (dcac != null) {dcac.tearDown(apnContext, "", null);}apnContext.setDataConnectionAc(null);}} else {// Connection is still there. Try to clean up.if (dcac != null) {//4if (apnContext.getState() != DctConstants.State.DISCONNECTING) {boolean disconnectAll = false;if (PhoneConstants.APN_TYPE_DUN.equals(apnContext.getApnType())) {// CAF_MSIM is this below condition required.// if (PhoneConstants.APN_TYPE_DUN.equals(PhoneConstants.APN_TYPE_DEFAULT)) {if (teardownForDun()) {if (DBG) log("tearing down dedicated DUN connection");// we need to tear it down - we brought it up just for dun and// other people are camped on it and now dun is done. We need// to stop using it and let the normal apn list get used to find// connections for the remaining desired connectionsdisconnectAll = true;}}if (DBG) {log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));}Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, apnContext);//4if (disconnectAll) {apnContext.getDcAc().tearDownAll(apnContext.getReason(), msg);} else {apnContext.getDcAc().tearDown(apnContext, apnContext.getReason(), msg);}apnContext.setState(DctConstants.State.DISCONNECTING);mDisconnectPendingCount++;}} else {// apn is connected but no reference to dcac.// Should not be happen, but reset the state in case.apnContext.setState(DctConstants.State.IDLE);mPhone.notifyDataConnection(apnContext.getReason(),apnContext.getApnType());}}} else {// force clean up the data connection.if (dcac != null) dcac.reqReset();apnContext.setState(DctConstants.State.IDLE);mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());apnContext.setDataConnectionAc(null);}if (mOmhApt != null) {mOmhApt.clearActiveApnProfile();}// Make sure reconnection alarm is cleaned up if there is no ApnContext// associated to the connection.if (dcac != null) {cancelReconnectAlarm(apnContext);}setupDataForSinglePdnArbitration(apnContext.getReason());if (DBG) {log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +" apnContext=" + apnContext + " dcac=" + apnContext.getDcAc());}}
/*** Tear down the connection through the apn on the network.** @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.* With AsyncResult.userObj set to the original msg.obj.*/public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) {if (DBG) {log("tearDown: apnContext=" + apnContext+ " reason=" + reason + " onCompletedMsg=" + onCompletedMsg);}sendMessage(DataConnection.EVENT_DISCONNECT,//7new DisconnectParams(apnContext, reason, onCompletedMsg));}
/*** The state machine is connected, expecting an EVENT_DISCONNECT.*/private class DcActiveState extends State {...@Overridepublic boolean processMessage(Message msg) {...case EVENT_DISCONNECT: {DisconnectParams dp = (DisconnectParams) msg.obj;if (DBG) {log("DcActiveState: EVENT_DISCONNECT dp=" + dp+ " dc=" + DataConnection.this);}if (mApnContexts.contains(dp.mApnContext)) {if (DBG) {log("DcActiveState msg.what=EVENT_DISCONNECT RefCount="+ mApnContexts.size());}if (mApnContexts.size() == 1) {mApnContexts.clear();mDisconnectParams = dp;mConnectionParams = null;dp.mTag = mTag;tearDownData(dp);transitionTo(mDisconnectingState);} else {mApnContexts.remove(dp.mApnContext);notifyDisconnectCompleted(dp, false);}} else {log("DcActiveState ERROR no such apnContext=" + dp.mApnContext+ " in this dc=" + DataConnection.this);notifyDisconnectCompleted(dp, false);}retVal = HANDLED;break;}
/*** TearDown the data connection when the deactivation is complete a Message with* msg.what == EVENT_DEACTIVATE_DONE and msg.obj == AsyncResult with AsyncResult.obj* containing the parameter o.** @param o is the object returned in the AsyncResult.obj.*/private void tearDownData(Object o) {int discReason = RILConstants.DEACTIVATE_REASON_NONE;if ((o != null) && (o instanceof DisconnectParams)) {DisconnectParams dp = (DisconnectParams)o;if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF)) {discReason = RILConstants.DEACTIVATE_REASON_RADIO_OFF;} else if (TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) {discReason = RILConstants.DEACTIVATE_REASON_PDP_RESET;}}if (mPhone.mCi.getRadioState().isOn()|| (mPhone.getServiceState().getRilDataRadioTechnology()== ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN )) {if (DBG) log("tearDownData radio is on, call deactivateDataCall");mPhone.mCi.deactivateDataCall(mCid, discReason,obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o));} else {if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");AsyncResult ar = new AsyncResult(o, null, null);sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, ar));}}
332



被折叠的 条评论
为什么被折叠?



