1 /* 2 * Copyright (C) 2019 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.ip; 18 19 import android.annotation.Hide; 20 import android.annotation.NonNull; 21 import android.net.NattKeepalivePacketData; 22 import android.net.ProxyInfo; 23 import android.net.TcpKeepalivePacketData; 24 import android.net.TcpKeepalivePacketDataParcelable; 25 import android.net.shared.Layer2Information; 26 import android.net.shared.ProvisioningConfiguration; 27 import android.net.util.KeepalivePacketDataUtil; 28 import android.os.Binder; 29 import android.os.RemoteException; 30 import android.util.Log; 31 32 /** 33 * A convenience wrapper for IpClient. 34 * 35 * Wraps IIpClient calls, making them a bit more friendly to use. Currently handles: 36 * - Clearing calling identity 37 * - Ignoring RemoteExceptions 38 * - Converting to stable parcelables 39 * 40 * By design, all methods on IIpClient are asynchronous oneway IPCs and are thus void. All the 41 * wrapper methods in this class return a boolean that callers can use to determine whether 42 * RemoteException was thrown. 43 */ 44 @Hide 45 public class IpClientManager { 46 @NonNull private final IIpClient mIpClient; 47 @NonNull private final String mTag; 48 IpClientManager(@onNull IIpClient ipClient, @NonNull String tag)49 public IpClientManager(@NonNull IIpClient ipClient, @NonNull String tag) { 50 mIpClient = ipClient; 51 mTag = tag; 52 } 53 IpClientManager(@onNull IIpClient ipClient)54 public IpClientManager(@NonNull IIpClient ipClient) { 55 this(ipClient, IpClientManager.class.getSimpleName()); 56 } 57 log(String s, Throwable e)58 private void log(String s, Throwable e) { 59 Log.e(mTag, s, e); 60 } 61 62 /** 63 * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be 64 * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to 65 * proceed. 66 */ completedPreDhcpAction()67 public boolean completedPreDhcpAction() { 68 final long token = Binder.clearCallingIdentity(); 69 try { 70 mIpClient.completedPreDhcpAction(); 71 return true; 72 } catch (RemoteException e) { 73 log("Error completing PreDhcpAction", e); 74 return false; 75 } finally { 76 Binder.restoreCallingIdentity(token); 77 } 78 } 79 80 /** 81 * Confirm the provisioning configuration. 82 */ confirmConfiguration()83 public boolean confirmConfiguration() { 84 final long token = Binder.clearCallingIdentity(); 85 try { 86 mIpClient.confirmConfiguration(); 87 return true; 88 } catch (RemoteException e) { 89 log("Error confirming IpClient configuration", e); 90 return false; 91 } finally { 92 Binder.restoreCallingIdentity(token); 93 } 94 } 95 96 /** 97 * Indicate that packet filter read is complete. 98 */ readPacketFilterComplete(byte[] data)99 public boolean readPacketFilterComplete(byte[] data) { 100 final long token = Binder.clearCallingIdentity(); 101 try { 102 mIpClient.readPacketFilterComplete(data); 103 return true; 104 } catch (RemoteException e) { 105 log("Error notifying IpClient of packet filter read", e); 106 return false; 107 } finally { 108 Binder.restoreCallingIdentity(token); 109 } 110 } 111 112 /** 113 * Shut down this IpClient instance altogether. 114 */ shutdown()115 public boolean shutdown() { 116 final long token = Binder.clearCallingIdentity(); 117 try { 118 mIpClient.shutdown(); 119 return true; 120 } catch (RemoteException e) { 121 log("Error shutting down IpClient", e); 122 return false; 123 } finally { 124 Binder.restoreCallingIdentity(token); 125 } 126 } 127 128 /** 129 * Start provisioning with the provided parameters. 130 */ startProvisioning(ProvisioningConfiguration prov)131 public boolean startProvisioning(ProvisioningConfiguration prov) { 132 final long token = Binder.clearCallingIdentity(); 133 try { 134 mIpClient.startProvisioning(prov.toStableParcelable()); 135 return true; 136 } catch (RemoteException e) { 137 log("Error starting IpClient provisioning", e); 138 return false; 139 } finally { 140 Binder.restoreCallingIdentity(token); 141 } 142 } 143 144 /** 145 * Stop this IpClient. 146 * 147 * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. 148 */ stop()149 public boolean stop() { 150 final long token = Binder.clearCallingIdentity(); 151 try { 152 mIpClient.stop(); 153 return true; 154 } catch (RemoteException e) { 155 log("Error stopping IpClient", e); 156 return false; 157 } finally { 158 Binder.restoreCallingIdentity(token); 159 } 160 } 161 162 /** 163 * Set the TCP buffer sizes to use. 164 * 165 * This may be called, repeatedly, at any time before or after a call to 166 * #startProvisioning(). The setting is cleared upon calling #stop(). 167 */ setTcpBufferSizes(String tcpBufferSizes)168 public boolean setTcpBufferSizes(String tcpBufferSizes) { 169 final long token = Binder.clearCallingIdentity(); 170 try { 171 mIpClient.setTcpBufferSizes(tcpBufferSizes); 172 return true; 173 } catch (RemoteException e) { 174 log("Error setting IpClient TCP buffer sizes", e); 175 return false; 176 } finally { 177 Binder.restoreCallingIdentity(token); 178 } 179 } 180 181 /** 182 * Set the HTTP Proxy configuration to use. 183 * 184 * This may be called, repeatedly, at any time before or after a call to 185 * #startProvisioning(). The setting is cleared upon calling #stop(). 186 */ setHttpProxy(ProxyInfo proxyInfo)187 public boolean setHttpProxy(ProxyInfo proxyInfo) { 188 final long token = Binder.clearCallingIdentity(); 189 try { 190 mIpClient.setHttpProxy(proxyInfo); 191 return true; 192 } catch (RemoteException e) { 193 log("Error setting IpClient proxy", e); 194 return false; 195 } finally { 196 Binder.restoreCallingIdentity(token); 197 } 198 } 199 200 /** 201 * Enable or disable the multicast filter. Attempts to use APF to accomplish the filtering, 202 * if not, Callback.setFallbackMulticastFilter() is called. 203 */ setMulticastFilter(boolean enabled)204 public boolean setMulticastFilter(boolean enabled) { 205 final long token = Binder.clearCallingIdentity(); 206 try { 207 mIpClient.setMulticastFilter(enabled); 208 return true; 209 } catch (RemoteException e) { 210 log("Error setting multicast filter", e); 211 return false; 212 } finally { 213 Binder.restoreCallingIdentity(token); 214 } 215 } 216 217 /** 218 * Add a TCP keepalive packet filter before setting up keepalive offload. 219 */ addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt)220 public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt) { 221 return addKeepalivePacketFilter(slot, KeepalivePacketDataUtil.toStableParcelable(pkt)); 222 } 223 224 /** 225 * Add a TCP keepalive packet filter before setting up keepalive offload. 226 * @deprecated This method is for use on pre-S platforms where TcpKeepalivePacketData is not 227 * system API. On newer platforms use 228 * addKeepalivePacketFilter(int, TcpKeepalivePacketData) instead. 229 */ 230 @Deprecated addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt)231 public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) { 232 final long token = Binder.clearCallingIdentity(); 233 try { 234 mIpClient.addKeepalivePacketFilter(slot, pkt); 235 return true; 236 } catch (RemoteException e) { 237 log("Error adding Keepalive Packet Filter ", e); 238 return false; 239 } finally { 240 Binder.restoreCallingIdentity(token); 241 } 242 } 243 244 /** 245 * Add a NAT-T keepalive packet filter before setting up keepalive offload. 246 */ addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt)247 public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) { 248 final long token = Binder.clearCallingIdentity(); 249 try { 250 mIpClient.addNattKeepalivePacketFilter( 251 slot, KeepalivePacketDataUtil.toStableParcelable(pkt)); 252 return true; 253 } catch (RemoteException e) { 254 log("Error adding NAT-T Keepalive Packet Filter ", e); 255 return false; 256 } finally { 257 Binder.restoreCallingIdentity(token); 258 } 259 } 260 261 /** 262 * Remove a keepalive packet filter after stopping keepalive offload. 263 */ removeKeepalivePacketFilter(int slot)264 public boolean removeKeepalivePacketFilter(int slot) { 265 final long token = Binder.clearCallingIdentity(); 266 try { 267 mIpClient.removeKeepalivePacketFilter(slot); 268 return true; 269 } catch (RemoteException e) { 270 log("Error removing Keepalive Packet Filter ", e); 271 return false; 272 } finally { 273 Binder.restoreCallingIdentity(token); 274 } 275 } 276 277 /** 278 * Set the L2 key and group hint for storing info into the memory store. 279 */ setL2KeyAndGroupHint(String l2Key, String groupHint)280 public boolean setL2KeyAndGroupHint(String l2Key, String groupHint) { 281 final long token = Binder.clearCallingIdentity(); 282 try { 283 mIpClient.setL2KeyAndGroupHint(l2Key, groupHint); 284 return true; 285 } catch (RemoteException e) { 286 log("Failed setL2KeyAndGroupHint", e); 287 return false; 288 } finally { 289 Binder.restoreCallingIdentity(token); 290 } 291 } 292 293 /** 294 * Notify IpClient that preconnection is complete and that the link is ready for use. 295 * The success parameter indicates whether the packets passed in by 'onPreconnectionStart' 296 * were successfully sent to the network or not. 297 */ notifyPreconnectionComplete(boolean success)298 public boolean notifyPreconnectionComplete(boolean success) { 299 final long token = Binder.clearCallingIdentity(); 300 try { 301 mIpClient.notifyPreconnectionComplete(success); 302 return true; 303 } catch (RemoteException e) { 304 log("Error notifying IpClient Preconnection completed", e); 305 return false; 306 } finally { 307 Binder.restoreCallingIdentity(token); 308 } 309 } 310 311 /** 312 * Update the bssid, L2 key and group hint layer2 information. 313 */ updateLayer2Information(Layer2Information info)314 public boolean updateLayer2Information(Layer2Information info) { 315 final long token = Binder.clearCallingIdentity(); 316 try { 317 mIpClient.updateLayer2Information(info.toStableParcelable()); 318 return true; 319 } catch (RemoteException e) { 320 log("Error updating layer2 information", e); 321 return false; 322 } finally { 323 Binder.restoreCallingIdentity(token); 324 } 325 } 326 } 327