数据连接相关类简介
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
ConnectivityManager 提供訪問ConnectivityService的接口,與ConnectivityService通過binder進(jìn)行通信
ConnectivityService 管理NetworkAgent
NetworkFactory
NetworkAgent 用于DataConnection和ConnectivityService進(jìn)行通信
NetworkAgentInfo
NetworkInfo
NetworkManagementService
NetworkCapabilities 用于描述一個網(wǎng)絡(luò)的能力,用來指定ConnectivityManager的需求以及檢查網(wǎng)絡(luò)。
NetworkRequest 定義一個網(wǎng)絡(luò)請求。
NetworkStatsService 統(tǒng)計網(wǎng)絡(luò)傳輸數(shù)據(jù),供其他系統(tǒng)服務(wù)使用。
NetworkMonitor
?
TelephonyManager.java
路徑:frameworks/base/telephony/java/android/telephony/
功能:為App提供獲取Telephony信息的接口。App也可注冊監(jiān)聽器來接收Telephony狀態(tài)的變化。
其中很多接口都是通過AIDL調(diào)用其他相關(guān)程序得到的,用到的AIDL接口及對應(yīng)實現(xiàn)包括:
ITelecomService --> TelecomServiceImpl.mBinderImpl --> Telecomm Service
IPhoneSubInfo --> PhoneSubInfoController
ITelephony --> PhoneInterfaceManager --> Telephony Service
ITelephonyRegistry --> TelephonyRegistry
?
DcTracker
Platform:Android-7.1.1_r22
public class DcTracker extends Handler {
// 一直為false,DcController.DccDefaultState.onDataStateChanged()中會用到,
// onDataStateChanged()是監(jiān)聽UNSOL_DATA_CALL_LIST_CHANGED的
public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
// 用于任務(wù)調(diào)度
private final AlarmManager mAlarmManager;
// 感覺沒啥用
/* Currently requested APN type (TODO: This should probably be a parameter not a member) */
private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
// 持有不同數(shù)據(jù)開/關(guān)的設(shè)置狀態(tài)
// All data enabling/disabling related settings
private final DataEnabledSettings mDataEnabledSettings = new DataEnabledSettings();
// 不能建立data的原因
public enum DataAllowFailReasonType {
NOT_ATTACHED(" - Not attached"),
RECORD_NOT_LOADED(" - SIM not loaded"),
ROAMING_DISABLED(" - Roaming and data roaming not enabled"),
INVALID_PHONE_STATE(" - PhoneState is not idle"),
CONCURRENT_VOICE_DATA_NOT_ALLOWED(" - Concurrent voice and data not allowed"),
PS_RESTRICTED(" - mIsPsRestricted= true"),
UNDESIRED_POWER_STATE(" - desiredPowerState= false"),
INTERNAL_DATA_DISABLED(" - mInternalDataEnabled= false"),
DEFAULT_DATA_UNSELECTED(" - defaultDataSelected= false"),
RADIO_DISABLED_BY_CARRIER(" - powerStateFromCarrier= false");
......
}
// 用于測試人員指定bingUp失敗的次數(shù)及原因。
/**
* A package level call that causes all DataConnection bringUp calls to fail a specific
* number of times. Here is an example that sets counter to 2 and cause to -3 for all instances:
* adb shell am broadcast -a com.android.internal.telephony.dataconnection.action_fail_bringup \
* --ei counter 2 --ei fail_cause -3
*
* Also you can add a suggested retry time if desired:
* --ei suggested_retry_time 5000
*
* The fail_cause is one of {@link DcFailCause}
*/
private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
// 新建DataConnection對象時會作為參數(shù)傳入
private DcController mDcc;
// 按優(yōu)先級排序的ApnContext隊列,會在DcTracker的構(gòu)造函數(shù)中進(jìn)行初始化。
// 初始值是從frameworks/base/core/res/res/values/config.xml中的networkAttributes讀取的,
// 一般情況下廠商會overlay。
/** kept in sync with mApnContexts
* Higher numbers are higher priority and sorted so highest priority is first */
private final PriorityQueue<ApnContext>mPrioritySortedApnContexts
// mAllApnSettings的內(nèi)容是從telephony.db->carriers中讀取的。
// telephony.db->carriers則是用apns.xml和apns-conf.xml中的內(nèi)容進(jìn)行初始化,
// 祥見TelephonyProvider.DatabaseHelper.initDatabase()
/** allApns holds all apns */
private ArrayList<ApnSetting> mAllApnSettings = null;
// ????????
/** emergency apn Setting*/
private ApnSetting mEmergencyApn = null;
// 關(guān)于provision apn,在config.xml中的"mobile_provisioning_apn"進(jìn)行了定義,但還是不知道是做啥的
// ????????
/* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
private boolean mIsProvisioning = false;
// ????????
/* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
private String mProvisioningUrl = null;
// ????????
/* The provision apn alarm intent used to disable the provisioning apn */
private PendingIntent mProvisioningApnAlarmIntent = null;
// ????????
/* Used to track stale provisioning apn alarms */
private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
// ????????
private AsyncChannel mReplyAc = new AsyncChannel();
// 處理以下廣播:
// ACTION_SCREEN_ON
// ACTION_SCREEN_OFF
// INTENT_RECONNECT_ALARM
// INTENT_DATA_STALL_ALARM
// INTENT_PROVISIONING_APN_ALARM
// NETWORK_STATE_CHANGED_ACTION
// WIFI_STATE_CHANGED_ACTION
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
// 統(tǒng)計每個周期內(nèi)上下行數(shù)據(jù)的任務(wù),狀態(tài)欄上數(shù)據(jù)上下行圖標(biāo)就是用的這個結(jié)果
private final Runnable mPollNetStat = new Runnable() {
// 監(jiān)聽Subscription變化
private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
// 監(jiān)聽以下設(shè)置的變化:
// DATA_ROAMING
// DEVICE_PROVISIONED
// DEVICE_PROVISIONING_MOBILE_DATA_ENABLED
private final SettingsObserver mSettingsObserver;
/**
* List of messages that are waiting to be posted, when data call disconnect
* is complete
*/
private ArrayList<Message> mDisconnectAllCompleteMsgList = new ArrayList<Message>();
// member variables
private final Phone mPhone;
private final UiccController mUiccController;
private final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
// 以下幾個是數(shù)據(jù)上下行圖標(biāo)相關(guān)的
private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
private long mTxPkts;
private long mRxPkts;
private int mNetStatPollPeriod;
private boolean mNetStatPollEnabled = false;
// 以下幾個是檢測數(shù)據(jù)連接是否正常的
private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
// Used to track stale data stall alarms.
private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
// The current data stall alarm intent
private PendingIntent mDataStallAlarmIntent = null;
// Number of packets sent since the last received packet
private long mSentSinceLastRecv;
// Controls when a simple recovery attempt it to be tried
private int mNoRecvPollCount = 0;
// Reference counter for enabling fail fast
private static int sEnableFailFastRefCounter = 0;
// True if data stall detection is enabled
private volatile boolean mDataStallDetectionEnabled = true;
// Data retry時,如果此屬性為true,就會使用一個較短的間隔時間
private volatile boolean mFailFast = false;
// True when in voice call
private boolean mInVoiceCall = false;
// wifi connection status will be updated by sticky intent
private boolean mIsWifiConnected = false;
// 感覺沒啥用
// When false we will not auto attach and manually attaching is required.
private boolean mAutoAttachOnCreationConfig = false;
private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
// MVNO是虛擬運營商
// Indicates if we found mvno-specific APNs in the full APN list.
// used to determine if we can accept mno-specific APN for tethering.
private boolean mMvnoMatched = false;
// 每個DataConnection對象對應(yīng)的唯一的Id號
/** Allows the generation of unique Id's for DataConnection objects */
private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
// 跟mPrioritySortedApnContexts差不多,保存各種類型的ApnContext
/** Phone.APN_TYPE_* ===> ApnContext */
private final ConcurrentHashMap<String, ApnContext> mApnContexts =
new ConcurrentHashMap<String, ApnContext>();
// 跟mApnContexts差不多,只是key變成了整數(shù)
private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
// 感覺沒啥用
private boolean mReregisterOnReconnectFailure = false;
// 只要讀取preferedApn返回的Cursor對象不為null,則置為true,即使Cursor中啥都沒有。
// 所以這個值一般都為true。
private boolean mCanSetPreferApn = false;
// 是否注上PS
private AtomicBoolean mAttached = new AtomicBoolean(false);
// 監(jiān)控Telephony.db->carriers的變化
/** Watches for changes to the APN db. */
private ApnChangeObserver mApnObserver;
// ?????
private final String mProvisionActionName;
private BroadcastReceiver mProvisionBroadcastReceiver;
private ProgressDialog mProvisioningSpinner;
// 似乎沒地方用啊!
public boolean mImsRegistrationState = false;
}
?
ApnContext
Platform:Android-7.1.1_r22
APN上下文,維護(hù)著apn的狀態(tài)、設(shè)置等。
每個類型的apn對應(yīng)一個ApnContext。
// 來自ActivePhoneSwitch/DEFAULT_SUBSCRIPTION_CHANGED等的網(wǎng)絡(luò)請求
private final ArrayList<NetworkRequest> mNetworkRequests = new ArrayList<>();
// 會從frameworks/base/core/res/res/values/config.xml讀取config_cell_retries_per_error_code來初始化,
// 這個值應(yīng)該會被overlay,這是一個Map列表,其中每一個Map的Key為建立Data時返回的錯誤類型,
// Value為重試次數(shù),若重試Value次后還是不能成功建立Data連接,則在其它條件滿足時就會重啟modem。
private final SparseIntArray mRetriesLeftPerErrorCode = new SparseIntArray();
private final RetryManager mRetryManager;
?
DataConnection
Platform:Android-7.1.1_r22
是一個狀態(tài)機。
一個DataConnection維護(hù)一個數(shù)據(jù)連接。
public class DataConnection extends StateMachine {
// 從DcTracker傳過來的
// The data connection controller
private DcController mDcController;
// 從DcTracker傳過來的
// The Tester for failing all bringup's
private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
// DataConnection實例的數(shù)量
private static AtomicInteger mInstanceNumber = new AtomicInteger(0);
// 用于和其它Handler進(jìn)行通信
private AsyncChannel mAc;
// 新建對象時傳進(jìn)來的DcTracker對象
// The DCT that's talking to us, we only support one!
private DcTracker mDct = null;
// Data建立成功后用來保存P-CSCF地址
protected String[] mPcscfAddr;
// 當(dāng)前連接的apn設(shè)置
private ApnSetting mApnSetting;
// 連接參數(shù)
private ConnectionParams mConnectionParams;
//斷開參數(shù)
private DisconnectParams mDisconnectParams;
// 建立連接失敗的原因(SETUP_DATA_CALL返回錯誤)
private DcFailCause mDcFailCause;
// 描述數(shù)據(jù)連接的連接屬性
private LinkProperties mLinkProperties = new LinkProperties();
// 數(shù)據(jù)連接建立成功的時間點
private long mCreateTime;
// 上次數(shù)據(jù)連接建立失敗的時間點
private long mLastFailTime;
// 上次數(shù)據(jù)連接建立失敗的原因(尚未發(fā)起SETUP_DATA_CALL)
private DcFailCause mLastFailCause;
// 沒有用
private Object mUserData;
// 保存Data的RAT
private int mRilRat = Integer.MAX_VALUE;
// Data的注冊狀態(tài)
private int mDataRegState = Integer.MAX_VALUE;
// 描述網(wǎng)絡(luò)接口的狀態(tài)
private NetworkInfo mNetworkInfo;
// 一個工具類,用來和Connectivity通信的
private NetworkAgent mNetworkAgent;
// 沒大明白做啥的,應(yīng)該是充當(dāng)一個標(biāo)識作用之類的吧
int mTag;
// 連接的id號,從modem傳上來的
public int mCid;
// 存儲連接的ApnContext與ConnectionParams的映射
public HashMap<ApnContext, ConnectionParams> mApnContexts = null;
// 沒有用
PendingIntent mReconnectIntent = null;
// 沒搞懂
/**
* Indicates if when this connection was established we had a restricted/privileged
* NetworkRequest and needed it to overcome data-enabled limitations.
*
* This gets set once per connection setup and is based on conditions at that time.
* We could theoretically have dynamic capabilities but now is not a good time to
* experiement with that.
*
* This flag overrides the APN-based restriction capability, restricting the network
* based on both having a NetworkRequest with restricted AND needing a restricted
* bit to overcome user-disabled status. This allows us to handle the common case
* of having both restricted requests and unrestricted requests for the same apn:
* if conditions require a restricted network to overcome user-disabled then it must
* be restricted, otherwise it is unrestricted (or restricted based on APN type).
*
* Because we're not supporting dynamic capabilities, if conditions change and we go from
* data-enabled to not or vice-versa we will need to tear down networks to deal with it
* at connection setup time with the new state.
*
* This supports a privileged app bringing up a network without general apps having access
* to it when the network is otherwise unavailable (hipri). The first use case is
* pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic
* other than from the privileged carrier-app.
*/
private boolean mRestrictedNetworkOverride = false;
// 數(shù)據(jù)連接的六種狀態(tài)
private DcDefaultState mDefaultState = new DcDefaultState();
private DcInactiveState mInactiveState = new DcInactiveState();
private DcActivatingState mActivatingState = new DcActivatingState();
private DcActiveState mActiveState = new DcActiveState();
private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
}
?
DcController
Platform:Android-7.1.1_r22
/**
* Data Connection Controller which is a package visible class and controls
* multiple data connections. For instance listening for unsolicited messages
* and then demultiplexing them to the appropriate DC.
*/
public class DcController extends StateMachine {
?
RetryManager
Platform:Android-7.1.1_r22
RetryManager管理著重試次數(shù)、重試間隔時間等配置。
RetryManager對象的建立是在ApnContext的構(gòu)造函數(shù)的完成的。
public ApnContext(Phone phone, String apnType, String logTag, NetworkConfig config,
DcTracker tracker) {
......
mRetryManager = new RetryManager(phone, apnType);
}
而Retry所需要使用的apn及間隔時間是在DcTracker中通過trySetupData() -> ApnContext.setWaitingApns() -> RetryManager.setWaitingApns()進(jìn)行設(shè)置的,且只有當(dāng)ApnContext為IDLE時才會設(shè)置。
DcTracker.java
private boolean trySetupData(ApnContext apnContext, ArrayList<ApnSetting> waitingApns) {
......
if (apnContext.getState() == DctConstants.State.IDLE) {
if (waitingApns == null) {
waitingApns = buildWaitingApns(apnContext.getApnType(), radioTech);
}
if (waitingApns.isEmpty()) {
......
return false;
} else {
apnContext.setWaitingApns(waitingApns);
if (DBG) {
log ("trySetupData: Create from mAllApnSettings : "
+ apnListToString(mAllApnSettings));
}
}
}
......
}
RetryManager.java
public void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
......
mWaitingApns = waitingApns; // 保存WaitingApns,通常情況下只有一個apn
// Since we replace the entire waiting APN list, we need to re-config this retry manager.
configureRetry(); // 配置Retry的間隔時間
for (ApnSetting apn : mWaitingApns) {
apn.permanentFailed = false;
}
}
配置重試次數(shù)、重試間隔時間。
private void configureRetry() {
......
// 初始化一個WaitingApns周期內(nèi)的重試間隔時間(針對WaitingApns中有多個apn的情況)
mInterApnDelay = b.getLong(
CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG,
DEFAULT_INTER_APN_DELAY);
// 初始化FailFast模式下的重試間隔時間
mFailFastInterApnDelay = b.getLong(
CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG,
DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING);
// 初始化通常情況下不同APN的重試間隔時間及次數(shù);
// 若當(dāng)前APN的配置不為空,則使用當(dāng)前APN的配置;
// 若當(dāng)前APN的配置為空且其他APN的配置不為空,則使用其他APN的配置;
// 若當(dāng)前APN和其他APN的配置都為空,則使用默認(rèn)配置
// Load all retry patterns for all different APNs.
String[] allConfigStrings = b.getStringArray(
CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS);
......
// 解析配置
configure(configString);
}
這里我們就不分析configure()的代碼了,直接用CarrierConfigManager中的默認(rèn)配置來說明。
sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{
"default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
+ "320000:5000,640000:5000,1280000:5000,1800000:5000",
"mms:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
+ "320000:5000,640000:5000,1280000:5000,1800000:5000",
"others:max_retries=3, 5000, 5000, 5000"});
這個配置包含了3個字符串,分別對default_apn、mms_apn及其它apn進(jìn)行配置。
每個配置的格式可表示為:
apn_type:[default_randomization=2000 | max_retries=3], 5000,10000,20000,40000,80000:5000,160000:5000
apn_type表示apn的類型;
default_randomization表示默認(rèn)隨機值邊界;
max_retries表示最大重試次數(shù),"infinite"表示無限次;
如果配置的最大重試次數(shù)小于實際配置的次數(shù),則取實際配置的次數(shù);
例如下面這種,雖然配置的最大重試次數(shù)為3,但后面配置了4個重試值,則實際的重試次數(shù)為4;
"others:max_retries=3, 5000, 5000, 5000, 5000"
如果配置的最大重試次數(shù)大于實際配置的次數(shù),則后面幾次未配置的值則使用最后一個配置值;
例如下面這種,配置的重試次數(shù)為5次,但只配置了3個值,則第4次和第5次就使用最后一個配置值,即3s;
"others:max_retries=5, 1000, 2000, 3000"
80000:5000表示間隔時間為80s,隨機值邊界為5s。
配置中的隨機值,是用來加在配置的間隔時間上的,例如配置的間隔時間為"80000:5000",那么實際上的間隔時間則為80s再加上一個0~5s之間的隨機值。之所以加上一個隨機值,是為了防止基站周圍的大量設(shè)備在同一時間發(fā)起重試請求。
ConnectivityManager
Platform:Android-7.1.1_r22
ConnectivityManager提供訪問ConnectivityService的接口,與ConnectivityService通過binder進(jìn)行通信
主要作用:
1.監(jiān)視網(wǎng)絡(luò)連接(WiFi、GPRS、UMTS等)
2.當(dāng)網(wǎng)絡(luò)連接變化時發(fā)送廣播
3.當(dāng)一個連接斷開時切換到另一個連接
4.為App提供查詢可用網(wǎng)絡(luò)的粗略/詳細(xì)狀態(tài)的接口
5.為App提供請求及選擇一個網(wǎng)絡(luò)來進(jìn)行數(shù)據(jù)傳輸?shù)慕涌?br />
/**
* Class that answers queries about the state of network connectivity. It also
* notifies applications when network connectivity changes. Get an instance
* of this class by calling
* {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
* <p>
* The primary responsibilities of this class are to:
* <ol>
* <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
* <li>Send broadcast intents when network connectivity changes</li>
* <li>Attempt to "fail over" to another network when connectivity to a network
* is lost</li>
* <li>Provide an API that allows applications to query the coarse-grained or fine-grained
* state of the available networks</li>
* <li>Provide an API that allows applications to request and select networks for their data
* traffic</li>
* </ol>
*/
?
ConnectivityService
Platform:Android-7.1.1_r22
由Zygote創(chuàng)建的SystemServer啟動的。
SystemServer.startOtherServices() {
......
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
......
}
啟動ConnectivityService時會創(chuàng)建2個NetworkRequest對象
mDefaultRequest:
類型為REQUEST,transport為空,創(chuàng)建好后馬上加入到mNetworkRequests。
mDefaultMobileDataRequest:
BACKGROUND_REQUEST,transport為CELLULAR,創(chuàng)建好后先不會加入到mNetworkRequests,
handleRegisterNetworkRequest()中加入到mNetworkRequests,
handleReleaseNetworkRequest()中再從mNetworkRequests移除。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
屬性值:
protected int mLingerDelayMs;
// How long to delay to removal of a pending intent based request.
// See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
private final int mReleasePendingIntentDelayMs;
private Tethering mTethering;
private final PermissionMonitor mPermissionMonitor;
private KeyStore mKeyStore;
@GuardedBy("mVpns")
private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
private boolean mLockdownEnabled;
private LockdownVpnTracker mLockdownTracker;
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
private Object mRulesLock = new Object();
/** Currently active network rules by UID. */
@GuardedBy("mRulesLock")
private SparseIntArray mUidRules = new SparseIntArray();
/** Set of ifaces that are costly. */
@GuardedBy("mRulesLock")
private ArraySet<String> mMeteredIfaces = new ArraySet<>();
/** Flag indicating if background data is restricted. */
@GuardedBy("mRulesLock")
private boolean mRestrictBackground;
final private Context mContext;
private int mNetworkPreference;
// 0 is full bad, 100 is full good
private int mDefaultInetConditionPublished = 0;
private int mNumDnsEntries;
private boolean mTestMode;
private static ConnectivityService sServiceInstance;
private INetworkManagementService mNetd;
private INetworkStatsService mStatsService;
private INetworkPolicyManager mPolicyManager;
private String mCurrentTcpBufferSizes;
private static final SparseArray<String> sMagicDecoderRing
/**
* used internally to change our mobile data enabled flag
*/
private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED = 2;
/**
* used internally to clear a wakelock when transitioning
* from one net to another. Clear happens when we get a new
* network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
* after a timeout if no network is found (typically 1 min).
*/
private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
/**
* used internally to reload global proxy settings
*/
private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
/**
* PAC manager has received new port.
*/
private static final int EVENT_PROXY_HAS_CHANGED = 16;
/**
* used internally when registering NetworkFactories
* obj = NetworkFactoryInfo
*/
private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
/**
* used internally when registering NetworkAgents
* obj = Messenger
*/
private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
/**
* used to add a network request
* includes a NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
/**
* indicates a timeout period is over - check if we had a network yet or not
* and if not, call the timeout callback (but leave the request live until they
* cancel it.
* includes a NetworkRequestInfo
*/
private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
/**
* used to add a network listener - no request
* includes a NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
/**
* used to remove a network request, either a listener or a real request
* arg1 = UID of caller
* obj = NetworkRequest
*/
private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
/**
* used internally when registering NetworkFactories
* obj = Messenger
*/
private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
/**
* used internally to expire a wakelock when transitioning
* from one net to another. Expire happens when we fail to find
* a new network (typically after 1 minute) -
* EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
* a replacement network.
*/
private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
/**
* Used internally to indicate the system is ready.
*/
private static final int EVENT_SYSTEM_READY = 25;
/**
* used to add a network request with a pending intent
* obj = NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
/**
* used to remove a pending intent and its associated network request.
* arg1 = UID of caller
* obj = PendingIntent
*/
private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
/**
* used to specify whether a network should be used even if unvalidated.
* arg1 = whether to accept the network if it's unvalidated (1 or 0)
* arg2 = whether to remember this choice in the future (1 or 0)
* obj = network
*/
private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
/**
* used to specify whether a network should not be penalized when it becomes unvalidated.
*/
private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
/**
* used to ask the user to confirm a connection to an unvalidated network.
* obj = network
*/
private static final int EVENT_PROMPT_UNVALIDATED = 29;
/**
* used internally to (re)configure mobile data always-on settings.
*/
private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30;
/**
* used to add a network listener with a pending intent
* obj = NetworkRequestInfo
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
/**
* Indicates a caller has requested to have its callback invoked with
* the latest LinkProperties or NetworkCapabilities.
*
* arg1 = UID of caller
* obj = NetworkRequest
*/
private static final int EVENT_REQUEST_LINKPROPERTIES = 32;
private static final int EVENT_REQUEST_NETCAPABILITIES = 33;
/** Handler thread used for both of the handlers below. */
@VisibleForTesting
protected final HandlerThread mHandlerThread;
/** Handler used for internal events. */
final private InternalHandler mHandler;
/** Handler used for incoming {@link NetworkStateTracker} events. */
final private NetworkStateTrackerHandler mTrackerHandler;
private boolean mSystemReady;
private Intent mInitialBroadcast;
private PowerManager.WakeLock mNetTransitionWakeLock;
private String mNetTransitionWakeLockCausedBy = "";
private int mNetTransitionWakeLockSerialNumber;
private int mNetTransitionWakeLockTimeout;
private final PowerManager.WakeLock mPendingIntentWakeLock;
// used in DBG mode to track inet condition reports
private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
private ArrayList mInetLog;
// track the current default http proxy - tell the world if we get a new one (real change)
private volatile ProxyInfo mDefaultProxy = null;
private Object mProxyLock = new Object();
private boolean mDefaultProxyDisabled = false;
// track the global proxy.
private ProxyInfo mGlobalProxy = null;
private PacManager mPacManager = null;
final private SettingsObserver mSettingsObserver;
private UserManager mUserManager;
NetworkConfig[] mNetConfigs;
int mNetworksDefined;
// the set of network types that can only be enabled by system/sig apps
List mProtectedNetworks;
private DataConnectionStats mDataConnectionStats;
TelephonyManager mTelephonyManager;
private KeepaliveTracker mKeepaliveTracker;
private NetworkNotificationManager mNotifier;
private LingerMonitor mLingerMonitor;
// sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
private final static int MIN_NET_ID = 100; // some reserved marks
private final static int MAX_NET_ID = 65535;
private int mNextNetId = MIN_NET_ID;
// sequence number of NetworkRequests
private int mNextNetworkRequestId = 1;
private final IpConnectivityLog mMetricsLog;
@VisibleForTesting
final AvoidBadWifiTracker mAvoidBadWifiTracker;
private INetworkManagementEventObserver mDataActivityObserver
private INetworkPolicyListener mPolicyListener
private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
// Map from UID to number of NetworkRequests that UID has filed.
@GuardedBy("mUidToNetworkRequestCount")
private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
private final HashSet<Integer> mBlockedAppUids = new HashSet();
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
private final NetworkRequest mDefaultRequest;
// Request used to optionally keep mobile data active even when higher
// priority networks like Wi-Fi are active.
private final NetworkRequest mDefaultMobileDataRequest;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
構(gòu)造方法:
protected ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
IpConnectivityLog logger) {
if (DBG) log("ConnectivityService starting up");
mMetricsLog = logger;
mDefaultRequest = createInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
mNetworkRequests.put(mDefaultRequest, defaultNRI);
mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
mDefaultMobileDataRequest = createInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
mHandlerThread = createHandlerThread();
mHandlerThread.start();
mHandler = new InternalHandler(mHandlerThread.getLooper());
mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
// setup our unique device name
if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
String id = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
if (id != null && id.length() > 0) {
String name = new String("android-").concat(id);
SystemProperties.set("net.hostname", name);
}
}
mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
mLingerDelayMs = SystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
mContext = checkNotNull(context, "missing Context");
mNetd = checkNotNull(netManager, "missing INetworkManagementService");
mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
mKeyStore = KeyStore.getInstance();
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
try {
mPolicyManager.setConnectivityListener(mPolicyListener);
mRestrictBackground = mPolicyManager.getRestrictBackground();
} catch (RemoteException e) {
// ouch, no rules updates means some processes may never get network
loge("unable to register INetworkPolicyListener" + e);
}
final PowerManager powerManager = (PowerManager) context.getSystemService(
Context.POWER_SERVICE);
mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_networkTransitionTimeout);
mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
// TODO: What is the "correct" way to do determine if this is a wifi only device?
boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
log("wifiOnly=" + wifiOnly);
String[] naStrings = context.getResources().getStringArray(
com.android.internal.R.array.networkAttributes);
for (String naString : naStrings) {
try {
NetworkConfig n = new NetworkConfig(naString);
if (VDBG) log("naString=" + naString + " config=" + n);
if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
loge("Error in networkAttributes - ignoring attempt to define type " +
n.type);
continue;
}
if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
log("networkAttributes - ignoring mobile as this dev is wifiOnly " +
n.type);
continue;
}
if (mNetConfigs[n.type] != null) {
loge("Error in networkAttributes - ignoring attempt to redefine type " +
n.type);
continue;
}
mLegacyTypeTracker.addSupportedType(n.type);
mNetConfigs[n.type] = n;
mNetworksDefined++;
} catch(Exception e) {
// ignore it - leave the entry null
}
}
// Forcibly add TYPE_VPN as a supported type, if it has not already been added via config.
if (mNetConfigs[TYPE_VPN] == null) {
// mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we
// don't need to add TYPE_VPN to mNetConfigs.
mLegacyTypeTracker.addSupportedType(TYPE_VPN);
mNetworksDefined++; // used only in the log() statement below.
}
if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
mProtectedNetworks = new ArrayList<Integer>();
int[] protectedNetworks = context.getResources().getIntArray(
com.android.internal.R.array.config_protectedNetworks);
for (int p : protectedNetworks) {
if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
mProtectedNetworks.add(p);
} else {
if (DBG) loge("Ignoring protectedNetwork " + p);
}
}
mTestMode = SystemProperties.get("cm.test.mode").equals("true")
&& SystemProperties.get("ro.build.type").equals("eng");
mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager);
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
//set up the listener for user state for creating user VPNs
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_STARTED);
intentFilter.addAction(Intent.ACTION_USER_STOPPED);
intentFilter.addAction(Intent.ACTION_USER_ADDED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
mContext.registerReceiverAsUser(
mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
try {
mNetd.registerObserver(mTethering);
mNetd.registerObserver(mDataActivityObserver);
} catch (RemoteException e) {
loge("Error registering observer :" + e);
}
if (DBG) {
mInetLog = new ArrayList();
}
mSettingsObserver = new SettingsObserver(mContext, mHandler);
registerSettingsCallbacks();
mDataConnectionStats = new DataConnectionStats(mContext);
mDataConnectionStats.startMonitoring();
mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mKeepaliveTracker = new KeepaliveTracker(mHandler);
mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
mContext.getSystemService(NotificationManager.class));
final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
mAvoidBadWifiTracker = createAvoidBadWifiTracker(
mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
}
frameworks/base/core/res/res/values/config.xml
<string-array translatable="false" name="networkAttributes">
name type radio priority restoreTime dependencyMet
<item>"wifi, 1, 1, 1, -1, true"</item>
<item>"mobile, 0, 0, 0, -1, true"</item>
<item>"mobile_mms, 2, 0, 4, 60000, true"</item>
<item>"mobile_supl, 3, 0, 2, 60000, true"</item>
<item>"mobile_dun, 4, 0, 2, 60000, true"</item>
<item>"mobile_hipri, 5, 0, 3, 60000, true"</item>
<item>"mobile_fota, 10, 0, 2, 60000, true"</item>
<item>"mobile_ims, 11, 0, 2, 60000, true"</item>
<item>"mobile_cbs, 12, 0, 2, 60000, true"</item>
<item>"bluetooth, 7, 7, 2, -1, true"</item>
<item>"mobile_emergency, 15, 0, 5, -1, true"</item>
</string-array>
NetworkAgent
用于特定承載代碼和ConnectivityService通信的工具類。
如:DataConnection.java、Vpn.java、WifiStateMachine.java等與ConnectivityService通信
NetworkCapabilities
用于描述一個網(wǎng)絡(luò)的能力,用來指定ConnectivityManager的需求以及檢查網(wǎng)絡(luò)。
/**
* This class represents the capabilities of a network. This is used both to specify
* needs to {@link ConnectivityManager} and when inspecting a network.
*
* Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
* of network selection. Rather than indicate a need for Wi-Fi because an application
* needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
* the application should specify it needs high bandwidth. Similarly if an application
* needs an unmetered network for a bulk transfer it can specify that rather than assuming
* all cellular based connections are metered and all Wi-Fi based connections are not.
*/
NetworkRequest
Platform:Android-7.1.1_r22
定義一個網(wǎng)絡(luò)請求。
通過ConnectivityManager#requestNetwork請求一個網(wǎng)絡(luò);
通過ConnectivityManager#registerNetworkCallback監(jiān)聽網(wǎng)絡(luò)變化。
/**
* Defines a request for a network, made through {@link NetworkRequest.Builder} and used
* to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
* via {@link ConnectivityManager#registerNetworkCallback}.
*/
public class NetworkRequest implements Parcelable {
public final NetworkCapabilities networkCapabilities;
// 請求id,ConnectivityService.mNextNetworkRequestId維護(hù)
/**
* Identifies the request. NetworkRequests should only be constructed by
* the Framework and given out to applications as tokens to be used to identify
* the request.
* @hide
*/
public final int requestId;
/**
* Set for legacy requests and the default. Set to TYPE_NONE for none.
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
public final int legacyType;
/**
* A NetworkRequest as used by the system can be one of the following types:
*
* - LISTEN, for which the framework will issue callbacks about any
* and all networks that match the specified NetworkCapabilities,
*
* - REQUEST, capable of causing a specific network to be created
* first (e.g. a telephony DUN request), the framework will issue
* callbacks about the single, highest scoring current network
* (if any) that matches the specified NetworkCapabilities, or
*
* - TRACK_DEFAULT, a hybrid of the two designed such that the
* framework will issue callbacks for the single, highest scoring
* current network (if any) that matches the capabilities of the
* default Internet request (mDefaultRequest), but which cannot cause
* the framework to either create or retain the existence of any
* specific network. Note that from the point of view of the request
* matching code, TRACK_DEFAULT is identical to REQUEST: its special
* behaviour is not due to different semantics, but to the fact that
* the system will only ever create a TRACK_DEFAULT with capabilities
* that are identical to the default request's capabilities, thus
* causing it to share fate in every way with the default request.
*
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
* no foreground requests is in the background. A network that has
* one or more background requests and loses its last foreground
* request to a higher-scoring network will not go into the
* background immediately, but will linger and go into the background
* after the linger timeout.
*
* - The value NONE is used only by applications. When an application
* creates a NetworkRequest, it does not have a type; the type is set
* by the system depending on the method used to file the request
* (requestNetwork, registerNetworkCallback, etc.).
*
* @hide
*/
public static enum Type {
NONE,
LISTEN,
TRACK_DEFAULT,
REQUEST,
BACKGROUND_REQUEST,
};
/**
* The type of the request. This is only used by the system and is always NONE elsewhere.
*
* @hide
*/
public final Type type;
?
NetworkStatsService
Platform:Android-7.1.1_r22
統(tǒng)計網(wǎng)絡(luò)傳輸數(shù)據(jù),供其他系統(tǒng)服務(wù)使用。
/**
* Collect and persist detailed network statistics, and provide this data to
* other system services.
*/
?
?
?
?
轉(zhuǎn)載于:https://my.oschina.net/igiantpanda/blog/2222667
總結(jié)
- 上一篇: ABB机器人开发基础之碰撞监控设置
- 下一篇: JDK1.8源码分析:LinkedHas