版本信息:
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
/*修改外置摄像头只能通过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
修改
[java] view plain copy
1. 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
2. old mode 100644
3. new mode 100755
4. index 09b3c9b..00fba2a
5. --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
6. +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
7. @@ -1734,7 +1734,7 @@ public final class DataConnection extends StateMachine {
8. misc.subscriberId = mPhone.getSubscriberId();
9. new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(),
10. "DcNetworkAgent", mNetworkInfo, makeNetworkCapabilities(), mLinkProperties,
11. - 50, misc);
12. + 100, misc);
13. }
14.
15. @Override
16. 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
17. old mode 100644
18. new mode 100755
19. index 4fce2ec..fdb59b1
20. --- a/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java
21. +++ b/frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DctController.java
22. @@ -152,7 +152,7 @@ public class DctController extends Handler {
23. new TelephonyNetworkFactory(this.getLooper(),
24. "TelephonyNetworkFactory", phoneBase,
25. mNetworkFilter[index]);
26. - mNetworkFactory[index].setScoreFilter(50);
27. + mNetworkFactory[index].setScoreFilter(100);
28. new Messenger(mNetworkFactory[index]);
29. "Telephony");
30. }
说明
网络优先级采用新的score机制.
以上改法, 将移动网络的score从50 加到 100.
从当前代码中看,
Ethernet (150), Wifi(60)
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java(Wifi)
[java] view plain copy
1. mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext,
2. "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter,
3. 60);
[java] view plain copy
1. mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext,
2. NETWORKTYPE, mNetworkCapabilitiesFilter);
3. mNetworkFactory.setScoreFilter(60);
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java(Ethernet)
[java] view plain copy
1. private static final int NETWORK_SCORE = 150;
2. // Create our NetworkAgent.
3. new NetworkAgent(mFactory.getLooper(), mContext,
4. NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
5. 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.