Merge "Fix up storage UI for old USB storage."
diff --git a/proguard.flags b/proguard.flags
index 8318101..6d41d17 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -10,4 +10,5 @@
 -keep class com.android.settings.MasterClear
 -keep class com.android.settings.MasterClearConfirm
 -keep class com.android.settings.accounts.*
+-keep class com.android.settings.fuelgauge.*
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1cf4697..93a7720 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -936,8 +936,8 @@
 
     <!-- Bluetooth settings: The title of the preference (list item) that initiates a scan for devices -->
     <string name="bluetooth_preference_scan_title">Scan for devices</string>
-    <!-- Bluetooth settings: The title of the action button that finds nearby devices [CHAR LIMIT=20] -->
-    <string name="bluetooth_preference_find_nearby_title">Scan</string>
+    <!-- Bluetooth settings: The title of the action button that initiates a scan for nearby devices [CHAR LIMIT=20] -->
+    <string name="bluetooth_scan_nearby_devices">Scan</string>
     <!-- Bluetooth settings: The sub heading for device settings. [CHAR LIMIT=30] -->
     <string name="bluetooth_preference_device_settings">Device settings</string>
     <!-- Bluetooth settings: The sub heading for paired devices. [CHAR LIMIT=30] -->
diff --git a/src/com/android/settings/ProgressCategory.java b/src/com/android/settings/ProgressCategory.java
index c5b68b6..bedcc98 100644
--- a/src/com/android/settings/ProgressCategory.java
+++ b/src/com/android/settings/ProgressCategory.java
@@ -23,7 +23,6 @@
 public class ProgressCategory extends ProgressCategoryBase {
 
     private boolean mProgress = false;
-    private View oldView = null;
 
     public ProgressCategory(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -39,13 +38,6 @@
         final int visibility = mProgress ? View.VISIBLE : View.INVISIBLE;
         textView.setVisibility(visibility);
         progressBar.setVisibility(visibility);
-
-        if (oldView != null) {
-            oldView.findViewById(R.id.scanning_progress).setVisibility(View.GONE);
-            oldView.findViewById(R.id.scanning_text).setVisibility(View.GONE);
-            oldView.setVisibility(View.GONE);
-        }
-        oldView = view;
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java
index 00e342c..e4f11a2 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java
@@ -42,6 +42,9 @@
     /** Bonded devices only filter (referenced directly). */
     static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter();
 
+    /** Unbonded devices only filter (referenced directly). */
+    static final Filter UNBONDED_DEVICE_FILTER = new UnbondedDeviceFilter();
+
     /** Table of singleton filter objects. */
     private static final Filter[] FILTERS = {
             ALL_FILTER,             // FILTER_TYPE_ALL
@@ -85,6 +88,13 @@
         }
     }
 
+    /** Filter that matches only unbonded devices. */
+    private static final class UnbondedDeviceFilter implements Filter {
+        public boolean matches(BluetoothDevice device) {
+            return device.getBondState() != BluetoothDevice.BOND_BONDED;
+        }
+    }
+
     /** Parent class of filters based on UUID and/or Bluetooth class. */
     private abstract static class ClassUuidFilter implements Filter {
         abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass);
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 391c941..06c708b 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -49,8 +49,6 @@
 
     private final CachedBluetoothDevice mCachedDevice;
 
-    private ImageView mDeviceSettings;
-
     private OnClickListener mOnSettingsClickListener;
 
     private AlertDialog mDisconnectDialog;
@@ -121,13 +119,13 @@
         btClass.setImageResource(getBtClassDrawable());
         btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
         btClass.setVisibility(View.VISIBLE);
-        mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails);
+        ImageView deviceDetails = (ImageView) view.findViewById(R.id.deviceDetails);
         if (mOnSettingsClickListener != null) {
-            mDeviceSettings.setOnClickListener(this);
-            mDeviceSettings.setTag(mCachedDevice);
-            mDeviceSettings.setAlpha(isEnabled() ? 255 : sDimAlpha);
+            deviceDetails.setOnClickListener(this);
+            deviceDetails.setTag(mCachedDevice);
+            deviceDetails.setAlpha(isEnabled() ? 255 : sDimAlpha);
         } else { // Hide the settings icon and divider
-            mDeviceSettings.setVisibility(View.GONE);
+            deviceDetails.setVisibility(View.GONE);
             View divider = view.findViewById(R.id.divider);
             if (divider != null) {
                 divider.setVisibility(View.GONE);
@@ -152,13 +150,13 @@
     }
 
     public void onClick(View v) {
-        if (v == mDeviceSettings) {
-            if (mOnSettingsClickListener != null) {
-                mOnSettingsClickListener.onClick(v);
-            }
+        // Should never be null by construction
+        if (mOnSettingsClickListener != null) {
+            mOnSettingsClickListener.onClick(v);
         }
     }
 
+    @Override
     public boolean equals(Object o) {
         if ((o == null) || !(o instanceof BluetoothDevicePreference)) {
             return false;
@@ -167,6 +165,7 @@
                 ((BluetoothDevicePreference) o).mCachedDevice);
     }
 
+    @Override
     public int hashCode() {
         return mCachedDevice.hashCode();
     }
@@ -174,8 +173,8 @@
     @Override
     public int compareTo(Preference another) {
         if (!(another instanceof BluetoothDevicePreference)) {
-            // Put other preference types above us
-            return 1;
+            // Rely on default sort
+            return super.compareTo(another);
         }
 
         return mCachedDevice
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index f20ad78..76bf623 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.view.Gravity;
@@ -31,6 +32,7 @@
 import android.view.View;
 import android.widget.Switch;
 
+import com.android.settings.ProgressCategory;
 import com.android.settings.R;
 
 /**
@@ -45,10 +47,8 @@
 
     private BluetoothEnabler mBluetoothEnabler;
 
-    /** Initialize the filter to show bonded devices only. */
-    //public BluetoothSettings() {
-    //    super(BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
-    //}
+    private PreferenceGroup mFoundDevicesCategory;
+    private boolean mFoundDevicesCategoryIsPresent;
 
     @Override
     void addPreferencesForActivity() {
@@ -101,9 +101,9 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
-        menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.bluetooth_preference_find_nearby_title)
+        menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.bluetooth_scan_nearby_devices)
                 //.setIcon(R.drawable.ic_menu_scan_network)
-                .setEnabled(bluetoothIsEnabled)
+                .setEnabled(bluetoothIsEnabled && !mLocalAdapter.isDiscovering())
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
         menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced)
                 //.setIcon(android.R.drawable.ic_menu_manage)
@@ -113,13 +113,9 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
-                // TODO
-//                if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
-//                    onAddNetworkPressed();
-//                }
             case MENU_ID_SCAN:
                 if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
-                    mLocalAdapter.startScanning(true);
+                    startScanning();
                 }
                 return true;
             case MENU_ID_ADVANCED:
