| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony.mocks; |
| |
| import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; |
| import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; |
| import static android.net.ConnectivityManager.NETID_UNSET; |
| import static android.net.ConnectivityManager.TYPE_NONE; |
| import static android.net.ConnectivityManager.TYPE_VPN; |
| import static android.net.ConnectivityManager.getNetworkTypeName; |
| import static android.net.ConnectivityManager.isNetworkTypeValid; |
| import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; |
| import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; |
| import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; |
| import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; |
| import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; |
| import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; |
| import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; |
| import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; |
| |
| import android.annotation.Nullable; |
| import android.app.AlarmManager; |
| import android.app.BroadcastOptions; |
| import android.app.Notification; |
| import android.app.NotificationManager; |
| import android.app.PendingIntent; |
| import android.content.BroadcastReceiver; |
| import android.content.ContentResolver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.pm.PackageManager; |
| import android.content.res.Configuration; |
| import android.content.res.Resources; |
| import android.database.ContentObserver; |
| import android.net.ConnectivityManager; |
| import android.net.ConnectivityManager.PacketKeepalive; |
| import android.net.IConnectivityManager; |
| import android.net.INetworkManagementEventObserver; |
| import android.net.INetworkPolicyListener; |
| import android.net.INetworkPolicyManager; |
| import android.net.INetworkStatsService; |
| import android.net.LinkProperties; |
| import android.net.LinkProperties.CompareResult; |
| import android.net.Network; |
| import android.net.NetworkAgent; |
| import android.net.NetworkCapabilities; |
| import android.net.NetworkConfig; |
| import android.net.NetworkInfo; |
| import android.net.NetworkInfo.DetailedState; |
| import android.net.NetworkMisc; |
| import android.net.NetworkQuotaInfo; |
| import android.net.NetworkRequest; |
| import android.net.NetworkState; |
| import android.net.NetworkUtils; |
| import android.net.Proxy; |
| import android.net.ProxyInfo; |
| import android.net.RouteInfo; |
| import android.net.UidRange; |
| import android.net.Uri; |
| import android.os.Binder; |
| import android.os.Build; |
| import android.os.Bundle; |
| import android.os.FileUtils; |
| import android.os.Handler; |
| import android.os.HandlerThread; |
| import android.os.IBinder; |
| import android.os.INetworkManagementService; |
| import android.os.Looper; |
| import android.os.Message; |
| import android.os.Messenger; |
| import android.os.ParcelFileDescriptor; |
| import android.os.PowerManager; |
| import android.os.Process; |
| import android.os.RemoteException; |
| import android.os.ResultReceiver; |
| import android.os.SystemClock; |
| import android.os.SystemProperties; |
| import android.os.UserHandle; |
| import android.os.UserManager; |
| import android.provider.Settings; |
| import android.security.Credentials; |
| import android.security.KeyStore; |
| import android.telephony.TelephonyManager; |
| import android.text.TextUtils; |
| import android.util.LocalLog; |
| import android.util.LocalLog.ReadOnlyLocalLog; |
| import android.util.Pair; |
| import android.util.Slog; |
| import android.util.SparseArray; |
| import android.util.SparseBooleanArray; |
| import android.util.SparseIntArray; |
| import android.util.Xml; |
| |
| import com.android.internal.R; |
| import com.android.internal.annotations.GuardedBy; |
| import com.android.internal.annotations.VisibleForTesting; |
| import com.android.internal.net.LegacyVpnInfo; |
| import com.android.internal.net.VpnConfig; |
| import com.android.internal.net.VpnInfo; |
| import com.android.internal.net.VpnProfile; |
| import com.android.internal.util.AsyncChannel; |
| import com.android.server.connectivity.NetworkAgentInfo; |
| import com.android.server.connectivity.NetworkMonitor; |
| |
| import java.io.File; |
| import java.io.FileDescriptor; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.net.Inet4Address; |
| import java.net.InetAddress; |
| import java.net.UnknownHostException; |
| import java.util.ArrayDeque; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| /** |
| * @hide |
| */ |
| public class ConnectivityServiceMock extends IConnectivityManager.Stub |
| implements PendingIntent.OnFinished { |
| private static final String TAG = "ConnectivityServiceMock"; |
| private static final boolean DBG = true; |
| private static final boolean VDBG = true; |
| |
| /** |
| * used internally when registering NetworkFactories |
| * obj = NetworkFactoryInfo |
| */ |
| private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; |
| |
| /** |
| * used internally when registering NetworkAgents |
| * obj = Messenger |
| */ |
| private static final int EVENT_REGISTER_NETWORK_AGENT = 18; |
| |
| /** |
| * used to add a network request |
| * includes a NetworkRequestInfo |
| */ |
| private static final int EVENT_REGISTER_NETWORK_REQUEST = 19; |
| |
| /** |
| * used to add a network listener - no request |
| * includes a NetworkRequestInfo |
| */ |
| private static final int EVENT_REGISTER_NETWORK_LISTENER = 21; |
| |
| /** |
| * used to remove a network request, either a listener or a real request |
| * arg1 = UID of caller |
| * obj = NetworkRequest |
| */ |
| private static final int EVENT_RELEASE_NETWORK_REQUEST = 22; |
| |
| /** |
| * used internally when registering NetworkFactories |
| * obj = Messenger |
| */ |
| private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23; |
| |
| |
| private final HandlerThread mHandlerThread; |
| /** Handler used for internal events. */ |
| final private InternalHandler mHandler; |
| /** Handler used for incoming {@link NetworkStateTracker} events. */ |
| final private NetworkStateTrackerHandler mTrackerHandler; |
| |
| final private Context mContext; |
| |
| public ConnectivityServiceMock(Context context) { |
| if (DBG) log("starting up"); |
| |
| mContext = context; |
| mHandlerThread = new HandlerThread("ConnectivityServiceMock"); |
| mHandlerThread.start(); |
| mHandler = new InternalHandler(mHandlerThread.getLooper()); |
| mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); |
| } |
| |
| public void die() { |
| // clean up threads/handlers |
| } |
| |
| private class InternalHandler extends Handler { |
| public InternalHandler(Looper looper) { |
| super(looper); |
| } |
| |
| @Override |
| public void handleMessage(Message msg) { |
| switch (msg.what) { |
| case EVENT_REGISTER_NETWORK_FACTORY: { |
| handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); |
| break; |
| } |
| case EVENT_UNREGISTER_NETWORK_FACTORY: { |
| handleUnregisterNetworkFactory((Messenger)msg.obj); |
| break; |
| } |
| case EVENT_REGISTER_NETWORK_AGENT: { |
| handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj); |
| break; |
| } |
| case EVENT_REGISTER_NETWORK_REQUEST: |
| case EVENT_REGISTER_NETWORK_LISTENER: { |
| handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj); |
| break; |
| } |
| case EVENT_RELEASE_NETWORK_REQUEST: { |
| handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1); |
| break; |
| } |
| } |
| } |
| } |
| |
| private class NetworkStateTrackerHandler extends Handler { |
| public NetworkStateTrackerHandler(Looper looper) { |
| super(looper); |
| } |
| |
| @Override |
| public void handleMessage(Message msg) { |
| NetworkInfo info; |
| switch (msg.what) { |
| case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { |
| handleAsyncChannelHalfConnect(msg); |
| break; |
| } |
| case AsyncChannel.CMD_CHANNEL_DISCONNECT: { |
| NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); |
| if (nai != null) nai.asyncChannel.disconnect(); |
| break; |
| } |
| case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { |
| handleAsyncChannelDisconnected(msg); |
| break; |
| } |
| } |
| } |
| } |
| |
| private boolean isRequest(NetworkRequest request) { |
| return mNetworkRequests.get(request).isRequest; |
| } |
| |
| private void handleAsyncChannelHalfConnect(Message msg) { |
| AsyncChannel ac = (AsyncChannel) msg.obj; |
| if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { |
| if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { |
| if (VDBG) log("NetworkFactory connected"); |
| // A network factory has connected. Send it all current NetworkRequests. |
| for (NetworkRequestInfo nri : mNetworkRequests.values()) { |
| if (nri.isRequest == false) continue; |
| //NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); |
| NetworkAgentInfo nai = null; |
| ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, |
| (nai != null ? nai.getCurrentScore() : 0), 0, nri.request); |
| } |
| } else { |
| loge("Error connecting NetworkFactory"); |
| mNetworkFactoryInfos.remove(msg.obj); |
| } |
| } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { |
| if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { |
| if (VDBG) log("NetworkAgent connected"); |
| // A network agent has requested a connection. Establish the connection. |
| mNetworkAgentInfos.get(msg.replyTo).asyncChannel. |
| sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); |
| } else { |
| loge("Error connecting NetworkAgent"); |
| NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); |
| //if (nai != null) { |
| // final boolean wasDefault = isDefaultNetwork(nai); |
| // synchronized (mNetworkForNetId) { |
| // mNetworkForNetId.remove(nai.network.netId); |
| // mNetIdInUse.delete(nai.network.netId); |
| // } |
| // // Just in case. |
| // mLegacyTypeTracker.remove(nai, wasDefault); |
| //} |
| } |
| } |
| } |
| |
| private void handleAsyncChannelDisconnected(Message msg) { |
| NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); |
| if (nai != null) { |
| if (DBG) { |
| log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); |
| } |
| // A network agent has disconnected. |
| // TODO - if we move the logic to the network agent (have them disconnect |
| // because they lost all their requests or because their score isn't good) |
| // then they would disconnect organically, report their new state and then |
| // disconnect the channel. |
| //if (nai.networkInfo.isConnected()) { |
| // nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, |
| // null, null); |
| //} |
| //final boolean wasDefault = isDefaultNetwork(nai); |
| //if (wasDefault) { |
| // mDefaultInetConditionPublished = 0; |
| //} |
| //notifyIfacesChanged(); |
| // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied |
| // by other networks that are already connected. Perhaps that can be done by |
| // sending all CALLBACK_LOST messages (for requests, not listens) at the end |
| // of rematchAllNetworksAndRequests |
| //notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); |
| //mKeepaliveTracker.handleStopAllKeepalives(nai, |
| // ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK); |
| nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); |
| mNetworkAgentInfos.remove(msg.replyTo); |
| //updateClat(null, nai.linkProperties, nai); |
| //synchronized (mNetworkForNetId) { |
| // // Remove the NetworkAgent, but don't mark the netId as |
| // // available until we've told netd to delete it below. |
| // mNetworkForNetId.remove(nai.network.netId); |
| //} |
| // Remove all previously satisfied requests. |
| //for (int i = 0; i < nai.networkRequests.size(); i++) { |
| // NetworkRequest request = nai.networkRequests.valueAt(i); |
| // NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId); |
| // if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { |
| // mNetworkForRequestId.remove(request.requestId); |
| // sendUpdatedScoreToFactories(request, 0); |
| // } |
| //} |
| //if (nai.networkRequests.get(mDefaultRequest.requestId) != null) { |
| // removeDataActivityTracking(nai); |
| // notifyLockdownVpn(nai); |
| // requestNetworkTransitionWakelock(nai.name()); |
| //} |
| //mLegacyTypeTracker.remove(nai, wasDefault); |
| //rematchAllNetworksAndRequests(null, 0); |
| //if (nai.created) { |
| // // Tell netd to clean up the configuration for this network |
| // // (routing rules, DNS, etc). |
| // // This may be slow as it requires a lot of netd shelling out to ip and |
| // // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it |
| // // after we've rematched networks with requests which should make a potential |
| // // fallback network the default or requested a new network from the |
| // // NetworkFactories, so network traffic isn't interrupted for an unnecessarily |
| // // long time. |
| // try { |
| // mNetd.removeNetwork(nai.network.netId); |
| // } catch (Exception e) { |
| // loge("Exception removing network: " + e); |
| // } |
| //} |
| //synchronized (mNetworkForNetId) { |
| // mNetIdInUse.delete(nai.network.netId); |
| //} |
| } else { |
| NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo); |
| if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name); |
| } |
| } |
| |
| private void log(String str) { |
| Slog.d(TAG, str); |
| } |
| private void loge(String str) { |
| Slog.e(TAG, str); |
| } |
| |
| // NetworkAgentInfo keyed off its connecting messenger |
| // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays |
| // NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). |
| private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = |
| new HashMap<Messenger, NetworkAgentInfo>(); |
| private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = |
| new HashMap<Messenger, NetworkFactoryInfo>(); |
| private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = |
| new HashMap<NetworkRequest, NetworkRequestInfo>(); |
| |
| private static class NetworkFactoryInfo { |
| public final String name; |
| public final Messenger messenger; |
| public final AsyncChannel asyncChannel; |
| |
| public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) { |
| this.name = name; |
| this.messenger = messenger; |
| this.asyncChannel = asyncChannel; |
| } |
| } |
| |
| private class NetworkRequestInfo implements IBinder.DeathRecipient { |
| static final boolean REQUEST = true; |
| static final boolean LISTEN = false; |
| |
| final NetworkRequest request; |
| final PendingIntent mPendingIntent; |
| boolean mPendingIntentSent; |
| private final IBinder mBinder; |
| final int mPid; |
| final int mUid; |
| final Messenger messenger; |
| final boolean isRequest; |
| |
| NetworkRequestInfo(NetworkRequest r, PendingIntent pi, boolean isRequest) { |
| request = r; |
| mPendingIntent = pi; |
| messenger = null; |
| mBinder = null; |
| mPid = getCallingPid(); |
| mUid = getCallingUid(); |
| this.isRequest = isRequest; |
| } |
| |
| NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, boolean isRequest) { |
| super(); |
| messenger = m; |
| request = r; |
| mBinder = binder; |
| mPid = getCallingPid(); |
| mUid = getCallingUid(); |
| this.isRequest = isRequest; |
| mPendingIntent = null; |
| |
| try { |
| mBinder.linkToDeath(this, 0); |
| } catch (RemoteException e) { |
| binderDied(); |
| } |
| } |
| |
| void unlinkDeathRecipient() { |
| if (mBinder != null) { |
| mBinder.unlinkToDeath(this, 0); |
| } |
| } |
| |
| public void binderDied() { |
| log("ConnectivityService NetworkRequestInfo binderDied(" + |
| request + ", " + mBinder + ")"); |
| releaseNetworkRequest(request); |
| } |
| |
| public String toString() { |
| return (isRequest ? "Request" : "Listen") + |
| " from uid/pid:" + mUid + "/" + mPid + |
| " for " + request + |
| (mPendingIntent == null ? "" : " to trigger " + mPendingIntent); |
| } |
| } |
| |
| |
| // sequence number of NetworkRequests |
| private int mNextNetworkRequestId = 1; |
| private synchronized int nextNetworkRequestId() { |
| return mNextNetworkRequestId++; |
| } |
| |
| @Override |
| public NetworkInfo getActiveNetworkInfo() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public Network getActiveNetwork() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public NetworkInfo getActiveNetworkInfoUnfiltered() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkInfo getNetworkInfo(int networkType) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkInfo[] getAllNetworkInfo() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public Network getNetworkForType(int networkType) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public Network[] getAllNetworks() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean isNetworkSupported(int networkType) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public LinkProperties getActiveLinkProperties() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public LinkProperties getLinkPropertiesForType(int networkType) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public LinkProperties getLinkProperties(Network network) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void requestLinkProperties(NetworkRequest networkRequest) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkCapabilities getNetworkCapabilities(Network network) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void requestNetworkCapabilities(NetworkRequest networkRequest) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkState[] getAllNetworkState() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkQuotaInfo getActiveNetworkQuotaInfo() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean isActiveNetworkMetered() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public int getRestoreDefaultNetworkDelay(int networkType) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public void setAcceptUnvalidated(Network network, boolean accept, boolean always) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public void setAvoidUnvalidated(Network network) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public int tether(String iface) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public int untether(String iface) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public int getLastTetherError(String iface) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetherableUsbRegexs() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetherableWifiRegexs() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetherableBluetoothRegexs() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public int setUsbTethering(boolean enable) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetherableIfaces() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetheredIfaces() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetheringErroredIfaces() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public String[] getTetheredDhcpRanges() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean isTetheringSupported() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void stopTethering(int type) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| |
| public void reportInetCondition(int networkType, int percentage) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public void reportNetworkConnectivity(Network network, boolean hasConnectivity) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public ProxyInfo getProxyForNetwork(Network network) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public void setGlobalProxy(ProxyInfo proxyProperties) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public ProxyInfo getGlobalProxy() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage, |
| int userId) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public ParcelFileDescriptor establishVpn(VpnConfig config) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void startLegacyVpn(VpnProfile profile) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public LegacyVpnInfo getLegacyVpnInfo(int userId) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public VpnInfo[] getAllVpnInfo() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public VpnConfig getVpnConfig(int userId) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean updateLockdownVpn() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdownEnabled) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public String getAlwaysOnVpnPackage(int userId) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public int checkMobileProvisioning(int suggestedTimeOutMs) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public String getMobileProvisioningUrl() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void setProvisioningNotificationVisible(boolean visible, int networkType, |
| String action) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void setAirplaneMode(boolean enable) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, |
| Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { |
| networkCapabilities = new NetworkCapabilities(networkCapabilities); |
| |
| if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) { |
| throw new IllegalArgumentException("Bad timeout specified"); |
| } |
| |
| NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, |
| nextNetworkRequestId(), NetworkRequest.Type.REQUEST); |
| NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder, true); |
| if (DBG) log("requestNetwork for " + nri); |
| |
| mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri)); |
| |
| return networkRequest; |
| } |
| |
| @Override |
| public boolean requestBandwidthUpdate(Network network) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| |
| @Override |
| public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, |
| PendingIntent operation) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void releasePendingNetworkRequest(PendingIntent operation) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, |
| Messenger messenger, IBinder binder) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, |
| PendingIntent operation) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void releaseNetworkRequest(NetworkRequest networkRequest) { |
| mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), |
| 0, networkRequest)); |
| } |
| |
| @Override |
| public void registerNetworkFactory(Messenger messenger, String name) { |
| NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); |
| mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); |
| } |
| |
| private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { |
| if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); |
| mNetworkFactoryInfos.put(nfi.messenger, nfi); |
| nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); |
| } |
| |
| @Override |
| public void unregisterNetworkFactory(Messenger messenger) { |
| mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger)); |
| } |
| |
| private void handleUnregisterNetworkFactory(Messenger messenger) { |
| NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger); |
| if (nfi == null) { |
| loge("Failed to find Messenger in unregisterNetworkFactory"); |
| return; |
| } |
| if (DBG) log("unregisterNetworkFactory for " + nfi.name); |
| } |
| |
| public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, |
| LinkProperties linkProperties, NetworkCapabilities networkCapabilities, |
| int currentScore, NetworkMisc networkMisc) { |
| // final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), |
| // new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties( |
| // linkProperties), new NetworkCapabilities(networkCapabilities), currentScore, |
| // mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this); |
| // synchronized (this) { |
| // nai.networkMonitor.systemReady = mSystemReady; |
| // } |
| // mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); |
| // return nai.network.netId; |
| throw new RuntimeException("not implemented"); |
| } |
| |
| private void handleRegisterNetworkAgent(NetworkAgentInfo na) { |
| if (VDBG) log("Got NetworkAgent Messenger"); |
| // mNetworkAgentInfos.put(na.messenger, na); |
| // synchronized (mNetworkForNetId) { |
| // mNetworkForNetId.put(na.network.netId, na); |
| // } |
| // na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger); |
| // NetworkInfo networkInfo = na.networkInfo; |
| // na.networkInfo = null; |
| // updateNetworkInfo(na, networkInfo); |
| } |
| |
| |
| private void handleRegisterNetworkRequest(NetworkRequestInfo nri) { |
| mNetworkRequests.put(nri.request, nri); |
| if (!nri.isRequest) { |
| for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { |
| if (nri.request.networkCapabilities.hasSignalStrength() && |
| network.satisfiesImmutableCapabilitiesOf(nri.request)) { |
| } |
| } |
| } |
| rematchAllNetworksAndRequests(null, 0); |
| if (nri.isRequest) { |
| sendUpdatedScoreToFactories(nri.request, 0); |
| } |
| } |
| |
| private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) { |
| NetworkRequestInfo nri = mNetworkRequests.get(request); |
| if (nri != null) { |
| if (DBG) log("releasing NetworkRequest " + request); |
| nri.unlinkDeathRecipient(); |
| mNetworkRequests.remove(request); |
| if (nri.isRequest) { |
| // Find all networks that are satisfying this request and remove the request |
| // from their request lists. |
| // TODO - it's my understanding that for a request there is only a single |
| // network satisfying it, so this loop is wasteful |
| //boolean wasKept = false; |
| //for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { |
| // if (nai.networkRequests.get(nri.request.requestId) != null) { |
| // nai.networkRequests.remove(nri.request.requestId); |
| // if (DBG) { |
| // log(" Removing from current network " + nai.name() + |
| // ", leaving " + nai.networkRequests.size() + |
| // " requests."); |
| // } |
| // if (unneeded(nai)) { |
| // if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); |
| // teardownUnneededNetwork(nai); |
| // } else { |
| // // suspect there should only be one pass through here |
| // // but if any were kept do the check below |
| // wasKept |= true; |
| // } |
| // } |
| //} |
| |
| //NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); |
| //if (nai != null) { |
| // mNetworkForRequestId.remove(nri.request.requestId); |
| //} |
| // Maintain the illusion. When this request arrived, we might have pretended |
| // that a network connected to serve it, even though the network was already |
| // connected. Now that this request has gone away, we might have to pretend |
| // that the network disconnected. LegacyTypeTracker will generate that |
| // phantom disconnect for this type. |
| //if (nri.request.legacyType != TYPE_NONE && nai != null) { |
| // boolean doRemove = true; |
| // if (wasKept) { |
| // // check if any of the remaining requests for this network are for the |
| // // same legacy type - if so, don't remove the nai |
| // for (int i = 0; i < nai.networkRequests.size(); i++) { |
| // NetworkRequest otherRequest = nai.networkRequests.valueAt(i); |
| // if (otherRequest.legacyType == nri.request.legacyType && |
| // isRequest(otherRequest)) { |
| // if (DBG) log(" still have other legacy request - leaving"); |
| // doRemove = false; |
| // } |
| // } |
| // } |
| // |
| // if (doRemove) { |
| // mLegacyTypeTracker.remove(nri.request.legacyType, nai, false); |
| // } |
| //} |
| |
| for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { |
| nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, |
| nri.request); |
| } |
| } else { |
| // listens don't have a singular affectedNetwork. Check all networks to see |
| // if this listen request applies and remove it. |
| //for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { |
| // nai.networkRequests.remove(nri.request.requestId); |
| // if (nri.request.networkCapabilities.hasSignalStrength() && |
| // nai.satisfiesImmutableCapabilitiesOf(nri.request)) { |
| // updateSignalStrengthThresholds(nai, "RELEASE", nri.request); |
| // } |
| //} |
| } |
| //callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED); |
| } |
| } |
| |
| private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) { |
| for (int i = 0; i < nai.numNetworkRequests(); i++) { |
| NetworkRequest nr = nai.requestAt(i); |
| // Don't send listening requests to factories. b/17393458 |
| if (!isRequest(nr)) continue; |
| sendUpdatedScoreToFactories(nr, nai.getCurrentScore()); |
| } |
| } |
| |
| private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) { |
| if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString()); |
| for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) { |
| nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0, |
| networkRequest); |
| } |
| } |
| |
| private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) { |
| } |
| |
| @Override |
| public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, |
| String resultData, Bundle resultExtras) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean addVpnAddress(String address, int prefixLength) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean removeVpnAddress(String address, int prefixLength) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public boolean setUnderlyingNetworksForVpn(Network[] networks) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public String getCaptivePortalServerUrl() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, |
| IBinder binder, String srcAddr, int srcPort, String dstAddr) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void stopKeepalive(Network network, int slot) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @Override |
| public void factoryReset() { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @VisibleForTesting |
| public NetworkMonitor createNetworkMonitor(Context context, Handler handler, |
| NetworkAgentInfo nai, NetworkRequest defaultRequest) { |
| throw new RuntimeException("not implemented"); |
| } |
| |
| @VisibleForTesting |
| public NetworkRequest defaultRequest = null; |
| @VisibleForTesting |
| public synchronized void addDefaultRequest() { |
| if (defaultRequest != null) return; |
| NetworkCapabilities netCap = new NetworkCapabilities(); |
| netCap.addCapability(NET_CAPABILITY_INTERNET); |
| netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED); |
| defaultRequest = requestNetwork(netCap, null, 0, new Binder(), |
| ConnectivityManager.TYPE_NONE); |
| } |
| |
| @VisibleForTesting |
| public synchronized void setCurrentScoreForRequest(NetworkRequest nr, int score) { |
| sendUpdatedScoreToFactories(nr, score); |
| } |
| |
| @VisibleForTesting |
| public synchronized void removeDefaultRequest() { |
| if (defaultRequest == null) return; |
| releaseNetworkRequest(defaultRequest); |
| defaultRequest = null; |
| } |
| |
| |
| } |