2 * Copyright (C) 2009, The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.net.vpn;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.ServiceConnection;
26 import android.os.Environment;
27 import android.os.SystemProperties;
28 import android.util.Log;
31 * The class provides interface to manage all VPN-related tasks, including:
33 * <li>The list of supported VPN types.
34 * <li>API's to start/stop the service of a particular type.
35 * <li>API's to start the settings activity.
36 * <li>API's to create a profile.
37 * <li>API's to register/unregister a connectivity receiver and the keys to
38 * access the fields in a connectivity broadcast event.
42 public class VpnManager {
43 // Action for broadcasting a connectivity state.
44 private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
45 /** Key to the profile name of a connectivity broadcast event. */
46 public static final String BROADCAST_PROFILE_NAME = "profile_name";
47 /** Key to the connectivity state of a connectivity broadcast event. */
48 public static final String BROADCAST_CONNECTION_STATE = "connection_state";
49 /** Key to the error code of a connectivity broadcast event. */
50 public static final String BROADCAST_ERROR_CODE = "err";
51 /** Error code to indicate an error from authentication. */
52 public static final int VPN_ERROR_AUTH = 51;
53 /** Error code to indicate the connection attempt failed. */
54 public static final int VPN_ERROR_CONNECTION_FAILED = 101;
55 /** Error code to indicate the server is not known. */
56 public static final int VPN_ERROR_UNKNOWN_SERVER = 102;
57 /** Error code to indicate an error from challenge response. */
58 public static final int VPN_ERROR_CHALLENGE = 5;
59 /** Error code to indicate an error of remote server hanging up. */
60 public static final int VPN_ERROR_REMOTE_HUNG_UP = 7;
61 /** Error code to indicate an error of remote PPP server hanging up. */
62 public static final int VPN_ERROR_REMOTE_PPP_HUNG_UP = 48;
63 /** Error code to indicate a PPP negotiation error. */
64 public static final int VPN_ERROR_PPP_NEGOTIATION_FAILED = 42;
65 /** Error code to indicate an error of losing connectivity. */
66 public static final int VPN_ERROR_CONNECTION_LOST = 103;
67 /** Largest error code used by VPN. */
68 public static final int VPN_ERROR_LARGEST = 200;
69 /** Error code to indicate a successful connection. */
70 public static final int VPN_ERROR_NO_ERROR = 0;
72 public static final String PROFILES_PATH = "/misc/vpn/profiles";
74 private static final String PACKAGE_PREFIX =
75 VpnManager.class.getPackage().getName() + ".";
77 // Action to start VPN service
78 private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
80 // Action to start VPN settings
81 private static final String ACTION_VPN_SETTINGS =
82 PACKAGE_PREFIX + "SETTINGS";
84 public static final String TAG = VpnManager.class.getSimpleName();
86 // TODO(oam): Test VPN when EFS is enabled (will do later)...
87 public static String getProfilePath() {
88 // This call will return the correct path if Encrypted FS is enabled or not.
89 return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH;
93 * Returns all supported VPN types.
95 public static VpnType[] getSupportedVpnTypes() {
96 return VpnType.values();
99 private Context mContext;
102 * Creates a manager object with the specified context.
104 public VpnManager(Context c) {
109 * Creates a VPN profile of the specified type.
111 * @param type the VPN type
112 * @return the profile object
114 public VpnProfile createVpnProfile(VpnType type) {
115 return createVpnProfile(type, false);
119 * Creates a VPN profile of the specified type.
121 * @param type the VPN type
122 * @param customized true if the profile is custom made
123 * @return the profile object
125 public VpnProfile createVpnProfile(VpnType type, boolean customized) {
127 VpnProfile p = (VpnProfile) type.getProfileClass().newInstance();
128 p.setCustomized(customized);
130 } catch (InstantiationException e) {
132 } catch (IllegalAccessException e) {
138 * Starts the VPN service to establish VPN connection.
140 public void startVpnService() {
141 mContext.startService(new Intent(ACTION_VPN_SERVICE));
145 * Stops the VPN service.
147 public void stopVpnService() {
148 mContext.stopService(new Intent(ACTION_VPN_SERVICE));
152 * Binds the specified ServiceConnection with the VPN service.
154 public boolean bindVpnService(ServiceConnection c) {
155 if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
156 Log.w(TAG, "failed to connect to VPN service");
159 Log.d(TAG, "succeeded to connect to VPN service");
164 /** Broadcasts the connectivity state of the specified profile. */
165 public void broadcastConnectivity(String profileName, VpnState s) {
166 broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR);
169 /** Broadcasts the connectivity state with an error code. */
170 public void broadcastConnectivity(String profileName, VpnState s,
172 Intent intent = new Intent(ACTION_VPN_CONNECTIVITY);
173 intent.putExtra(BROADCAST_PROFILE_NAME, profileName);
174 intent.putExtra(BROADCAST_CONNECTION_STATE, s);
175 if (error != VPN_ERROR_NO_ERROR) {
176 intent.putExtra(BROADCAST_ERROR_CODE, error);
178 mContext.sendBroadcast(intent);
181 public void registerConnectivityReceiver(BroadcastReceiver r) {
182 IntentFilter filter = new IntentFilter();
183 filter.addAction(VpnManager.ACTION_VPN_CONNECTIVITY);
184 mContext.registerReceiver(r, filter);
187 public void unregisterConnectivityReceiver(BroadcastReceiver r) {
188 mContext.unregisterReceiver(r);
191 /** Starts the VPN settings activity. */
192 public void startSettingsActivity() {
193 Intent intent = new Intent(ACTION_VPN_SETTINGS);
194 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
195 mContext.startActivity(intent);
198 /** Creates an intent to start the VPN settings activity. */
199 public Intent createSettingsActivityIntent() {
200 Intent intent = new Intent(ACTION_VPN_SETTINGS);
201 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);