1 /* 2 * Copyright (C) 2009, 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.vpn; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.ServiceConnection; 24 import android.util.Log; 25 26 /** 27 * The class provides interface to manage all VPN-related tasks, including: 28 * <ul> 29 * <li>The list of supported VPN types. 30 * <li>API's to start/stop the service of a particular type. 31 * <li>API's to start the settings activity. 32 * <li>API's to create a profile. 33 * <li>API's to register/unregister a connectivity receiver and the keys to 34 * access the fields in a connectivity broadcast event. 35 * </ul> 36 * {@hide} 37 */ 38 public class VpnManager { 39 // Action for broadcasting a connectivity state. 40 private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity"; 41 /** Key to the profile name of a connectivity broadcast event. */ 42 public static final String BROADCAST_PROFILE_NAME = "profile_name"; 43 /** Key to the connectivity state of a connectivity broadcast event. */ 44 public static final String BROADCAST_CONNECTION_STATE = "connection_state"; 45 /** Key to the error code of a connectivity broadcast event. */ 46 public static final String BROADCAST_ERROR_CODE = "err"; 47 /** Error code to indicate an error from authentication. */ 48 public static final int VPN_ERROR_AUTH = 51; 49 /** Error code to indicate the connection attempt failed. */ 50 public static final int VPN_ERROR_CONNECTION_FAILED = 101; 51 /** Error code to indicate the server is not known. */ 52 public static final int VPN_ERROR_UNKNOWN_SERVER = 102; 53 /** Error code to indicate an error from challenge response. */ 54 public static final int VPN_ERROR_CHALLENGE = 5; 55 /** Error code to indicate an error of remote server hanging up. */ 56 public static final int VPN_ERROR_REMOTE_HUNG_UP = 7; 57 /** Error code to indicate an error of remote PPP server hanging up. */ 58 public static final int VPN_ERROR_REMOTE_PPP_HUNG_UP = 48; 59 /** Error code to indicate a PPP negotiation error. */ 60 public static final int VPN_ERROR_PPP_NEGOTIATION_FAILED = 42; 61 /** Error code to indicate an error of losing connectivity. */ 62 public static final int VPN_ERROR_CONNECTION_LOST = 103; 63 /** Largest error code used by VPN. */ 64 public static final int VPN_ERROR_LARGEST = 200; 65 /** Error code to indicate a successful connection. */ 66 public static final int VPN_ERROR_NO_ERROR = 0; 67 68 public static final String PROFILES_PATH = "/data/misc/vpn/profiles"; 69 70 private static final String PACKAGE_PREFIX = 71 VpnManager.class.getPackage().getName() + "."; 72 73 // Action to start VPN service 74 private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE"; 75 76 // Action to start VPN settings 77 private static final String ACTION_VPN_SETTINGS = 78 PACKAGE_PREFIX + "SETTINGS"; 79 80 private static final String TAG = VpnManager.class.getSimpleName(); 81 82 /** 83 * Returns all supported VPN types. 84 */ getSupportedVpnTypes()85 public static VpnType[] getSupportedVpnTypes() { 86 return VpnType.values(); 87 } 88 89 private Context mContext; 90 91 /** 92 * Creates a manager object with the specified context. 93 */ VpnManager(Context c)94 public VpnManager(Context c) { 95 mContext = c; 96 } 97 98 /** 99 * Creates a VPN profile of the specified type. 100 * 101 * @param type the VPN type 102 * @return the profile object 103 */ createVpnProfile(VpnType type)104 public VpnProfile createVpnProfile(VpnType type) { 105 return createVpnProfile(type, false); 106 } 107 108 /** 109 * Creates a VPN profile of the specified type. 110 * 111 * @param type the VPN type 112 * @param customized true if the profile is custom made 113 * @return the profile object 114 */ createVpnProfile(VpnType type, boolean customized)115 public VpnProfile createVpnProfile(VpnType type, boolean customized) { 116 try { 117 VpnProfile p = (VpnProfile) type.getProfileClass().newInstance(); 118 p.setCustomized(customized); 119 return p; 120 } catch (InstantiationException e) { 121 return null; 122 } catch (IllegalAccessException e) { 123 return null; 124 } 125 } 126 127 /** 128 * Starts the VPN service to establish VPN connection. 129 */ startVpnService()130 public void startVpnService() { 131 mContext.startService(new Intent(ACTION_VPN_SERVICE)); 132 } 133 134 /** 135 * Stops the VPN service. 136 */ stopVpnService()137 public void stopVpnService() { 138 mContext.stopService(new Intent(ACTION_VPN_SERVICE)); 139 } 140 141 /** 142 * Binds the specified ServiceConnection with the VPN service. 143 */ bindVpnService(ServiceConnection c)144 public boolean bindVpnService(ServiceConnection c) { 145 if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) { 146 Log.w(TAG, "failed to connect to VPN service"); 147 return false; 148 } else { 149 Log.d(TAG, "succeeded to connect to VPN service"); 150 return true; 151 } 152 } 153 154 /** Broadcasts the connectivity state of the specified profile. */ broadcastConnectivity(String profileName, VpnState s)155 public void broadcastConnectivity(String profileName, VpnState s) { 156 broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR); 157 } 158 159 /** Broadcasts the connectivity state with an error code. */ broadcastConnectivity(String profileName, VpnState s, int error)160 public void broadcastConnectivity(String profileName, VpnState s, 161 int error) { 162 Intent intent = new Intent(ACTION_VPN_CONNECTIVITY); 163 intent.putExtra(BROADCAST_PROFILE_NAME, profileName); 164 intent.putExtra(BROADCAST_CONNECTION_STATE, s); 165 if (error != VPN_ERROR_NO_ERROR) { 166 intent.putExtra(BROADCAST_ERROR_CODE, error); 167 } 168 mContext.sendBroadcast(intent); 169 } 170 registerConnectivityReceiver(BroadcastReceiver r)171 public void registerConnectivityReceiver(BroadcastReceiver r) { 172 IntentFilter filter = new IntentFilter(); 173 filter.addAction(VpnManager.ACTION_VPN_CONNECTIVITY); 174 mContext.registerReceiver(r, filter); 175 } 176 unregisterConnectivityReceiver(BroadcastReceiver r)177 public void unregisterConnectivityReceiver(BroadcastReceiver r) { 178 mContext.unregisterReceiver(r); 179 } 180 181 /** Starts the VPN settings activity. */ startSettingsActivity()182 public void startSettingsActivity() { 183 Intent intent = new Intent(ACTION_VPN_SETTINGS); 184 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 185 mContext.startActivity(intent); 186 } 187 188 /** Creates an intent to start the VPN settings activity. */ createSettingsActivityIntent()189 public Intent createSettingsActivityIntent() { 190 Intent intent = new Intent(ACTION_VPN_SETTINGS); 191 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 192 return intent; 193 } 194 } 195