版本信息:
android5.1.1
Linux version 3.10.49
需求:通过4g访问外网,同时通过wifi访问内网。
android系统默认情况下,wifi连网时,4g数据链接会被强制断开,但实际有需要wifi和4g同时上网,为了满足这个要求,需要修改android的网络管理机制。
首先实现wifi连网时,不让4g数据链接被强制断开:
修改 frameworks/base/services/core/java/com/android/server/ConnectivityService.java
private void teardownUnneededNetwork(NetworkAgentInfo nai) {
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest nr = nai.networkRequests.valueAt(i);
// Ignore listening requests.
if (!isRequest(nr)) continue;
loge("Dead network still had at least " + nr);
break;
}
//nai.asyncChannel.disconnect();
}
把nai.asyncChannel.disconnect(); 行mark掉。
这样wifi连网,4g数据链接不会被强制断开了。
$ netcfg
rmnet0 UP 0.0.0.0/0 0x00000041 00:00:00:00:00:00
r_rmnet_data8 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
r_rmnet_data0 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data4 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data2 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data3 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data1 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data0 UP 10.66.94.93/30 0x00000041 00:00:00:00:00:00
rmnet_data7 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data5 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
rmnet_data6 DOWN 0.0.0.0/0 0x00000000 00:00:00:00:00:00
wlan0 UP 192.168.10.10/24 0x00001043 34:87:3d:31:e4:77
sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00
p2p0 UP 0.0.0.0/0 0x00001003 36:87:3d:31:e4:77
lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
dummy0 DOWN 0.0.0.0/0 0x00000082 d6:d1:38:38:ed:c8
但此时,网络访问默认还是走wifi通道,把wifi AP与外网断开,ping下192.168.10.1可以ping通,但www.baidu.com会发现ping不通,
指定network,再ping
ping -I rmnet_data0 www.baidu.com
会发现可以ping通,说明此时wifi和4g都已经连上网了。
APP程序可以通过setProcessDefaultNetwork把进程和network绑定来访问特定网络。
https://yq.aliyun.com/articles/341803
https://blog.csdn.net/wr132/article/details/78429159
/*修改外置摄像头只能通过wifi上网 begin 20180619*/
import android.net.ConnectivityManager;import android.content.Context;
import android.net.NetworkRequest;
import android.net.NetworkCapabilities;
import android.net.Network;
/*修改外置摄像头只能通过wifi上网 end 20180619*/
/*修改外置摄像头只能通过wifi上网 begin 20180619*/
//设置该APP只能通过wifi传输数据
public void setwifiNet(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder req = new NetworkRequest.Builder();
//req.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
// 设置指定的网络传输类型 wifi
req.addTransportType(NetworkCapabilities.TRANSPORT_WIFI );
cm.requestNetwork(req.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
try {
/*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager.setProcessDefaultNetwork(network);
} else {
connectivityManager.bindProcessToNetwork(network);
}*/
//if (Build.VERSION.SDK_INT >= 23) {
// cm.bindProcessToNetwork(network);
//} else {
// 23后这个方法舍弃了
ConnectivityManager.setProcessDefaultNetwork(network);
//}
} catch (IllegalStateException e) {
Log.e(TAG, "ConnectivityManager.NetworkCallback.onAvailable: ", e);
}
}
// Be sure to override other options in NetworkCallback() too...
});
}
/*修改外置摄像头只能通过wifi上网 end 20180619*/
但我们的要求是一个APP有的数据走wifi有的数据走4g,不希望APP和某个network绑定,这样就是要求默认走4g上网,访问内网ip则走wifi.即修改系统让4g的优先级优于wifi,修改route rule,使得访问内网ip时,则走wifi.
修改系统让4g的优先级优于wifi:
android5.1是依据网络评分来评定网络的优先级,默认情况下,wifi的评分比4g高。可以修改
修改网络连接优先级为
Ethernet > Mobile > Wifi
修改
- diff --git a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
- old mode 100644
- new mode 100755
- index 09b3c9b..00fba2a
- --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
- +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
- @@ -1734,7 +1734,7 @@ public final class DataConnection extends StateMachine {
- misc.subscriberId = mPhone.getSubscriberId();
- mNetworkAgent = new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(),
- "DcNetworkAgent", mNetworkInfo, makeNetworkCapabilities(), mLinkProperties,
- - 50, misc);
- + 100, misc);
- }
- @Override
- diff --git a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java
- old mode 100644
- new mode 100755
- index 4fce2ec..fdb59b1
- --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java
- +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java
- @@ -152,7 +152,7 @@ public class DctController extends Handler {
- mNetworkFactory[index] = new TelephonyNetworkFactory(this.getLooper(),
- mPhones[index].getContext(), "TelephonyNetworkFactory", phoneBase,
- mNetworkFilter[index]);
- - mNetworkFactory[index].setScoreFilter(50);
- + mNetworkFactory[index].setScoreFilter(100);
- mNetworkFactoryMessenger[index] = new Messenger(mNetworkFactory[index]);
- cm.registerNetworkFactory(mNetworkFactoryMessenger[index], "Telephony");
- }
说明
网络优先级采用新的score机制.
以上改法, 将移动网络的score从50 加到 100.
从当前代码中看, Ethernet (150), Wifi(60)
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java(Wifi)
- mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,
- "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,
- mLinkProperties, 60);
- mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext,
- NETWORKTYPE, mNetworkCapabilitiesFilter);
- mNetworkFactory.setScoreFilter(60);
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java(Ethernet)
- private static final int NETWORK_SCORE = 150;
- // Create our NetworkAgent.
- mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
- NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
- NETWORK_SCORE) {
把4g网络评分强制改为100,这样可以确保总是大于wifi网络的评分。
更新系统,ping www.baidu.com可以ping通,说明此时系统优先走4g网络(wifi AP与外网断开)。 ping 192.168.10.1 不通。
修改route rule:
查看默认route rule:
ip rule
0: from all lookup local
10000: from all fwmark 0xc0000/0xd0000 lookup 99
13000: from all fwmark 0x10063/0x1ffff lookup 97
13000: from all fwmark 0x10064/0x1ffff lookup 1022
13000: from all fwmark 0x10065/0x1ffff lookup 1005
14000: from all oif wlan0 lookup 1022
14000: from all oif rmnet_data0 lookup 1005
15000: from all fwmark 0x0/0x10000 lookup 99
16000: from all fwmark 0x0/0x10000 lookup 98
17000: from all fwmark 0x0/0x10000 lookup 97
19000: from all fwmark 0x64/0x1ffff lookup 1022
19000: from all fwmark 0x65/0x1ffff lookup 1005
22000: from all fwmark 0x0/0xffff lookup 1005
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000: from all unreachable
尝试添加一条route rule:
ip rule add to 192.168.10.0/24 table wlan0 pref 100
修改后route rule:
0: from all lookup local
100: from all to 192.168.10.0/24 lookup 1022
10000: from all fwmark 0xc0000/0xd0000 lookup 99
13000: from all fwmark 0x10063/0x1ffff lookup 97
13000: from all fwmark 0x10064/0x1ffff lookup 1022
13000: from all fwmark 0x10065/0x1ffff lookup 1005
14000: from all oif wlan0 lookup 1022
14000: from all oif rmnet_data0 lookup 1005
15000: from all fwmark 0x0/0x10000 lookup 99
16000: from all fwmark 0x0/0x10000 lookup 98
17000: from all fwmark 0x0/0x10000 lookup 97
19000: from all fwmark 0x64/0x1ffff lookup 1022
19000: from all fwmark 0x65/0x1ffff lookup 1005
22000: from all fwmark 0x0/0xffff lookup 1005
23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
32000: from all unreachable
这样就可以直接ping 通192.168.10.1了。
APP程序没有修改route rule的权限,我们想让系统在wifi连接AP后自动添加需要的一条route rule.
可以修改netd (system/netd/server/),netd有权限修改route rule.