From a3d7e61812f8d68ca109280c4e7589e4f968723a Mon Sep 17 00:00:00 2001 From: Jaewan Kim Date: Mon, 20 Oct 2014 12:03:46 +0900 Subject: Add an API to check availability of Ethernet interface. Bug: 18045481 Change-Id: I3fb517c3e7fa807e2937fda92026301e312be986 --- .../server/ethernet/EthernetNetworkFactory.java | 61 ++++++++++++++------ .../server/ethernet/EthernetServiceImpl.java | 67 ++++++++++++++-------- 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/java/com/android/server/ethernet/EthernetNetworkFactory.java b/java/com/android/server/ethernet/EthernetNetworkFactory.java index 2d0a957..bbb99d8 100644 --- a/java/com/android/server/ethernet/EthernetNetworkFactory.java +++ b/java/com/android/server/ethernet/EthernetNetworkFactory.java @@ -19,27 +19,25 @@ 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.NetworkUtils; import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; -import android.net.LinkAddress; 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.NetworkRequest; -import android.net.EthernetManager; +import android.net.NetworkUtils; import android.net.StaticIpConfiguration; import android.os.Handler; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Looper; -import android.os.Message; -import android.os.Messenger; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; @@ -50,9 +48,6 @@ import com.android.server.net.BaseNetworkObserver; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.net.Inet4Address; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; /** @@ -96,6 +91,9 @@ class EthernetNetworkFactory { /** 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; @@ -103,10 +101,11 @@ class EthernetNetworkFactory { private NetworkInfo mNetworkInfo; private LinkProperties mLinkProperties; - EthernetNetworkFactory() { + EthernetNetworkFactory(RemoteCallbackList listeners) { mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); mLinkProperties = new LinkProperties(); initNetworkCapabilities(); + mListeners = listeners; } private class LocalNetworkFactory extends NetworkFactory { @@ -177,9 +176,8 @@ class EthernetNetworkFactory { } synchronized (this) { - if (mIface.isEmpty()) { - mIface = iface; - mHwAddr = config.getHardwareAddress(); + if (!isTrackingInterface()) { + setInterfaceInfoLocked(iface, config.getHardwareAddress()); mNetworkInfo.setIsAvailable(true); mNetworkInfo.setExtraInfo(mHwAddr); } else { @@ -195,7 +193,7 @@ class EthernetNetworkFactory { 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) || !mIface.isEmpty()) + if (!iface.matches(mIfaceMatch) || isTrackingInterface()) return false; Log.d(TAG, "Started tracking interface " + iface); @@ -211,8 +209,7 @@ class EthernetNetworkFactory { // TODO: Unify this codepath with stop(). synchronized (this) { NetworkUtils.stopDhcp(mIface); - mIface = ""; - mHwAddr = null; + setInterfaceInfoLocked("", null); mNetworkInfo.setExtraInfo(null); mLinkUp = false; mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); @@ -413,8 +410,7 @@ class EthernetNetworkFactory { updateAgent(); mLinkProperties = new LinkProperties(); mNetworkAgent = null; - mIface = ""; - mHwAddr = null; + setInterfaceInfoLocked("", null); mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); mFactory.unregister(); } @@ -429,8 +425,35 @@ class EthernetNetworkFactory { 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 (!TextUtils.isEmpty(mIface)) { + if (isTrackingInterface()) { pw.println("Tracking interface: " + mIface); pw.increaseIndent(); pw.println("MAC address: " + mHwAddr); diff --git a/java/com/android/server/ethernet/EthernetServiceImpl.java b/java/com/android/server/ethernet/EthernetServiceImpl.java index 42d98f6..bb1cc51 100644 --- a/java/com/android/server/ethernet/EthernetServiceImpl.java +++ b/java/com/android/server/ethernet/EthernetServiceImpl.java @@ -18,37 +18,25 @@ package com.android.server.ethernet; import android.content.Context; import android.content.pm.PackageManager; -import com.android.internal.util.IndentingPrintWriter; -import android.net.ConnectivityManager; import android.net.IEthernetManager; +import android.net.IEthernetServiceListener; import android.net.IpConfiguration; import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; -import android.net.LinkAddress; -import android.net.NetworkAgent; -import android.net.NetworkInfo; -import android.net.NetworkRequest; -import android.net.RouteInfo; -import android.net.StaticIpConfiguration; import android.os.Binder; -import android.os.IBinder; import android.os.Handler; import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.os.INetworkManagementService; +import android.os.RemoteCallbackList; import android.os.RemoteException; -import android.os.ServiceManager; -import android.text.TextUtils; import android.util.Log; import android.util.PrintWriterPrinter; +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. @@ -60,14 +48,13 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { private final Context mContext; private final EthernetConfigStore mEthernetConfigStore; - private final INetworkManagementService mNMService; private final AtomicBoolean mStarted = new AtomicBoolean(false); private IpConfiguration mIpConfiguration; - private ConnectivityManager mCM; private Handler mHandler; - private NetworkInfo mNetworkInfo; private final EthernetNetworkFactory mTracker; + private final RemoteCallbackList mListeners = + new RemoteCallbackList(); public EthernetServiceImpl(Context context) { mContext = context; @@ -77,10 +64,7 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { Log.i(TAG, "Read stored IP configuration: " + mIpConfiguration); - IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); - mNMService = INetworkManagementService.Stub.asInterface(b); - - mTracker = new EthernetNetworkFactory(); + mTracker = new EthernetNetworkFactory(mListeners); } private void enforceAccessPermission() { @@ -103,7 +87,6 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { public void start() { Log.i(TAG, "Starting Ethernet service"); - mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); HandlerThread handlerThread = new HandlerThread("EthernetServiceThread"); handlerThread.start(); @@ -118,6 +101,7 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { * Get Ethernet configuration * @return the Ethernet Configuration, contained in {@link IpConfiguration}. */ + @Override public IpConfiguration getConfiguration() { enforceAccessPermission(); @@ -129,6 +113,7 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { /** * Set Ethernet configuration */ + @Override public void setConfiguration(IpConfiguration config) { if (!mStarted.get()) { Log.w(TAG, "System isn't ready enough to change ethernet configuration"); @@ -150,6 +135,40 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { } } + /** + * 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, " "); -- cgit v1.2.3