写在前面
本次目的
详细步骤
device的修改
device\qcom\common\rootdir\etc\init.qcom.rc
device/qcom/msm8909/msm8909.mk
device/qcom/common/device/overlay/frameworks/base/core/res/res/values/config.xml
frameworks的修改
frameworks/base/core/java/android/net/EthernetManager.java
frameworks\base\core\java\android\net\IEthernetManager.aidl
frameworks\base\core\java\android\provider\Settings.java.
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java
frameworks/base/core/res/res/values/config.xml
frameworks/base/core/java/android/content/Intent.java
frameworks/base/core/res/res/values/symbols.xml
frameworks/base/packages/SystemUI/res/drawable/ethernet_connected.png
frameworks/base/packages/SystemUI/res/drawable/ethernet_connecting.png
frameworks/base/packages/SystemUI/res/drawable/ethernet_disconnected.png
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
packages的修改
packages/apps/Settings/AndroidManifest.xml
packages/apps/Settings/res/layout/eth_configure.xml
packages/apps/Settings/res/values/strings.xml
packages/apps/Settings/res/xml/ethernet_settings.xml
packages/apps/Settings/src/com/android/settings/Settings.java
packages/apps/Settings/src/com/android/settings/SettingsActivity.java
packages/apps/Settings/src/com/android/settings/ethernet/EthernetDialog.java
packages/apps/Settings/src/com/android/settings/ethernet/EthernetEnabler.java
packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java
packages/apps/Settings/res/drawable-hdpi/ic_settings_dock_alpha.png
packages/apps/Settings/res/drawable/ic_settings_dock.xml
重新编译
本次小结
SOC:Qualcomm msm8909
Core-Board:SC20-CE QA/PJ
Base-Board:xxx
Linux Kernel:xxx
Android:7.1
为安卓系统增加以太网功能,能够在系统设置菜单中找到以太网选项,完成以太网功能设置,并且在系统状态栏能够提示以太网网络状态。
如果您需要了解如何添加和调试相关驱动,比如这里用的RTL8152(USB转以太网芯片),可以参考我的这篇博客:
https://blog.csdn.net/uestc_ganlin/article/details/90692753
添加以下内容:
service dhcpcd_eth0 /system/bin/dhcpcd -ABDKL
class main
disabled
oneshot
service iprenew_eth0 /system/bin/dhcpcd -n
class late_start
disabled
oneshot
在“PRODUCT_COPY_FILES”中加入以下内容,注意上一个值的后面不要漏掉结束“\”:
frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml
修改完成后像这样:
# Feature definition files for msm8953
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:system/etc/permissions/android.hardware.sensor.accelerometer.xml \
frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \
frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \
frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \
frameworks/native/data/etc/android.hardware.sensor.proximity.xml:system/etc/permissions/android.hardware.sensor.proximity.xml \
frameworks/native/data/etc/android.hardware.sensor.barometer.xml:system/etc/permissions/android.hardware.sensor.barometer.xml \
frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:system/etc/permissions/android.hardware.sensor.stepcounter.xml \
frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:system/etc/permissions/android.hardware.sensor.stepdetector.xml \
frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml
加入以下内容:
ethernet
修改完后像这样:
managed_profile
ime
sync_failing
sync_active
cast
hotspot
location
bluetooth
nfc
femtoicon
tty
speakerphone
zen
mute
volume
wifi
ethernet
cdma_eri
data_connection
phone_evdo_signal
phone_signal
battery
alarm_clock
secure
clock
添加以下内容:
public static final int ETH_STATE_UNKNOWN = 0; //law
public static final int ETH_STATE_DISABLED = 1;
public static final int ETH_STATE_ENABLED = 2;
public void start() {
try {
mService.Trackstart();
} catch (NullPointerException | RemoteException e) {
}
}
public void stop() {
try {
mService.Trackstop();
} catch (NullPointerException | RemoteException e) {
}
}
添加以下内容:
void Trackstart();//add by law
void Trackstop();
添加以下内容:
/**
* law add
* {@hide}
*/
public static final String ETHERNET_ON = "ethernet_on";//add by law
添加以下依赖内容:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
在此类中增加Handler属性:
private Handler mHandler;
增加一个状态标志并创建一个广播接收:
private boolean isStatusBarReady= false;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "klein----BroadcastReceiver--action = " + action);
if (action.equals(Intent.ACTION_ETHERNET_STATUSBAR_READY)) {
isStatusBarReady = true;
Log.d(TAG,"statusbar is ready, update current status");
if (mLinkUp){
Log.d(TAG,"updateAgent connected");
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_ETHERNET_CONNECTED);
mContext.sendBroadcast(intent1);
}else{
Log.d(TAG,"updateAgent disconnected");
Intent intent2 = new Intent();
intent2.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
mContext.sendBroadcast(intent2);
}
}
}
};
在“updateInterfaceState”方法中加入更新状态的逻辑:
if (up){
Log.d(TAG,"updateAgent connected");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_CONNECTED);
mContext.sendBroadcast(intent);
}else{
Log.d(TAG,"updateAgent disconnected");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
mContext.sendBroadcast(intent);
}
在“onRequestNetwork”方法中 “ ipProvisioningThread”线程初始化时加入判断:
//if error then stop and restart add by law
if((mContext != null) && (mHandler != null)) {
Log.d(TAG, "Setting static ip failed now restart");
stop();
start(mContext,mHandler);
}
在“start”方法中加入以下内容:
mHandler = target;//add by law
if(!iface.equals("eth0"))//add by hclydao make sure the interface is eth0
continue;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
mContext.registerReceiver(mIntentReceiver, filter);
Log.d(TAG, "klein----EthernetNetworkFactory start");
完整的文件内容如下:
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.ethernet;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpResults;
import android.net.EthernetManager;
import android.net.IEthernetServiceListener;
import android.net.InterfaceConfiguration;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.StaticIpConfiguration;
import android.net.ip.IpManager;
import android.net.ip.IpManager.ProvisioningConfiguration;
import android.net.ip.IpManager.WaitForProvisioningCallback;
import android.os.Handler;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.net.BaseNetworkObserver;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
/**
* Manages connectivity for an Ethernet interface.
*
* Ethernet Interfaces may be present at boot time or appear after boot (e.g.,
* for Ethernet adapters connected over USB). This class currently supports
* only one interface. When an interface appears on the system (or is present
* at boot time) this class will start tracking it and bring it up, and will
* attempt to connect when requested. Any other interfaces that subsequently
* appear will be ignored until the tracked interface disappears. Only
* interfaces whose names match the config_ethernet_iface_regex
* regular expression are tracked.
*
* This class reports a static network score of 70 when it is tracking an
* interface and that interface's link is up, and a score of 0 otherwise.
*
* @hide
*/
class EthernetNetworkFactory {
private static final String NETWORK_TYPE = "Ethernet";
private static final String TAG = "EthernetNetworkFactory";
private static final int NETWORK_SCORE = 70;
private static final boolean DBG = true;
private Handler mHandler;
/** Tracks interface changes. Called from NetworkManagementService. */
private InterfaceObserver mInterfaceObserver;
/** For static IP configuration */
private EthernetManager mEthernetManager;
/** To set link state and configure IP addresses. */
private INetworkManagementService mNMService;
/* To communicate with ConnectivityManager */
private NetworkCapabilities mNetworkCapabilities;
private NetworkAgent mNetworkAgent;
private LocalNetworkFactory mFactory;
private Context mContext;
/** Product-dependent regular expression of interface names we track. */
private static String mIfaceMatch = "";
/** To notify Ethernet status. */
private final RemoteCallbackList mListeners;
/** Data members. All accesses to these must be synchronized(this). */
private static String mIface = "";
private String mHwAddr;
private static boolean mLinkUp;
private NetworkInfo mNetworkInfo;
private LinkProperties mLinkProperties;
private IpManager mIpManager;
private Thread mIpProvisioningThread;
private boolean isStatusBarReady= false;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "klein----BroadcastReceiver--action = " + action);
if (action.equals(Intent.ACTION_ETHERNET_STATUSBAR_READY)) {
isStatusBarReady = true;
Log.d(TAG,"statusbar is ready, update current status");
if (mLinkUp){
Log.d(TAG,"updateAgent connected");
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_ETHERNET_CONNECTED);
mContext.sendBroadcast(intent1);
}else{
Log.d(TAG,"updateAgent disconnected");
Intent intent2 = new Intent();
intent2.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
mContext.sendBroadcast(intent2);
}
}
}
};
EthernetNetworkFactory(RemoteCallbackList listeners) {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
mLinkProperties = new LinkProperties();
initNetworkCapabilities();
mListeners = listeners;
}
private class LocalNetworkFactory extends NetworkFactory {
LocalNetworkFactory(String name, Context context, Looper looper) {
super(looper, context, name, new NetworkCapabilities());
}
protected void startNetwork() {
onRequestNetwork();
}
protected void stopNetwork() {
}
}
private void stopIpManagerLocked() {
if (mIpManager != null) {
mIpManager.shutdown();
mIpManager = null;
}
}
private void stopIpProvisioningThreadLocked() {
stopIpManagerLocked();
if (mIpProvisioningThread != null) {
mIpProvisioningThread.interrupt();
mIpProvisioningThread = null;
}
}
/**
* Updates interface state variables.
* Called on link state changes or on startup.
*/
private void updateInterfaceState(String iface, boolean up) {
if (!mIface.equals(iface)) {
return;
}
Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));
if (up){
Log.d(TAG,"updateAgent connected");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_CONNECTED);
mContext.sendBroadcast(intent);
}else{
Log.d(TAG,"updateAgent disconnected");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
mContext.sendBroadcast(intent);
}
synchronized(this) {
mLinkUp = up;
mNetworkInfo.setIsAvailable(up);
if (!up) {
// Tell the agent we're disconnected. It will call disconnect().
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
stopIpProvisioningThreadLocked();
}
updateAgent();
// set our score lower than any network could go
// so we get dropped. TODO - just unregister the factory
// when link goes down.
mFactory.setScoreFilter(up ? NETWORK_SCORE : -1);
}
}
private class InterfaceObserver extends BaseNetworkObserver {
@Override
public void interfaceLinkStateChanged(String iface, boolean up) {
updateInterfaceState(iface, up);
}
@Override
public void interfaceAdded(String iface) {
maybeTrackInterface(iface);
}
@Override
public void interfaceRemoved(String iface) {
stopTrackingInterface(iface);
}
}
private void setInterfaceUp(String iface) {
// Bring up the interface so we get link status indications.
try {
mNMService.setInterfaceUp(iface);
String hwAddr = null;
InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
if (config == null) {
Log.e(TAG, "Null iterface config for " + iface + ". Bailing out.");
return;
}
synchronized (this) {
if (!isTrackingInterface()) {
setInterfaceInfoLocked(iface, config.getHardwareAddress());
mNetworkInfo.setIsAvailable(true);
mNetworkInfo.setExtraInfo(mHwAddr);
} else {
Log.e(TAG, "Interface unexpectedly changed from " + iface + " to " + mIface);
mNMService.setInterfaceDown(iface);
}
}
} catch (RemoteException e) {
Log.e(TAG, "Error upping interface " + mIface + ": " + e);
}
}
private boolean maybeTrackInterface(String iface) {
// If we don't already have an interface, and if this interface matches
// our regex, start tracking it.
if (!iface.matches(mIfaceMatch) || isTrackingInterface())
return false;
Log.d(TAG, "Started tracking interface " + iface);
setInterfaceUp(iface);
return true;
}
private void stopTrackingInterface(String iface) {
if (!iface.equals(mIface))
return;
Log.d(TAG, "Stopped tracking interface " + iface);
// TODO: Unify this codepath with stop().
synchronized (this) {
stopIpProvisioningThreadLocked();
setInterfaceInfoLocked("", null);
mNetworkInfo.setExtraInfo(null);
mLinkUp = false;
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
updateAgent();
mNetworkAgent = null;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
mLinkProperties = new LinkProperties();
}
}
private boolean setStaticIpAddress(StaticIpConfiguration staticConfig) {
if (staticConfig.ipAddress != null &&
staticConfig.gateway != null &&
staticConfig.dnsServers.size() > 0) {
try {
Log.i(TAG, "Applying static IPv4 configuration to " + mIface + ": " + staticConfig);
InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface);
config.setLinkAddress(staticConfig.ipAddress);
mNMService.setInterfaceConfig(mIface, config);
return true;
} catch(RemoteException|IllegalStateException e) {
Log.e(TAG, "Setting static IP address failed: " + e.getMessage());
}
} else {
Log.e(TAG, "Invalid static IP configuration.");
}
return false;
}
public void updateAgent() {
synchronized (EthernetNetworkFactory.this) {
if (mNetworkAgent == null) return;
if (DBG) {
Log.i(TAG, "Updating mNetworkAgent with: " +
mNetworkCapabilities + ", " +
mNetworkInfo + ", " +
mLinkProperties);
}
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
mNetworkAgent.sendLinkProperties(mLinkProperties);
// never set the network score below 0.
mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
}
}
/* Called by the NetworkFactory on the handler thread. */
public void onRequestNetwork() {
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread != null) {
return;
}
}
final Thread ipProvisioningThread = new Thread(new Runnable() {
public void run() {
if (DBG) {
Log.d(TAG, String.format("starting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
LinkProperties linkProperties;
IpConfiguration config = mEthernetManager.getConfiguration();
if (config.getIpAssignment() == IpAssignment.STATIC) {
if (!setStaticIpAddress(config.getStaticIpConfiguration())) {
//if error then stop and restart add by law
if((mContext != null) && (mHandler != null)) {
Log.d(TAG, "Setting static ip failed now restart");
stop();
start(mContext,mHandler);
}
// We've already logged an error.
return;
}
linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
} else {
mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
WaitForProvisioningCallback ipmCallback = new WaitForProvisioningCallback() {
@Override
public void onLinkPropertiesChange(LinkProperties newLp) {
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null && mNetworkInfo.isConnected()) {
mLinkProperties = newLp;
mNetworkAgent.sendLinkProperties(newLp);
}
}
}
};
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
mIpManager = new IpManager(mContext, mIface, ipmCallback);
if (config.getProxySettings() == ProxySettings.STATIC ||
config.getProxySettings() == ProxySettings.PAC) {
mIpManager.setHttpProxy(config.getHttpProxy());
}
final String tcpBufferSizes = mContext.getResources().getString(
com.android.internal.R.string.config_ethernet_tcp_buffers);
if (!TextUtils.isEmpty(tcpBufferSizes)) {
mIpManager.setTcpBufferSizes(tcpBufferSizes);
}
final ProvisioningConfiguration provisioningConfiguration =
mIpManager.buildProvisioningConfiguration()
.withProvisioningTimeoutMs(0)
.build();
mIpManager.startProvisioning(provisioningConfiguration);
}
linkProperties = ipmCallback.waitForProvisioning();
if (linkProperties == null) {
Log.e(TAG, "IP provisioning error");
// set our score lower than any network could go
// so we get dropped.
mFactory.setScoreFilter(-1);
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
}
return;
}
}
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null) {
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
stopIpManagerLocked();
mIpProvisioningThread = null;
return;
}
mLinkProperties = linkProperties;
mNetworkInfo.setIsAvailable(true);
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
// Create our NetworkAgent.
mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
NETWORK_SCORE) {
public void unwanted() {
synchronized(EthernetNetworkFactory.this) {
if (this == mNetworkAgent) {
stopIpManagerLocked();
mLinkProperties.clear();
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
mHwAddr);
updateAgent();
mNetworkAgent = null;
try {
mNMService.clearInterfaceAddresses(mIface);
} catch (Exception e) {
Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
} else {
Log.d(TAG, "Ignoring unwanted as we have a more modern " +
"instance");
}
}
};
};
mIpProvisioningThread = null;
}
if (DBG) {
Log.d(TAG, String.format("exiting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
}
});
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread == null) {
mIpProvisioningThread = ipProvisioningThread;
mIpProvisioningThread.start();
}
}
}
/**
* Begin monitoring connectivity
*/
public synchronized void start(Context context, Handler target) {
// The services we use.
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
// Interface match regex.
mIfaceMatch = context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
// Create and register our NetworkFactory.
mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());
mFactory.setCapabilityFilter(mNetworkCapabilities);
mFactory.setScoreFilter(-1); // this set high when we have an iface
mFactory.register();
mContext = context;
mHandler = target;//add by law
// Start tracking interface change events.
mInterfaceObserver = new InterfaceObserver();
try {
mNMService.registerObserver(mInterfaceObserver);
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
// If an Ethernet interface is already connected, start tracking that.
// Otherwise, the first Ethernet interface to appear will be tracked.
try {
final String[] ifaces = mNMService.listInterfaces();
for (String iface : ifaces) {
synchronized(this) {
if (maybeTrackInterface(iface)) {
// We have our interface. Track it.
// Note: if the interface already has link (e.g., if we
// crashed and got restarted while it was running),
// we need to fake a link up notification so we start
// configuring it. Since we're already holding the lock,
// any real link up/down notification will only arrive
// after we've done this.
if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
if(!iface.equals("eth0"))//add by hclydao make sure the interface is eth0
continue;
updateInterfaceState(iface, true);
}
break;
}
}
}
} catch (RemoteException|IllegalStateException e) {
Log.e(TAG, "Could not get list of interfaces " + e);
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
mContext.registerReceiver(mIntentReceiver, filter);
Log.d(TAG, "klein----EthernetNetworkFactory start");
}
public synchronized void stop() {
stopIpProvisioningThreadLocked();
// ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object
// with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here:
// that sets the state to IDLE, and ConnectivityService will still think we're connected.
//
// TODO: stop using explicit comparisons to DISCONNECTED / SUSPENDED in ConnectivityService,
// and instead use isConnectedOrConnecting().
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
mLinkUp = false;
updateAgent();
mLinkProperties = new LinkProperties();
mNetworkAgent = null;
setInterfaceInfoLocked("", null);
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
mFactory.unregister();
}
private void initNetworkCapabilities() {
mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
// We have no useful data on bandwidth. Say 100M up and 100M down. :-(
mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100 * 1000);
mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100 * 1000);
}
public synchronized boolean isTrackingInterface() {
return !TextUtils.isEmpty(mIface);
}
/**
* Set interface information and notify listeners if availability is changed.
* This should be called with the lock held.
*/
private void setInterfaceInfoLocked(String iface, String hwAddr) {
boolean oldAvailable = isTrackingInterface();
mIface = iface;
mHwAddr = hwAddr;
boolean available = isTrackingInterface();
if (oldAvailable != available) {
int n = mListeners.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
mListeners.getBroadcastItem(i).onAvailabilityChanged(available);
} catch (RemoteException e) {
// Do nothing here.
}
}
mListeners.finishBroadcast();
}
}
synchronized void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
if (isTrackingInterface()) {
pw.println("Tracking interface: " + mIface);
pw.increaseIndent();
pw.println("MAC address: " + mHwAddr);
pw.println("Link state: " + (mLinkUp ? "up" : "down"));
pw.decreaseIndent();
} else {
pw.println("Not tracking any interface");
}
pw.println();
pw.println("NetworkInfo: " + mNetworkInfo);
pw.println("LinkProperties: " + mLinkProperties);
pw.println("NetworkAgent: " + mNetworkAgent);
if (mIpManager != null) {
pw.println("IpManager:");
pw.increaseIndent();
mIpManager.dump(fd, pw, args);
pw.decreaseIndent();
}
}
}
添加以下内容:
import android.net.EthernetManager;
import android.os.Looper;
import android.provider.Settings;
int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
if(enable != EthernetManager.ETH_STATE_ENABLED) {
Log.i(TAG, "Ethernet is not enable");
return;
}
//law
class TstartThread extends Thread {
public void run() {
Looper.prepare();
mTracker.start(mContext, mHandler);
mStarted.set(true);
Looper.loop();
}
}
public void Trackstart() { //add by hclydao
new TstartThread().start();
}
public void Trackstop() {
Log.i(TAG, "Stop Ethernet service");
Thread tstopthread = new Thread(new Runnable() {
public void run() {
Looper.prepare();
mTracker.stop();
mStarted.set(false);
Looper.loop();
}
});
tstopthread.start();
}
完整内容如下:
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.ethernet;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.IEthernetManager;
import android.net.IEthernetServiceListener;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.provider.Settings;
import android.net.EthernetManager;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.os.Looper;
import android.provider.Settings;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* EthernetServiceImpl handles remote Ethernet operation requests by implementing
* the IEthernetManager interface.
*
* @hide
*/
public class EthernetServiceImpl extends IEthernetManager.Stub {
private static final String TAG = "EthernetServiceImpl";
private final Context mContext;
private final EthernetConfigStore mEthernetConfigStore;
private final AtomicBoolean mStarted = new AtomicBoolean(false);
private IpConfiguration mIpConfiguration;
private Handler mHandler;
private final EthernetNetworkFactory mTracker;
private final RemoteCallbackList mListeners =
new RemoteCallbackList();
public EthernetServiceImpl(Context context) {
mContext = context;
Log.i(TAG, "Creating EthernetConfigStore");
mEthernetConfigStore = new EthernetConfigStore();
mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();
Log.i(TAG, "Read stored IP configuration: " + mIpConfiguration);
mTracker = new EthernetNetworkFactory(mListeners);
}
private void enforceAccessPermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE,
"EthernetService");
}
private void enforceConnectivityInternalPermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CONNECTIVITY_INTERNAL,
"ConnectivityService");
}
public void start() {
Log.i(TAG, "Starting Ethernet service");
HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
if(enable != EthernetManager.ETH_STATE_ENABLED) {
Log.i(TAG, "Ethernet is not enable");
return;
}
mTracker.start(mContext, mHandler);
mStarted.set(true);
}
//law
class TstartThread extends Thread {
public void run() {
Looper.prepare();
mTracker.start(mContext, mHandler);
mStarted.set(true);
Looper.loop();
}
}
public void Trackstart() { //add by hclydao
new TstartThread().start();
}
public void Trackstop() {
Log.i(TAG, "Stop Ethernet service");
Thread tstopthread = new Thread(new Runnable() {
public void run() {
Looper.prepare();
mTracker.stop();
mStarted.set(false);
Looper.loop();
}
});
tstopthread.start();
}
/**
* Get Ethernet configuration
* @return the Ethernet Configuration, contained in {@link IpConfiguration}.
*/
@Override
public IpConfiguration getConfiguration() {
enforceAccessPermission();
synchronized (mIpConfiguration) {
return new IpConfiguration(mIpConfiguration);
}
}
/**
* Set Ethernet configuration
*/
@Override
public void setConfiguration(IpConfiguration config) {
if (!mStarted.get()) {
Log.w(TAG, "System isn't ready enough to change ethernet configuration");
}
enforceConnectivityInternalPermission();
synchronized (mIpConfiguration) {
mEthernetConfigStore.writeIpAndProxyConfigurations(config);
// TODO: this does not check proxy settings, gateways, etc.
// Fix this by making IpConfiguration a complete representation of static configuration.
if (!config.equals(mIpConfiguration)) {
mIpConfiguration = new IpConfiguration(config);
mTracker.stop();
mTracker.start(mContext, mHandler);
}
}
}
/**
* Indicates whether the system currently has one or more
* Ethernet interfaces.
*/
@Override
public boolean isAvailable() {
enforceAccessPermission();
return mTracker.isTrackingInterface();
}
/**
* Addes a listener.
* @param listener A {@link IEthernetServiceListener} to add.
*/
public void addListener(IEthernetServiceListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
enforceAccessPermission();
mListeners.register(listener);
}
/**
* Removes a listener.
* @param listener A {@link IEthernetServiceListener} to remove.
*/
public void removeListener(IEthernetServiceListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
enforceAccessPermission();
mListeners.unregister(listener);
}
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump EthernetService from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
return;
}
pw.println("Current Ethernet state: ");
pw.increaseIndent();
mTracker.dump(fd, pw, args);
pw.decreaseIndent();
pw.println();
pw.println("Stored Ethernet configuration: ");
pw.increaseIndent();
pw.println(mIpConfiguration);
pw.decreaseIndent();
pw.println("Handler:");
pw.increaseIndent();
mHandler.dump(new PrintWriterPrinter(pw), "EthernetServiceImpl");
pw.decreaseIndent();
}
}
添加以下内容:
@string/status_bar_ethernet
ethernet
加入以下内容:
/** @hide */
public static final String ACTION_ETHERNET_ON = "android.intent.action.ETHERNET_ON";
/** @hide */
public static final String ACTION_ETHERNET_CONNECTED = "android.intent.action.ETHERNET_CONNECTED";
/** @hide */
public static final String ACTION_ETHERNET_DISCONNECTED = "android.intent.action.ETHERNET_DISCONNECTED";
/** @hide */
public static final String ACTION_ETHERNET_OFF = "android.intent.action.ETHERNET_OFF";
/** @hide */
public static final String ACTION_ETHERNET_STATUSBAR_READY = "android.intent.action.ETHERNET_STATUSBAR_READY";
加入以下内容:
添加以下内容:
import android.provider.Settings;
import android.net.EthernetManager;
private static final boolean DEBUG = true; //Log.isLoggable(TAG, Log.DEBUG);
private final String mSlotEthernet;
private static final int ETHERNET_ON = 1;
private static final int ETHERNET_OFF = 2;
private static final int ETHERNET_CONNECTED = 3;
private static final int ETHERNET_DISCONNECTED = 4;
private boolean mEthernetConnected = false;
在“PhoneStatusBarPolicy”中添加:
mSlotEthernet = context.getString(com.android.internal.R.string.status_bar_ethernet);
filter.addAction(Intent.ACTION_ETHERNET_ON);
filter.addAction(Intent.ACTION_ETHERNET_OFF);
filter.addAction(Intent.ACTION_ETHERNET_CONNECTED);
filter.addAction(Intent.ACTION_ETHERNET_DISCONNECTED);
mIconController.setIcon(mSlotEthernet, R.drawable.ethernet_disconnected, null);
mIconController.setIconVisibility(mSlotEthernet, false);
Log.d(TAG, "klein----PhoneStatusBarPolicy--broadcasts register ");
// listen for broadcasts
Log.d(TAG, "klein----PhoneStatusBarPolicy--tell ethernet that statusbar is ready");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
mContext.sendBroadcast(intent);
添加“updateEthernet” 方法:
private void updateEthernet(int mEthernetConnectedNewState) {
Log.d(TAG, "klein----updateEthernet--isEthernetConnected = " + mEthernetConnectedNewState);
int ethernetIconId = 0;
String ethernetDescription = null;
int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);
boolean isEthernetOpened = (enable == EthernetManager.ETH_STATE_ENABLED);
Log.d(TAG, "klein----updateEthernet--isEthernetOpened = " + isEthernetOpened);
if ((mEthernetConnectedNewState == ETHERNET_CONNECTED)){
mEthernetConnected = true;
}else if (mEthernetConnectedNewState == ETHERNET_DISCONNECTED){
mEthernetConnected = false;
}
if (isEthernetOpened){
Log.d(TAG, "klein----set false");
mIconController.setIconVisibility(mSlotEthernet, false);
if (mEthernetConnected){
mIconController.setIcon(mSlotEthernet, R.drawable.ethernet_connected, null);
mIconController.setIconVisibility(mSlotEthernet, true);
} else {
mIconController.setIconVisibility(mSlotEthernet, false);
}
} else {
mEthernetConnected = false;
mIconController.setIconVisibility(mSlotEthernet, false);
}
}
在“BroadcastReceiver mIntentReceiver”的“onReceive”方法中增加:
else if (action.equals(Intent.ACTION_ETHERNET_ON)) {
updateEthernet(ETHERNET_ON);
}else if (action.equals(Intent.ACTION_ETHERNET_CONNECTED)) {
updateEthernet(ETHERNET_CONNECTED);
}else if (action.equals(Intent.ACTION_ETHERNET_DISCONNECTED)) {
updateEthernet(ETHERNET_DISCONNECTED);
}else if (action.equals(Intent.ACTION_ETHERNET_OFF)) {
updateEthernet(ETHERNET_OFF);
}
添加以下内容:
完整文件内容如下:
加入以下内容:
Ethernet
Configure Ethernet device
Ethernet
Ethernet Devices:
Connection Type
DHCP
Static IP
DNS address
Gateway address
IP address
Ethernet
Turn on Ethernet
Ethernet configuration
Configure Ethernet devices
Netmask
Turn off Ethernet
Turn on Ethernet
Failed to set: Please enter the valid characters 0~255
can\'t be empty
Network prefix length
完整的内容如下:
添加如下内容:
public static class EthernetSettingsActivity extends SettingsActivity { /*empty */ }
添加以下内容:
import com.android.settings.ethernet.EthernetSettings;
在“String[] SETTINGS_FOR_RESTRICTED”中加入:
Settings.EthernetSettingsActivity.class.getName(),
在“String[] ENTRY_FRAGMENTS”中加入:
EthernetSettings.class.getName(),//add by law
在“doUpdateTilesList”方法中加入:
setTileEnabled(new ComponentName(packageName,
Settings.EthernetSettingsActivity.class.getName()),
pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
新增此文件:
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ethernet;
import com.android.settings.R;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.util.Slog;
import android.view.inputmethod.InputMethodManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.os.Environment;
import android.util.SparseArray;
import android.net.StaticIpConfiguration;
import android.net.EthernetManager;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.Iterator;
import android.text.TextUtils;
import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import com.android.settings.Utils;
import android.widget.Toast;
import android.net.EthernetManager;
import android.provider.Settings;
class EthernetDialog extends AlertDialog implements DialogInterface.OnClickListener, DialogInterface.OnShowListener,
DialogInterface.OnDismissListener{
private final String TAG = "EthConfDialog";
private static final boolean localLOGV = true;
/* This value comes from "wifi_ip_settings" resource array */
private static final int DHCP = 0;
private static final int STATIC_IP = 1;
private IpAssignment mIpAssignment = IpAssignment.DHCP;
private StaticIpConfiguration mStaticIpConfiguration = null;
private View mView;
private RadioButton mConTypeDhcp;
private RadioButton mConTypeManual;
private EditText mIpaddr;
private EditText mDns;
private EditText mGw;
//private EditText mMask;
private EditText mprefix;
private Context mContext;
private EthernetManager mEthManager;
private ConnectivityManager mCM;
public EthernetDialog(Context context,EthernetManager EthManager,ConnectivityManager cm) {
super(context);
Slog.d(TAG, "klein----EthernetDialog");
mContext = context;
mEthManager = EthManager;
mCM = cm;
buildDialogContent(context);
setOnShowListener(this);
setOnDismissListener(this);
}
public void onShow(DialogInterface dialog) {
if (localLOGV) Slog.d(TAG, "onShow");
UpdateInfo();
// soft keyboard pops up on the disabled EditText. Hide it.
InputMethodManager imm = (InputMethodManager)mContext.getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_IMPLICIT_ONLY);
}
public void onDismiss(DialogInterface dialog) {
if (localLOGV) Slog.d(TAG, "onDismiss");
}
public void UpdateInfo() {
int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
if(enable == EthernetManager.ETH_STATE_ENABLED) {
//if(mEthManager.isAvailable()) {
IpConfiguration ipinfo = mEthManager.getConfiguration();
if(ipinfo != null) {
if(ipinfo.ipAssignment == IpAssignment.DHCP) {
mConTypeDhcp.setChecked(true);
mIpaddr.setEnabled(false);
mDns.setEnabled(false);
mGw.setEnabled(false);
//mMask.setEnabled(true);
mprefix.setEnabled(false);
mDns.setText("");
mGw.setText("");
mprefix.setText("");
mIpaddr.setText("");
if(mCM != null) {
LinkProperties lp = mCM.getLinkProperties(ConnectivityManager.TYPE_ETHERNET);
if(lp != null) {
mIpaddr.setText(formatIpAddresses(lp));
}
}
} else {
mConTypeManual.setChecked(true);
mIpaddr.setEnabled(true);
mDns.setEnabled(true);
mGw.setEnabled(true);
//mMask.setEnabled(true);
mprefix.setEnabled(true);
StaticIpConfiguration staticConfig = ipinfo.getStaticIpConfiguration();
if (staticConfig != null) {
if (staticConfig.ipAddress != null) {
mIpaddr.setText(staticConfig.ipAddress.getAddress().getHostAddress());
mprefix.setText(Integer.toString(staticConfig.ipAddress.getNetworkPrefixLength()));
}
if (staticConfig.gateway != null) {
mGw.setText(staticConfig.gateway.getHostAddress());
}
Iterator dnsIterator = staticConfig.dnsServers.iterator();
if (dnsIterator.hasNext()) {
mDns.setText(dnsIterator.next().getHostAddress());
}
}
}
}
}
}
public int buildDialogContent(Context context) {
this.setTitle(R.string.eth_config_title);
this.setView(mView = getLayoutInflater().inflate(R.layout.eth_configure, null));
mConTypeDhcp = (RadioButton) mView.findViewById(R.id.dhcp_radio);
mConTypeManual = (RadioButton) mView.findViewById(R.id.manual_radio);
mIpaddr = (EditText)mView.findViewById(R.id.ipaddr_edit);
mprefix = (EditText)mView.findViewById(R.id.prefix_edit);
// mMask = (EditText)mView.findViewById(R.id.netmask_edit);
mDns = (EditText)mView.findViewById(R.id.eth_dns_edit);
mGw = (EditText)mView.findViewById(R.id.eth_gw_edit);
mConTypeDhcp.setChecked(true);
mConTypeManual.setChecked(false);
mIpaddr.setEnabled(false);
// mMask.setEnabled(false);
mprefix.setEnabled(false);
mDns.setEnabled(false);
mGw.setEnabled(false);
mConTypeManual.setOnClickListener(new RadioButton.OnClickListener() {
public void onClick(View v) {
mIpaddr.setEnabled(true);
mDns.setEnabled(true);
mGw.setEnabled(true);
//mMask.setEnabled(true);
mprefix.setEnabled(true);
mIpAssignment = IpAssignment.STATIC;
if(TextUtils.isEmpty(mIpaddr.getText().toString()))
mIpaddr.setText("192.168.1.15");
if(TextUtils.isEmpty(mDns.getText().toString()))
mDns.setText("192.168.1.1");
if(TextUtils.isEmpty(mGw.getText().toString()))
mGw.setText("192.168.1.1");
if(TextUtils.isEmpty(mprefix.getText().toString()))
mprefix.setText("24");
}
});
mConTypeDhcp.setOnClickListener(new RadioButton.OnClickListener() {
public void onClick(View v) {
mIpaddr.setEnabled(false);
mDns.setEnabled(false);
mGw.setEnabled(false);
//mMask.setEnabled(false);
mprefix.setEnabled(false);
mIpAssignment = IpAssignment.DHCP;
mDns.setText("");
mGw.setText("");
mprefix.setText("");
mIpaddr.setText("");
}
});
this.setInverseBackgroundForced(true);
this.setButton(BUTTON_POSITIVE, context.getText(R.string.menu_save), this);
this.setButton(BUTTON_NEGATIVE, context.getText(R.string.menu_cancel), this);
UpdateInfo();
return 0;
}
private String formatIpAddresses(LinkProperties prop) {
if (prop == null) return null;
Iterator iter = prop.getAllAddresses().iterator();
// If there are no entries, return null
if (!iter.hasNext()) return null;
// Concatenate all available addresses, comma separated
String addresses = "";
while (iter.hasNext()) {
addresses += iter.next().getHostAddress();
if (iter.hasNext()) addresses += "\n";
}
return addresses;
}
private Inet4Address getIPv4Address(String text) {
try {
return (Inet4Address) NetworkUtils.numericToInetAddress(text);
} catch (IllegalArgumentException|ClassCastException e) {
return null;
}
}
private int validateIpConfigFields(StaticIpConfiguration staticIpConfiguration) {
String ipAddr = mIpaddr.getText().toString();
Inet4Address inetAddr = getIPv4Address(ipAddr);
if (inetAddr == null) {
return 2;
}
/*
String netmask = mMask.getText().toString();
if (TextUtils.isEmpty(netmask))
return 11;
Inet4Address netmas = getIPv4Address(netmask);
if (netmas == null) {
return 12;
}
int nmask = NetworkUtils.inetAddressToInt(netmas);
int prefixlength = NetworkUtils.netmaskIntToPrefixLength(nmask);
*/
int networkPrefixLength = -1;
try {
networkPrefixLength = Integer.parseInt(mprefix.getText().toString());
if (networkPrefixLength < 0 || networkPrefixLength > 32) {
return 3;
}
staticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
} catch (NumberFormatException e) {
// Set the hint as default after user types in ip address
}
String gateway = mGw.getText().toString();
InetAddress gatewayAddr = getIPv4Address(gateway);
if (gatewayAddr == null) {
return 4;
}
staticIpConfiguration.gateway = gatewayAddr;
String dns = mDns.getText().toString();
InetAddress dnsAddr = null;
dnsAddr = getIPv4Address(dns);
if (dnsAddr == null) {
return 5;
}
staticIpConfiguration.dnsServers.add(dnsAddr);
return 0;
}
private void handle_saveconf() {
if (mConTypeDhcp.isChecked()) {
Slog.i(TAG,"mode dhcp");
mEthManager.setConfiguration(new IpConfiguration(mIpAssignment, ProxySettings.NONE,
null, null));
} else {
Slog.i(TAG,"mode static ip");
if(isIpAddress(mIpaddr.getText().toString())
&& isIpAddress(mGw.getText().toString())
&& isIpAddress(mDns.getText().toString())) {
if(TextUtils.isEmpty(mIpaddr.getText().toString())
|| TextUtils.isEmpty(mprefix.getText().toString())
|| TextUtils.isEmpty(mGw.getText().toString())
|| TextUtils.isEmpty(mDns.getText().toString())) {
Toast.makeText(mContext, R.string.eth_settings_empty, Toast.LENGTH_LONG).show();
return ;
}
mStaticIpConfiguration = new StaticIpConfiguration();
int result = validateIpConfigFields(mStaticIpConfiguration);
if (result != 0) {
Toast.makeText(mContext, " error id is " + result, Toast.LENGTH_LONG).show();
return ;
} else {
mEthManager.setConfiguration( new IpConfiguration(mIpAssignment, ProxySettings.NONE,
mStaticIpConfiguration, null));
}
} else
Toast.makeText(mContext, R.string.eth_settings_error, Toast.LENGTH_LONG).show();
}
}
private boolean isIpAddress(String value) {
int start = 0;
int end = value.indexOf('.');
int numBlocks = 0;
while (start < value.length()) {
if (end == -1) {
end = value.length();
}
try {
int block = Integer.parseInt(value.substring(start, end));
if ((block > 255) || (block < 0)) {
return false;
}
} catch (NumberFormatException e) {
return false;
}
numBlocks++;
start = end + 1;
end = value.indexOf('.', start);
}
return numBlocks == 4;
}
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_POSITIVE:
handle_saveconf();
break;
case BUTTON_NEGATIVE:
//Don't need to do anything
break;
default:
}
}
}
新增此文件:
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* developed by [email protected]
*/
package com.android.settings.ethernet;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.preference.CheckBoxPreference;
import java.util.ArrayList;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.R;
import com.android.settings.widget.SwitchBar;
import com.android.settings.SettingsActivity;
import android.widget.Switch;
import android.util.Slog;
import android.net.EthernetManager;
import android.provider.Settings;
public class EthernetEnabler implements SwitchBar.OnSwitchChangeListener {
private final String TAG = "EthernetEnabler";
private Context mContext;
private SwitchBar mSwitchBar;
private boolean mListeningToOnSwitchChange = false;
private EthernetDialog mEthDialog = null;
private EthernetManager mEthManager;
public void setConfigDialog(EthernetDialog Dialog) {
mEthDialog = Dialog;
}
public EthernetEnabler(Context context, SwitchBar switchBar,EthernetManager ethernetManager) {
mContext = context;
mSwitchBar = switchBar;
mEthManager = ethernetManager;
setupSwitchBar();
}
public void resume(Context context) {
mContext = context;
if (!mListeningToOnSwitchChange) {
mSwitchBar.addOnSwitchChangeListener(this);
mListeningToOnSwitchChange = true;
}
}
public void pause() {
if (mListeningToOnSwitchChange) {
mSwitchBar.removeOnSwitchChangeListener(this);
mListeningToOnSwitchChange = false;
}
}
public void setupSwitchBar() {
if (!mListeningToOnSwitchChange) {
mSwitchBar.addOnSwitchChangeListener(this);
mListeningToOnSwitchChange = true;
}
mSwitchBar.show();
int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
if(enable == EthernetManager.ETH_STATE_ENABLED) {
mSwitchBar.setChecked(true);
Log.d(TAG,"setupSwitchBar on");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_ON);
mContext.sendBroadcast(intent);
} else {
mSwitchBar.setChecked(false);
Log.d(TAG,"setupSwitchBar off");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_OFF);
mContext.sendBroadcast(intent);
}
}
public void teardownSwitchBar() {
if (mListeningToOnSwitchChange) {
mSwitchBar.removeOnSwitchChangeListener(this);
mListeningToOnSwitchChange = false;
}
mSwitchBar.hide();
}
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
Log.d(TAG,"klein--isChecked = " + isChecked);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ETHERNET_ON,
isChecked ? EthernetManager.ETH_STATE_ENABLED : EthernetManager.ETH_STATE_DISABLED);
if(isChecked) {
//if(mEthDialog != null)
//mEthDialog.show();
} else {
Log.d(TAG,"klein--onSwitchChanged off");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_OFF);
mContext.sendBroadcast(intent);
if(mEthManager != null)
mEthManager.stop();
}
if(isChecked){
Log.d(TAG,"klein--onSwitchChanged on");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_ETHERNET_ON);
mContext.sendBroadcast(intent);
if(mEthManager != null){
mEthManager.start();
}
}
}
}
新增此文件:
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* developed by [email protected]
*/
package com.android.settings.ethernet;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.support.v7.preference.AndroidResources;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceRecyclerViewAccessibilityDelegate;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.preference.CheckBoxPreference;
import java.util.ArrayList;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.R;
import com.android.settings.widget.SwitchBar;
import com.android.settings.SettingsActivity;
import android.widget.Switch;
import android.app.Activity;
import android.app.ActivityManager;
import android.net.EthernetManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Slog;
import android.widget.Toast;
import android.os.Looper;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
public class EthernetSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener{
private static final String TAG = "EthernetSettings";
private EthernetEnabler mEthEnabler;
private static final String KEY_CONF_ETH = "ETHERNET_CONFIG";
private EthernetDialog mEthDialog = null;
private Preference mEthConfigPref;
private ConnectivityManager mCM;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.ethernet_settings);
mEthConfigPref = (Preference)findPreference(KEY_CONF_ETH);
mEthConfigPref.setOnPreferenceChangeListener(this);
mEthConfigPref.setOnPreferenceClickListener(this);
}
@Override
public void onStart() {
super.onStart();
// On/off switch is hidden for Setup Wizard (returns null)
mEthEnabler = createEthernetEnabler();
mCM = (ConnectivityManager)getActivity().getSystemService(
Context.CONNECTIVITY_SERVICE);
mEthDialog = new EthernetDialog(getActivity(),(EthernetManager)getSystemService(Context.ETHERNET_SERVICE),mCM);
mEthEnabler.setConfigDialog(mEthDialog);
}
@Override
public void onResume() {
final Activity activity = getActivity();
super.onResume();
if (mEthEnabler != null) {
mEthEnabler.resume(activity);
}
}
@Override
public void onPause() {
super.onPause();
if (mEthEnabler != null) {
mEthEnabler.pause();
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (mEthEnabler != null) {
mEthEnabler.teardownSwitchBar();
}
}
/**
* @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)
*/
/* package */
EthernetEnabler createEthernetEnabler() {
final SettingsActivity activity = (SettingsActivity) getActivity();
return new EthernetEnabler(activity, activity.getSwitchBar(),(EthernetManager)getSystemService(Context.ETHERNET_SERVICE));
}
public boolean onPreferenceChange(Preference preference, Object objValue) {
return true;
}
/**
* [email protected]
* onPreferenceTreeClick
*/
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
Log.d(TAG, "leave empty");
return false;
}
/**
* [email protected]
* onPreferenceClick
*/
public boolean onPreferenceClick(Preference preference){
Log.d(TAG, "klein---onPreferenceClick");
if (preference == mEthConfigPref) {
final SettingsActivity activity = (SettingsActivity) getActivity();
if(activity.getSwitchBar().isChecked()) {
if(mEthDialog != null){
mEthDialog.show();
}
} else {
Toast.makeText(getActivity(), "please turn on ethernet",
Toast.LENGTH_LONG).show();
}
}
return false;
}
@Override
protected int getMetricsCategory(){
return MetricsEvent.WIFI;
}
}
新增此文件:
新增此文件:
修改完上述文件后重新编译系统固件,使用新的固件启动系统,尝试相关操作。
这个人很懒,什么也没有留下!