13192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt/*
23192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * Copyright (C) 2014 The Android Open Source Project
33192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt *
43192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
53192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * you may not use this file except in compliance with the License.
63192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * You may obtain a copy of the License at
73192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt *
83192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt *      http://www.apache.org/licenses/LICENSE-2.0
93192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt *
103192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
113192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
123192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * See the License for the specific language governing permissions and
143192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * limitations under the License.
153192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt */
163192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
173192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltpackage android.net;
183192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
193192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.content.Context;
203192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.os.Handler;
213192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.os.Looper;
223192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.os.Message;
233192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.os.Messenger;
243192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.util.Log;
253192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport android.util.SparseArray;
263192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
27348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
283d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwaltimport com.android.internal.util.IndentingPrintWriter;
293192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltimport com.android.internal.util.Protocol;
303192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
313d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwaltimport java.io.FileDescriptor;
323d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwaltimport java.io.PrintWriter;
333d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt
343192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt/**
353192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * A NetworkFactory is an entity that creates NetworkAgent objects.
363192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * The bearers register with ConnectivityService using {@link #register} and
373192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * their factory will start receiving scored NetworkRequests.  NetworkRequests
383192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
393192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * overridden function.  All of these can be dynamic - changing NetworkCapabilities
403192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * or score forces re-evaluation of all current requests.
413192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt *
423192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * If any requests pass the filter some overrideable functions will be called.
433192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * If the bearer only cares about very simple start/stopNetwork callbacks, those
443192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * functions can be overridden.  If the bearer needs more interaction, it can
453192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * override addNetworkRequest and removeNetworkRequest which will give it each
463192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * request that passes their current filters.
473192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt * @hide
483192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt **/
493192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwaltpublic class NetworkFactory extends Handler {
503192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private static final boolean DBG = true;
51fc0c6890c675494b15cd847b20c5a5ede491fc3cRobert Greenwalt    private static final boolean VDBG = false;
523192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
533192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private static final int BASE = Protocol.BASE_NETWORK_FACTORY;
543192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    /**
553192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Pass a network request to the bearer.  If the bearer believes it can
563192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * satisfy the request it should connect to the network and create a
573192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * NetworkAgent.  Once the NetworkAgent is fully functional it will
583192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * register itself with ConnectivityService using registerNetworkAgent.
593192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * If the bearer cannot immediately satisfy the request (no network,
603192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * user disabled the radio, lower-scored network) it should remember
613192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * any NetworkRequests it may be able to satisfy in the future.  It may
623192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * disregard any that it will never be able to service, for example
633192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * those requiring a different bearer.
643192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * msg.obj = NetworkRequest
653192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * msg.arg1 = score - the score of the any network currently satisfying this
663192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            request.  If this bearer knows in advance it cannot
673192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            exceed this score it should not try to connect, holding the request
683192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            for the future.
693192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            Note that subsequent events may give a different (lower
703192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            or higher) score for this request, transmitted to each
713192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            NetworkFactory through additional CMD_REQUEST_NETWORK msgs
723192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            with the same NetworkRequest but an updated score.
733192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            Also, network conditions may change for this bearer
743192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *            allowing for a better score in the future.
753192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     */
763192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public static final int CMD_REQUEST_NETWORK = BASE;
773192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
783192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    /**
793192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Cancel a network request
803192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * msg.obj = NetworkRequest
813192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     */
823192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public static final int CMD_CANCEL_REQUEST = BASE + 1;
833192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
843192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    /**
853192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Internally used to set our best-guess score.
863192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * msg.arg1 = new score
873192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     */
883192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private static final int CMD_SET_SCORE = BASE + 2;
893192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
903192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    /**
913192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Internally used to set our current filter for coarse bandwidth changes with
923192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * technology changes.
933192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * msg.obj = new filter
943192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     */
953192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private static final int CMD_SET_FILTER = BASE + 3;
963192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
973192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private final Context mContext;
983192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private final String LOG_TAG;
993192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1003192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private final SparseArray<NetworkRequestInfo> mNetworkRequests =
1013192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            new SparseArray<NetworkRequestInfo>();
1023192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1033192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private int mScore;
1043192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private NetworkCapabilities mCapabilityFilter;
1053192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1063192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private int mRefCount = 0;
1073192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private Messenger mMessenger = null;
1083192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1093192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public NetworkFactory(Looper looper, Context context, String logTag,
1103192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            NetworkCapabilities filter) {
1113192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        super(looper);
1123192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        LOG_TAG = logTag;
1133192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        mContext = context;
1143192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        mCapabilityFilter = filter;
1153192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1163192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1173192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void register() {
1183192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (DBG) log("Registering NetworkFactory");
1193192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (mMessenger == null) {
1203192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            mMessenger = new Messenger(this);
1213192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);
1223192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
1233192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1243192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1253192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void unregister() {
1263192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (DBG) log("Unregistering NetworkFactory");
1273192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (mMessenger != null) {
1283192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            ConnectivityManager.from(mContext).unregisterNetworkFactory(mMessenger);
1293192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            mMessenger = null;
1303192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
1313192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1323192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1333192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    @Override
1343192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void handleMessage(Message msg) {
1353192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        switch (msg.what) {
1363192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            case CMD_REQUEST_NETWORK: {
1373192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                handleAddRequest((NetworkRequest)msg.obj, msg.arg1);
1383192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                break;
1393192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            }
1403192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            case CMD_CANCEL_REQUEST: {
1413192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                handleRemoveRequest((NetworkRequest) msg.obj);
1423192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                break;
1433192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            }
1443192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            case CMD_SET_SCORE: {
1453192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                handleSetScore(msg.arg1);
1463192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                break;
1473192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            }
1483192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            case CMD_SET_FILTER: {
1493192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                handleSetFilter((NetworkCapabilities) msg.obj);
1503192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                break;
1513192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            }
1523192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
1533192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1543192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1553192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private class NetworkRequestInfo {
1563192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        public final NetworkRequest request;
1573192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        public int score;
1583192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        public boolean requested; // do we have a request outstanding, limited by score
1593192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1603192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        public NetworkRequestInfo(NetworkRequest request, int score) {
1613192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            this.request = request;
1623192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            this.score = score;
1633192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            this.requested = false;
1643192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
1653d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt
1663d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        @Override
1673d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        public String toString() {
1683d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt            return "{" + request + ", score=" + score + ", requested=" + requested + "}";
1693d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        }
1703192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1713192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
172ffa390b6f37f20ab5f4ebf5c861c565db200107eLorenzo Colitti    @VisibleForTesting
173ffa390b6f37f20ab5f4ebf5c861c565db200107eLorenzo Colitti    protected void handleAddRequest(NetworkRequest request, int score) {
1743192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
1753192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (n == null) {
176fc0c6890c675494b15cd847b20c5a5ede491fc3cRobert Greenwalt            if (DBG) log("got request " + request + " with score " + score);
1773192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            n = new NetworkRequestInfo(request, score);
1783192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            mNetworkRequests.put(n.request.requestId, n);
1793192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        } else {
180fc0c6890c675494b15cd847b20c5a5ede491fc3cRobert Greenwalt            if (VDBG) log("new score " + score + " for exisiting request " + request);
1813192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            n.score = score;
1823192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
183fc0c6890c675494b15cd847b20c5a5ede491fc3cRobert Greenwalt        if (VDBG) log("  my score=" + mScore + ", my filter=" + mCapabilityFilter);
1843192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1853192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        evalRequest(n);
1863192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1873192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
188ffa390b6f37f20ab5f4ebf5c861c565db200107eLorenzo Colitti    @VisibleForTesting
189ffa390b6f37f20ab5f4ebf5c861c565db200107eLorenzo Colitti    protected void handleRemoveRequest(NetworkRequest request) {
1903192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
191348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        if (n != null) {
1923192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            mNetworkRequests.remove(request.requestId);
193348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt            if (n.requested) releaseNetworkFor(n.request);
1943192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
1953192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
1963192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
1973192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private void handleSetScore(int score) {
1983192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        mScore = score;
1993192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        evalRequests();
2003192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2013192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2023192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private void handleSetFilter(NetworkCapabilities netCap) {
2033192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        mCapabilityFilter = netCap;
2043192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        evalRequests();
2053192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2063192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2073192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    /**
2083192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Overridable function to provide complex filtering.
2093192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * Called for every request every time a new NetworkRequest is seen
2103192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * and whenever the filterScore or filterNetworkCapabilities change.
2113192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *
2123192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * acceptRequest can be overriden to provide complex filter behavior
2133192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * for the incoming requests
2143192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *
2153192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * For output, this class will call {@link #needNetworkFor} and
2163192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * {@link #releaseNetworkFor} for every request that passes the filters.
2173192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * If you don't need to see every request, you can leave the base
2183192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * implementations of those two functions and instead override
2193192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * {@link #startNetwork} and {@link #stopNetwork}.
2203192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *
2213192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * If you want to see every score fluctuation on every request, set
2223192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * your score filter to a very high number and watch {@link #needNetworkFor}.
2233192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     *
2243192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     * @return {@code true} to accept the request.
2253192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt     */
2263192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public boolean acceptRequest(NetworkRequest request, int score) {
2273192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        return true;
2283192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2293192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2303192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private void evalRequest(NetworkRequestInfo n) {
2312ffe412b0eb8f53043356fe50dc4ceb04d267fa2Robert Greenwalt        if (VDBG) log("evalRequest");
2323192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (n.requested == false && n.score < mScore &&
2333192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                n.request.networkCapabilities.satisfiedByNetworkCapabilities(
2343192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                mCapabilityFilter) && acceptRequest(n.request, n.score)) {
2352ffe412b0eb8f53043356fe50dc4ceb04d267fa2Robert Greenwalt            if (VDBG) log("  needNetworkFor");
2363192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            needNetworkFor(n.request, n.score);
2373192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            n.requested = true;
2383192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        } else if (n.requested == true &&
2393192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                (n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
2403192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
2412ffe412b0eb8f53043356fe50dc4ceb04d267fa2Robert Greenwalt            if (VDBG) log("  releaseNetworkFor");
2423192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            releaseNetworkFor(n.request);
2433192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            n.requested = false;
2442ffe412b0eb8f53043356fe50dc4ceb04d267fa2Robert Greenwalt        } else {
2452ffe412b0eb8f53043356fe50dc4ceb04d267fa2Robert Greenwalt            if (VDBG) log("  done");
2463192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
2473192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2483192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2493192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    private void evalRequests() {
2503192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        for (int i = 0; i < mNetworkRequests.size(); i++) {
2513192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            NetworkRequestInfo n = mNetworkRequests.valueAt(i);
2523192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2533192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt            evalRequest(n);
2543192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        }
2553192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2563192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2573192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    // override to do simple mode (request independent)
2583192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    protected void startNetwork() { }
2593192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    protected void stopNetwork() { }
2603192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2613192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    // override to do fancier stuff
2623192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    protected void needNetworkFor(NetworkRequest networkRequest, int score) {
2633192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (++mRefCount == 1) startNetwork();
2643192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2653192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2663192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    protected void releaseNetworkFor(NetworkRequest networkRequest) {
2673192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        if (--mRefCount == 0) stopNetwork();
2683192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2693192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2703192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2713192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void addNetworkRequest(NetworkRequest networkRequest, int score) {
2723192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        sendMessage(obtainMessage(CMD_REQUEST_NETWORK,
2733192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt                new NetworkRequestInfo(networkRequest, score)));
2743192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2753192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2763192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void removeNetworkRequest(NetworkRequest networkRequest) {
2773192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        sendMessage(obtainMessage(CMD_CANCEL_REQUEST, networkRequest));
2783192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2793192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2803192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void setScoreFilter(int score) {
2813192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
2823192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2833192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
2843192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    public void setCapabilityFilter(NetworkCapabilities netCap) {
2853192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
2863192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2873192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt
288348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    @VisibleForTesting
289348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    protected int getRequestCount() {
290348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt        return mNetworkRequests.size();
291348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt    }
292348e98dba046a33c4ba6069ef7a6ac18c2040fe2Robert Greenwalt
2933192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    protected void log(String s) {
2943192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt        Log.d(LOG_TAG, s);
2953192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt    }
2966b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt
2973d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2983d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
2993d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        pw.println(toString());
3003d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        pw.increaseIndent();
3013d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        for (int i = 0; i < mNetworkRequests.size(); i++) {
3023d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt            pw.println(mNetworkRequests.valueAt(i));
3033d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        }
3043d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt        pw.decreaseIndent();
3053d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt    }
3063d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt
3076b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt    @Override
3086b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt    public String toString() {
3096b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt        StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter=").
3106b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt                append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=").
3113d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt                append(mNetworkRequests.size()).append(", refCount=").append(mRefCount).
3123d68dee11913cc271c248652b3a90c6a127da36cRobert Greenwalt                append("}");
3136b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt        return sb.toString();
3146b746b5e142a26629f8cbe3f6e637be1ab775e81Robert Greenwalt    }
3153192dec32180f56733e631c2d9ec62fa1359283dRobert Greenwalt}
316