前言
朋友们,网卡功能真的是太太太太常用了,这次我又带着 10.0 的以太网静态IP功能来了,相比 9.0 而言,
framework 没啥大变化,可以直接对比移植。Settings 部分也没啥大变化,preference 对应的包由 v7
变成 androidx,这个导报的时候注意下就行。
效果图
效果图就不贴了,和 9.0 一样都是横屏,差别不大。
上代码
app层
Settins 源码和9.0无差别,完整代码资源链接
这里列下差异地方。
vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\ethernet\EthernetStaticIP.java
9.0 导包
import android.support.v7.preference.Preference; import android.preference.PreferenceActivity; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.CheckBoxPreference; import android.support.v7.preference.EditTextPreference; import android.support.v14.preference.SwitchPreference;
10.0 导包
import androidx.preference.Preference; import android.preference.PreferenceActivity; import androidx.preference.PreferenceScreen; import androidx.preference.CheckBoxPreference; import androidx.preference.EditTextPreference; import androidx.preference.SwitchPreference;
framework 层
修改文件清单
alps/frameworks/base/api/current.txt alps/frameworks/base/core/java/android/provider/Settings.java alps/frameworks/base/proto/src/metrics_constants/metrics_constants.proto alps/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java alps/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetTracker.java
几个注意点
Settings.java 新增字段编译
10.0 之前通过执行命令 make update-api,将新增字段保存到 frameworks/base/api/current.txt 文件中,
这样 java 类引用编译时不报错。10.0 编译命令修改为 make api-stubs-docs-update-current-api
不插网线设置静态IP保存后显示网卡图标bug
不知道你的版本是否也存在这样的bug,不插网线的情况下,设置完静态 ip 各项参数保存后
你惊奇发现状态栏网卡图标出来了。来看下问题日志
2020-05-29 10:07:59.537 1078-1416/system_process D/MtkConnectivityService: registerNetworkAgent NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: e8:11:ca:03:da:07, failover: false, available: true, roaming: false]} network{101} nethandle{437197393933} lp{{InterfaceName: eth0 LinkAddresses: [ 192.168.40.30/24 ] DnsAddresses: [ /8.8.8.8 ] Domains: 192.168.40.1 MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152 Routes: [ 192.168.40.0/24 -> 0.0.0.0 eth0,255.255.255.255/32 -> 0.0.0.0 eth0,0.0.0.0/0 -> 255.255.255.255 eth0 ]}} nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]} Score{0} everValidated{false} lastValidated{false} created{false} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} captivePortalValidationPending{false} partialConnectivity{false} acceptPartialConnectivity{false} clat{mBaseIface: null, mIface: null, mState: IDLE} } 2020-05-29 10:07:59.545 1078-1373/system_process D/MtkConnectivityService: NetworkAgentInfo [Ethernet () - 101] EVENT_NETWORK_INFO_CHANGED, going from initial to CONNECTED 2020-05-29 10:07:59.550 1078-1373/system_process D/MtkConnectivityService: Setting DNS servers for network 101 to [/8.8.8.8] 2020-05-29 10:07:59.555 1078-1373/system_process D/MtkConnectivityService: Adding iface eth0 to network 101 2020-05-29 10:07:59.570 1078-1373/system_process D/MtkConnectivityService: Setting DNS servers for network 101 to [/8.8.8.8] 2020-05-29 10:07:59.594 1078-1373/system_process D/MtkConnectivityService: Switching to new default network: NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: e8:11:ca:03:da:07, failover: false, available: true, roaming: false]} network{101} nethandle{437197393933} lp{{InterfaceName: eth0 LinkAddresses: [ 192.168.40.30/24 ] DnsAddresses: [ /8.8.8.8 ] Domains: 192.168.40.1 MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152 Routes: [ 192.168.40.0/24 -> 0.0.0.0 eth0,255.255.255.255/32 -> 0.0.0.0 eth0,0.0.0.0/0 -> 255.255.255.255 eth0 ]}} nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]} Score{0} everValidated{false} lastValidated{false} created{true} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} captivePortalValidationPending{false} partialConnectivity{false} acceptPartialConnectivity{false} clat{mBaseIface: null, mIface: null, mState: IDLE} } 2020-05-29 10:07:59.624 1078-1373/system_process D/MtkConnectivityService: Sending CONNECTED broadcast for type 9 NetworkAgentInfo [Ethernet () - 101] isDefaultNetwork=true
理解下大意为你保存了一个默认网络配置信息(new default network)后,发送 connected 通知出去,所以图标就显示出来了。
这是什么骚操作,一看日志tag就知道是 mkt 自己加的,搜索去看下源码
vendor\mediatek\proprietary\frameworks\opt\net\services\core\java\com\android\server\MtkConnectivityService.java
/** Adds the given network to the specified legacy type list. */ public void add(int type, NetworkAgentInfo nai) { if (!isTypeSupported(type)) { return; // Invalid network type. } if (VDBG) log("Adding agent " + nai + " for legacy network type " + type); ArrayList<NetworkAgentInfo> list = mTypeLists[type]; if (list.contains(nai)) { return; } synchronized (mTypeLists) { list.add(nai); } // Send a broadcast if this is the first network of its type or if it's the default. final boolean isDefaultNetwork = mService.isDefaultNetwork(nai); if ((list.size() == 1) || isDefaultNetwork) { maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork); mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type); } }
可以看到当网络列表集合只有一个配置,或是默认网络时,发送 CONNECTED 通知。开始我以为把这里加入网线状态判断后再发送
通知,后来尝试后发现并不行,那就转战应用层去处理这个bug吧。
解决思路
找到网卡图标显示的逻辑,当收到 CONNECTED 通知时同时判断网线是否已经插入,未插入则无效消息,不显示图标
那么问题来了,怎么知道网线是否已经插入或拨出呢。一般来讲这都需要驱动通过gpio口控制监听发送按键消息或
其它通知给上层。分析网线插入拨出相关日志,我发现在 framework 层中就能干这个活,EthernetTracker 中
就已经监听了网口状态。来看下日志
拔出 2020-05-29 09:03:55.847 1104-1131/? I/EthernetTracker: interfaceLinkStateChanged, iface: wlan0, up: false 2020-05-29 09:03:55.848 1104-1447/? E/EthernetTracker: updateInterfaceState up==false modified=false 2020-05-29 09:03:55.847 1104-1131/? I/EthernetTracker: interfaceLinkStateChanged, iface: eth0, up: false 2020-05-29 09:03:55.848 1104-1447/? E/EthernetTracker: updateInterfaceState up==false modified=false 插入 2020-05-29 09:04:55.847 1104-1131/? I/EthernetTracker: interfaceLinkStateChanged, iface: eth0, up: true 2020-05-29 09:04:55.848 1104-1447/? E/EthernetTracker: updateInterfaceState up==true modified=false
主要通过 NetworkManagementService 注册 InterfaceObserver,当网络状态改变时收到实时响应。
frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetTracker.java
private class InterfaceObserver extends BaseNetworkObserver { @Override public void interfaceLinkStateChanged(String iface, boolean up) { if (DBG) { Log.i(TAG, "interfaceLinkStateChanged, iface: " + iface + ", up: " + up); } mHandler.post(() -> updateInterfaceState(iface, up)); } @Override public void interfaceAdded(String iface) { mHandler.post(() -> maybeTrackInterface(iface)); } @Override public void interfaceRemoved(String iface) { mHandler.post(() -> removeInterface(iface)); } } private void updateInterfaceState(String iface, boolean up) { boolean modified = mFactory.updateInterfaceLinkState(iface, up); Log.e(TAG, "updateInterfaceState up==" + up + " modified="+modified); //cczheng add sys.ethernet.up for listen netline in or out if ("eth0".equals(iface)) { android.os.SystemProperties.set("sys.ethernet.up", String.valueOf(up)); }//E if (modified) { boolean restricted = isRestrictedInterface(iface); int n = mListeners.beginBroadcast(); for (int i = 0; i < n; i++) { try { if (restricted) { ListenerInfo listenerInfo = (ListenerInfo) mListeners.getBroadcastCookie(i); if (!listenerInfo.canUseRestrictedNetworks) { continue; } } mListeners.getBroadcastItem(i).onAvailabilityChanged(iface, up); } catch (RemoteException e) { // Do nothing here. } } mListeners.finishBroadcast(); } }
可以看到我在 updateInterfaceState() 中增加了 prop 保存网线插拔状态,为啥选用 prop 保存呢?因为网卡图标显示在
SystemUI 中,算是跨应用通讯吧,prop 简单方便,就不用 Settings.System/Global 之类的了。接下来修改 SystemUI
网卡图标显示监听在 EthernetSignalController 中
vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\policy\EthernetSignalController.java
@Override public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { mCurrentState.connected = connectedTransports.get(mTransportType); super.updateConnectivity(connectedTransports, validatedTransports); } @Override public void notifyListeners(SignalCallback callback) { boolean ethernetVisible = mCurrentState.connected; String contentDescription = getStringIfExists(getContentDescription()); cczheng add visible for fix ethernet staticip set don't inset netline show bug android.util.Log.e("MtkConnectivityService", " systemui ethernetVisible="+ethernetVisible + " contentDescription="+contentDescription); boolean netLineIn = android.os.SystemProperties.getBoolean("sys.ethernet.up", false); android.util.Log.e("MtkConnectivityService", " systemui EthernetSignalController netline state ="+netLineIn); if (ethernetVisible){ ethernetVisible = netLineIn; android.util.Log.e("MtkConnectivityService", "new ethernetVisible="+ethernetVisible); }//E // TODO: wire up data transfer using WifiSignalPoller. callback.setEthernetIndicators(new IconState(ethernetVisible, getCurrentIconId(), contentDescription)); } 网线未插入情况,点击设置静态ip收到的日志 2020-05-30 09:19:29.089 1456-1676/com.android.systemui E/MtkConnectivityService: systemui ethernetVisible=true contentDescription=以太网已断开连接。 2020-05-30 09:19:29.089 1456-1676/com.android.systemui E/MtkConnectivityService: systemui EthernetSignalController netline state =false 网线插入,点击设置静态ip收到的日志 2020-05-30 09:19:29.089 1456-1676/com.android.systemui E/MtkConnectivityService: systemui ethernetVisible=true contentDescription=以太网已断开连接。 2020-05-30 09:19:29.089 1456-1676/com.android.systemui E/MtkConnectivityService: systemui EthernetSignalController netline state =true
可以看到我们需要过滤网线未插入收到的无效消息,读取网线状态 sys.ethernet.up 布尔值,当 ethernetVisible 为 true 时,校验状态
这样改完后测试发现还有坑,坑在真正 setIconVisibility 地方,也就是 StatusBarSignalPolicy
vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarSignalPolicy.java
@Override public void setEthernetIndicators(IconState state) { boolean visible = state.visible && !mBlockEthernet; int resId = state.icon; String description = state.contentDescription; //cczheng add visible for fix ethernet staticip set don't inset netline show bug if (visible && resId > 0) { //if (resId > 0) { mIconController.setIcon(mSlotEthernet, resId, description); mIconController.setIconVisibility(mSlotEthernet, true); } else { mIconController.setIconVisibility(mSlotEthernet, false); } }
发现了吗,传递进来的 visible 根本就没用上,这是什么大坑啊,将 visible 作为判断依据即可。
好了,这样 bug 就解决了,收工。
20200720 增加更新
网络优先级设置
网卡 > wifi > 4G
frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetNetworkFactory.java
public class EthernetNetworkFactory extends NetworkFactory { private final static String TAG = EthernetNetworkFactory.class.getSimpleName(); final static boolean DBG = true; private final static int NETWORK_SCORE = 110; private static final String NETWORK_TYPE = "Ethernet"; .... private static final SparseArray<TransportInfo> sTransports = new SparseArray(); static { // LowpanInterfaceTracker.NETWORK_SCORE sTransports.put(NetworkCapabilities.TRANSPORT_LOWPAN, new TransportInfo(ConnectivityManager.TYPE_NONE, 30)); // WifiAwareDataPathStateManager.NETWORK_FACTORY_SCORE_AVAIL sTransports.put(NetworkCapabilities.TRANSPORT_WIFI_AWARE, new TransportInfo(ConnectivityManager.TYPE_NONE, 1)); // EthernetNetworkFactory.NETWORK_SCORE sTransports.put(NetworkCapabilities.TRANSPORT_ETHERNET, new TransportInfo(ConnectivityManager.TYPE_ETHERNET, NETWORK_SCORE));//70 // BluetoothTetheringNetworkFactory.NETWORK_SCORE sTransports.put(NetworkCapabilities.TRANSPORT_BLUETOOTH, new TransportInfo(ConnectivityManager.TYPE_BLUETOOTH, 69)); // WifiNetworkFactory.SCORE_FILTER / NetworkAgent.WIFI_BASE_SCORE sTransports.put(NetworkCapabilities.TRANSPORT_WIFI, new TransportInfo(ConnectivityManager.TYPE_WIFI, 60)); // TelephonyNetworkFactory.TELEPHONY_NETWORK_SCORE sTransports.put(NetworkCapabilities.TRANSPORT_CELLULAR, new TransportInfo(ConnectivityManager.TYPE_MOBILE, 50)); }
TRANSPORT_LOWPAN 低速无限个域网 比分 30
TRANSPORT_WIFI_AWARE wifi相邻设备发现 比分 1
TRANSPORT_ETHERNET 网卡 比分 70
TRANSPORT_BLUETOOTH 蓝牙 比分 69
TRANSPORT_WIFI wifi 比分 60
TRANSPORT_CELLULAR 移动网络 比分 50
按照以往经验只修改 NETWORK_SCORE 值从 70 改成 110 是不行的,有隐藏的坑。
还需要修改 ConnectivityManager.TYPE_ETHERNET 对应赋值为 NETWORK_SCORE
因为获取 getNetworkScore() 方法如下
private int getNetworkScore() { // never set the network score below 0. if (!mLinkUp) { Log.e(TAG, " getNetworkScore mLinkUp false"); return 0; } int[] transportTypes = mCapabilities.getTransportTypes(); if (transportTypes.length < 1) { Log.w(TAG, "Network interface '" + mLinkProperties.getInterfaceName() + "' has no " + "transport type associated with it. Score set to zero"); return 0; } TransportInfo transportInfo = sTransports.get(transportTypes[0], /* if dne */ null); if (transportInfo != null) { Log.e(TAG, " getNetworkScore transportInfo.mScore="+transportInfo.mScore); return transportInfo.mScore; } return 0; }
如果只修改 NETWORK_SCORE=110,你会神奇的发现,当网卡接入局域网时,不能上外网时,打开SIM卡流量开关,
网卡图标消失了,而且网络自动切换到移动网络了。感觉很人性化有没有,可是我并不想要帮我自动切换到移动网络啊。
来看问题日志
局域网转移动网络 2020-07-20 11:38:37.933 1101-1742/system_process D/MtkConnectivityService: currentScore = 30, newScore = 50 2020-07-20 11:38:37.933 1101-1742/system_process D/MtkConnectivityService: rematch for NetworkAgentInfo [MOBILE (LTE) - 104] 2020-07-20 11:38:37.933 1101-1742/system_process D/MtkConnectivityService: accepting network in place of null 2020-07-20 11:38:37.934 1101-1742/system_process D/MtkConnectivityService: sending new Min Network Score(50): NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN] ] 2020-07-20 11:38:37.945 1101-1742/system_process D/MtkConnectivityService: Switching to new default network: NetworkAgentInfo{ ni{[type: MOBILE[LTE], state: CONNECTED/CONNECTED, reason: connected, extra: ctnet, failover: false, available: true, roaming: false]} network{104} nethandle{450082295821} lp{{InterfaceName: ccmni1 LinkAddresses: [ 10.53.196.22/32,240e:ba:c806:8619::1/64 ] DnsAddresses: [ /240e:4e::66,/240e:4e:800::66,/219.146.1.66,/219.147.1.66 ] Domains: null MTU: 1460 TcpBufferSizes: 2097152,4194304,8388608,262144,524288,1048576 Routes: [ 0.0.0.0/0 -> 10.53.196.22 ccmni1,::/0 -> :: ccmni1,10.53.196.22/32 -> 0.0.0.0 ccmni1,240e:ba:c806:8619::/64 -> :: ccmni1 ]}} nc{[ Transports: CELLULAR Capabilities: XCAP&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=51200Kbps LinkDnBandwidth>=102400Kbps Specifier: <1>]} Score{50} everValidated{true} lastValidated{true} created{true} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} captivePortalValidationPending{false} partialConnectivity{false} acceptPartialConnectivity{false} clat{mBaseIface: null, mIface: null, mState: IDLE} } 开机默认局域网情况 2020-07-20 17:13:46.916 1101-1742/system_process D/MtkConnectivityService: currentScore = 0, newScore = 30 2020-07-20 17:13:46.916 1101-1742/system_process D/MtkConnectivityService: rematch for NetworkAgentInfo [Ethernet - 106] 2020-07-20 17:13:46.916 1087-1380/system_process D/MtkConnectivityService: Switching to new default network: NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: e8:11:ca:03:53:98, failover: false, available: true, roaming: false]} network{100} nethandle{432902426637} lp{{InterfaceName: eth0 LinkAddresses: [ fe80::3c1a:67e3:a3cb:4b59/64,192.168.1.114/24 ] DnsAddresses: [ /8.8.8.8,/192.168.1.1 ] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152 Routes: [ fe80::/64 -> :: eth0,192.168.1.0/24 -> 0.0.0.0 eth0,0.0.0.0/0 -> 192.168.1.1 eth0 ]}} nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]} Score{30} everValidated{false} lastValidated{false} created{true} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} captivePortalValidationPending{false} partialConnectivity{false} acceptPartialConnectivity{false} clat{mBaseIface: null, mIface: null, mState: IDLE} }
搜索 Switching to new default 关键字,找到 MtkConnectivityService.java 好吧又是这货
vendor\mediatek\proprietary\frameworks\opt\net\services\core\java\com\android\server\MtkConnectivityService.java
private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) { if (!newNetwork.everConnected) return; boolean keep = newNetwork.isVPN(); boolean isNewDefault = false; NetworkAgentInfo oldDefaultNetwork = null; final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork(); final int score = newNetwork.getCurrentScore(); ..... if (VDBG || DDBG) { log("currentScore = " + (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + ", newScore = " + score); }
看到上面打印 newScore 值来自 newNetwork.getCurrentScore() 方法,搜索找到 NetworkAgentInfo.java 中
frameworks\base\services\core\java\com\android\server\connectivity\NetworkAgentInfo.java
private int getCurrentScore(boolean pretendValidated) { // TODO: We may want to refactor this into a NetworkScore class that takes a base score from // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the // score. The NetworkScore class would provide a nice place to centralize score constants // so they are not scattered about the transports. // If this network is explicitly selected and the user has decided to use it even if it's // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly // selected and we're trying to see what its score could be. This ensures that we don't tear // down an explicitly selected network before the user gets a chance to prefer it when // a higher-scoring network (e.g., Ethernet) is available. if (networkMisc.explicitlySelected && (networkMisc.acceptUnvalidated || pretendValidated)) { return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE; } int score = currentScore; if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) { score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY; } if (score < 0) score = 0; return score; }
一直好奇上面的网卡 30 分是怎么来的?看到这里就明白了,我们修改的 NETWORK_SCORE=110 并没有用,实际取得是 sTransports 中
70,然后在 getCurrentScore() 中由于网络不是有效的能上网网络,则需要减去 UNVALIDATED_SCORE_PENALTY 40
30 = sTransports.TRANSPORT_ETHERNET - UNVALIDATED_SCORE_PENALTY
frameworks\base\services\core\java\com\android\server\connectivity\ConnectivityConstants.java
public class ConnectivityConstants { // Penalty applied to scores of Networks that have not been validated. public static final int UNVALIDATED_SCORE_PENALTY = 40; // Score for explicitly connected network. // // This ensures that a) the explicitly selected network is never trumped by anything else, and // b) the explicitly selected network is never torn down. public static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100; // VPNs typically have priority over other networks. Give them a score that will // let them win every single time. public static final int VPN_DEFAULT_SCORE = 101; }
这样问题就搞清楚了。还有坑在 wifi 和 局域网同时连接,wifi 图标依旧显示,修改如下地方即可
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -89,8 +89,12 @@ public class WifiSignalController extends // only show wifi in the cluster if connected or if wifi-only boolean visibleWhenEnabled = mContext.getResources().getBoolean( R.bool.config_showWifiIndicatorWhenEnabled); Log.v(TAG,"mCurrentState.inetCondition = " + mCurrentState.inetCondition); boolean wifiVisible = mCurrentState.enabled && (mCurrentState.connected || !mHasMobileData || visibleWhenEnabled) && (mCurrentState.inetCondition == 1); //cczheng add mCurrentState.inetCondition == 1 for fix eth icon and wifi icon same show String wifiDesc = wifiVisible ? mCurrentState.ssid : null; boolean ssidPresent = wifiVisible && mCurrentState.ssid != null; String contentDescription = getStringIfExists(getContentDescription());