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        }
102db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai
103db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        public void interfaceClassDataActivityChanged(String label, boolean active) {
104db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai            // Ignored.
105db3c8678e5cbdfec011afaf25bde2091152c30adHaoyu Bai        }
1061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private EthernetDataTracker() {
1091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORKTYPE, "");
1101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkProperties = new LinkProperties();
1111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkCapabilities = new LinkCapabilities();
1121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private void interfaceAdded(String iface) {
115c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        if (!iface.matches(sIfaceMatch))
1161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            return;
1171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Log.d(TAG, "Adding " + iface);
1191997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
120efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        synchronized(this) {
1211997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            if(!mIface.isEmpty())
1221997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                return;
1231997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            mIface = iface;
1241997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        }
1251997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
126198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        // we don't get link status indications unless the iface is up - bring it up
127198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        try {
128198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            mNMService.setInterfaceUp(iface);
129198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        } catch (Exception e) {
130198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            Log.e(TAG, "Error upping interface " + iface + ": " + e);
131198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        }
132198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt
1331997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo.setIsAvailable(true);
1341997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
1351997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1361997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1371997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1384bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    public void disconnect() {
1391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        NetworkUtils.stopDhcp(mIface);
1411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mLinkProperties.clear();
1431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mNetworkInfo.setIsAvailable(false);
144d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
1451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
1471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
1501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        msg.sendToTarget();
1511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1524bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1534bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
1544bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        try {
1554bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            service.clearInterfaceAddresses(mIface);
1564bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        } catch (Exception e) {
1574bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
1584bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        }
1594bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    }
1604bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen
1614bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen    private void interfaceRemoved(String iface) {
1624bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        if (!iface.equals(mIface))
1634bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen            return;
1644bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen
1654bcbefdc5f24702dbbae485d016997e3efb5e5ccMike J. Chen        Log.d(TAG, "Removing " + iface);
166efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        disconnect();
1671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mIface = "";
1681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    private void runDhcp() {
1711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        Thread dhcpThread = new Thread(new Runnable() {
1721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            public void run() {
1731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
1741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
1751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                    Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
1761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                    return;
1771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                }
1781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mLinkProperties = dhcpInfoInternal.makeLinkProperties();
1791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                mLinkProperties.setInterfaceName(mIface);
1801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
181d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
1821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
1831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby                msg.sendToTarget();
1841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby            }
1851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        });
1861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        dhcpThread.start();
1871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public static synchronized EthernetDataTracker getInstance() {
1901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        if (sInstance == null) sInstance = new EthernetDataTracker();
1911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return sInstance;
1921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public Object Clone() throws CloneNotSupportedException {
1951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        throw new CloneNotSupportedException();
1961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
1971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
1981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void setTeardownRequested(boolean isRequested) {
1991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mTeardownRequested.set(isRequested);
2001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isTeardownRequested() {
2031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mTeardownRequested.get();
2041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Begin monitoring connectivity
2081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void startMonitoring(Context context, Handler target) {
2101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mContext = context;
2111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mCsHandler = target;
2121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        // register for notifications from NetworkManagement Service
2141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
215198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt        mNMService = INetworkManagementService.Stub.asInterface(b);
216f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
2171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mInterfaceObserver = new InterfaceObserver(this);
218c96a667162fab44a250503caccb770109a9cb69aMike J. Chen
219f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        // enable and try to connect to an ethernet interface that
220f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        // already exists
221c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        sIfaceMatch = context.getResources().getString(
222c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            com.android.internal.R.string.config_ethernet_iface_regex);
223c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        try {
224198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            final String[] ifaces = mNMService.listInterfaces();
225c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            for (String iface : ifaces) {
226c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                if (iface.matches(sIfaceMatch)) {
227c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    mIface = iface;
228198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt                    mNMService.setInterfaceUp(iface);
229198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
230b6b72f5411d02b928441543dc4c5e8545e48920aVishal Mahaveer                    mLinkUp = config.hasFlag("up");
231d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                    if (config != null && mHwAddr == null) {
232efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood                        mHwAddr = config.getHardwareAddress();
233d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                        if (mHwAddr != null) {
234d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                            mNetworkInfo.setExtraInfo(mHwAddr);
235d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                        }
236d60ae7f6688ea83df536c2eb1101a74ae1914ac6Doug Zongker                    }
2371d28fef92e516b0144d7844413194ba9e953b317Jason Simmons
2381d28fef92e516b0144d7844413194ba9e953b317Jason Simmons                    // if a DHCP client had previously been started for this interface, then stop it
2391d28fef92e516b0144d7844413194ba9e953b317Jason Simmons                    NetworkUtils.stopDhcp(mIface);
2401d28fef92e516b0144d7844413194ba9e953b317Jason Simmons
241c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    reconnect();
242c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                    break;
243c96a667162fab44a250503caccb770109a9cb69aMike J. Chen                }
244c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            }
245c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        } catch (RemoteException e) {
246c96a667162fab44a250503caccb770109a9cb69aMike J. Chen            Log.e(TAG, "Could not get list of interfaces " + e);
247c96a667162fab44a250503caccb770109a9cb69aMike J. Chen        }
248f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen
249f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        try {
250198bc11d099008531b7e445d9715698421d6e644Robert Greenwalt            mNMService.registerObserver(mInterfaceObserver);
251f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        } catch (RemoteException e) {
252f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen            Log.e(TAG, "Could not register InterfaceObserver " + e);
253f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen        }
2541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Disable connectivity to a network
2581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: do away with return value after making MobileDataStateTracker async
2591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean teardown() {
2611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mTeardownRequested.set(true);
2621997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        NetworkUtils.stopDhcp(mIface);
2631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return true;
2641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Re-enable connectivity to a network after a {@link #teardown()}.
2681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean reconnect() {
270efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        if (mLinkUp) {
271efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood            mTeardownRequested.set(false);
272efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood            runDhcp();
273efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        }
274efeba018bde81e02e1255714e3d4eeeb43c055e7Mike Lockwood        return mLinkUp;
2751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
277da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    @Override
278da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    public void captivePortalCheckComplete() {
279da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff        // not implemented
280da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff    }
281da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff
2821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Turn the wireless radio off for a network.
2841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param turnOn {@code true} to turn the radio on, {@code false}
2851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean setRadio(boolean turnOn) {
2871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return true;
2881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return true - If are we currently tethered with another device.
2921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
2931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized boolean isAvailable() {
2941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mNetworkInfo.isAvailable();
2951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
2961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
2971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
2981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Tells the underlying networking system that the caller wants to
2991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * begin using the named feature. The interpretation of {@code feature}
3001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * is completely up to each networking implementation.
3011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param feature the name of the feature to be used
3021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingPid the process ID of the process that is issuing this request
3031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingUid the user ID of the process that is issuing this request
3041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return an integer value representing the outcome of the request.
3051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * The interpretation of this value is specific to each networking
3061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * implementation+feature combination, except that the value {@code -1}
3071997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * always indicates failure.
3081997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: needs to go away
3091997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3101997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
3111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return -1;
3121997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3131997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3141997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3151997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Tells the underlying networking system that the caller is finished
3161997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * using the named feature. The interpretation of {@code feature}
3171997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * is completely up to each networking implementation.
3181997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param feature the name of the feature that is no longer needed.
3191997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingPid the process ID of the process that is issuing this request
3201997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @param callingUid the user ID of the process that is issuing this request
3211997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return an integer value representing the outcome of the request.
3221997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * The interpretation of this value is specific to each networking
3231997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * implementation+feature combination, except that the value {@code -1}
3241997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * always indicates failure.
3251997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * TODO: needs to go away
3261997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3271997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
3281997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return -1;
3291997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3301997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3318e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    @Override
3328e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    public void setUserDataEnable(boolean enabled) {
3338e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        Log.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
3348e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
3358e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
3368e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    @Override
3378e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    public void setPolicyDataEnable(boolean enabled) {
3388e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        Log.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")");
3391997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3401997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3411997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3421997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Check if private DNS route is set for the network
3431997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3441997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isPrivateDnsRouteSet() {
3451997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mPrivateDnsRouteSet.get();
3461997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3471997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3481997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3491997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Set a flag indicating private DNS route is set
3501997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3511997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void privateDnsRouteSet(boolean enabled) {
3521997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mPrivateDnsRouteSet.set(enabled);
3531997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3541997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3551997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3561997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch NetworkInfo for the network
3571997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3581997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized NetworkInfo getNetworkInfo() {
3591997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mNetworkInfo;
3601997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3611997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3621997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3631997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch LinkProperties for the network
3641997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3651997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public synchronized LinkProperties getLinkProperties() {
3661997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return new LinkProperties(mLinkProperties);
3671997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3681997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3691997069436f0d47583a0b700c12ed63132cf3312Benoit Goby   /**
3701997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * A capability is an Integer/String pair, the capabilities
3711997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * are defined in the class LinkSocket#Key.
3721997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     *
3731997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * @return a copy of this connections capabilities, may be empty but never null.
3741997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3751997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public LinkCapabilities getLinkCapabilities() {
3761997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return new LinkCapabilities(mLinkCapabilities);
3771997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3781997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3791997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3801997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Fetch default gateway address for the network
3811997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3821997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public int getDefaultGatewayAddr() {
3831997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mDefaultGatewayAddr.get();
3841997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3851997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3861997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3871997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Check if default route is set
3881997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3891997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public boolean isDefaultRouteSet() {
3901997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return mDefaultRouteSet.get();
3911997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3921997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
3931997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
3941997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Set a flag indicating default route is set for the network
3951997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
3961997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public void defaultRouteSet(boolean enabled) {
3971997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        mDefaultRouteSet.set(enabled);
3981997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
3991997069436f0d47583a0b700c12ed63132cf3312Benoit Goby
4001997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    /**
4011997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * Return the system properties name associated with the tcp buffer sizes
4021997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     * for this network.
4031997069436f0d47583a0b700c12ed63132cf3312Benoit Goby     */
4041997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    public String getTcpBufferSizesPropName() {
4051997069436f0d47583a0b700c12ed63132cf3312Benoit Goby        return "net.tcp.buffersize.wifi";
4061997069436f0d47583a0b700c12ed63132cf3312Benoit Goby    }
407af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt
408af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt    public void setDependencyMet(boolean met) {
409af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt        // not supported on this network
410af6eddb1c285a11841a2e1e0e3a41636f6bfd63dRobert Greenwalt    }
4111997069436f0d47583a0b700c12ed63132cf3312Benoit Goby}
412