UpstreamNetworkMonitor.java revision b583b03675492280ab87f1eff30c05709cafba23
19bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline/* 29bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * Copyright (C) 2017 The Android Open Source Project 39bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 49bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * Licensed under the Apache License, Version 2.0 (the "License"); 59bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * you may not use this file except in compliance with the License. 69bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * You may obtain a copy of the License at 79bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 89bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * http://www.apache.org/licenses/LICENSE-2.0 99bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 109bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * Unless required by applicable law or agreed to in writing, software 119bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * distributed under the License is distributed on an "AS IS" BASIS, 129bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * See the License for the specific language governing permissions and 149bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * limitations under the License. 159bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline */ 169bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 179bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klinepackage com.android.server.connectivity.tethering; 189bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 19dd8e8911c69dd68d268f892373b174bc7b422db8Erik Klineimport static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 20dd8e8911c69dd68d268f892373b174bc7b422db8Erik Klineimport static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; 21dd8e8911c69dd68d268f892373b174bc7b422db8Erik Kline 229bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.content.Context; 23b583b03675492280ab87f1eff30c05709cafba23Erik Klineimport android.os.Handler; 24b583b03675492280ab87f1eff30c05709cafba23Erik Klineimport android.os.Looper; 259bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.ConnectivityManager; 269bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.ConnectivityManager.NetworkCallback; 279bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.LinkProperties; 289bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.Network; 299bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.NetworkCapabilities; 309bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.NetworkRequest; 319bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.net.NetworkState; 329bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport android.util.Log; 339bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 34885a9098cf19eaee5a164c5ca771aec5926f2efdErik Klineimport com.android.internal.annotations.VisibleForTesting; 359bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport com.android.internal.util.StateMachine; 369bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 379bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klineimport java.util.HashMap; 389bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 399bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 409bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline/** 419bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * A class to centralize all the network and link properties information 429bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * pertaining to the current and any potential upstream network. 439bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 449bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * Calling #start() registers two callbacks: one to track the system default 45d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * network and a second to observe all networks. The latter is necessary 46d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * while the expression of preferred upstreams remains a list of legacy 47d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * connectivity types. In future, this can be revisited. 489bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 499bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * The methods and data members of this class are only to be accessed and 509bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * modified from the tethering master state machine thread. Any other 519bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * access semantics would necessitate the addition of locking. 529bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 539bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * TODO: Move upstream selection logic here. 549bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * 55d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * All callback methods are run on the same thread as the specified target 56d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * state machine. This class does not require locking when accessed from this 57d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * thread. Access from other threads is not advised. 58d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline * 599bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline * @hide 609bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline */ 619bba340fd4edd5aea91d612a332f964b0d63cf34Erik Klinepublic class UpstreamNetworkMonitor { 629bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private static final String TAG = UpstreamNetworkMonitor.class.getSimpleName(); 639bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private static final boolean DBG = false; 649bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private static final boolean VDBG = false; 659bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 669bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public static final int EVENT_ON_AVAILABLE = 1; 679bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public static final int EVENT_ON_CAPABILITIES = 2; 689bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public static final int EVENT_ON_LINKPROPERTIES = 3; 699bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public static final int EVENT_ON_LOST = 4; 709bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 7135bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline private static final int CALLBACK_LISTEN_ALL = 1; 7235bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline private static final int CALLBACK_TRACK_DEFAULT = 2; 7335bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline private static final int CALLBACK_MOBILE_REQUEST = 3; 74d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 759bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private final Context mContext; 769bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private final StateMachine mTarget; 77b583b03675492280ab87f1eff30c05709cafba23Erik Kline private final Handler mHandler; 789bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private final int mWhat; 799bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>(); 809bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private ConnectivityManager mCM; 81d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline private NetworkCallback mListenAllCallback; 829bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private NetworkCallback mDefaultNetworkCallback; 839bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private NetworkCallback mMobileNetworkCallback; 849bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private boolean mDunRequired; 85d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline private Network mCurrentDefault; 869bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 879bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, int what) { 889bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mContext = ctx; 899bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mTarget = tgt; 90b583b03675492280ab87f1eff30c05709cafba23Erik Kline mHandler = mTarget.getHandler(); 919bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mWhat = what; 929bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 939bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 94885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline @VisibleForTesting 95885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline public UpstreamNetworkMonitor(StateMachine tgt, int what, ConnectivityManager cm) { 96885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline this(null, tgt, what); 97885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline mCM = cm; 98885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline } 99885a9098cf19eaee5a164c5ca771aec5926f2efdErik Kline 1009bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void start() { 1019bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline stop(); 1029bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 103d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline final NetworkRequest listenAllRequest = new NetworkRequest.Builder() 104d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline .clearCapabilities().build(); 10535bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL); 106b583b03675492280ab87f1eff30c05709cafba23Erik Kline cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler); 1079bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 10835bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT); 109b583b03675492280ab87f1eff30c05709cafba23Erik Kline cm().registerDefaultNetworkCallback(mDefaultNetworkCallback, mHandler); 1109bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1119bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1129bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void stop() { 1139bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline releaseMobileNetworkRequest(); 1149bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1159bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline releaseCallback(mDefaultNetworkCallback); 1169bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mDefaultNetworkCallback = null; 1179bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 118d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline releaseCallback(mListenAllCallback); 119d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline mListenAllCallback = null; 1209bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1219bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mNetworkMap.clear(); 1229bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1239bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 124efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline public void updateMobileRequiresDun(boolean dunRequired) { 1259bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline final boolean valueChanged = (mDunRequired != dunRequired); 1269bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mDunRequired = dunRequired; 1279bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (valueChanged && mobileNetworkRequested()) { 1289bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline releaseMobileNetworkRequest(); 1299bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline registerMobileNetworkRequest(); 1309bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1319bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1329bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1339bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public boolean mobileNetworkRequested() { 1349bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return (mMobileNetworkCallback != null); 1359bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1369bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1379bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void registerMobileNetworkRequest() { 138efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline if (mMobileNetworkCallback != null) { 139efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline Log.e(TAG, "registerMobileNetworkRequest() already registered"); 140efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline return; 141efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline } 1429bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 14335bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline // The following use of the legacy type system cannot be removed until 14435bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline // after upstream selection no longer finds networks by legacy type. 14535bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline // See also http://b/34364553 . 14635bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI; 14735bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline 14835bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder() 14935bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType)) 15035bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline .build(); 1519bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1529bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline // The existing default network and DUN callbacks will be notified. 1539bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline // Therefore, to avoid duplicate notifications, we only register a no-op. 15435bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline mMobileNetworkCallback = new UpstreamNetworkCallback(CALLBACK_MOBILE_REQUEST); 1559bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 156efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline // TODO: Change the timeout from 0 (no onUnavailable callback) to some 157efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline // moderate callback timeout. This might be useful for updating some UI. 158efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline // Additionally, we log a message to aid in any subsequent debugging. 159efdd3f4ce04d3e1741831982ff86a58da6b542d3Erik Kline Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest); 1609bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 161b583b03675492280ab87f1eff30c05709cafba23Erik Kline cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler); 1629bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1639bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1649bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void releaseMobileNetworkRequest() { 1659bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (mMobileNetworkCallback == null) return; 1669bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1679bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline cm().unregisterNetworkCallback(mMobileNetworkCallback); 1689bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mMobileNetworkCallback = null; 1699bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1709bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 1719bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public NetworkState lookup(Network network) { 1729bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return (network != null) ? mNetworkMap.get(network) : null; 1739bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1749bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 175d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline private void handleAvailable(int callbackType, Network network) { 176d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline if (VDBG) Log.d(TAG, "EVENT_ON_AVAILABLE for " + network); 177d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 1789bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (!mNetworkMap.containsKey(network)) { 1799bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mNetworkMap.put(network, 1809bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline new NetworkState(null, null, null, network, null, null)); 1819bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 1829bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 183d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Always request whatever extra information we can, in case this 184d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // was already up when start() was called, in which case we would 185d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // not have been notified of any information that had not changed. 18635bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline switch (callbackType) { 18735bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline case CALLBACK_LISTEN_ALL: 18835bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline break; 18935bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline case CALLBACK_TRACK_DEFAULT: 19032858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline if (mDefaultNetworkCallback == null) { 19132858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // The callback was unregistered in the interval between 192b583b03675492280ab87f1eff30c05709cafba23Erik Kline // ConnectivityService enqueueing onAvailable() and our 193b583b03675492280ab87f1eff30c05709cafba23Erik Kline // handling of it here on the mHandler thread. 194b583b03675492280ab87f1eff30c05709cafba23Erik Kline // 19532858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // Clean-up of this network entry is deferred to the 19632858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // handling of onLost() by other callbacks. 197b583b03675492280ab87f1eff30c05709cafba23Erik Kline // 198b583b03675492280ab87f1eff30c05709cafba23Erik Kline // These request*() calls can be deleted post oag/339444. 19932858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline return; 20032858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline } 20132858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline 20235bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline cm().requestNetworkCapabilities(mDefaultNetworkCallback); 20335bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline cm().requestLinkProperties(mDefaultNetworkCallback); 20435bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline mCurrentDefault = network; 20535bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline break; 20635bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline case CALLBACK_MOBILE_REQUEST: 20732858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline if (mMobileNetworkCallback == null) { 20832858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // The callback was unregistered in the interval between 209b583b03675492280ab87f1eff30c05709cafba23Erik Kline // ConnectivityService enqueueing onAvailable() and our 210b583b03675492280ab87f1eff30c05709cafba23Erik Kline // handling of it here on the mHandler thread. 211b583b03675492280ab87f1eff30c05709cafba23Erik Kline // 21232858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // Clean-up of this network entry is deferred to the 21332858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline // handling of onLost() by other callbacks. 214b583b03675492280ab87f1eff30c05709cafba23Erik Kline // 215b583b03675492280ab87f1eff30c05709cafba23Erik Kline // These request*() calls can be deleted post oag/339444. 21632858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline return; 21732858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline } 21832858e14caa09fbb3eb4081f114f2a99181c9643Erik Kline 21935bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline cm().requestNetworkCapabilities(mMobileNetworkCallback); 22035bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline cm().requestLinkProperties(mMobileNetworkCallback); 22135bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline break; 222d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline } 2239bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 224d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Requesting updates for mListenAllCallback is not currently possible 225d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // because it's a "listen". Two possible solutions to getting updates 226d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // about networks without waiting for a change (which might never come) 227d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // are: 228d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // 229d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // [1] extend request{NetworkCapabilities,LinkProperties}() to 230d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // take a Network argument and have ConnectivityService do 231d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // what's required (if the network satisfies the request) 232d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // 233d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // [2] explicitly file a NetworkRequest for each connectivity type 234d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // listed as a preferred upstream and wait for these callbacks 235d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // to be notified (requires tracking many more callbacks). 236d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // 237d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Until this is addressed, networks that exist prior to the "listen" 238d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // registration and which do not subsequently change will not cause 239d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // us to learn their NetworkCapabilities nor their LinkProperties. 240d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 241d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // TODO: If sufficient information is available to select a more 242d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // preferable upstream, do so now and notify the target. 2439bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline notifyTarget(EVENT_ON_AVAILABLE, network); 2449bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 2459bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 2469bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private void handleNetCap(Network network, NetworkCapabilities newNc) { 247d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline final NetworkState prev = mNetworkMap.get(network); 248d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline if (prev == null || newNc.equals(prev.networkCapabilities)) { 249d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Ignore notifications about networks for which we have not yet 250d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // received onAvailable() (should never happen) and any duplicate 251d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // notifications (e.g. matching more than one of our callbacks). 2529bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return; 2539bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 254d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 2559bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (VDBG) { 2569bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline Log.d(TAG, String.format("EVENT_ON_CAPABILITIES for %s: %s", 2579bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline network, newNc)); 2589bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 2599bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 260d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline mNetworkMap.put(network, new NetworkState( 261d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline null, prev.linkProperties, newNc, network, null, null)); 262d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // TODO: If sufficient information is available to select a more 263d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // preferable upstream, do so now and notify the target. 2649bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline notifyTarget(EVENT_ON_CAPABILITIES, network); 2659bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 2669bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 2679bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private void handleLinkProp(Network network, LinkProperties newLp) { 268d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline final NetworkState prev = mNetworkMap.get(network); 269d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline if (prev == null || newLp.equals(prev.linkProperties)) { 270d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Ignore notifications about networks for which we have not yet 271d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // received onAvailable() (should never happen) and any duplicate 272d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // notifications (e.g. matching more than one of our callbacks). 2739bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return; 2749bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 275d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 2769bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (VDBG) { 2779bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline Log.d(TAG, String.format("EVENT_ON_LINKPROPERTIES for %s: %s", 2789bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline network, newLp)); 2799bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 2809bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 281d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline mNetworkMap.put(network, new NetworkState( 282d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline null, newLp, prev.networkCapabilities, network, null, null)); 283d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // TODO: If sufficient information is available to select a more 284d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // preferable upstream, do so now and notify the target. 2859bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline notifyTarget(EVENT_ON_LINKPROPERTIES, network); 2869bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 2879bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 288d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline private void handleLost(int callbackType, Network network) { 28935bf06c968ecbae502efd9cfb13fff9b7ddf9d6aErik Kline if (callbackType == CALLBACK_TRACK_DEFAULT) { 290d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline mCurrentDefault = null; 291d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Receiving onLost() for a default network does not necessarily 292d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // mean the network is gone. We wait for a separate notification 293d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // on either the LISTEN_ALL or MOBILE_REQUEST callbacks before 294d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // clearing all state. 2959bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return; 2969bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 297d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 298d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline if (!mNetworkMap.containsKey(network)) { 299d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // Ignore loss of networks about which we had not previously 300d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // learned any information or for which we have already processed 301d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // an onLost() notification. 302d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline return; 3039bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 304d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 305d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline if (VDBG) Log.d(TAG, "EVENT_ON_LOST for " + network); 306d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 307d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // TODO: If sufficient information is available to select a more 308d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // preferable upstream, do so now and notify the target. Likewise, 309d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // if the current upstream network is gone, notify the target of the 310d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline // fact that we now have no upstream at all. 3119bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline notifyTarget(EVENT_ON_LOST, mNetworkMap.remove(network)); 3129bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3139bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3149bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline // Fetch (and cache) a ConnectivityManager only if and when we need one. 3159bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private ConnectivityManager cm() { 3169bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (mCM == null) { 3179bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mCM = mContext.getSystemService(ConnectivityManager.class); 3189bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3199bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline return mCM; 3209bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3219bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3229bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline /** 323b583b03675492280ab87f1eff30c05709cafba23Erik Kline * A NetworkCallback class that handles information of interest directly 324b583b03675492280ab87f1eff30c05709cafba23Erik Kline * in the thread on which it is invoked. To avoid locking, this MUST be 325b583b03675492280ab87f1eff30c05709cafba23Erik Kline * run on the same thread as the target state machine's handler. 3269bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline */ 3279bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private class UpstreamNetworkCallback extends NetworkCallback { 328d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline private final int mCallbackType; 329d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 330d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline UpstreamNetworkCallback(int callbackType) { 331d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline mCallbackType = callbackType; 332d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline } 333d2ec3919cb87931b2c143d0c1b98caf37039d882Erik Kline 3349bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline @Override 3359bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void onAvailable(Network network) { 336b583b03675492280ab87f1eff30c05709cafba23Erik Kline checkExpectedThread(); 337b583b03675492280ab87f1eff30c05709cafba23Erik Kline handleAvailable(mCallbackType, network); 3389bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3399bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3409bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline @Override 3419bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) { 342b583b03675492280ab87f1eff30c05709cafba23Erik Kline checkExpectedThread(); 343b583b03675492280ab87f1eff30c05709cafba23Erik Kline handleNetCap(network, newNc); 3449bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3459bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3469bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline @Override 3479bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void onLinkPropertiesChanged(Network network, LinkProperties newLp) { 348b583b03675492280ab87f1eff30c05709cafba23Erik Kline checkExpectedThread(); 349b583b03675492280ab87f1eff30c05709cafba23Erik Kline handleLinkProp(network, newLp); 3509bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3519bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 352b583b03675492280ab87f1eff30c05709cafba23Erik Kline // TODO: Handle onNetworkSuspended(); 353b583b03675492280ab87f1eff30c05709cafba23Erik Kline // TODO: Handle onNetworkResumed(); 354b583b03675492280ab87f1eff30c05709cafba23Erik Kline 3559bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline @Override 3569bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline public void onLost(Network network) { 357b583b03675492280ab87f1eff30c05709cafba23Erik Kline checkExpectedThread(); 358b583b03675492280ab87f1eff30c05709cafba23Erik Kline handleLost(mCallbackType, network); 359b583b03675492280ab87f1eff30c05709cafba23Erik Kline } 360b583b03675492280ab87f1eff30c05709cafba23Erik Kline 361b583b03675492280ab87f1eff30c05709cafba23Erik Kline private void checkExpectedThread() { 362b583b03675492280ab87f1eff30c05709cafba23Erik Kline if (Looper.myLooper() != mHandler.getLooper()) { 363b583b03675492280ab87f1eff30c05709cafba23Erik Kline Log.wtf(TAG, "Handling callback in unexpected thread."); 364b583b03675492280ab87f1eff30c05709cafba23Erik Kline } 3659bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3669bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3679bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3689bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private void releaseCallback(NetworkCallback cb) { 3699bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline if (cb != null) cm().unregisterNetworkCallback(cb); 3709bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3719bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3729bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private void notifyTarget(int which, Network network) { 3739bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline notifyTarget(which, mNetworkMap.get(network)); 3749bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3759bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline 3769bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline private void notifyTarget(int which, NetworkState netstate) { 3779bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline mTarget.sendMessage(mWhat, which, 0, netstate); 3789bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline } 3799bba340fd4edd5aea91d612a332f964b0d63cf34Erik Kline} 380