Android13 以太网和WIFI共存

2 篇文章 3 订阅
1 篇文章 0 订阅
本文介绍了如何在Android系统中实现WiFi和以太网同时开启的兼容性,通过修改ConnectivityService、NetworkAgentInfo和RouteController等关键组件的源码,配置网络共存路由表,确保WiFi优先。
摘要由CSDN通过智能技术生成

一、引言

        在实际的项目开发中,特别用到以太网相关功能时,往往会涉及wifi和以太网同时打开的情况,android原生对于这块的兼容很少,只会有一个生效,会优先使用以太网,故此需要改变系统机制做兼容。

二、实现部分

        思路:其实我们要做的无非就是让底层认为两者共存时现在就是要使用wifi上网的就行,那么我们就得在网络通路上做文章,也就是要配置“网络共存路由表”,大体上关于上层网络涉及的包就是Connectivity与system目录下的netd两个包,我们可以从这两个包的源码开始查看。

        2.1、上层系统服务部分

1.ConnectivityService.java类的unneeded方法中过滤以太网和wifi的检测,使能共存

+++ b/packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
@@ -322,11 +322,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
     private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller";
 
     private static final boolean DBG = true;
     private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final boolean LOGD_BLOCKED_NETWORKINFO = true;

     /**
      * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
      * by OEMs for configuration purposes, as this value is overridden by
@@ -4601,6 +4610,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
         ensureRunningOnConnectivityServiceThread();
 
+        // added by cgt ethernet and wifi coexist start
+        boolean needed = nai.isWIFI();
+        needed = nai.isETHERNET();
+        Log.d(TAG, "---> unneeded: needed=" + needed);
+        if (needed) {
+           return false;
+        }
+        // added by cgt ethernet and wifi coexist end

         if (!nai.everConnected || nai.isVPN() || nai.isInactive()
                 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
             return false;

2.NetworkAgentInfo.java类中添加判断当前网络是否是以太网或者wifi的方法

+++ b/packages/modules/Connectivity/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -943,6 +943,18 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRa
         return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
     }
 
+    // added by cgt ethernet and wifi coexist start
+    /** Whether this network is a WIFI. */
+    public boolean isWIFI() {
+        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+    }
+
+    /** Whether this network is a ETHERNET. */
+    public boolean isETHERNET() {
+        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET);
+    }
+    // added by cgt ethernet and wifi coexist end
+
     /**
      * Whether this network should propagate the capabilities from its underlying networks.
      * Currently only true for VPNs.

3.NetworkRanker.java类中配置wifi优先并且在mightBeat方法中过滤wifi和以太网 

+++ b/packages/modules/Connectivity/service/src/com/android/server/connectivity/NetworkRanker.java
@@ -46,10 +46,18 @@ import java.util.Collection;
 import java.util.List;
 import java.util.function.Predicate;
 
+// added by cgt ethernet and wifi coexist start
+import android.util.Log;
+// added by cgt ethernet and wifi coexist end
+
 /**
  * A class that knows how to find the best network matching a request out of a list of networks.
  */
 public class NetworkRanker {
+    // added by cgt ethernet and wifi coexist start
+    private static final String TAG = "NetworkRanker";
+    // added by cgt ethernet and wifi coexist end
+
     // Historically the legacy ints have been 0~100 in principle (though the highest score in
     // AOSP has always been 90). This is relied on by VPNs that send a legacy score of 101.
     public static final int LEGACY_INT_MAX = 100;
@@ -80,9 +88,25 @@ public class NetworkRanker {
     }
 
     // Transport preference order, if it comes down to that.
+	 // added by cgt ethernet and wifi coexist start
-    private static final int[] PREFERRED_TRANSPORTS_ORDER = { TRANSPORT_ETHERNET, TRANSPORT_WIFI,
+    //private static final int[] PREFERRED_TRANSPORTS_ORDER = { TRANSPORT_ETHERNET, TRANSPORT_WIFI,
+    //        TRANSPORT_BLUETOOTH, TRANSPORT_CELLULAR };
+    private static int[] PREFERRED_TRANSPORTS_ORDER = { TRANSPORT_ETHERNET, TRANSPORT_WIFI,
+            TRANSPORT_BLUETOOTH, TRANSPORT_CELLULAR };
+    private static int[] PREFERRED_TRANSPORTS_ORDER_COEXIST = { TRANSPORT_WIFI, TRANSPORT_ETHERNET,
             TRANSPORT_BLUETOOTH, TRANSPORT_CELLULAR };
 
+    static {
+        PREFERRED_TRANSPORTS_ORDER = PREFERRED_TRANSPORTS_ORDER_COEXIST;
+    }
+    // added by cgt ethernet and wifi coexist end
+
     // Function used to partition a list into two working areas depending on whether they
     // satisfy a predicate. All items satisfying the predicate will be put in |positive|, all
     // items that don't will be put in |negative|.
@@ -310,6 +334,20 @@ public class NetworkRanker {
         // is always better than no network.
         if (null == champion) return true;
         // If there is no champion, the offer can always beat.
+        // added by cgt ethernet and wifi coexist start
+        boolean needed = contestant.getCapsNoCopy().hasTransport(TRANSPORT_WIFI);
+        needed = contestant.getCapsNoCopy().hasTransport(TRANSPORT_ETHERNET);
+        Log.d(TAG, "---> mightBeat: needed=" + needed);
+        if (needed) {
+            return true;
+        }
+        // added by cgt ethernet and wifi coexist end
         // Otherwise rank them.
         final ArrayList<Scoreable> candidates = new ArrayList<>();
         candidates.add(champion);

        

        2.2、上层netd服务部分

1.RouteController.cpp类中的Init方法配置一条新的直通的路由信息取代原生的配置

diff --git a/system/netd/server/RouteController.cpp b/system/netd/server/RouteController.cpp
index d2af9a375a2..22377105e1f 100644
--- a/system/netd/server/RouteController.cpp
+++ b/system/netd/server/RouteController.cpp
@@ -40,6 +40,10 @@
 #include "netid_client.h"
 #include "netutils/ifc.h"
 
+// added by cgt ethernet and wifi coexist start
+#include <android-base/properties.h>
+// added by cgt ethernet and wifi coexist end
+
 using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::WriteStringToFile;
@@ -773,6 +777,18 @@ int RouteController::configureDummyNetwork() {
     return 0;
 }
 
+// added by cgt ethernet and wifi coexist start
+// Add a new rule to look up the 'main' table, with the same selectors as the "default network"
+// rule, but with a lower priority. We will never create routes in the main table; it should only be
+// used for directly-connected routes implicitly created by the kernel when adding IP addresses.
+// This is necessary, for example, when adding a route through a directly-connected gateway: in
+// order to add the route, there must already be a directly-connected route that covers the gateway.
+[[nodiscard]] static int addDirectlyConnectedRule() {
+    return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_DIRECTLY_CONNECTED, RT_TABLE_MAIN,
+                        MARK_UNSET, MARK_UNSET, IIF_NONE, OIF_NONE, INVALID_UID, INVALID_UID);
+}
+// added by cgt ethernet and wifi coexist end
+
 // Add an explicit unreachable rule close to the end of the prioriy list to make it clear that
 // relying on the kernel-default "from all lookup main" rule at priority 32766 is not intended
 // behaviour. We do flush the kernel-default rules at startup, but having an explicit unreachable
@@ -1259,6 +1275,13 @@ int RouteController::Init(unsigned localNetId) {
     if (int ret = addLocalNetworkRules(localNetId)) {
         return ret;
     }
+    // added by cgt ethernet and wifi coexist start
+    if (int ret = addDirectlyConnectedRule()) {
+        return ret;
+    }
+    // added by cgt ethernet and wifi coexist end
     if (int ret = addUnreachableRule()) {
         return ret;
     }

2.RouteController.h类中定义一个使用的变量

diff --git a/system/netd/server/RouteController.h b/system/netd/server/RouteController.h
index ff41678d551..2604266995c 100644
--- a/system/netd/server/RouteController.h
+++ b/system/netd/server/RouteController.h
@@ -82,6 +82,9 @@ constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK               = 29000;
 // the network, it will not work. That will potentially cause a user-visible error.
 constexpr int32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE           = 30000;
 constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK                   = 31000;
+// added by cgt ethernet and wifi coexist start
+constexpr int32_t RULE_PRIORITY_DIRECTLY_CONNECTED                = 9999;
+// added by cgt ethernet and wifi coexist end
 constexpr int32_t RULE_PRIORITY_UNREACHABLE                       = 32000;
 // clang-format on
 

三、结论

        至此wifi以太网共存分享就完成了,其实都是项目促使我们去实现这些功能,每当有新需求时不要去抗拒,而是觉得自我又要得到提升,保持学习才能成长。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驻足观雨听风吟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值