NetlinkTracker.java revision c18cbfdf8d40e7a526a088225cb32341e1ea0920
110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti/*
210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Copyright (C) 2014 The Android Open Source Project
310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License");
510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * you may not use this file except in compliance with the License.
610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * You may obtain a copy of the License at
710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *      http://www.apache.org/licenses/LICENSE-2.0
910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
1010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Unless required by applicable law or agreed to in writing, software
1110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS,
1210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * See the License for the specific language governing permissions and
1410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * limitations under the License.
1510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti */
1610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
1710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittipackage com.android.server.net;
1810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
1910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.net.LinkAddress;
2010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.net.LinkProperties;
21c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colittiimport android.net.RouteInfo;
2210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittiimport android.util.Log;
2310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
2410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti/**
2510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Keeps track of link configuration received from Netlink.
2610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
2710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Instances of this class are expected to be owned by subsystems such as Wi-Fi
2810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * or Ethernet that manage one or more network interfaces. Each interface to be
2910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * tracked needs its own {@code NetlinkTracker}.
3010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
3110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * An instance of this class is constructed by passing in an interface name and
3210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * a callback. The owner is then responsible for registering the tracker with
3310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * NetworkManagementService. When the class receives update notifications from
3410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * the NetworkManagementService notification threads, it applies the update to
3510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * its local LinkProperties, and if something has changed, notifies its owner of
3610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * the update via the callback.
3710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
3810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * The owner can then call {@code getLinkProperties()} in order to find out
3910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * what changed. If in the meantime the LinkProperties stored here have changed,
4010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * this class will return the current LinkProperties. Because each change
4110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * triggers an update callback after the change is made, the owner may get more
4210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * callbacks than strictly necessary (some of which may be no-ops), but will not
4310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * be out of sync once all callbacks have been processed.
4410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
4510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * Threading model:
4610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
4710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - The owner of this class is expected to create it, register it, and call
4810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *   getLinkProperties or clearLinkProperties on its thread.
4910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - Most of the methods in the class are inherited from BaseNetworkObserver
5010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *   and are called by NetworkManagementService notification threads.
5110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * - All accesses to mLinkProperties must be synchronized(this). All the other
5210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *   member variables are immutable once the object is constructed.
5310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
5410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * This class currently tracks IPv4 and IPv6 addresses. In the future it will
5510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * track routes and DNS servers.
5610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti *
5710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti * @hide
5810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti */
5910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colittipublic class NetlinkTracker extends BaseNetworkObserver {
6010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
6110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private final String TAG;
6210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
6310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public interface Callback {
6410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        public void update();
6510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
6610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
6710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private final String mInterfaceName;
6810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private final Callback mCallback;
6910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private final LinkProperties mLinkProperties;
7010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
7110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private static final boolean DBG = true;
7210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
7310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public NetlinkTracker(String iface, Callback callback) {
7410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        TAG = "NetlinkTracker/" + iface;
7510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mInterfaceName = iface;
7610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mCallback = callback;
7710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mLinkProperties = new LinkProperties();
7810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mLinkProperties.setInterfaceName(mInterfaceName);
7910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
8010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
8110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    private void maybeLog(String operation, String iface, LinkAddress address) {
8210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        if (DBG) {
8310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            Log.d(TAG, operation + ": " + address + " on " + iface +
8410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti                    " flags " + address.getFlags() + " scope " + address.getScope());
8510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        }
8610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
8710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
88c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    private void maybeLog(String operation, Object o) {
89c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        if (DBG) {
90c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            Log.d(TAG, operation + ": " + o.toString());
91c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        }
92c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    }
93c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti
9410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    @Override
9510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public void addressUpdated(String iface, LinkAddress address) {
9610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        if (mInterfaceName.equals(iface)) {
9710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            maybeLog("addressUpdated", iface, address);
9810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            boolean changed;
9910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            synchronized (this) {
10010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti                changed = mLinkProperties.addLinkAddress(address);
10110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            }
10210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            if (changed) {
10310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti                mCallback.update();
10410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            }
10510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        }
10610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
10710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
10810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    @Override
10910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public void addressRemoved(String iface, LinkAddress address) {
11010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        if (mInterfaceName.equals(iface)) {
11110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            maybeLog("addressRemoved", iface, address);
11210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            boolean changed;
11310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            synchronized (this) {
11410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti                changed = mLinkProperties.removeLinkAddress(address);
11510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            }
11610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            if (changed) {
11710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti                mCallback.update();
11810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti            }
11910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        }
12010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
12110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
122c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    @Override
123c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    public void routeUpdated(RouteInfo route) {
124c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        if (mInterfaceName.equals(route.getInterface())) {
125c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            maybeLog("routeUpdated", route);
126c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            boolean changed;
127c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            synchronized (this) {
128c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                changed = mLinkProperties.addRoute(route);
129c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            }
130c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            if (changed) {
131c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                mCallback.update();
132c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            }
133c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        }
134c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    }
135c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti
136c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    @Override
137c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    public void routeRemoved(RouteInfo route) {
138c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        if (mInterfaceName.equals(route.getInterface())) {
139c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            maybeLog("routeRemoved", route);
140c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            boolean changed;
141c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            synchronized (this) {
142c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                changed = mLinkProperties.removeRoute(route);
143c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            }
144c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            if (changed) {
145c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti                mCallback.update();
146c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti            }
147c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti        }
148c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti    }
149c18cbfdf8d40e7a526a088225cb32341e1ea0920Lorenzo Colitti
15010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    /**
15110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti     * Returns a copy of this object's LinkProperties.
15210accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti     */
15310accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public synchronized LinkProperties getLinkProperties() {
15410accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        return new LinkProperties(mLinkProperties);
15510accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
15610accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti
15710accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    public synchronized void clearLinkProperties() {
15810accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mLinkProperties.clear();
15910accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti        mLinkProperties.setInterfaceName(mInterfaceName);
16010accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti    }
16110accbb46e82b3178ff26124041f3ab7d6c1802dLorenzo Colitti}
162