Android 5.1 open data flow 数据开启流程
首先我们来看看下面的关系图:

private View.OnClickListener mDataEnabledListener = new View.OnClickListener() {
@Override
public 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);
}
};
enabled);
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 flag
android.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);
}
enable);
/** @hide */
@SystemApi
public 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}
*/
@Override
public 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);
}
}
@Override
public void setDataEnabled(boolean enable) {
mDcTracker.setDataEnabled(enable);
}
msg =
obtainMessage(DctConstants.CMD_SET_USER_DATA_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);
}
@Override
public 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);
}
}
}
}
@Override
// TODO: We shouldnt need this.
protected boolean onTrySetupData(String reason) {
if (DBG) log("onTrySetupData: reason=" + reason);
setupDataOnConnectableApns(reason);
return true;
}
trySetupData(apnContext);
<span style="background-color: rgb(255, 255, 255);"> private void setupDataOnConnectableApns(String reason) {
if (DBG) log("setupDataOnConnectableApns: " + reason);
for (ApnContext apnContext : mPrioritySortedApnContexts) {
if (DBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
if (apnContext.getState() == DctConstants.State.FAILED) {
apnContext.setState(DctConstants.State.IDLE);
}
if (apnContext.isConnectable()) {
log("setupDataOnConnectableApns: isConnectable() call trySetupData");
apnContext.setReason(reason);
trySetupData(apnContext);
}
}
}</span>
retValue =setupData(apnContext,
radioTech);
private boolean trySetupData(ApnContext apnContext) {
...
if (apnContext.isConnectable() && (isEmergencyApn ||
(isDataAllowed(apnContext) &&
getAnyDataEnabled(checkUserDataEnabled) && !isEmergency()))) {
if (apnContext.getState() == DctConstants.State.FAILED) {
if (DBG) log("trySetupData: make a FAILED ApnContext IDLE so its reusable");
apnContext.setState(DctConstants.State.IDLE);
}
int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
if (apnContext.getState() == DctConstants.State.IDLE) {
ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType(),
radioTech);
if (waitingApns.isEmpty()) {
notifyNoData(DcFailCause.MISSING_UNKNOWN_APN, apnContext);
notifyOffApnsOfAvailability(apnContext.getReason());
if (DBG) log("trySetupData: X No APN found retValue=false");
return false;
} else {
apnContext.setWaitingApns(waitingApns);
if (DBG) {
log ("trySetupData: Create from mAllApnSettings : "
+ apnListToString(mAllApnSettings));
}
}
}
if (DBG) {
log("trySetupData: call setupData, waitingApns : "
+ apnListToString(apnContext.getWaitingApns()));
}
boolean retValue = setupData(apnContext, radioTech);//7
notifyOffApnsOfAvailability(apnContext.getReason());
if (DBG) log("trySetupData: X retValue=" + retValue);
return retValue;
} else {
if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
&& apnContext.isConnectable()) {
mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
}
notifyOffApnsOfAvailability(apnContext.getReason());
if (DBG) log ("trySetupData: X apnContext not 'ready' retValue=false");
return false;
}
}
dcac.bringUp(apnContext,msg);
getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,
private boolean setupData(ApnContext apnContext, int radioTech) {
if (DBG) log("setupData: apnContext=" + apnContext);
ApnSetting apnSetting;
DcAsyncChannel dcac = null;
apnSetting = apnContext.getNextWaitingApn();
if (apnSetting == null) {
if (DBG) log("setupData: return for no apn found!");
return false;
}
int profileId = apnSetting.profileId;
if (profileId == 0) {
profileId = getApnProfileID(apnContext.getApnType());
}
// On CDMA, if we're explicitly asking for DUN, we need have
// a dun-profiled connection so we can't share an existing one
// On GSM/LTE we can share existing apn connections provided they support
// this type.
if (apnContext.getApnType() != PhoneConstants.APN_TYPE_DUN ||
teardownForDun() == false) {
dcac = checkForCompatibleConnectedApnContext(apnContext);
if (dcac != null) {
// Get the dcacApnSetting for the connection we want to share.
ApnSetting dcacApnSetting = dcac.getApnSettingSync();
if (dcacApnSetting != null) {
// Setting is good, so use it.
apnSetting = dcacApnSetting;
}
}
}
if (dcac == null) {
if (isOnlySingleDcAllowed(radioTech)) {
if (isHigherPriorityApnContextActive(apnContext)) {
if (DBG) {
log("setupData: Higher priority ApnContext active. Ignoring call");
}
return false;
}
// Only lower priority calls left. Disconnect them all in this single PDP case
// so that we can bring up the requested higher priority call (once we receive
// repsonse for deactivate request for the calls we are about to disconnect
if (cleanUpAllConnections(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
// If any call actually requested to be disconnected, means we can't
// bring up this connection yet as we need to wait for those data calls
// to be disconnected.
if (DBG) log("setupData: Some calls are disconnecting first. Wait and retry");
return false;
}
// No other calls are active, so proceed
if (DBG) log("setupData: Single pdp. Continue setting up data call.");
}
dcac = findFreeDataConnection();
if (dcac == null) {
dcac = createDataConnection();
}
if (dcac == null) {
if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
return false;
}
}
if (DBG) log("setupData: dcac=" + dcac + " apnSetting=" + apnSetting);
apnContext.setDataConnectionAc(dcac);
apnContext.setApnSetting(apnSetting);
apnContext.setState(DctConstants.State.CONNECTING);
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
Message msg = obtainMessage();
msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
msg.obj = apnContext;
dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,
msg);//8
if (DBG) log("setupData: initing!");
return true;
}
/**
* Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
* Used for cellular networks that use Acesss Point Names (APN) such
* as GSM networks.
*
* @param apnContext is the Access Point Name to bring up a connection to
* @param initialMaxRetry the number of retires for initial bringup.
* @param profileId for the conneciton
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
* With AsyncResult.userObj set to the original msg.obj,
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
*/
public void bringUp(ApnContext apnContext, int initialMaxRetry, int profileId,
int rilRadioTechnology, boolean retryWhenSSChange, Message onCompletedMsg) {
if (DBG) {
log("bringUp: apnContext=" + apnContext + " initialMaxRetry=" + initialMaxRetry
+ " onCompletedMsg=" + onCompletedMsg);
}
sendMessage(DataConnection.EVENT_CONNECT,//9
new ConnectionParams(apnContext, initialMaxRetry, profileId,
rilRadioTechnology, retryWhenSSChange, onCompletedMsg));
}
/**
* The state machine is inactive and expects a EVENT_CONNECT.
*/
private class DcInactiveState extends State {
... @Override
public boolean processMessage(Message msg) {
... case EVENT_CONNECT:
if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT");
ConnectionParams cp = (ConnectionParams) msg.obj;
if (initConnection(cp)) {
onConnect(mConnectionParams);//10
transitionTo(mActivatingState);
} else {
if (DBG) {
log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed");
}
notifyConnectCompleted(cp, DcFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
false);
}
retVal = HANDLED;
break;
mPhone.mCi.setupDataCall
/**
* Begin setting up a data connection, calls setupDataCall
* and the ConnectionParams will be returned with the
* EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
*
* @param cp is the connection parameters
*/
private void onConnect(ConnectionParams cp) {
if (DBG) log("onConnect: carrier='" + mApnSetting.carrier
+ "' APN='" + mApnSetting.apn
+ "' proxy='" + mApnSetting.proxy + "' port='" + mApnSetting.port + "'"); // Check if we should fake an error.
if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter > 0) {
...
} mCreateTime = -1;
mLastFailTime = -1;
mLastFailCause = DcFailCause.NONE; // The data profile's profile ID must be set when it is created.
int dataProfileId;
if (mApnSetting.getApnProfileType() == ApnProfileType.PROFILE_TYPE_OMH) {
dataProfileId = mApnSetting.getProfileId() + RILConstants.DATA_PROFILE_OEM_BASE;
log("OMH profile, dataProfile id = " + dataProfileId);
} else {
dataProfileId = cp.mProfileId;
} // msg.obj will be returned in AsyncResult.userObj;
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
msg.obj = cp; int authType = mApnSetting.authType;
if (authType == -1) {
authType = TextUtils.isEmpty(mApnSetting.user) ? RILConstants.SETUP_DATA_AUTH_NONE
: RILConstants.SETUP_DATA_AUTH_PAP_CHAP;
} String protocol;
if (mPhone.getServiceState().getRoaming()) {
protocol = mApnSetting.roamingProtocol;
} else {
protocol = mApnSetting.protocol;
} mPhone.mCi.setupDataCall(//11
Integer.toString(cp.mRilRat + 2),
Integer.toString(dataProfileId),
mApnSetting.apn, mApnSetting.user, mApnSetting.password,
Integer.toString(authType),
protocol, msg);
}
android/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java
这个类是通讯中的使用类。
Android 5.1 open data flow 数据开启流程的更多相关文章
- 数据可视化 —— 数据流图(Data Flow Diagram)
数据流图(Data Flow Diagram):简称 DFD,它从数据传递和加工角度,以图形方式来表达系统的逻辑功能.数据在系统内部的逻辑流向和逻辑变换过程,是结构化系统分析方法的主要表达工具及用于表 ...
- Android first --- 页面跳转及数据传递
页面跳转即数据传递 创建第二个界面Acivity *需要在清单文件中添加配置一个Actuvity标签 标签中如果带有这个子节点,则会在Android中添加一个快捷图标 <intent-filte ...
- Android Volley和Gson实现网络数据加载
Android Volley和Gson实现网络数据加载 先看接口 1 升级接口 http://s.meibeike.com/mcloud/ota/cloudService POST请求 参数列表如下 ...
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
- 微软BI 之SSIS 系列 - 理解Data Flow Task 中的同步与异步, 阻塞,半阻塞和全阻塞以及Buffer 缓存概念
开篇介绍 在 SSIS Dataflow 数据流中的组件可以分为 Synchronous 同步和 Asynchronous 异步这两种类型. 同步与异步 Synchronous and Asynchr ...
- Android开发之利用SQLite进行数据存储
Android开发之利用SQLite进行数据存储 Android开发之利用SQLite进行数据存储 SQLite数据库简单介绍 Android中怎样使用SQLite 1 创建SQLiteOpenHel ...
- (转载)Android之三种网络请求解析数据(最佳案例)
[置顶] Android之三种网络请求解析数据(最佳案例) 2016-07-25 18:02 4725人阅读 评论(0) 收藏 举报 分类: Gson.Gson解析(1) 版权声明:本文为博主原创 ...
- SSIS Data Flow优化
一,数据流设计优化 数据流有两个特性:流和在内存缓冲区中处理数据,根据数据流的这两个特性,对数据流进行优化. 1,流,同时对数据进行提取,转换和加载操作 流,就是在source提取数据时,转换组件处理 ...
- SSIS Data Flow 的 Execution Tree 和 Data Pipeline
一,Execution Tree 执行树是数据流组件(转换和适配器)基于同步关系所建立的逻辑分组,每一个分组都是一个执行树的开始和结束,也可以将执行树理解为一个缓冲区的开始和结束,即缓冲区的整个生命周 ...
随机推荐
- java代码过滤emoji表情
可以新建一个过滤器的类,在类中书写如下代码: public static String filterEmoji(String source) { if(source != null ...
- win7 64位DCOM配置(关于导出excel 配置计算机组件服务)(转)
http://blog.sina.com.cn/s/blog_9323b3a50101qrxm.html [解决方案1] 1:在服务器上安装office的Excel软件. 2:在"开始&qu ...
- Java 仿迅雷多线程下载
package net.webjoy.jackluo.android_json; /** * 1.http Range "bytes="+ start+end * 2.Random ...
- C#字符串处理(String与StringBuilder)
首先介绍一下常用的几个功能:Compare(str1,str2)——比较两个字符串str1,str2的大小,如果大于返回正数,等于返回0,小于返回负数!IndexOf——定位字符串中第一次出现某个给定 ...
- 【android应用市场】android应用市场集合
一.举例 1.酷市场 2.apkpure 国外的应用市场,可不用FQ,没有google play的一些限制 相当于google play的镜像,可以下载google play的应用 3.360手机助手 ...
- [CareerCup] 16.5 Semphore 信号旗
16.5 Suppose we have the following code:public class Foo { public Foo() { . . . } public void first( ...
- ado.net 连接,删除,添加
ado.net数据库访问技术将数据库中的数据,提取到内存中,展示给用户看还可以将内存中的数据写入数据库中去 并不是唯一的数据库访问技术,但是它是最底层的数据库访问技术 数据库: create data ...
- Spark RDD Operations(2)
处理数据类型为Value型的Transformation算子可以根据RDD变换算子的输入分区与输出分区关系分为以下几种类型. 1)输入分区与输出分区一对一型. 2)输入分区与输出分区多对一型. 3)输 ...
- 关于ASP.NET Web API 客户端的请求报文中添加 Authorization
当你使用客户端发送请求 Web API 的时候,因为API 有验证,所以你的请求报文中必须有”Authorization“,那么就需要手动添加了! HttpClient client = new Ht ...
- 模拟状态为inactive的日志损坏的恢复实验(完全恢复)
1查看当前日志状态 从这里可以看到我们现在有三组日志,每组日志中只有1个成员.为了演示这个实验,我们为每个组增加1个成员. 2为每组增加组成员 添加后我们验证一下目前各日志成员的状态: 从上面的视图中 ...