OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / packages / VpnServices / src / com / android / server / vpn / VpnServiceBinder.java
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 com.android.server.vpn;
18
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;
33
34 import java.io.File;
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;
41
42 /**
43  * The service class for managing a VPN connection. It implements the
44  * {@link IVpnService} binder interface.
45  */
46 public class VpnServiceBinder extends Service {
47     private static final String TAG = VpnServiceBinder.class.getSimpleName();
48     private static final boolean DBG = true;
49
50     private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states";
51
52     // The actual implementation is delegated to the VpnService class.
53     private VpnService<? extends VpnProfile> mService;
54
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;
60     }
61
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);
65         }
66
67         public void disconnect() {
68             VpnServiceBinder.this.disconnect();
69         }
70
71         public void checkStatus(VpnProfile p) {
72             VpnServiceBinder.this.checkStatus(p);
73         }
74     };
75
76     @Override
77     public void onCreate() {
78         super.onCreate();
79         checkSavedStates();
80     }
81
82
83     @Override
84     public void onStart(Intent intent, int startId) {
85         super.onStart(intent, startId);
86     }
87
88     @Override
89     public IBinder onBind(Intent intent) {
90         return mBinder;
91     }
92
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);
98         oos.close();
99     }
100
101     void removeStates() {
102         try {
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);
107         }
108     }
109
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);
114
115         new Thread(new Runnable() {
116             public void run() {
117                 s.onConnect(username, password);
118             }
119         }).start();
120         return true;
121     }
122
123     private synchronized void disconnect() {
124         if (mService == null) return;
125         final VpnService s = mService;
126
127         new Thread(new Runnable() {
128             public void run() {
129                 s.onDisconnect();
130             }
131         }).start();
132     }
133
134     private synchronized void checkStatus(VpnProfile p) {
135         if ((mService == null)
136                 || (!p.getName().equals(mService.mProfile.getName()))) {
137             broadcastConnectivity(p.getName(), VpnState.IDLE);
138         } else {
139             broadcastConnectivity(p.getName(), mService.getState());
140         }
141     }
142
143     private void checkSavedStates() {
144         try {
145             ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
146                     getStateFilePath()));
147             mService = (VpnService<? extends VpnProfile>) ois.readObject();
148             mService.recover(this);
149             ois.close();
150         } catch (FileNotFoundException e) {
151             // do nothing
152         } catch (Throwable e) {
153             Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
154             removeStates();
155         }
156     }
157
158     private VpnService<? extends VpnProfile> createService(VpnProfile p) {
159         switch (p.getType()) {
160             case L2TP:
161                 L2tpService l2tp = new L2tpService();
162                 l2tp.setContext(this, (L2tpProfile) p);
163                 return l2tp;
164
165             case PPTP:
166                 PptpService pptp = new PptpService();
167                 pptp.setContext(this, (PptpProfile) p);
168                 return pptp;
169
170             case L2TP_IPSEC_PSK:
171                 L2tpIpsecPskService psk = new L2tpIpsecPskService();
172                 psk.setContext(this, (L2tpIpsecPskProfile) p);
173                 return psk;
174
175             case L2TP_IPSEC:
176                 L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
177                 l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
178                 return l2tpIpsec;
179
180             default:
181                 return null;
182         }
183     }
184
185     private void broadcastConnectivity(String name, VpnState s) {
186         new VpnManager(this).broadcastConnectivity(name, s);
187     }
188 }