11997069436f0d47583a0b700c12ed63132cf3312Benoit Goby/*
21997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Copyright (C) 2010 The Android Open Source Project
31997069436f0d47583a0b700c12ed63132cf3312Benoit Goby *
41997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Licensed under the Apache License, Version 2.0 (the "License");
51997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * you may not use this file except in compliance with the License.
61997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * You may obtain a copy of the License at
71997069436f0d47583a0b700c12ed63132cf3312Benoit Goby *
81997069436f0d47583a0b700c12ed63132cf3312Benoit Goby *      http://www.apache.org/licenses/LICENSE-2.0
91997069436f0d47583a0b700c12ed63132cf3312Benoit Goby *
101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * Unless required by applicable law or agreed to in writing, software
111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * distributed under the License is distributed on an "AS IS" BASIS,
121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * See the License for the specific language governing permissions and
141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * limitations under the License.
151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */
161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
171997069436f0d47583a0b700c12ed63132cf3312Benoit Gobypackage android.net;
181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
191997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.content.Context;
201997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.net.NetworkInfo.DetailedState;
211997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.Handler;
221997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.IBinder;
231997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.INetworkManagementService;
241997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.Message;
251997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.RemoteException;
261997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.os.ServiceManager;
271997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport android.util.Log;
281997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
291997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport java.util.concurrent.atomic.AtomicBoolean;
301997069436f0d47583a0b700c12ed63132cf3312Benoit Gobyimport java.util.concurrent.atomic.AtomicInteger;
311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby/**
331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * This class tracks the data connection associated with Ethernet
341997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * This is a singleton class and an instance will be created by
351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * ConnectivityService.
361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby * @hide
371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby */
381997069436f0d47583a0b700c12ed63132cf3312Benoit Gobypublic class EthernetDataTracker implements NetworkStateTracker {
391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private static final String NETWORKTYPE = "ETHERNET";
401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private static final String TAG = "Ethernet";
411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
47f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen    private static boolean mLinkUp;
481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private LinkProperties mLinkProperties;
491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private LinkCapabilities mLinkCapabilities;
501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private NetworkInfo mNetworkInfo;
511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private InterfaceObserver mInterfaceObserver;
52d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker    private String mHwAddr;
531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /* For sending events to connectivity service handler */
551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private Handler mCsHandler;
561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private Context mContext;
571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private static EthernetDataTracker sInstance;
59c96a667162fab44a250503caccb770109a9cb69aMike J. Chen    private static String sIfaceMatch = "";
601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private static String mIface = "";
611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
62198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt    private INetworkManagementService mNMService;
63198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt
641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        private EthernetDataTracker mTracker;
661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        InterfaceObserver(EthernetDataTracker tracker) {
681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            super();
691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            mTracker = tracker;
701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
72f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        public void interfaceStatusChanged(String iface, boolean up) {
73f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen            Log.d(TAG, "Interface status changed: " + iface + (up ? "up" : "down"));
74f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        }
75f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
76f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        public void interfaceLinkStateChanged(String iface, boolean up) {
77f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen            if (mIface.equals(iface) && mLinkUp != up) {
78f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down"));
79f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                mLinkUp = up;
80efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood                mTracker.mNetworkInfo.setIsAvailable(up);
81f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
82f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                // use DHCP
83f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                if (up) {
84f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                    mTracker.reconnect();
85f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                } else {
864bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen                    mTracker.disconnect();
87f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                }
88f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen            }
891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        public void interfaceAdded(String iface) {
921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            mTracker.interfaceAdded(iface);
931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        public void interfaceRemoved(String iface) {
961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            mTracker.interfaceRemoved(iface);
971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
9812b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall
9912b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall        public void limitReached(String limitName, String iface) {
10012b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall            // Ignored.
10112b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall        }
1021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private EthernetDataTracker() {
1051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, "");
1061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkProperties = new LinkProperties();
1071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkCapabilities = new LinkCapabilities();
1081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private void interfaceAdded(String iface) {
111c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        if (!iface.matches(sIfaceMatch))
1121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            return;
1131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Log.d(TAG, "Adding " + iface);
1151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
116efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        synchronized(this) {
1171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            if(!mIface.isEmpty())
1181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                return;
1191997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            mIface = iface;
1201997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
1211997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
122198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        // we don't get link status indications unless the iface is up - bring it up
123198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        try {
124198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            mNMService.setInterfaceUp(iface);
125198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        } catch (Exception e) {
126198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            Log.e(TAG, "Error upping interface " + iface + ": " + e);
127198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        }
128198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt
1291997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo.setIsAvailable(true);
1301997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
1311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1344bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    public void disconnect() {
1351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        NetworkUtils.stopDhcp(mIface);
1371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1381997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkProperties.clear();
1391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo.setIsAvailable(false);
140d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
1411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
1431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
1461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1484bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1494bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
1504bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        try {
1514bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            service.clearInterfaceAddresses(mIface);
1524bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        } catch (Exception e) {
1534bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
1544bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        }
1554bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    }
1564bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen
1574bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    private void interfaceRemoved(String iface) {
1584bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        if (!iface.equals(mIface))
1594bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            return;
1604bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen
1614bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        Log.d(TAG, "Removing " + iface);
162efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        disconnect();
1631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mIface = "";
1641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private void runDhcp() {
1671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Thread dhcpThread = new Thread(new Runnable() {
1681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            public void run() {
1691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
1701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
1711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                    Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
1721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                    return;
1731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                }
1741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mLinkProperties = dhcpInfoInternal.makeLinkProperties();
1751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mLinkProperties.setInterfaceName(mIface);
1761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
177d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
1781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
1791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                msg.sendToTarget();
1801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            }
1811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        });
1821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        dhcpThread.start();
1831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public static synchronized EthernetDataTracker getInstance() {
1861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        if (sInstance == null) sInstance = new EthernetDataTracker();
1871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return sInstance;
1881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public Object Clone() throws CloneNotSupportedException {
1911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        throw new CloneNotSupportedException();
1921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void setTeardownRequested(boolean isRequested) {
1951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mTeardownRequested.set(isRequested);
1961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isTeardownRequested() {
1991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mTeardownRequested.get();
2001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Begin monitoring connectivity
2041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void startMonitoring(Context context, Handler target) {
2061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mContext = context;
2071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mCsHandler = target;
2081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        // register for notifications from NetworkManagement Service
2101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
211198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        mNMService = INetworkManagementService.Stub.asInterface(b);
212f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
2131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mInterfaceObserver = new InterfaceObserver(this);
214c96a667162fab44a250503caccb770109a9cb69aMike J. Chen
215f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        // enable and try to connect to an ethernet interface that
216f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        // already exists
217c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        sIfaceMatch = context.getResources().getString(
218c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            com.android.internal.R.string.config_ethernet_iface_regex);
219c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        try {
220198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            final String[] ifaces = mNMService.listInterfaces();
221c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            for (String iface : ifaces) {
222c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                if (iface.matches(sIfaceMatch)) {
223c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    mIface = iface;
224198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt                    mNMService.setInterfaceUp(iface);
225198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
226f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen                    mLinkUp = config.isActive();
227d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                    if (config != null && mHwAddr == null) {
228efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood                        mHwAddr = config.getHardwareAddress();
229d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                        if (mHwAddr != null) {
230d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                            mNetworkInfo.setExtraInfo(mHwAddr);
231d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                        }
232d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                    }
233c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    reconnect();
234c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    break;
235c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                }
236c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            }
237c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        } catch (RemoteException e) {
238c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            Log.e(TAG, "Could not get list of interfaces " + e);
239c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        }
240f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
241f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        try {
242198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            mNMService.registerObserver(mInterfaceObserver);
243f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        } catch (RemoteException e) {
244f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen            Log.e(TAG, "Could not register InterfaceObserver " + e);
245f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        }
2461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Disable connectivity to a network
2501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: do away with return value after making MobileDataStateTracker async
2511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2521997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean teardown() {
2531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mTeardownRequested.set(true);
2541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        NetworkUtils.stopDhcp(mIface);
2551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return true;
2561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Re-enable connectivity to a network after a {@link #teardown()}.
2601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean reconnect() {
262efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        if (mLinkUp) {
263efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood            mTeardownRequested.set(false);
264efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood            runDhcp();
265efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        }
266efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        return mLinkUp;
2671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Turn the wireless radio off for a network.
2711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param turnOn {@code true} to turn the radio on, {@code false}
2721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean setRadio(boolean turnOn) {
2741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return true;
2751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return true - If are we currently tethered with another device.
2791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized boolean isAvailable() {
2811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mNetworkInfo.isAvailable();
2821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Tells the underlying networking system that the caller wants to
2861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * begin using the named feature. The interpretation of {@code feature}
2871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * is completely up to each networking implementation.
2881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param feature the name of the feature to be used
2891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingPid the process ID of the process that is issuing this request
2901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingUid the user ID of the process that is issuing this request
2911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return an integer value representing the outcome of the request.
2921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * The interpretation of this value is specific to each networking
2931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * implementation+feature combination, except that the value {@code -1}
2941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * always indicates failure.
2951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: needs to go away
2961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
2981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return -1;
2991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Tells the underlying networking system that the caller is finished
3031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * using the named feature. The interpretation of {@code feature}
3041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * is completely up to each networking implementation.
3051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param feature the name of the feature that is no longer needed.
3061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingPid the process ID of the process that is issuing this request
3071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingUid the user ID of the process that is issuing this request
3081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return an integer value representing the outcome of the request.
3091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * The interpretation of this value is specific to each networking
3101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * implementation+feature combination, except that the value {@code -1}
3111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * always indicates failure.
3121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: needs to go away
3131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
3151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return -1;
3161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3188e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    @Override
3198e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    public void setUserDataEnable(boolean enabled) {
3208e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        Log.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
3218e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
3228e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
3238e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    @Override
3248e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    public void setPolicyDataEnable(boolean enabled) {
3258e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        Log.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")");
3261997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3271997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3281997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3291997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Check if private DNS route is set for the network
3301997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3311997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isPrivateDnsRouteSet() {
3321997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mPrivateDnsRouteSet.get();
3331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3341997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Set a flag indicating private DNS route is set
3371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3381997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void privateDnsRouteSet(boolean enabled) {
3391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mPrivateDnsRouteSet.set(enabled);
3401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch NetworkInfo for the network
3441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized NetworkInfo getNetworkInfo() {
3461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mNetworkInfo;
3471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch LinkProperties for the network
3511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3521997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized LinkProperties getLinkProperties() {
3531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return new LinkProperties(mLinkProperties);
3541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby   /**
3571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * A capability is an Integer/String pair, the capabilities
3581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * are defined in the class LinkSocket#Key.
3591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     *
3601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return a copy of this connections capabilities, may be empty but never null.
3611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3621997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public LinkCapabilities getLinkCapabilities() {
3631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return new LinkCapabilities(mLinkCapabilities);
3641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch default gateway address for the network
3681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int getDefaultGatewayAddr() {
3701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mDefaultGatewayAddr.get();
3711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Check if default route is set
3751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isDefaultRouteSet() {
3771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mDefaultRouteSet.get();
3781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Set a flag indicating default route is set for the network
3821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void defaultRouteSet(boolean enabled) {
3841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mDefaultRouteSet.set(enabled);
3851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Return the system properties name associated with the tcp buffer sizes
3891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * for this network.
3901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public String getTcpBufferSizesPropName() {
3921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return "net.tcp.buffersize.wifi";
3931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
394af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt
395af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt    public void setDependencyMet(boolean met) {
396af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt        // not supported on this network
397af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt    }
3981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby}
399