/* * Copyright 2011 yingxinwu.g@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package xink.vpn; import xink.vpn.wrapper.KeyStore; import xink.vpn.wrapper.VpnProfile; import xink.vpn.wrapper.VpnState; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; /** * Help desktop widgets to unlock keystore (must be invoked in an activity) */ public class ToggleVpn extends Activity { private static final String TAG = "xink.ToggleVpn"; private VpnProfileRepository repository; private VpnActor vpnActor; private KeyStore keyStore; private Runnable resumeAction; /** Called when the activity is first created. */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); keyStore = new KeyStore(getApplicationContext()); vpnActor = new VpnActor(getApplicationContext()); toggleVpn(getIntent()); } private VpnProfileRepository getRepository() { if (repository == null) { repository = VpnProfileRepository.getInstance(getApplicationContext()); } return repository; } /* * (non-Javadoc) * * @see android.app.Activity#onNewIntent(android.content.Intent) */ @Override protected void onNewIntent(final Intent intent) { toggleVpn(intent); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume, check and run resume action"); if (resumeAction != null) { Runnable action = resumeAction; resumeAction = null; runOnUiThread(action); } } private void toggleVpn(final Intent data) { VpnState state = getRepository().getActiveVpnState(); switch (state) { case IDLE: connect(); break; case CONNECTED: disconnect(); break; default: Log.i(TAG, "intent not handled, currentState=" + state); finish(); break; } } private void connect() { Log.d(TAG, "connect ..."); VpnProfile p = getRepository().getActiveProfile(); if (p == null) { Utils.showToast(getApplicationContext(), R.string.err_no_active_vpn); Log.e(TAG, "connect failed, no active vpn"); finish(); return; } connect(p); } private void connect(final VpnProfile p) { if (unlockKeyStoreIfNeeded(p)) { try { vpnActor.connect(p); } finally { finish(); } } } private boolean unlockKeyStoreIfNeeded(final VpnProfile p) { if (!p.needKeyStoreToConnect() || keyStore.isUnlocked()) return true; Log.i(TAG, "keystore is locked, unlock it now and reconnect later."); resumeAction = new Runnable() { @Override public void run() { // redo this after unlock activity return connect(p); } }; keyStore.unlock(this); return false; } private void disconnect() { Log.d(TAG, "disconnect ..."); try { vpnActor.disconnect(); } finally { finish(); } } }