2 * Copyright (C) 2007 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.settings.vpn;
19 import com.android.settings.R;
21 import android.app.AlertDialog;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.content.ServiceConnection;
27 import android.net.vpn.IVpnService;
28 import android.net.vpn.VpnManager;
29 import android.net.vpn.VpnProfile;
30 import android.net.vpn.VpnState;
31 import android.os.Bundle;
32 import android.os.IBinder;
33 import android.os.Parcelable;
34 import android.os.RemoteException;
35 import android.util.Log;
36 import android.view.View;
37 import android.widget.EditText;
38 import android.widget.TextView;
39 import android.widget.Toast;
41 import java.io.IOException;
45 public class AuthenticationActor implements VpnProfileActor,
46 DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
47 private static final String TAG = AuthenticationActor.class.getName();
48 private static final int ONE_SECOND = 1000; // ms
50 private static final String STATE_IS_DIALOG_OPEN = "is_dialog_open";
51 private static final String STATE_USERNAME = "username";
52 private static final String STATE_PASSWORD = "password";
54 private Context mContext;
55 private TextView mUsernameView;
56 private TextView mPasswordView;
58 private VpnProfile mProfile;
60 private VpnManager mVpnManager;
61 private AlertDialog mConnectDialog;
62 private AlertDialog mDisconnectDialog;
64 public AuthenticationActor(Context context, VpnProfile p) {
67 mVpnManager = new VpnManager(context);
71 public VpnProfile getProfile() {
76 public synchronized void connect() {
81 public void onClick(DialogInterface dialog, int which) {
82 dismissConnectDialog();
84 case DialogInterface.BUTTON1: // connect
85 if (validateInputs()) {
86 broadcastConnectivity(VpnState.CONNECTING);
91 case DialogInterface.BUTTON2: // cancel
92 broadcastConnectivity(VpnState.CANCELLED);
98 public void onCancel(DialogInterface dialog) {
99 dismissConnectDialog();
100 broadcastConnectivity(VpnState.CANCELLED);
103 private void connect(String username, String password) {
104 Context c = mContext;
105 mConnectDialog = new AlertDialog.Builder(c)
106 .setView(createConnectView(username, password))
107 .setTitle(c.getString(R.string.vpn_connect_to) + " "
108 + mProfile.getName())
109 .setPositiveButton(c.getString(R.string.vpn_connect_button),
111 .setNegativeButton(c.getString(R.string.vpn_cancel_button),
113 .setOnCancelListener(this)
115 mConnectDialog.show();
119 public synchronized void onSaveState(Bundle outState) {
120 outState.putBoolean(STATE_IS_DIALOG_OPEN, (mConnectDialog != null));
121 if (mConnectDialog != null) {
122 assert(mConnectDialog.isShowing());
123 outState.putBoolean(STATE_IS_DIALOG_OPEN, (mConnectDialog != null));
124 outState.putString(STATE_USERNAME,
125 mUsernameView.getText().toString());
126 outState.putString(STATE_PASSWORD,
127 mPasswordView.getText().toString());
128 dismissConnectDialog();
133 public synchronized void onRestoreState(final Bundle savedState) {
134 boolean isDialogOpen = savedState.getBoolean(STATE_IS_DIALOG_OPEN);
136 connect(savedState.getString(STATE_USERNAME),
137 savedState.getString(STATE_PASSWORD));
141 private synchronized void dismissConnectDialog() {
142 mConnectDialog.dismiss();
143 mConnectDialog = null;
146 private void connectInternal() {
147 mVpnManager.startVpnService();
148 ServiceConnection c = new ServiceConnection() {
149 public void onServiceConnected(ComponentName className,
151 boolean success = false;
153 success = IVpnService.Stub.asInterface(service)
155 mUsernameView.getText().toString(),
156 mPasswordView.getText().toString());
157 mPasswordView.setText("");
158 } catch (Throwable e) {
159 Log.e(TAG, "connect()", e);
162 mContext.unbindService(this);
165 Log.d(TAG, "~~~~~~ connect() failed!");
166 // TODO: pop up a dialog
167 broadcastConnectivity(VpnState.IDLE);
169 Log.d(TAG, "~~~~~~ connect() succeeded!");
174 public void onServiceDisconnected(ComponentName className) {
178 if (!bindService(c)) broadcastConnectivity(VpnState.IDLE);
182 public void disconnect() {
183 ServiceConnection c = new ServiceConnection() {
184 public void onServiceConnected(ComponentName className,
187 IVpnService.Stub.asInterface(service).disconnect();
188 } catch (RemoteException e) {
189 Log.e(TAG, "disconnect()", e);
192 mContext.unbindService(this);
193 broadcastConnectivity(VpnState.IDLE);
197 public void onServiceDisconnected(ComponentName className) {
205 public void checkStatus() {
206 ServiceConnection c = new ServiceConnection() {
207 public synchronized void onServiceConnected(ComponentName className,
210 IVpnService.Stub.asInterface(service).checkStatus(mProfile);
211 } catch (Throwable e) {
212 Log.e(TAG, "checkStatus()", e);
218 public void onServiceDisconnected(ComponentName className) {
222 if (bindService(c)) {
223 // wait for a second, let status propagate
226 mContext.unbindService(c);
229 private boolean bindService(ServiceConnection c) {
230 return mVpnManager.bindVpnService(c);
233 private void broadcastConnectivity(VpnState s) {
234 mVpnManager.broadcastConnectivity(mProfile.getName(), s);
237 // returns true if inputs pass validation
238 private boolean validateInputs() {
239 Context c = mContext;
241 if (Util.isNullOrEmpty(mUsernameView.getText().toString())) {
242 error = c.getString(R.string.vpn_username);
243 } else if (Util.isNullOrEmpty(mPasswordView.getText().toString())) {
244 error = c.getString(R.string.vpn_password);
249 new AlertDialog.Builder(c)
250 .setTitle(c.getString(R.string.vpn_you_miss_a_field))
251 .setMessage(String.format(
252 c.getString(R.string.vpn_please_fill_up), error))
253 .setPositiveButton(c.getString(R.string.vpn_back_button),
254 createBackButtonListener())
260 private View createConnectView(String username, String password) {
261 View v = View.inflate(mContext, R.layout.vpn_connect_dialog_view, null);
262 mUsernameView = (TextView) v.findViewById(R.id.username_value);
263 mPasswordView = (TextView) v.findViewById(R.id.password_value);
264 mUsernameView.setText(username);
265 mPasswordView.setText(password);
266 copyFieldsFromOldView(v);
271 private void copyFieldsFromOldView(View newView) {
272 if (mView == null) return;
273 mUsernameView.setText(
274 ((TextView) mView.findViewById(R.id.username_value)).getText());
275 mPasswordView.setText(
276 ((TextView) mView.findViewById(R.id.password_value)).getText());
279 private DialogInterface.OnClickListener createBackButtonListener() {
280 return new DialogInterface.OnClickListener() {
281 public void onClick(DialogInterface dialog, int which) {
288 private void wait(Object o, int ms) {
292 } catch (Exception e) {}