1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import android.annotation.IntRange; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.RequiresPermission; 23 import android.annotation.SystemApi; 24 import android.content.Context; 25 import android.os.Handler; 26 import android.os.Looper; 27 import android.os.Message; 28 import android.os.Messenger; 29 import android.util.Log; 30 31 /** 32 * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device 33 * to networks and makes them available to to the core network stack by creating 34 * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted 35 * with via networking APIs such as {@link ConnectivityManager}. 36 * 37 * Subclasses should implement {@link #onNetworkRequested} and {@link #onNetworkRequestWithdrawn} 38 * to receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the 39 * best (highest-scoring) network for any request is generally not used by the system, and torn 40 * down. 41 * 42 * @hide 43 */ 44 @SystemApi 45 public class NetworkProvider { 46 /** 47 * {@code providerId} value that indicates the absence of a provider. It is the providerId of 48 * any NetworkProvider that is not currently registered, and of any NetworkRequest that is not 49 * currently being satisfied by a network. 50 */ 51 public static final int ID_NONE = -1; 52 53 /** 54 * A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any 55 * provider, so they use this constant for clarity instead of NONE. 56 * @hide only used by ConnectivityService. 57 */ 58 public static final int ID_VPN = -2; 59 60 /** 61 * The first providerId value that will be allocated. 62 * @hide only used by ConnectivityService. 63 */ 64 public static final int FIRST_PROVIDER_ID = 1; 65 66 /** @hide only used by ConnectivityService */ 67 public static final int CMD_REQUEST_NETWORK = 1; 68 /** @hide only used by ConnectivityService */ 69 public static final int CMD_CANCEL_REQUEST = 2; 70 71 private final Messenger mMessenger; 72 private final String mName; 73 private final ConnectivityManager mCm; 74 75 private int mProviderId = ID_NONE; 76 77 /** 78 * Constructs a new NetworkProvider. 79 * 80 * @param looper the Looper on which to run {@link #onNetworkRequested} and 81 * {@link #onNetworkRequestWithdrawn}. 82 * @param name the name of the listener, used only for debugging. 83 * 84 * @hide 85 */ 86 @SystemApi NetworkProvider(@onNull Context context, @NonNull Looper looper, @NonNull String name)87 public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { 88 mCm = ConnectivityManager.from(context); 89 90 Handler handler = new Handler(looper) { 91 @Override 92 public void handleMessage(Message m) { 93 switch (m.what) { 94 case CMD_REQUEST_NETWORK: 95 onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2); 96 break; 97 case CMD_CANCEL_REQUEST: 98 onNetworkRequestWithdrawn((NetworkRequest) m.obj); 99 break; 100 default: 101 Log.e(mName, "Unhandled message: " + m.what); 102 } 103 } 104 }; 105 mMessenger = new Messenger(handler); 106 mName = name; 107 } 108 109 // TODO: consider adding a register() method so ConnectivityManager does not need to call this. 110 /** @hide */ getMessenger()111 public @Nullable Messenger getMessenger() { 112 return mMessenger; 113 } 114 115 /** @hide */ getName()116 public @NonNull String getName() { 117 return mName; 118 } 119 120 /** 121 * Returns the ID of this provider. This is known only once the provider is registered via 122 * {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}. 123 * This ID must be used when registering any {@link NetworkAgent}s. 124 */ getProviderId()125 public int getProviderId() { 126 return mProviderId; 127 } 128 129 /** @hide */ setProviderId(int providerId)130 public void setProviderId(int providerId) { 131 mProviderId = providerId; 132 } 133 134 /** 135 * Called when a NetworkRequest is received. The request may be a new request or an existing 136 * request with a different score. 137 * 138 * @param request the NetworkRequest being received 139 * @param score the score of the network currently satisfying the request, or 0 if none. 140 * @param providerId the ID of the provider that created the network currently satisfying this 141 * request, or {@link #ID_NONE} if none. 142 * 143 * @hide 144 */ 145 @SystemApi onNetworkRequested(@onNull NetworkRequest request, @IntRange(from = 0, to = 99) int score, int providerId)146 public void onNetworkRequested(@NonNull NetworkRequest request, 147 @IntRange(from = 0, to = 99) int score, int providerId) {} 148 149 /** 150 * Called when a NetworkRequest is withdrawn. 151 * @hide 152 */ 153 @SystemApi onNetworkRequestWithdrawn(@onNull NetworkRequest request)154 public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {} 155 156 /** 157 * Asserts that no provider will ever be able to satisfy the specified request. The provider 158 * must only call this method if it knows that it is the only provider on the system capable of 159 * satisfying this request, and that the request cannot be satisfied. The application filing the 160 * request will receive an {@link NetworkCallback#onUnavailable()} callback. 161 * 162 * @param request the request that permanently cannot be fulfilled 163 * @hide 164 */ 165 @SystemApi 166 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) declareNetworkRequestUnfulfillable(@onNull NetworkRequest request)167 public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { 168 mCm.declareNetworkRequestUnfulfillable(request); 169 } 170 } 171