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 com.android.server.vpn;
19 import android.app.Service;
20 import android.content.Intent;
21 import android.net.vpn.IVpnService;
22 import android.net.vpn.L2tpIpsecProfile;
23 import android.net.vpn.L2tpIpsecPskProfile;
24 import android.net.vpn.L2tpProfile;
25 import android.net.vpn.PptpProfile;
26 import android.net.vpn.VpnManager;
27 import android.net.vpn.VpnProfile;
28 import android.net.vpn.VpnState;
29 import android.os.Environment;
30 import android.os.IBinder;
31 import android.os.SystemProperties;
32 import android.util.Log;
35 import java.io.FileInputStream;
36 import java.io.FileNotFoundException;
37 import java.io.FileOutputStream;
38 import java.io.IOException;
39 import java.io.ObjectInputStream;
40 import java.io.ObjectOutputStream;
43 * The service class for managing a VPN connection. It implements the
44 * {@link IVpnService} binder interface.
46 public class VpnServiceBinder extends Service {
47 private static final String TAG = VpnServiceBinder.class.getSimpleName();
48 private static final boolean DBG = true;
50 private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states";
52 // The actual implementation is delegated to the VpnService class.
53 private VpnService<? extends VpnProfile> mService;
55 // TODO(oam): Test VPN when EFS is enabled (will do later)...
56 private static String getStateFilePath() {
57 // This call will return the correcu directory whether Encrypted FS is enabled or not
58 // Disabled: /data/misc/vpn/.states Enabled: /data/secure/misc/vpn/.states
59 return Environment.getSecureDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
62 private final IBinder mBinder = new IVpnService.Stub() {
63 public boolean connect(VpnProfile p, String username, String password) {
64 return VpnServiceBinder.this.connect(p, username, password);
67 public void disconnect() {
68 VpnServiceBinder.this.disconnect();
71 public void checkStatus(VpnProfile p) {
72 VpnServiceBinder.this.checkStatus(p);
77 public void onCreate() {
84 public void onStart(Intent intent, int startId) {
85 super.onStart(intent, startId);
89 public IBinder onBind(Intent intent) {
93 void saveStates() throws IOException {
94 if (DBG) Log.d("VpnServiceBinder", " saving states");
95 ObjectOutputStream oos =
96 new ObjectOutputStream(new FileOutputStream(getStateFilePath()));
97 oos.writeObject(mService);
101 void removeStates() {
103 File f = new File(getStateFilePath());
104 if (f.exists()) f.delete();
105 } catch (Throwable e) {
106 if (DBG) Log.d("VpnServiceBinder", " remove states: " + e);
110 private synchronized boolean connect(final VpnProfile p,
111 final String username, final String password) {
112 if (mService != null) return false;
113 final VpnService s = mService = createService(p);
115 new Thread(new Runnable() {
117 s.onConnect(username, password);
123 private synchronized void disconnect() {
124 if (mService == null) return;
125 final VpnService s = mService;
127 new Thread(new Runnable() {
134 private synchronized void checkStatus(VpnProfile p) {
135 if ((mService == null)
136 || (!p.getName().equals(mService.mProfile.getName()))) {
137 broadcastConnectivity(p.getName(), VpnState.IDLE);
139 broadcastConnectivity(p.getName(), mService.getState());
143 private void checkSavedStates() {
145 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
146 getStateFilePath()));
147 mService = (VpnService<? extends VpnProfile>) ois.readObject();
148 mService.recover(this);
150 } catch (FileNotFoundException e) {
152 } catch (Throwable e) {
153 Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
158 private VpnService<? extends VpnProfile> createService(VpnProfile p) {
159 switch (p.getType()) {
161 L2tpService l2tp = new L2tpService();
162 l2tp.setContext(this, (L2tpProfile) p);
166 PptpService pptp = new PptpService();
167 pptp.setContext(this, (PptpProfile) p);
171 L2tpIpsecPskService psk = new L2tpIpsecPskService();
172 psk.setContext(this, (L2tpIpsecPskProfile) p);
176 L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
177 l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
185 private void broadcastConnectivity(String name, VpnState s) {
186 new VpnManager(this).broadcastConnectivity(name, s);