@@ -137,24 +133,12 @@
         return super.onOptionsItemSelected(item);
     }
 
-    private final View.OnClickListener mListener = new View.OnClickListener() {
-        public void onClick(View v) {
-            // User clicked on advanced options icon for a device in the list
-            if (v.getTag() instanceof CachedBluetoothDevice) {
-                CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
-
-                Preference pref = new Preference(getActivity());
-                pref.setTitle(device.getName());
-                pref.setFragment(DeviceProfilesSettings.class.getName());
-                pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
-                        device.getDevice());
-                ((PreferenceActivity) getActivity()).onPreferenceStartFragment(
-                        BluetoothSettings.this, pref);
-            } else {
-                Log.w(TAG, "onClick() called for other View: " + v);
-            }
+    private void startScanning() {
+        if (!mFoundDevicesCategoryIsPresent) {
+            getPreferenceScreen().addPreference(mFoundDevicesCategory);
         }
-    };
+        mLocalAdapter.startScanning(true);
+    }
 
     @Override
     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
@@ -162,12 +146,6 @@
         super.onDevicePreferenceClick(btPreference);
     }
 
-    @Override
-    public void onBluetoothStateChanged(int bluetoothState) {
-        super.onBluetoothStateChanged(bluetoothState);
-        updateContent(bluetoothState);
-    }
-
     private void updateContent(int bluetoothState) {
         final PreferenceScreen preferenceScreen = getPreferenceScreen();
         getActivity().invalidateOptionsMenu();
@@ -176,9 +154,34 @@
         switch (bluetoothState) {
             case BluetoothAdapter.STATE_ON:
                 preferenceScreen.removeAll();
-                // Repopulate (which isn't too bad since it's cached in the settings bluetooth manager)
-                addDevices();
-                mLocalAdapter.startScanning(false);
+
+                // Add bonded devices from cache first
+                setFilter(BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
+                setDeviceListGroup(preferenceScreen);
+                preferenceScreen.setOrderingAsAdded(true);
+
+                addCachedDevices();
+                int numberOfPairedDevices = preferenceScreen.getPreferenceCount();
+
+                // Found devices category
+                mFoundDevicesCategory = new ProgressCategory(getActivity(), null);
+                mFoundDevicesCategory.setTitle(R.string.bluetooth_preference_found_devices);
+                preferenceScreen.addPreference(mFoundDevicesCategory);
+                mFoundDevicesCategoryIsPresent = true;
+
+                // Unbonded found devices from cache
+                setFilter(BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER);
+                setDeviceListGroup(mFoundDevicesCategory);
+                addCachedDevices();
+
+                int numberOfUnpairedDevices = mFoundDevicesCategory.getPreferenceCount();
+                if (numberOfUnpairedDevices == 0) {
+                    preferenceScreen.removePreference(mFoundDevicesCategory);
+                    mFoundDevicesCategoryIsPresent = false;
+                }
+
+                if (numberOfPairedDevices == 0) startScanning();
+
                 return;
 
             case BluetoothAdapter.STATE_TURNING_OFF:
@@ -197,31 +200,63 @@
                 break;
         }
 
+        setDeviceListGroup(preferenceScreen);
         removeAllDevices();
+
         // TODO: from xml, add top padding. Same as in wifi
         Preference emptyListPreference = new Preference(getActivity());
         emptyListPreference.setTitle(messageId);
         preferenceScreen.addPreference(emptyListPreference);
     }
 
-    public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
-        if (bondState == BluetoothDevice.BOND_BONDED) {
-            // add to "Paired devices" list after remote-initiated pairing
-            if (mDevicePreferenceMap.get(cachedDevice) == null) {
-                createDevicePreference(cachedDevice);
-            }
-        } else if (bondState == BluetoothDevice.BOND_NONE) {
-            // remove unpaired device from paired devices list
-            onDeviceDeleted(cachedDevice);
-        }
+    @Override
+    public void onBluetoothStateChanged(int bluetoothState) {
+        super.onBluetoothStateChanged(bluetoothState);
+        updateContent(bluetoothState);
     }
 
+    @Override
+    public void onScanningStateChanged(boolean started) {
+        super.onScanningStateChanged(started);
+        // Update 'Scan' option enabled state
+        getActivity().invalidateOptionsMenu();
+    }
+
+    public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
+        setDeviceListGroup(getPreferenceScreen());
+        removeAllDevices();
+        updateContent(mLocalAdapter.getBluetoothState());
+    }
+
+    private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            // User clicked on advanced options icon for a device in the list
+            if (v.getTag() instanceof CachedBluetoothDevice) {
+                CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+
+                Preference pref = new Preference(getActivity());
+                pref.setTitle(device.getName());
+                pref.setFragment(DeviceProfilesSettings.class.getName());
+                pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
+                        device.getDevice());
+                ((PreferenceActivity) getActivity()).onPreferenceStartFragment(
+                        BluetoothSettings.this, pref);
+            } else {
+                Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
+            }
+        }
+    };
+
     /**
      * Add a listener, which enables the advanced settings icon.
      * @param preference the newly added preference
      */
     @Override
     void initDevicePreference(BluetoothDevicePreference preference) {
-        preference.setOnSettingsClickListener(mListener);
+        CachedBluetoothDevice cachedDevice = preference.getCachedDevice();
+        if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
+            // Only paired device have an associated advanced settings screen
+            preference.setOnSettingsClickListener(mDeviceProfilesListener);
+        }
     }
 }
diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
index 409edb9..9783fd7 100644
--- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
+++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
@@ -62,7 +62,7 @@
         mFilter = BluetoothDeviceFilter.ALL_FILTER;
     }
 
-    DeviceListPreferenceFragment(BluetoothDeviceFilter.Filter filter) {
+    final void setFilter(BluetoothDeviceFilter.Filter filter) {
         mFilter = filter;
     }
 
@@ -84,14 +84,10 @@
         addPreferencesForActivity();
 
         mDeviceListGroup = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
-        if (mDeviceListGroup == null) {
-            // If null, device preferences are added directly to the root of the preference screen
-            mDeviceListGroup = getPreferenceScreen();
-            mDeviceListGroup.setOrderingAsAdded(false);
-        }
-        if (mDeviceListGroup == null) {
-            Log.e(TAG, "Could not find device list preference object!");
-        }
+    }
+
+    void setDeviceListGroup(PreferenceGroup preferenceGroup) {
+        mDeviceListGroup = preferenceGroup;
     }
 
     /** Add preferences from the subclass. */
@@ -121,7 +117,7 @@
         mDeviceListGroup.removeAll();
     }
 
-    void addDevices() {
+    void addCachedDevices() {
         Collection<CachedBluetoothDevice> cachedDevices =
                 mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
         for (CachedBluetoothDevice cachedDevice : cachedDevices) {
@@ -159,7 +155,7 @@
             return;
         }
 
-        // No update while list shows state message
+        // Prevent updates while the list shows one of the state messages
         if (mLocalAdapter.getBluetoothState() != BluetoothAdapter.STATE_ON) return;
 
         if (mFilter.matches(cachedDevice.getDevice())) {
@@ -199,7 +195,6 @@
         if (mDeviceListGroup instanceof ProgressCategory) {
             ((ProgressCategory) mDeviceListGroup).setProgress(start);
         }
-        // else TODO Add a spinner at the end of the list to show in progress state
     }
 
     public void onBluetoothStateChanged(int bluetoothState) {
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index 3aeb7e2..8b32941 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -55,7 +55,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        addDevices();
+        addCachedDevices();
         mLocalAdapter.startScanning(true);
     }
 
diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java
index b3e417b..92ad362 100644
--- a/src/com/android/settings/vpn2/VpnDialog.java
+++ b/src/com/android/settings/vpn2/VpnDialog.java
@@ -36,15 +36,15 @@
 import android.widget.TextView;
 
 class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener {
-    private static final String DUMMY = "\r\r\r\r";
+    private static final String DUMMY = "\r";
 
     private static String getDummy(String secret) {
         return secret.isEmpty() ? "" : DUMMY;
     }
 
-    private static String getSecret(TextView dummy) {
-        String secret = dummy.getText().toString();
-        return DUMMY.equals(secret) ? "" : secret;
+    private static String getSecret(String oldSecret, TextView view) {
+        String newSecret = view.getText().toString();
+        return DUMMY.equals(newSecret) ? oldSecret : newSecret;
     }
 
     private final KeyStore mKeyStore = KeyStore.getInstance();
@@ -116,7 +116,7 @@
         mIpsecSecret.setText(getDummy(mProfile.ipsecSecret));
         loadCertificates(mIpsecUserCert, Credentials.USER_CERTIFICATE,
                 0, mProfile.ipsecUserCert);
-        loadCertificates(mIpsecUserCert, Credentials.CA_CERTIFICATE,
+        loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE,
                 R.string.vpn_no_ca_cert, mProfile.ipsecCaCert);
         mSaveLogin.setChecked(mProfile.saveLogin);
 
@@ -186,7 +186,7 @@
         if (parent == mType) {
             changeType(position);
         }
-        getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validate(false));
+        getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validate(mEditing));
     }
 
     @Override
@@ -252,24 +252,24 @@
     private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) {
         Context context = getContext();
         String first = (firstId == 0) ? "" : context.getString(firstId);
-        String[] certs = mKeyStore.saw(prefix);
+        String[] certificates = mKeyStore.saw(prefix);
 
-        if (certs == null || certs.length == 0) {
-            certs = new String[] {first};
+        if (certificates == null || certificates.length == 0) {
+            certificates = new String[] {first};
         } else {
-            String[] array = new String[certs.length + 1];
+            String[] array = new String[certificates.length + 1];
             array[0] = first;
-            System.arraycopy(certs, 0, array, 1, certs.length);
-            certs = array;
+            System.arraycopy(certificates, 0, array, 1, certificates.length);
+            certificates = array;
         }
 
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(
-                context, android.R.layout.simple_spinner_item, certs);
+                context, android.R.layout.simple_spinner_item, certificates);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         spinner.setAdapter(adapter);
 
-        for (int i = 1; i < certs.length; ++i) {
-            if (certs[i].equals(selected)) {
+        for (int i = 1; i < certificates.length; ++i) {
+            if (certificates[i].equals(selected)) {
                 spinner.setSelection(i);
                 break;
             }
@@ -287,7 +287,7 @@
         profile.type = mType.getSelectedItemPosition();
         profile.server = mServer.getText().toString().trim();
         profile.username = mUsername.getText().toString();
-        profile.password = getSecret(mPassword);
+        profile.password = getSecret(mProfile.password, mPassword);
         profile.domains = mDomains.getText().toString().trim();
         profile.routes = mRoutes.getText().toString().trim();
 
@@ -298,14 +298,14 @@
                 break;
 
             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
-                profile.l2tpSecret = getSecret(mL2tpSecret);
+                profile.l2tpSecret = getSecret(mProfile.l2tpSecret, mL2tpSecret);
                 // fall through
             case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
-                profile.ipsecSecret = getSecret(mIpsecSecret);
+                profile.ipsecSecret = getSecret(mProfile.ipsecSecret, mIpsecSecret);
                 break;
 
             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
-                profile.l2tpSecret = getSecret(mL2tpSecret);
+                profile.l2tpSecret = getSecret(mProfile.l2tpSecret, mL2tpSecret);
                 // fall through
             case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
                 if (mIpsecCaCert.getSelectedItemPosition() != 0) {
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 6662dd9..56fb983 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -20,9 +20,11 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
+import android.net.IConnectivityManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.ServiceManager;
 import android.preference.Preference;
 import android.preference.PreferenceGroup;
 import android.security.Credentials;
@@ -57,8 +59,11 @@
 
     private HashMap<String, VpnPreference> mPreferences;
     private VpnDialog mDialog;
+
+    private Handler mUpdater;
+
+    // The key of the profile for the current ContextMenu.
     private String mSelectedKey;
-    private Handler mHandler;
 
     @Override
     public void onCreate(Bundle savedState) {
@@ -145,10 +150,10 @@
         }
 
         // Start monitoring.
-        if (mHandler == null) {
-            mHandler = new Handler(this);
+        if (mUpdater == null) {
+            mUpdater = new Handler(this);
         }
-        mHandler.sendEmptyMessage(0);
+        mUpdater.sendEmptyMessage(0);
 
         // Register for context menu. Hmmm, getListView() is hidden?
         registerForContextMenu(getListView());
@@ -194,7 +199,7 @@
 
             // If we are not editing, connect!
             if (!mDialog.isEditing()) {
-                connect(profile.key);
+                connect(profile);
             }
         }
     }
@@ -274,19 +279,74 @@
 
     @Override
     public boolean handleMessage(Message message) {
-        mHandler.removeMessages(0);
+        mUpdater.removeMessages(0);
 
         if (isResumed()) {
 
 
 
 
-            mHandler.sendEmptyMessageDelayed(0, 1000);
+            mUpdater.sendEmptyMessageDelayed(0, 1000);
         }
         return true;
     }
 
-    private void connect(String key) {
+    private static IConnectivityManager getService() {
+        return IConnectivityManager.Stub.asInterface(
+                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    }
+
+    private void connect(VpnProfile profile) {
+        String[] racoon = null;
+        switch (profile.type) {
+            case VpnProfile.TYPE_L2TP_IPSEC_PSK:
+                racoon = new String[] {
+                    profile.server, "1701", profile.ipsecSecret,
+                };
+                break;
+            case VpnProfile.TYPE_L2TP_IPSEC_RSA:
+                racoon = new String[] {
+                    profile.server, "1701",
+                    Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert,
+                    Credentials.USER_CERTIFICATE + profile.ipsecUserCert,
+                    Credentials.CA_CERTIFICATE + profile.ipsecCaCert,
+                };
+                break;
+            case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
+                break;
+            case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
+                break;
+            case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
+                break;
+        }
+
+        String[] mtpd = null;
+        switch (profile.type) {
+            case VpnProfile.TYPE_PPTP:
+                mtpd = new String[] {
+                    "pptp", profile.server, "1723",
+                    "name", profile.username, "password", profile.password,
+                    "linkname", "vpn", "refuse-eap", "nodefaultroute",
+                    "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
+                    (profile.mppe ? "+mppe" : "nomppe"),
+                };
+                break;
+            case VpnProfile.TYPE_L2TP_IPSEC_PSK:
+            case VpnProfile.TYPE_L2TP_IPSEC_RSA:
+                mtpd = new String[] {
+                    "l2tp", profile.server, "1701", profile.l2tpSecret,
+                    "name", profile.username, "password", profile.password,
+                    "linkname", "vpn", "refuse-eap", "nodefaultroute",
+                    "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
+                };
+                break;
+        }
+
+        try {
+//            getService().doLegacyVpn(racoon, mtpd);
+        } catch (Exception e) {
+            Log.e(TAG, "connect", e);
+        }
     }
 
     private void disconnect(String key) {
@@ -331,7 +391,7 @@
 
         @Override
         public int compareTo(Preference preference) {
-            int result = 1;
+            int result = -1;
             if (preference instanceof VpnPreference) {
                 VpnPreference another = (VpnPreference) preference;