diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
new file mode 100644
index 0000000..f47d679
--- /dev/null
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.internal.telephony.PhoneStateIntentReceiver;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.provider.Settings;
+import android.telephony.ServiceState;
+
+public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener {
+
+    private final Context mContext;
+
+    private PhoneStateIntentReceiver mPhoneStateReceiver;
+    
+    private final CheckBoxPreference mCheckBoxPref;
+
+    private static final int EVENT_SERVICE_STATE_CHANGED = 3;
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_SERVICE_STATE_CHANGED:
+                    onAirplaneModeChanged();
+                    break;
+            }
+        }
+    };
+
+    public AirplaneModeEnabler(Context context, CheckBoxPreference airplaneModeCheckBoxPreference) {
+        
+        mContext = context;
+        mCheckBoxPref = airplaneModeCheckBoxPreference;
+        
+        airplaneModeCheckBoxPreference.setPersistent(false);
+    
+        mPhoneStateReceiver = new PhoneStateIntentReceiver(mContext, mHandler);
+        mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
+    }
+
+    public void resume() {
+        
+        // This is the widget enabled state, not the preference toggled state
+        mCheckBoxPref.setEnabled(true);
+        mCheckBoxPref.setChecked(isAirplaneModeOn());
+
+        mPhoneStateReceiver.registerIntent();
+        mCheckBoxPref.setOnPreferenceChangeListener(this);
+    }
+    
+    public void pause() {
+        mPhoneStateReceiver.unregisterIntent();
+        mCheckBoxPref.setOnPreferenceChangeListener(null);
+    }
+    
+    private boolean isAirplaneModeOn() {
+        return Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+    }
+
+    private void setAirplaneModeOn(boolean enabling) {
+        
+        mCheckBoxPref.setEnabled(false);
+        mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
+                : R.string.airplane_mode_turning_off);
+        
+        // Change the system setting
+        Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 
+                                enabling ? 1 : 0);
+        
+        // Post the intent
+        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        intent.putExtra("state", enabling);
+        mContext.sendBroadcast(intent);
+    }
+
+    /**
+     * Called when we've received confirmation that the airplane mode was set.
+     */
+    private void onAirplaneModeChanged() {
+        ServiceState serviceState = mPhoneStateReceiver.getServiceState();
+        boolean isPhoneOff = serviceState.getState() == ServiceState.STATE_POWER_OFF;
+        mCheckBoxPref.setChecked(isPhoneOff);
+        mCheckBoxPref.setSummary(R.string.airplane_mode_summary);            
+        mCheckBoxPref.setEnabled(true);
+    }
+    
+    /**
+     * Called when someone clicks on the checkbox preference.
+     */
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        setAirplaneModeOn((Boolean) newValue);
+        return true;
+    }
+
+}
diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java
new file mode 100644
index 0000000..9b74eea
--- /dev/null
+++ b/src/com/android/settings/ApnEditor.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.AlertDialog;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.provider.Telephony;
+import com.android.internal.telephony.TelephonyProperties;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+
+
+public class ApnEditor extends PreferenceActivity 
+        implements SharedPreferences.OnSharedPreferenceChangeListener {
+    
+
+    private final static String TAG = ApnEditor.class.getSimpleName();
+    
+    private final static String SAVED_POS = "pos";
+    
+    private static final int MENU_DELETE = Menu.FIRST;
+    private static final int MENU_SAVE = Menu.FIRST + 1;
+    private static final int MENU_CANCEL = Menu.FIRST + 2;
+    
+    private static String sNotSet;
+    private EditTextPreference mName;
+    private EditTextPreference mApn;
+    private EditTextPreference mProxy;
+    private EditTextPreference mPort;
+    private EditTextPreference mUser;
+    private EditTextPreference mServer;
+    private EditTextPreference mPassword;
+    private EditTextPreference mMmsc;
+    private EditTextPreference mMcc;
+    private EditTextPreference mMnc;
+    private EditTextPreference mMmsProxy;
+    private EditTextPreference mMmsPort;
+    private EditTextPreference mApnType;
+    
+    private Uri mUri;
+    private Cursor mCursor;
+    private boolean mNewApn;
+    private boolean mFirstTime;
+    private Resources mRes;
+    
+    /**
+     * Standard projection for the interesting columns of a normal note.
+     */
+    private static final String[] sProjection = new String[] {
+            Telephony.Carriers._ID,     // 0
+            Telephony.Carriers.NAME,    // 1
+            Telephony.Carriers.APN,     // 2
+            Telephony.Carriers.PROXY,   // 3
+            Telephony.Carriers.PORT,    // 4
+            Telephony.Carriers.USER,    // 5
+            Telephony.Carriers.SERVER,  // 6
+            Telephony.Carriers.PASSWORD, // 7
+            Telephony.Carriers.MMSC, // 8
+            Telephony.Carriers.MCC, // 9
+            Telephony.Carriers.MNC, // 10
+            Telephony.Carriers.NUMERIC, // 11
+            Telephony.Carriers.MMSPROXY,// 12
+            Telephony.Carriers.MMSPORT, // 13
+            Telephony.Carriers.TYPE, // 14
+    };
+    
+    private static final int ID_INDEX = 0;
+    private static final int NAME_INDEX = 1;
+    private static final int APN_INDEX = 2;
+    private static final int PROXY_INDEX = 3;
+    private static final int PORT_INDEX = 4;
+    private static final int USER_INDEX = 5;
+    private static final int SERVER_INDEX = 6;
+    private static final int PASSWORD_INDEX = 7;
+    private static final int MMSC_INDEX = 8;
+    private static final int MCC_INDEX = 9;
+    private static final int MNC_INDEX = 10;
+    private static final int MMSPROXY_INDEX = 12;
+    private static final int MMSPORT_INDEX = 13;
+    private static final int TYPE_INDEX = 14;
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.apn_editor);
+
+        sNotSet = getResources().getString(R.string.apn_not_set);
+        mName = (EditTextPreference) findPreference("apn_name");
+        mApn = (EditTextPreference) findPreference("apn_apn");
+        mProxy = (EditTextPreference) findPreference("apn_http_proxy");
+        mPort = (EditTextPreference) findPreference("apn_http_port");
+        mUser = (EditTextPreference) findPreference("apn_user");
+        mServer = (EditTextPreference) findPreference("apn_server");
+        mPassword = (EditTextPreference) findPreference("apn_password");
+        mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy");
+        mMmsPort = (EditTextPreference) findPreference("apn_mms_port");
+        mMmsc = (EditTextPreference) findPreference("apn_mmsc");
+        mMcc = (EditTextPreference) findPreference("apn_mcc");
+        mMnc = (EditTextPreference) findPreference("apn_mnc");
+        mApnType = (EditTextPreference) findPreference("apn_type");
+        
+        mRes = getResources();
+        
+        final Intent intent = getIntent();
+        final String action = intent.getAction();
+
+        mFirstTime = icicle == null;
+        
+        if (action.equals(Intent.ACTION_EDIT)) {
+            mUri = intent.getData();
+        } else if (action.equals(Intent.ACTION_INSERT)) {
+            if (mFirstTime) {
+                mUri = getContentResolver().insert(intent.getData(), new ContentValues());
+            } else {
+                mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, 
+                        icicle.getInt(SAVED_POS));
+            }
+            mNewApn = true;
+            // If we were unable to create a new note, then just finish
+            // this activity.  A RESULT_CANCELED will be sent back to the
+            // original activity if they requested a result.
+            if (mUri == null) {
+                Log.w(TAG, "Failed to insert new telephony provider into "
+                        + getIntent().getData());
+                finish();
+                return;
+            }
+            
+            // The new entry was created, so assume all will end well and
+            // set the result to be returned.
+            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
+
+        } else {
+            finish();
+            return;
+        }
+
+        mCursor = managedQuery(mUri, sProjection, null, null);
+        mCursor.moveToFirst();
+        
+        fillUi();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+    }
+    
+    @Override
+    public void onPause() {
+        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+        super.onPause();        
+    }
+    
+    private void fillUi() {
+        if (mFirstTime) {            
+            mFirstTime = false;
+            // Fill in all the values from the db in both text editor and summary
+            mName.setText(mCursor.getString(NAME_INDEX));
+            mApn.setText(mCursor.getString(APN_INDEX));
+            mProxy.setText(mCursor.getString(PROXY_INDEX));
+            mPort.setText(mCursor.getString(PORT_INDEX));
+            mUser.setText(mCursor.getString(USER_INDEX));
+            mServer.setText(mCursor.getString(SERVER_INDEX));
+            mPassword.setText(mCursor.getString(PASSWORD_INDEX));
+            mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
+            mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
+            mMmsc.setText(mCursor.getString(MMSC_INDEX));
+            mMcc.setText(mCursor.getString(MCC_INDEX));
+            mMnc.setText(mCursor.getString(MNC_INDEX));
+            mApnType.setText(mCursor.getString(TYPE_INDEX));
+            if (mNewApn) {
+                String numeric = 
+                    SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
+                // MCC is first 3 chars and then in 2 - 3 chars of MNC
+                if (numeric != null && numeric.length() > 4) {
+                    // Country code
+                    String mcc = numeric.substring(0, 3);
+                    // Network code
+                    String mnc = numeric.substring(3);
+                    // Auto populate MNC and MCC for new entries, based on what SIM reports
+                    mMcc.setText(mcc);
+                    mMnc.setText(mnc);
+                }
+            }
+        }
+        
+        mName.setSummary(checkNull(mName.getText()));
+        mApn.setSummary(checkNull(mApn.getText()));
+        mProxy.setSummary(checkNull(mProxy.getText()));
+        mPort.setSummary(checkNull(mPort.getText()));
+        mUser.setSummary(checkNull(mUser.getText()));
+        mServer.setSummary(checkNull(mServer.getText()));
+        mPassword.setSummary(starify(mPassword.getText()));
+        mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
+        mMmsPort.setSummary(checkNull(mMmsPort.getText()));
+        mMmsc.setSummary(checkNull(mMmsc.getText()));
+        mMcc.setSummary(checkNull(mMcc.getText()));
+        mMnc.setSummary(checkNull(mMnc.getText()));
+        mApnType.setSummary(checkNull(mApnType.getText()));
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        // If it's a new APN, then cancel will delete the new entry in onPause
+        if (!mNewApn) {
+            menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
+                .setIcon(android.R.drawable.ic_menu_delete);
+        }
+        menu.add(0, MENU_SAVE, 0, R.string.menu_save)
+            .setIcon(android.R.drawable.ic_menu_save);
+        menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel)
+            .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_DELETE:
+            deleteApn();
+            return true;
+        case MENU_SAVE:
+            if (validateAndSave(false)) {
+                finish();
+            }
+            return true;
+        case MENU_CANCEL:
+            if (mNewApn) {
+                getContentResolver().delete(mUri, null, null);
+            }
+            finish();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_BACK: {
+                if (validateAndSave(false)) {
+                    finish();
+                }
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle icicle) {
+        super.onSaveInstanceState(icicle);
+        validateAndSave(true);
+        icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
+    }
+    
+    /**
+     * Check the key fields' validity and save if valid.
+     * @param force save even if the fields are not valid, if the app is
+     *        being suspended
+     * @return true if the data was saved
+     */
+    private boolean validateAndSave(boolean force) {
+        String name = checkNotSet(mName.getText());
+        String apn = checkNotSet(mApn.getText());
+        String mcc = checkNotSet(mMcc.getText());
+        String mnc = checkNotSet(mMnc.getText());
+        
+        String errorMsg = null;
+        if (name.length() < 1) {
+            errorMsg = mRes.getString(R.string.error_name_empty);
+        } else if (apn.length() < 1) {
+            errorMsg = mRes.getString(R.string.error_apn_empty);
+        } else if (mcc.length() != 3) {
+            errorMsg = mRes.getString(R.string.error_mcc_not3);
+        } else if ((mnc.length() & 0xFFFE) != 2) {
+            errorMsg = mRes.getString(R.string.error_mnc_not23);
+        }
+        
+        if (errorMsg != null && !force) {
+            showErrorMessage(errorMsg);
+            return false;
+        }
+        
+        if (!mCursor.moveToFirst()) {
+            Log.w(TAG,
+                    "Could not go to the first row in the Cursor when saving data.");
+            return false;
+        }
+        
+        ContentValues values = new ContentValues();
+        
+        values.put(Telephony.Carriers.NAME, name);
+        values.put(Telephony.Carriers.APN, apn);
+        values.put(Telephony.Carriers.PROXY, checkNotSet(mProxy.getText()));
+        values.put(Telephony.Carriers.PORT, checkNotSet(mPort.getText()));
+        values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText()));
+        values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText()));
+        values.put(Telephony.Carriers.USER, checkNotSet(mUser.getText()));
+        values.put(Telephony.Carriers.SERVER, checkNotSet(mServer.getText()));
+        values.put(Telephony.Carriers.PASSWORD, checkNotSet(mPassword.getText()));
+        values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText()));            
+        values.put(Telephony.Carriers.TYPE, checkNotSet(mApnType.getText()));
+
+        values.put(Telephony.Carriers.MCC, mcc);
+        values.put(Telephony.Carriers.MNC, mnc);
+        
+        values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
+        
+        getContentResolver().update(mUri, values, null, null);
+        
+        return true;
+    }
+
+    private void showErrorMessage(String message) {
+        new AlertDialog.Builder(this)
+            .setTitle(R.string.error_title)
+            .setMessage(message)
+            .setPositiveButton(android.R.string.ok, null)
+            .show();
+    }
+
+    private void deleteApn() {
+        getContentResolver().delete(mUri, null, null);
+        finish();
+    }
+    
+    private String starify(String value) {
+        if (value == null || value.length() == 0) {
+            return sNotSet;
+        } else {
+            char[] password = new char[value.length()];
+            for (int i = 0; i < password.length; i++) {
+                password[i] = '*';
+            }
+            return new String(password);
+        }
+    }
+    
+    private String checkNull(String value) {
+        if (value == null || value.length() == 0) {
+            return sNotSet;
+        } else {
+            return value;
+        }
+    }
+    
+    private String checkNotSet(String value) {
+        if (value == null || value.equals(sNotSet)) {
+            return "";
+        } else {
+            return value;
+        }
+    }
+    
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        Preference pref = findPreference(key);
+        if (pref != null) {
+            pref.setSummary(checkNull(sharedPreferences.getString(key, "")));
+        }
+    }
+}
diff --git a/src/com/android/settings/ApnSettings.java b/src/com/android/settings/ApnSettings.java
new file mode 100644
index 0000000..ea13ee7
--- /dev/null
+++ b/src/com/android/settings/ApnSettings.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Telephony;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class ApnSettings extends PreferenceActivity {
+
+    public static final String EXTRA_POSITION = "position";
+    
+    private static final int ID_INDEX = 0;
+    private static final int NAME_INDEX = 1;
+    private static final int APN_INDEX = 2;
+
+    private static final int MENU_NEW = Menu.FIRST;
+    
+    private Cursor mCursor;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.apn_settings);    
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        fillList();
+    }
+    
+    private void fillList() {
+        mCursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] {
+                "_id", "name", "apn"}, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+
+        PreferenceCategory apnList = (PreferenceCategory) findPreference("apn_list");
+        apnList.removeAll();
+        
+        mCursor.moveToFirst();
+        while (!mCursor.isAfterLast()) {
+            String name = mCursor.getString(NAME_INDEX);
+            String apn = mCursor.getString(APN_INDEX);
+            
+            Preference pref = new Preference((Context) this);
+            pref.setKey(mCursor.getString(ID_INDEX));
+            pref.setTitle(name);
+            pref.setSummary(apn);
+            pref.setPersistent(false);
+            apnList.addPreference(pref);
+            mCursor.moveToNext();
+        }
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_NEW, 0, 
+                getResources().getString(R.string.menu_new))
+                .setIcon(android.R.drawable.ic_menu_add);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_NEW:
+            addNewApn();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    
+    private void addNewApn() {
+        startActivity(new Intent(Intent.ACTION_INSERT, Telephony.Carriers.CONTENT_URI));
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        int pos = Integer.parseInt(preference.getKey());
+        Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
+        startActivity(new Intent(Intent.ACTION_EDIT, url));
+        return true;
+    }
+}
diff --git a/src/com/android/settings/ApplicationSettings.java b/src/com/android/settings/ApplicationSettings.java
new file mode 100644
index 0000000..0ee2789
--- /dev/null
+++ b/src/com/android/settings/ApplicationSettings.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+
+public class ApplicationSettings extends PreferenceActivity implements
+        DialogInterface.OnClickListener {
+    
+    private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications";
+
+    private CheckBoxPreference mToggleAppInstallation;
+    
+    private DialogInterface mWarnInstallApps;
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.application_settings);
+
+        mToggleAppInstallation = (CheckBoxPreference) findPreference(KEY_TOGGLE_INSTALL_APPLICATIONS);
+        mToggleAppInstallation.setChecked(isNonMarketAppsAllowed());
+        
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mToggleAppInstallation) {
+            if (mToggleAppInstallation.isChecked()) {
+                mToggleAppInstallation.setChecked(false);
+                warnAppInstallation();
+            } else {
+                setNonMarketAppsAllowed(false);
+            }
+        }
+        
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if (dialog == mWarnInstallApps && which == DialogInterface.BUTTON1) {
+            setNonMarketAppsAllowed(true);
+            mToggleAppInstallation.setChecked(true);
+        }
+    }
+
+    private void setNonMarketAppsAllowed(boolean enabled) {
+        // Change the system setting
+        Settings.System.putInt(getContentResolver(), Settings.System.INSTALL_NON_MARKET_APPS, 
+                                enabled ? 1 : 0);
+    }
+    
+    private boolean isNonMarketAppsAllowed() {
+            return Settings.System.getInt(getContentResolver(), 
+                                           Settings.System.INSTALL_NON_MARKET_APPS, 0) > 0;
+    }
+
+    private void warnAppInstallation() {
+        mWarnInstallApps = new AlertDialog.Builder(this)
+                .setTitle(getString(R.string.error_title))
+                .setIcon(com.android.internal.R.drawable.ic_dialog_alert)
+                .setMessage(getResources().getString(R.string.install_all_warning))
+                .setPositiveButton(android.R.string.yes, this)
+                .setNegativeButton(android.R.string.no, null)
+                .show();
+    }
+    
+    
+}
diff --git a/src/com/android/settings/BandMode.java b/src/com/android/settings/BandMode.java
new file mode 100644
index 0000000..1297cad
--- /dev/null
+++ b/src/com/android/settings/BandMode.java
@@ -0,0 +1,217 @@
+package com.android.settings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import android.os.Bundle;
+import android.os.Message;
+import android.os.Handler;
+import android.os.AsyncResult;
+import android.util.Log;
+import android.content.DialogInterface;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.Window;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+import android.widget.AdapterView;
+
+
+/**
+ * Radio Band Mode Selection Class
+ *
+ * It will query baseband about all available band modes and display them
+ * in screen. It will display all six band modes if the query failed.
+ *
+ * After user select one band, it will send the selection to baseband.
+ *
+ * It will alter user the result of select operation and exit, no matter success
+ * or not.
+ *
+ */
+public class BandMode extends Activity {
+    private static final String LOG_TAG = "phone";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_BAND_SCAN_COMPLETED = 100;
+    private static final int EVENT_BAND_SELECTION_DONE = 200;
+
+    private static final String[] BAND_NAMES = new String[] {
+            "Automatic",
+            "EURO Band",
+            "USA Band",
+            "JAPAN Band",
+            "AUS Band",
+            "AUS2 Band"
+    };
+
+    private ListView mBandList;
+    private ArrayAdapter mBandListAdapter;
+    private BandListItem mTargetBand = null;
+    private DialogInterface mProgressPanel;
+
+    private Phone mPhone = null;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        
+        setContentView(R.layout.band_mode);
+
+        setTitle(getString(R.string.band_mode_title));
+        getWindow().setLayout(WindowManager.LayoutParams.FILL_PARENT,
+                                    WindowManager.LayoutParams.WRAP_CONTENT);
+
+        mPhone = PhoneFactory.getDefaultPhone();
+
+        mBandList = (ListView) findViewById(R.id.band);
+        mBandListAdapter = new ArrayAdapter<BandListItem>(this,
+                android.R.layout.simple_list_item_1);
+        mBandList.setAdapter(mBandListAdapter);
+        mBandList.setOnItemClickListener(mBandSelectionHandler);
+
+
+
+        loadBandList();
+    }
+
+    private AdapterView.OnItemClickListener mBandSelectionHandler =
+            new AdapterView.OnItemClickListener () {
+                public void onItemClick(AdapterView parent, View v,
+                        int position, long id) {
+
+                    getWindow().setFeatureInt(
+                            Window.FEATURE_INDETERMINATE_PROGRESS,
+                            Window.PROGRESS_VISIBILITY_ON);
+
+                    mTargetBand = (BandListItem) parent.getAdapter().getItem(position);
+
+                    if (DBG) log("Select band : " + mTargetBand.toString());
+
+                    Message msg =
+                            mHandler.obtainMessage(EVENT_BAND_SELECTION_DONE);
+                    mPhone.setBandMode(mTargetBand.getBand(), msg);
+                }
+            };
+
+    private class BandListItem {
+        private int mBandMode = Phone.BM_UNSPECIFIED;
+
+        public BandListItem(int bm) {
+            mBandMode = bm;
+        }
+
+        public int getBand() {
+            return mBandMode;
+        }
+
+        public String toString() {
+            return BAND_NAMES[mBandMode];
+        }
+    }
+
+    private void loadBandList() {
+        String str = getString(R.string.band_mode_loading);
+
+        if (DBG) log(str);
+
+
+        //ProgressDialog.show(this, null, str, true, true, null);
+        mProgressPanel = new AlertDialog.Builder(this)
+            .setMessage(str)
+            .show();
+
+        Message msg = mHandler.obtainMessage(EVENT_BAND_SCAN_COMPLETED);
+        mPhone.queryAvailableBandMode(msg);
+
+    }
+
+    private void bandListLoaded(AsyncResult result) {
+        if (DBG) log("network list loaded");
+
+        if (mProgressPanel != null) mProgressPanel.dismiss();
+
+        clearList();
+
+        boolean addBandSuccess = false;
+        BandListItem item;
+
+        if (result.result != null) {
+            int bands[] = (int[])result.result;
+            int size = bands[0];
+
+            if (size > 0) {
+                for (int i=1; i<size; i++) {
+                    item = new BandListItem(bands[i]);
+                    mBandListAdapter.add(item);
+                    if (DBG) log("Add " + item.toString());
+                }
+                addBandSuccess = true;
+            }
+        }
+
+        if (addBandSuccess == false) {
+            if (DBG) log("Error in query, add default list");
+            for (int i=0; i<Phone.BM_BOUNDARY; i++) {
+                item = new BandListItem(i);
+                mBandListAdapter.add(item);
+                if (DBG) log("Add default " + item.toString());
+            }
+        }
+        mBandList.requestFocus();
+    }
+
+    private void displayBandSelectionResult(Throwable ex) {
+        String status = getString(R.string.band_mode_set)
+                +" [" + mTargetBand.toString() + "] ";
+
+        if (ex != null) {
+            status = status + getString(R.string.band_mode_failed);
+        } else {
+            status = status + getString(R.string.band_mode_succeeded);
+        }
+
+        mProgressPanel = new AlertDialog.Builder(this)
+            .setMessage(status)
+            .setPositiveButton(android.R.string.ok, null).show();
+    }
+
+    private void clearList() {
+        while(mBandListAdapter.getCount() > 0) {
+            mBandListAdapter.remove(
+                    mBandListAdapter.getItem(0));
+        }
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[BandsList] " + msg);
+    }
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_BAND_SCAN_COMPLETED:
+                    ar = (AsyncResult) msg.obj;
+
+                    bandListLoaded(ar);
+                    break;
+
+                case EVENT_BAND_SELECTION_DONE:
+                    ar = (AsyncResult) msg.obj;
+
+                    getWindow().setFeatureInt(
+                            Window.FEATURE_INDETERMINATE_PROGRESS,
+                            Window.PROGRESS_VISIBILITY_OFF);
+
+                    displayBandSelectionResult(ar.exception);
+                    break;
+            }
+        }
+    };
+
+
+}
diff --git a/src/com/android/settings/BatteryInfo.java b/src/com/android/settings/BatteryInfo.java
new file mode 100644
index 0000000..ef60fc3
--- /dev/null
+++ b/src/com/android/settings/BatteryInfo.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.pim.DateUtils;
+import android.widget.TextView;
+
+import com.android.internal.app.IBatteryStats;
+
+public class BatteryInfo extends Activity {
+    private TextView mStatus;
+    private TextView mLevel;
+    private TextView mScale;
+    private TextView mHealth;
+    private TextView mVoltage;
+    private TextView mTemperature;
+    private TextView mTechnology;
+    private TextView mUptime;
+    private TextView mAwakeBattery;
+    private TextView mAwakePlugged;
+    private TextView mScreenOn;
+    private IBatteryStats mBatteryStats;
+    private IPowerManager mScreenStats;
+    
+    private static final int EVENT_TICK = 1;
+    
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_TICK:
+                    updateBatteryStats();
+                    sendEmptyMessageDelayed(EVENT_TICK, 1000);
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Format a number of tenths-units as a decimal string without using a
+     * conversion to float.  E.g. 347 -> "34.7"
+     */
+    private final String tenthsToFixedString(int x) {
+        int tens = x / 10;
+        return new String("" + tens + "." + (x - 10*tens));
+    }
+
+   /**
+    *Listens for intent broadcasts
+    */
+    private IntentFilter   mIntentFilter;
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                int plugType = intent.getIntExtra("plugged", 0);
+
+                mLevel.setText("" + intent.getIntExtra("level", 0));
+                mScale.setText("" + intent.getIntExtra("scale", 0));
+                mVoltage.setText("" + intent.getIntExtra("voltage", 0) + " "
+                        + getString(R.string.battery_info_voltage_units));
+                mTemperature.setText("" + tenthsToFixedString(intent.getIntExtra("temperature", 0))
+                        + getString(R.string.battery_info_temperature_units));
+                mTechnology.setText("" + intent.getStringExtra("technology"));
+                
+                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
+                String statusString;
+                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
+                    statusString = getString(R.string.battery_info_status_charging);
+                    if (plugType > 0) {
+                        statusString = statusString + " " + getString(
+                                (plugType == BatteryManager.BATTERY_PLUGGED_AC)
+                                        ? R.string.battery_info_status_charging_ac
+                                        : R.string.battery_info_status_charging_usb);
+                    }
+                } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+                    statusString = getString(R.string.battery_info_status_discharging);
+                } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
+                    statusString = getString(R.string.battery_info_status_not_charging);
+                } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
+                    statusString = getString(R.string.battery_info_status_full);
+                } else {
+                    statusString = getString(R.string.battery_info_status_unknown);
+                }
+                mStatus.setText(statusString);
+
+                int health = intent.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN);
+                String healthString;
+                if (health == BatteryManager.BATTERY_HEALTH_GOOD) {
+                    healthString = getString(R.string.battery_info_health_good);
+                } else if (health == BatteryManager.BATTERY_HEALTH_OVERHEAT) {
+                    healthString = getString(R.string.battery_info_health_overheat);
+                } else if (health == BatteryManager.BATTERY_HEALTH_DEAD) {
+                    healthString = getString(R.string.battery_info_health_dead);
+                } else if (health == BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE) {
+                    healthString = getString(R.string.battery_info_health_over_voltage);
+                } else if (health == BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE) {
+                    healthString = getString(R.string.battery_info_health_unspecified_failure);
+                } else {
+                    healthString = getString(R.string.battery_info_health_unknown);
+                }
+                mHealth.setText(healthString);
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.battery_info);
+
+        // create the IntentFilter that will be used to listen
+        // to battery status broadcasts
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        mStatus = (TextView)findViewById(R.id.status);
+        mLevel = (TextView)findViewById(R.id.level);
+        mScale = (TextView)findViewById(R.id.scale);
+        mHealth = (TextView)findViewById(R.id.health);
+        mTechnology = (TextView)findViewById(R.id.technology);
+        mVoltage = (TextView)findViewById(R.id.voltage);
+        mTemperature = (TextView)findViewById(R.id.temperature);
+        mUptime = (TextView) findViewById(R.id.uptime);
+        mAwakeBattery = (TextView) findViewById(R.id.awakeBattery);
+        mAwakePlugged = (TextView) findViewById(R.id.awakePlugged);
+        mScreenOn = (TextView) findViewById(R.id.screenOn);
+        
+        // Get awake time plugged in and on battery
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
+        mScreenStats = IPowerManager.Stub.asInterface(ServiceManager.getService(POWER_SERVICE));
+        mHandler.sendEmptyMessageDelayed(EVENT_TICK, 1000);
+        
+        registerReceiver(mIntentReceiver, mIntentFilter);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mHandler.removeMessages(EVENT_TICK);
+        
+        // we are no longer on the screen stop the observers
+        unregisterReceiver(mIntentReceiver);
+    }
+
+    private void updateBatteryStats() {
+        long uptime = SystemClock.elapsedRealtime();
+        mUptime.setText(DateUtils.formatElapsedTime(uptime / 1000));
+        
+        if (mBatteryStats != null) {
+            try {
+                long awakeTimeBattery = mBatteryStats.getAwakeTimeBattery();
+                long awakeTimePluggedIn = mBatteryStats.getAwakeTimePlugged();
+                mAwakeBattery.setText(DateUtils.formatElapsedTime(awakeTimeBattery / 1000) 
+                        + " (" + (100 * awakeTimeBattery / uptime) + "%)");
+                mAwakePlugged.setText(DateUtils.formatElapsedTime(awakeTimePluggedIn / 1000)
+                        + " (" + (100 * awakeTimePluggedIn / uptime) + "%)");
+            } catch (RemoteException re) {
+                mAwakeBattery.setText("Unknown");
+                mAwakePlugged.setText("Unknown");            
+            }
+        }
+        if (mScreenStats != null) {
+            try {
+                long screenOnTime = mScreenStats.getScreenOnTime();
+                mScreenOn.setText(DateUtils.formatElapsedTime(screenOnTime / 1000));
+            } catch (RemoteException re) {
+                mScreenOn.setText("Unknown");
+            }
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/BluetoothDataEntry.java b/src/com/android/settings/BluetoothDataEntry.java
new file mode 100644
index 0000000..1c7e0b6
--- /dev/null
+++ b/src/com/android/settings/BluetoothDataEntry.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnKeyListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class BluetoothDataEntry extends Activity implements OnKeyListener {
+    
+    private Bundle extras;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.bluetooth_data_entry);
+
+        mDataLabel = (TextView)findViewById(R.id.dataLabel);
+        mDataEntry = (EditText)findViewById(R.id.dataEntry);
+        mConfirmButton = (Button)findViewById(R.id.confirmButton);
+        mCancelButton = (Button)findViewById(R.id.cancelButton);
+
+        mDataEntry.setOnKeyListener(this);
+        Intent intent = getIntent();
+        String label = null;
+        {
+            String labelExtra = intent.getStringExtra("label");
+            if (labelExtra != null) {
+                label = labelExtra;
+            }
+        }
+        extras = intent.getBundleExtra("extras");
+        if (label != null && label.length() > 0) {
+            mDataLabel.setText(label);
+        }
+
+        mConfirmButton.setOnClickListener(new ConfirmButtonListener());
+        mCancelButton.setOnClickListener(new CancelButtonListener());
+    }
+
+    private class ConfirmButtonListener implements OnClickListener {
+        public void onClick(View v) {
+            activityResult(RESULT_OK, mDataEntry.getText().toString(), extras);
+        }
+    }
+
+    private class CancelButtonListener implements OnClickListener {
+        public void onClick(View v) {
+            activityResult(RESULT_CANCELED, null, null);
+        }
+    }
+
+    protected void activityResult(int result, String data, Bundle extras) {
+        setResult(result, (new Intent()).setAction(data).putExtras(extras));
+        finish();
+    }
+
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER 
+                || keyCode == KeyEvent.KEYCODE_ENTER) {
+            activityResult(RESULT_OK, mDataEntry.getText().toString(), extras);
+            return true;
+        }
+        return false;
+    }
+
+    protected TextView mDataLabel;
+    protected EditText mDataEntry;
+    protected Button mConfirmButton;
+    protected Button mCancelButton;
+}
diff --git a/src/com/android/settings/BluetoothListItem.java b/src/com/android/settings/BluetoothListItem.java
new file mode 100644
index 0000000..c75be13
--- /dev/null
+++ b/src/com/android/settings/BluetoothListItem.java
@@ -0,0 +1,72 @@
+package com.android.settings;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import java.util.Map;
+
+/**
+ * This class extends Preference to display bluetooth status icons. One
+ * icon specifies the connection/pairing status that is right-aligned.
+ * An optional headset icon can be added to its left as well.
+ */
+public class BluetoothListItem extends Preference {
+
+    private boolean mIsHeadset;
+    private int mWeight;
+    
+    public BluetoothListItem(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWidgetLayoutResource(R.layout.preference_widget_btdevice_status);
+    }
+
+    private void updateIcons(View view) {
+        ImageView headsetView = (ImageView) view.findViewById(R.id.device_headset);
+        headsetView.setVisibility(mIsHeadset ? View.VISIBLE : View.GONE);
+    }
+
+    @Override
+    public void onBindView(View view) {
+        super.onBindView(view);
+        updateIcons(view);
+    }
+
+    /**
+     * Set whether the device is of headset type
+     * @param headset whether or not the headset icon should be shown
+     */
+    public void setHeadset(boolean headset) {
+        mIsHeadset = headset;
+        notifyChanged();
+    }
+
+    /**
+     * Sets the weight for ordering by signal strength or importance
+     * @param weight the ordering weight
+     */
+    public void setWeight(int weight) {
+        mWeight = weight;
+    }
+
+    /**
+     * Returns the currently set ordering weight
+     * @return the current ordering weight
+     */
+    public int getWeight() {
+        return mWeight;
+    }
+    
+    @Override
+    public int compareTo(Preference another) {
+        int diff = ((BluetoothListItem)another).mWeight - mWeight;
+        // Let the new one be after the old one, if they are the same weight
+        // TODO: Implement a more reliable way to consistently order items of
+        // the same weight
+        if (diff == 0) diff = 1;
+        return diff;
+    }
+}
diff --git a/src/com/android/settings/BluetoothPINEntry.java b/src/com/android/settings/BluetoothPINEntry.java
new file mode 100644
index 0000000..8933c03
--- /dev/null
+++ b/src/com/android/settings/BluetoothPINEntry.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.NotificationManager;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class BluetoothPINEntry extends BluetoothDataEntry {
+    private BluetoothDevice mBluetooth;
+    private String mAddress;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        Intent intent = getIntent();
+        if (!intent.getAction().equals(BluetoothIntent.PAIRING_REQUEST_ACTION))
+        {
+            Log.e(this.getClass().getName(),
+                  "Error: this activity may be started only with intent " +
+                  BluetoothIntent.PAIRING_REQUEST_ACTION);
+            finish();
+        }
+        
+        // Cancel the notification, if any
+        NotificationManager manager = (NotificationManager) 
+        getSystemService(Context.NOTIFICATION_SERVICE);
+        manager.cancel(0xb100ceee);
+        
+        mAddress = intent.getStringExtra(BluetoothIntent.ADDRESS);
+
+        mBluetooth = (BluetoothDevice)getSystemService(BLUETOOTH_SERVICE);
+        
+        String remoteName = mBluetooth.getRemoteName(mAddress);
+        if (remoteName == null) {
+            remoteName = mAddress;
+        }
+            
+        mDataLabel.setText(getString(R.string.bluetooth_enter_pin_msg) + remoteName);
+    }
+
+    @Override
+    public void activityResult(int result, String data, Bundle extras) {
+        switch (result) {
+        case RESULT_OK:
+            byte[] pin = BluetoothDevice.convertPinToBytes(mDataEntry.getText().toString());
+            if (pin == null) {
+                return;
+            }
+            mBluetooth.setPin(mAddress, pin);
+            break;
+        case RESULT_CANCELED:
+            mBluetooth.cancelPin(mAddress);
+            break;
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/settings/BluetoothPinRequest.java b/src/com/android/settings/BluetoothPinRequest.java
new file mode 100644
index 0000000..d6a12f3
--- /dev/null
+++ b/src/com/android/settings/BluetoothPinRequest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+
+/**
+ * This class handles the Bluetooth pairing PIN request from the bluetooth service
+ * It checks if the BluetoothSettings activity is currently visible and lets that
+ * activity handle the request. Otherwise it puts a Notification in the status bar,
+ * which can be clicked to bring up the PIN entry dialog. 
+ */
+public class BluetoothPinRequest extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent.getAction().equals(BluetoothIntent.PAIRING_REQUEST_ACTION)) {
+            if (BluetoothSettings.isRunning()) {
+                // Let the BluetoothSettings activity handle it
+                return;
+            } else {
+                Resources res = context.getResources();
+                String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+                Notification pair = new Notification(
+                        android.R.drawable.stat_sys_data_bluetooth,
+                        res.getString(R.string.bluetooth_notif_ticker),
+                        System.currentTimeMillis());
+
+                Intent pinIntent = new Intent();
+                pinIntent.setClass(context, BluetoothPINEntry.class);
+                pinIntent.putExtra(BluetoothIntent.ADDRESS, address); 
+                pinIntent.setAction(BluetoothIntent.PAIRING_REQUEST_ACTION);
+                PendingIntent pending = PendingIntent.getActivity(context, 0, 
+                        pinIntent, PendingIntent.FLAG_ONE_SHOT);
+                
+                String name = intent.getStringExtra(BluetoothIntent.NAME);
+                
+                if (name == null) {
+                    BluetoothDevice bluetooth = 
+                        (BluetoothDevice)context.getSystemService(Context.BLUETOOTH_SERVICE);
+                    name = bluetooth.getRemoteName(address);
+                    if (name == null) {
+                        name = address;
+                    }
+                }
+                
+                pair.setLatestEventInfo(context, 
+                        res.getString(R.string.bluetooth_notif_title), 
+                        res.getString(R.string.bluetooth_notif_message) + name, 
+                        pending);
+                
+                NotificationManager manager = (NotificationManager) 
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                manager.notify(0xb100ceee, pair);
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/BluetoothSettings.java b/src/com/android/settings/BluetoothSettings.java
new file mode 100644
index 0000000..6a19ec4
--- /dev/null
+++ b/src/com/android/settings/BluetoothSettings.java
@@ -0,0 +1,1035 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothIntent;
+import android.bluetooth.DeviceClass;
+import android.bluetooth.IBluetoothDeviceCallback;
+import android.bluetooth.IBluetoothHeadsetCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.text.method.PasswordTransformationMethod;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnKeyListener;
+import android.widget.AdapterView;
+import android.widget.EditText;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+import java.util.HashMap;
+
+public class BluetoothSettings
+        extends PreferenceActivity
+        implements OnSharedPreferenceChangeListener, OnKeyListener,
+                View.OnCreateContextMenuListener {
+
+    private static final String TAG = "BluetoothSettings";
+
+    private static final int MENU_SCAN_ID = Menu.FIRST;
+    private static final int MENU_CLEAR_ID = Menu.FIRST + 1;
+    
+    private static final int MENU_CONNECT = ContextMenu.FIRST;
+    private static final int MENU_DISCONNECT = ContextMenu.FIRST + 1;
+    private static final int MENU_PAIR = ContextMenu.FIRST + 2;
+    private static final int MENU_UNPAIR = ContextMenu.FIRST + 3;
+    
+    private static final String BT_ENABLE = "bt_checkbox";
+    private static final String BT_VISIBILITY = "bt_visibility";
+    private static final String BT_NAME = "bt_name";
+    
+    private static final String BT_KEY_PREFIX = "bt_dev_";
+    private static final int BT_KEY_LENGTH = BT_KEY_PREFIX.length();
+    private static final String FREEZE_ADDRESSES = "addresses";
+    private static final String FREEZE_TYPES = "types";
+    private static final String FREEZE_PIN = "pinText";
+    private static final String FREEZE_PIN_ADDRESS = "pinAddress";
+    private static final String FREEZE_RSSI = "rssi";
+    private static final String FREEZE_DISCOVERABLE_START = "dstart";
+    
+    private static final int HANDLE_FAILED_TO_CONNECT = 1;
+    private static final int HANDLE_CONNECTING = 2;
+    private static final int HANDLE_CONNECTED = 3;
+    private static final int HANDLE_DISCONNECTED = 4;
+    private static final int HANDLE_PIN_REQUEST = 5;
+    private static final int HANDLE_DISCOVERABLE_TIMEOUT = 6;
+    private static final int HANDLE_INITIAL_SCAN = 7;
+    private static final int HANDLE_PAIRING_FAILED = 8;
+    private static final int HANDLE_PAIRING_PASSED = 9;
+    private static final int HANDLE_PAUSE_TIMEOUT = 10;
+    
+
+    
+    private static String STR_CONNECTED;
+    private static String STR_PAIRED;
+    private static String STR_PAIRED_NOT_NEARBY;
+    private static String STR_NOT_CONNECTED;
+    private static String STR_CONNECTING;
+    private static String STR_PAIRING;
+    
+    private static final int WEIGHT_CONNECTED = 1;
+    private static final int WEIGHT_PAIRED = 0;
+    private static final int WEIGHT_UNKNOWN = -1;
+    
+    private CheckBoxPreference mBTToggle;
+    private CheckBoxPreference mBTVisibility;
+    private EditTextPreference mBTName;
+    private ProgressCategory mBTDeviceList;
+    private AlertDialog mPinDialog;
+    private String      mPinAddress;
+    private EditText    mPinEdit;
+    private View        mPinButton1;
+    private String      mDisconnectAddress;
+    
+    private BluetoothDevice mBluetooth;
+    private BluetoothHeadset mBluetoothHeadset;
+    private boolean mIsEnabled;
+    private String mLastConnected;
+    private static boolean sIsRunning;
+    private static DeviceCallback sDeviceCallback;    
+    private IntentFilter mIntentFilter;
+    private Resources mRes;
+    private long mDiscoverableStartTime;
+    private int mDiscoverableTime;
+    private static final String DISCOVERABLE_TIME = "debug.bt.discoverable_time";
+    private static final int DISCOVERABLE_TIME_DEFAULT = 120;
+    private boolean mAutoDiscovery;
+    // After a few seconds after a pause, if the user doesn't restart the 
+    // BT settings, then we need to cleanup a few things in the message handler
+    private static final int PAUSE_TIMEOUT = 3000;
+    
+    private boolean mStartScan;
+    private static final String AUTO_DISCOVERY = "debug.bt.auto_discovery";
+    private HashMap<String,Preference> mDeviceMap;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.bluetooth_settings);
+    
+        // Deal with restarted activities by passing a static callback object to
+        // the Bluetooth service
+        if (sDeviceCallback == null) {
+            sDeviceCallback = new DeviceCallback();
+        }
+        sDeviceCallback.setHandler(mHandler);
+        
+        mDiscoverableTime = SystemProperties.getInt(DISCOVERABLE_TIME, -1);
+        if (mDiscoverableTime <= 0) {
+            mDiscoverableTime= DISCOVERABLE_TIME_DEFAULT;
+        }
+        mAutoDiscovery = SystemProperties.getBoolean(AUTO_DISCOVERY, true);
+
+        if (!initBluetoothAPI()) {
+            finish();
+            return;
+        }
+        initUI();
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+        
+        mDeviceMap = new HashMap<String,Preference>();
+        if (icicle != null && icicle.containsKey(FREEZE_ADDRESSES)) {
+            addDevices(icicle.getStringArray(FREEZE_ADDRESSES), 
+                    icicle.getStringArray(FREEZE_TYPES), 
+                    icicle.getIntArray(FREEZE_RSSI));
+            if (icicle.containsKey(FREEZE_PIN)) {
+                String savedPin = icicle.getString(FREEZE_PIN);
+                String pinAddress = icicle.getString(FREEZE_PIN_ADDRESS);
+                mPinDialog = showPinDialog(savedPin, pinAddress);
+            }
+            mDiscoverableStartTime = icicle.getLong(FREEZE_DISCOVERABLE_START);
+        } else {
+            mStartScan = true;
+        }
+    }
+
+    private void initUI() {
+        mBTToggle = (CheckBoxPreference) findPreference(BT_ENABLE);
+        mBTVisibility = (CheckBoxPreference) findPreference(BT_VISIBILITY);
+        mBTName = (EditTextPreference) findPreference(BT_NAME);
+        mBTDeviceList = (ProgressCategory) findPreference("bt_device_list");
+        mBTDeviceList.setOrderingAsAdded(false);
+        mRes = getResources();
+        if (mIsEnabled) {
+            String name = mBluetooth.getName();
+            if (name != null) {
+                mBTName.setSummary(name);
+            }
+        }
+        mBTVisibility.setEnabled(mIsEnabled);
+        mBTName.setEnabled(mIsEnabled);
+        STR_CONNECTED = mRes.getString(R.string.bluetooth_connected);
+        STR_PAIRED = mRes.getString(R.string.bluetooth_paired);
+        STR_PAIRED_NOT_NEARBY = 
+            mRes.getString(R.string.bluetooth_paired_not_nearby);
+        STR_CONNECTING = mRes.getString(R.string.bluetooth_connecting);
+        STR_PAIRING = mRes.getString(R.string.bluetooth_pairing);
+        STR_NOT_CONNECTED = mRes.getString(R.string.bluetooth_not_connected);
+        getListView().setOnCreateContextMenuListener(this);
+    }
+    
+    private boolean initBluetoothAPI() {
+        mIntentFilter =
+            new IntentFilter(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.BONDING_CREATED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.ENABLED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.PAIRING_REQUEST_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.MODE_CHANGED_ACTION);
+        
+        mBluetooth = (BluetoothDevice)getSystemService(BLUETOOTH_SERVICE);
+        mBluetoothHeadset = new BluetoothHeadset(this);
+        if (mBluetooth == null) { // If the environment doesn't support BT
+            return false;
+        }
+        mIsEnabled = mBluetooth.isEnabled();
+        return true;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        sIsRunning = true;
+        mHandler.removeMessages(HANDLE_PAUSE_TIMEOUT);
+        registerReceiver(mReceiver, mIntentFilter);
+
+        mIsEnabled = mBluetooth.isEnabled();
+        updateStatus();
+        final boolean discoverable = mBluetooth.getMode() == 
+            BluetoothDevice.MODE_DISCOVERABLE;
+        mBTDeviceList.setProgress(mIsEnabled && mBluetooth.isDiscovering());
+        mBTVisibility.setChecked(mIsEnabled && discoverable);
+        
+        if (discoverable) {
+            mHandler.sendMessage(
+                    mHandler.obtainMessage(HANDLE_DISCOVERABLE_TIMEOUT));            
+        }
+        
+        if (mIsEnabled && mStartScan) {
+            // First attempt after 100ms
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(HANDLE_INITIAL_SCAN, 1), 100);
+        }
+        mStartScan = false;
+        
+        // Check if headset status changed since we paused
+        String connected = mBluetoothHeadset.getHeadsetAddress();
+        if (connected != null) {
+            updateRemoteDeviceStatus(connected);
+        }
+        if (mLastConnected != null) {
+            updateRemoteDeviceStatus(mLastConnected);
+        }
+    }
+    
+    @Override
+    protected void onPause() {
+        sIsRunning = false;
+
+        unregisterReceiver(mReceiver);
+
+        // Wait for a few seconds and cleanup any pending requests, states
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(HANDLE_PAUSE_TIMEOUT, 
+                        new Object[] { mBluetooth, mPinAddress }), 
+                PAUSE_TIMEOUT);
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        mBluetoothHeadset.close();
+        sDeviceCallback.setHandler(null);
+        
+        super.onDestroy();
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration c) {
+        super.onConfigurationChanged(c);
+        // Don't do anything on keyboardHidden/orientation change, as we need
+        // to make sure that we don't lose pairing request intents.
+    }
+    
+    public static boolean isRunning() {
+        return sIsRunning;
+    }
+    
+    @Override
+    protected void onSaveInstanceState(Bundle icicle) {
+        int deviceCount = mBTDeviceList.getPreferenceCount();
+        String [] addresses = new String[deviceCount];
+        String [] states = new String[deviceCount];
+        int [] weights = new int[deviceCount];
+        for (int i = 0; i < deviceCount; i++) {
+            BluetoothListItem p = (BluetoothListItem) mBTDeviceList.getPreference(i);
+            CharSequence summary = p.getSummary();
+            if (summary != null) {
+                states[i] = summary.toString();
+            } else {
+                states[i] = STR_NOT_CONNECTED;
+            }
+            addresses[i] = getAddressFromKey(p.getKey());
+            weights[i] = p.getWeight();
+        }
+        icicle.putStringArray(FREEZE_ADDRESSES, addresses);
+        icicle.putStringArray(FREEZE_TYPES, states);
+        icicle.putIntArray(FREEZE_RSSI, weights);
+        icicle.putLong(FREEZE_DISCOVERABLE_START, mDiscoverableStartTime);
+        if (mPinDialog != null && mPinDialog.isShowing()) {
+            icicle.putString(FREEZE_PIN, mPinEdit.getText().toString());
+            icicle.putString(FREEZE_PIN_ADDRESS, mPinAddress);
+        }
+        super.onSaveInstanceState(icicle);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_SCAN_ID, 0, 
+                mRes.getString(R.string.bluetooth_scan_for_devices))
+            .setIcon(R.drawable.ic_menu_scan_bluetooth);
+        menu.add(0, MENU_CLEAR_ID, 0, 
+                mRes.getString(R.string.bluetooth_clear_list))
+            .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_SCAN_ID:
+            startScanning();
+            return true;
+        case MENU_CLEAR_ID:
+            clearDevices();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+    
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        if (!(menuInfo instanceof AdapterContextMenuInfo)) {
+            return;
+        }
+        int position = ((AdapterContextMenuInfo)menuInfo).position;
+        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position);
+        if (!(pref instanceof BluetoothListItem)) {
+            return;
+        }
+        String address = getAddressFromKey(pref.getKey());
+        // Setup the menu header
+        String name = mBluetooth.getRemoteName(address);
+        menu.setHeaderTitle(name != null? name : address);
+        int n = 0;
+        if (mBluetoothHeadset.isConnected(address)) {
+            menu.add(0, MENU_DISCONNECT, n++, R.string.bluetooth_disconnect);            
+        } else {
+            menu.add(0, MENU_CONNECT, n++, R.string.bluetooth_connect);
+        }
+        if (mBluetooth.hasBonding(address)) {
+            menu.add(0, MENU_UNPAIR, n++, R.string.bluetooth_unpair);
+        } else {
+            menu.add(0, MENU_PAIR, n++, R.string.bluetooth_pair);
+        }
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo info;
+        if (!(item.getMenuInfo() instanceof AdapterContextMenuInfo)) {
+            return false;
+        }
+        info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().
+                getItem(info.position);
+        String address = getAddressFromKey(pref.getKey());
+        mBluetooth.cancelDiscovery();
+        switch (item.getItemId()) {
+            case MENU_DISCONNECT:
+                if (mBluetoothHeadset.isConnected(address)) {
+                    mBluetoothHeadset.disconnectHeadset();
+                }
+                break;
+            case MENU_CONNECT:
+                if (!mBluetoothHeadset.isConnected(address)) {
+                    updateRemoteDeviceStatus(address, STR_CONNECTING); 
+                    connect(pref, address);
+                }
+                break;
+            case MENU_UNPAIR:
+                if (mBluetooth.hasBonding(address)) {
+                    mBluetooth.removeBonding(address);
+                    updateRemoteDeviceStatus(address);
+                }
+                break;
+            case MENU_PAIR:
+                if (!mBluetooth.hasBonding(address)) {
+                    pair(pref, address);
+                }
+                break;
+        }
+        return true;
+    }
+    
+    private void startScanning() {
+        if (mIsEnabled && mBluetooth.isDiscovering()) {
+            return;
+        }
+        resetDeviceListUI();
+        if (mIsEnabled) {
+            mBluetooth.startDiscovery();
+        }
+    }
+
+    private void clearDevices() {
+        String [] addresses = mBluetooth.listBondings();
+        if (addresses != null) {
+            for (int i = 0; i < addresses.length; i++) {
+                unbond(addresses[i]);
+            }
+        }
+        resetDeviceListUI();
+    }
+    
+    /* Update the Bluetooth toggle and visibility summary */
+    private void updateStatus() {
+        boolean started = mIsEnabled;
+        mBTToggle.setChecked(started);
+    }
+    
+    private void updateRemoteDeviceStatus(String address) {
+        if (address != null) {
+            Preference device = mDeviceMap.get(address);
+            if (device == null) {
+                // This device is not in our discovered list
+                // Let's add the device, if BT is not shut down already
+                if (mIsEnabled) {
+                    addDeviceToUI(address, null, null, WEIGHT_PAIRED);
+                }
+                return;
+            }
+            device.setEnabled(true);
+            if (address.equals(mBluetoothHeadset.getHeadsetAddress())) {
+                int state = mBluetoothHeadset.getState();
+                switch (state) {
+                    case BluetoothHeadset.STATE_CONNECTED:
+                        device.setSummary(STR_CONNECTED);
+                        mLastConnected = address;
+                        break;
+                    case BluetoothHeadset.STATE_CONNECTING:
+                        device.setSummary(STR_CONNECTING);
+                        break;
+                    case BluetoothHeadset.STATE_DISCONNECTED:
+                        if (mBluetooth.hasBonding(address)) {
+                            device.setSummary(STR_PAIRED);
+                        }
+                        break;
+                }
+            } else if (mBluetooth.hasBonding(address)) {
+                device.setSummary(STR_PAIRED);
+            } else {
+                device.setSummary(STR_NOT_CONNECTED);
+            }
+        }
+    }
+    
+    private void updateRemoteDeviceStatus(String address, String summary) {
+        Preference device = mDeviceMap.get(address);
+        if (device != null) {
+            device.setEnabled(true);
+            device.setSummary(summary);
+        }
+    }
+    
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        if (key.equals(BT_NAME)) {
+            String name = sharedPreferences.getString(key, null);
+            if (name == null) {
+                return;
+            }
+            if (mBluetooth.setName(name)) {
+                mBTName.setSummary(name);
+            }
+        }
+    }
+        
+    private String getAddressFromKey(String key) {
+        if (key != null) {
+            return key.substring(BT_KEY_LENGTH);
+        }
+        return "";
+    }
+
+    private void sendPin(String pin) {
+        byte[] pinBytes = BluetoothDevice.convertPinToBytes(pin);
+        if (pinBytes == null) {
+            mBluetooth.cancelPin(mPinAddress);
+        } else {
+            mBluetooth.setPin(mPinAddress, pinBytes);
+        }
+        mPinAddress = null;
+    }
+    
+    private AlertDialog showPinDialog(String savedPin, String pinAddress) {
+        if (mPinDialog != null) {
+            return mPinDialog;
+        }
+        View view = LayoutInflater.from(this).inflate(
+                R.layout.bluetooth_pin_entry, null);
+        mPinEdit = (EditText) view.findViewById(R.id.text);
+        mPinEdit.setTransformationMethod(PasswordTransformationMethod.getInstance());
+        mPinEdit.setOnKeyListener(this);
+        mPinAddress = pinAddress;
+        
+        if (savedPin != null) {
+            mPinEdit.setText(savedPin);
+        }
+        
+        String remoteName = mBluetooth.getRemoteName(mPinAddress);
+        if (remoteName == null) {
+            remoteName = mPinAddress;
+        }
+            
+        AlertDialog ad = new AlertDialog.Builder(this)
+            .setTitle(getString(R.string.bluetooth_notif_title))
+            .setMessage(getString(R.string.bluetooth_enter_pin_msg) + remoteName)
+            .setView(view)
+            .setPositiveButton(android.R.string.ok, mDisconnectListener)
+            .setNegativeButton(android.R.string.cancel, mDisconnectListener)
+            .setOnCancelListener(mCancelListener)
+            .show();
+        ad.setCanceledOnTouchOutside(false);
+        // Making an assumption here that the dialog buttons have the ids starting
+        // with ...button1 as below
+        mPinButton1 = ad.findViewById(com.android.internal.R.id.button1);
+        if (mPinButton1 != null) {
+            mPinButton1.setEnabled(savedPin != null? savedPin.length() > 0 : false);
+        }
+        return ad;
+    }
+    
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mBTToggle) {
+            toggleBT();
+            return false;
+        } else if (preference == mBTVisibility) {
+            boolean vis = mBTVisibility.isChecked();
+            if (!vis) {
+                // Cancel discoverability
+                mBluetooth.setMode(BluetoothDevice.MODE_CONNECTABLE);
+                mHandler.removeMessages(HANDLE_DISCOVERABLE_TIMEOUT);
+            } else {
+                mBluetooth.setMode(BluetoothDevice.MODE_DISCOVERABLE);
+                mBTVisibility.setSummaryOn(
+                        getResources().getString(R.string.bluetooth_is_discoverable,
+                                String.valueOf(mDiscoverableTime)));
+                mDiscoverableStartTime = SystemClock.elapsedRealtime();
+                mHandler.sendMessageDelayed(
+                        mHandler.obtainMessage(HANDLE_DISCOVERABLE_TIMEOUT), 1000);
+            }
+        } else {
+            String key = preference.getKey();
+            if (key.startsWith(BT_KEY_PREFIX)) {
+                // Extract the device address from the key
+                String address = getAddressFromKey(key);
+                if (mBluetoothHeadset.isConnected(address)) {
+                    askDisconnect(address);
+                } else if (mBluetooth.hasBonding(address)) {
+                    if (mIsEnabled) {
+                        mBluetooth.cancelDiscovery();
+                    }
+                    updateRemoteDeviceStatus(address, STR_CONNECTING); 
+                    connect(preference, address);
+                } else {
+                    if (mIsEnabled) {
+                        mBluetooth.cancelDiscovery();
+                    }
+                    pair(preference, address);
+                }
+            }
+        }
+        return false;
+    }
+
+    /* Handle the key input to the PIN entry dialog */
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        
+        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER 
+                || keyCode == KeyEvent.KEYCODE_ENTER) {
+            String pin = ((EditText)v).getText().toString(); 
+            if (pin != null && pin.length() > 0) {
+                sendPin(pin);
+                mPinDialog.dismiss();
+                return true;
+            }
+        } else if (mPinButton1 != null) {
+            boolean valid =
+                    BluetoothDevice.convertPinToBytes(((EditText)v).getText().toString()) != null;
+            mPinButton1.setEnabled(valid);
+        }
+        return false;
+    }
+    
+    private void askDisconnect(String address) {
+        String name = mBluetooth.getRemoteName(address);
+        if (name == null) {
+            name = mRes.getString(R.string.bluetooth_device);
+        }
+        String message = mRes.getString(R.string.bluetooth_disconnect_blank, name);
+
+        mDisconnectAddress = address;
+        
+        AlertDialog ad = new AlertDialog.Builder(this)
+                .setTitle(message)
+                .setPositiveButton(android.R.string.ok, mDisconnectListener)
+                .setNegativeButton(android.R.string.cancel, null)
+                .show();
+        ad.setCanceledOnTouchOutside(false);
+
+    }
+
+    private void pairingDone(String address, boolean result) {
+        Preference pref = mDeviceMap.get(address);
+        if (pref != null) {
+            pref.setEnabled(true);
+            updateRemoteDeviceStatus(address);
+        } else if (result) {
+            // We've paired to a device that isn't in our list
+            addDeviceToUI(address, STR_PAIRED, mBluetooth.getRemoteName(address), 
+                    WEIGHT_PAIRED);
+        }
+    }
+    
+    private void pair(Preference pref, String address) {
+        pref.setEnabled(false);
+        pref.setSummary(STR_PAIRING);
+        mBluetooth.createBonding(address, sDeviceCallback);
+    }
+    
+    private void connect(Preference pref, String address) {
+        pref.setEnabled(false);
+        //TODO: Prompt the user to confirm they will disconnect current headset
+        disconnect();
+        mBluetoothHeadset.connectHeadset(address, mHeadsetCallback);
+    }
+
+    private void disconnect() {
+        int state = mBluetoothHeadset.getState();
+        if (state == BluetoothHeadset.STATE_CONNECTING ||
+                state == BluetoothHeadset.STATE_CONNECTED) {
+            mBluetoothHeadset.disconnectHeadset();
+        }
+    }
+    
+    private void toggleBT() {
+        if (mIsEnabled) {
+            mBTToggle.setSummaryOn(mRes.getString(R.string.bluetooth_stopping));
+            mBTDeviceList.setProgress(false);
+            // Force shutdown.
+            mBluetooth.cancelDiscovery();
+            mBluetooth.disable();
+        } else {
+            mBTToggle.setSummaryOff(mRes.getString(R.string.bluetooth_enabling));
+            mBTToggle.setChecked(false);
+            mBTToggle.setEnabled(false);
+            if (!mBluetooth.enable()) {
+                mBTToggle.setEnabled(true);
+            }
+        }
+    }
+
+    private void addDeviceToUI(String address, String summary, String name, 
+            int rssi) {
+        
+        if (address == null) {
+            return;
+        }
+
+        BluetoothListItem p;
+        if (mDeviceMap.containsKey(address)) {
+            p = (BluetoothListItem) mDeviceMap.get(address);
+            if (summary != null && summary.equals(STR_NOT_CONNECTED)) {
+                if (mBluetooth.hasBonding(address)) {
+                    summary = STR_PAIRED;
+                }
+            }
+            CharSequence oldSummary = p.getSummary();
+            if (oldSummary != null && oldSummary.equals(STR_CONNECTED)) {
+                summary = STR_CONNECTED; // Don't override connected with paired
+                mLastConnected = address;
+            }
+        } else {
+            p = new BluetoothListItem(this, null);
+        }
+        if (name == null) {
+            name = mBluetooth.getRemoteName(address);
+        }
+        if (name == null) {
+            name = address;
+        }
+
+        p.setTitle(name);
+        p.setSummary(summary);
+        p.setKey(BT_KEY_PREFIX + address);
+        // Enable the headset icon if it is most probably a headset class device
+        if (DeviceClass.getMajorClass(mBluetooth.getRemoteClass(address)) == 
+                DeviceClass.MAJOR_CLASS_AUDIO_VIDEO) {
+            p.setHeadset(true);
+        }
+        p.setWeight(rssi);
+        if (!mDeviceMap.containsKey(address)) {
+            mBTDeviceList.addPreference(p);
+            mDeviceMap.put(address, p);
+        }
+    }
+
+    private void addDevices(String [] addresses,
+            String[] deviceStatus, int[] rssi) {
+        for (int i = 0; i < addresses.length; i++) {
+            String status = deviceStatus[i];
+            String name = mBluetooth.getRemoteName(addresses[i]);
+            String address = addresses[i];
+            // Query the status if it's not known
+            if (status == null) {
+                if (mBluetoothHeadset.isConnected(addresses[i])) {
+                    status = STR_CONNECTED;
+                    mLastConnected = address;
+                } else if (mBluetooth.hasBonding(addresses[i])) {
+                    status = STR_PAIRED;
+                } else {
+                    status = STR_NOT_CONNECTED;
+                }
+            }
+            addDeviceToUI(address, status, name, rssi[i]);
+        }
+    }
+    
+    private void removeDeviceFromUI(String address) {
+        Preference p = mDeviceMap.get(address);
+        if (p == null) {
+            return;
+        }
+        mBTDeviceList.removePreference(p);
+        mDeviceMap.remove(address);
+    }
+    
+    private void updateDeviceName(String address, String name) {
+        Preference p = mDeviceMap.get(address);
+        if (p != null) {
+            p.setTitle(name);
+        }
+    }
+        
+    private void resetDeviceListUI() {
+        mDeviceMap.clear();
+
+        while (mBTDeviceList.getPreferenceCount() > 0) {
+            mBTDeviceList.removePreference(mBTDeviceList.getPreference(0));
+        }
+        if (!mIsEnabled) {
+            return;
+        }
+        
+        String connectedDevice = mBluetoothHeadset.getHeadsetAddress();
+        if (connectedDevice != null && mBluetoothHeadset.isConnected(connectedDevice)) {
+            addDeviceToUI(connectedDevice, STR_CONNECTED, 
+                    mBluetooth.getRemoteName(connectedDevice), WEIGHT_CONNECTED);
+        }
+        String [] bondedDevices = mBluetooth.listBondings();
+        if (bondedDevices != null) {
+            for (int i = 0; i < bondedDevices.length; i++) {
+                addDeviceToUI(bondedDevices[i], STR_PAIRED_NOT_NEARBY, 
+                        mBluetooth.getRemoteName(bondedDevices[i]), WEIGHT_PAIRED);
+            }
+        }
+    }
+    
+    private void unbond(String address) {
+        mBluetooth.removeBonding(address);
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+            if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
+                mIsEnabled = true;
+                mBTToggle.setChecked(true);
+                mBTToggle.setSummaryOn(mRes.getString(R.string.bluetooth_enabled));
+                mBTToggle.setEnabled(true);
+                String name = mBluetooth.getName();
+                if (name != null) {
+                    mBTName.setSummary(name);
+                }
+                // save the "enabled" setting to database, so we can
+                // remember it on startup.
+                Settings.System.putInt(getContentResolver(),
+                                       Settings.System.BLUETOOTH_ON, 1);
+                resetDeviceListUI();
+                if (mAutoDiscovery) {
+                    mBluetooth.startDiscovery();
+                }
+            } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
+                mIsEnabled = false;
+                mBTToggle.setSummaryOff(mRes.getString(R.string.bluetooth_disabled));
+                resetDeviceListUI();
+                mBTVisibility.setChecked(false);
+                // save the "disabled" setting to database
+                Settings.System.putInt(getContentResolver(), 
+                                       Settings.System.BLUETOOTH_ON, 0);
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)) {
+                if (address != null) {
+                    int rssi = intent.getShortExtra(BluetoothIntent.RSSI, 
+                            (short) WEIGHT_UNKNOWN);
+                    addDeviceToUI(address, STR_NOT_CONNECTED, null, rssi);
+                }
+            } else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) {
+                String name = intent.getStringExtra(BluetoothIntent.NAME);
+                updateDeviceName(address, name);
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) {
+                removeDeviceFromUI(address);
+            } else if (action.equals(BluetoothIntent.PAIRING_REQUEST_ACTION)) {
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_PIN_REQUEST, address));
+            } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
+                int state = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
+                                               BluetoothHeadset.STATE_ERROR);
+                if (state == BluetoothHeadset.STATE_CONNECTED) {
+                    mHandler.sendMessage(mHandler.obtainMessage(HANDLE_CONNECTED, address));
+                } else if (state == BluetoothHeadset.STATE_DISCONNECTED) {
+                    mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISCONNECTED, address));
+                } else if (state == BluetoothHeadset.STATE_CONNECTING) {
+                    mHandler.sendMessage(mHandler.obtainMessage(HANDLE_CONNECTING, address));                    
+                }
+            } else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) {
+                mBTDeviceList.setProgress(true);
+            } else if (action.equals(BluetoothIntent.DISCOVERY_COMPLETED_ACTION)) {
+                mBTDeviceList.setProgress(false);
+            } else if (action.equals(BluetoothIntent.MODE_CHANGED_ACTION)) {
+                mBTVisibility.setChecked(
+                        mBluetooth.getMode() == BluetoothDevice.MODE_DISCOVERABLE);
+            } else if (action.equals(BluetoothIntent.BONDING_CREATED_ACTION)) {
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_PAIRING_PASSED, address));
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) { 
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_CONNECTED, address));
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION)) { 
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISCONNECTED, address));
+            }
+        }
+    };
+
+    
+    static class DeviceCallback extends IBluetoothDeviceCallback.Stub {
+        Handler messageHandler;
+
+        public void setHandler(Handler handler) {
+            synchronized (this) {
+                messageHandler = handler;
+            }
+        }
+        
+        public void onCreateBondingResult(String address, int result) {
+            synchronized (this) {
+                if (messageHandler != null) {
+                    if (result == BluetoothDevice.RESULT_FAILURE) {
+                        messageHandler.sendMessage(messageHandler.obtainMessage(
+                                HANDLE_PAIRING_FAILED, address));
+                    } else {
+                        messageHandler.sendMessage(messageHandler.obtainMessage(
+                                HANDLE_PAIRING_PASSED, address));
+                    }
+                }
+            }
+        }
+        
+        public void onEnableResult(int result) { }
+        public void onGetRemoteServiceChannelResult(String address, int channel) { }
+    };
+    
+    private IBluetoothHeadsetCallback mHeadsetCallback = new IBluetoothHeadsetCallback.Stub() {
+        public void onConnectHeadsetResult(String address, int resultCode) {
+            if (resultCode == BluetoothHeadset.RESULT_SUCCESS) {
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_CONNECTED, address));
+            } else {
+                // Make toast in UI thread
+                mHandler.sendMessage(mHandler.obtainMessage(HANDLE_FAILED_TO_CONNECT, resultCode,
+                            -1, address));
+            }
+        }
+    };
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case HANDLE_CONNECTED:
+                case HANDLE_DISCONNECTED:
+                case HANDLE_CONNECTING:
+                    updateRemoteDeviceStatus((String) msg.obj);
+                    break;
+                case HANDLE_FAILED_TO_CONNECT:
+                    updateRemoteDeviceStatus((String) msg.obj);
+                    String name = mBluetooth.getRemoteName((String) msg.obj);
+                    if (name == null) {
+                        name = (String) msg.obj;
+                    }
+                    if (msg.arg1 == BluetoothHeadset.RESULT_FAILURE) {
+                        Toast.makeText(BluetoothSettings.this, 
+                                mRes.getString(R.string.failed_to_connect, name),
+                                Toast.LENGTH_SHORT).show();
+                    }
+                    break;
+                case HANDLE_PIN_REQUEST:
+                    mPinDialog = showPinDialog(null, (String) msg.obj);
+                    break;
+                case HANDLE_DISCOVERABLE_TIMEOUT:
+                    long nowTime = SystemClock.elapsedRealtime();
+                    int secondsLeft = mDiscoverableTime
+                            - (int) (nowTime - mDiscoverableStartTime) / 1000;
+                    if (secondsLeft > 0) {
+                        mBTVisibility.setSummaryOn(
+                                getResources().getString(R.string.bluetooth_is_discoverable,
+                                        String.valueOf(secondsLeft)));
+                        sendMessageDelayed(obtainMessage(HANDLE_DISCOVERABLE_TIMEOUT), 1000);
+                    } else {
+                        mBluetooth.setMode(BluetoothDevice.MODE_CONNECTABLE);
+                        mBTVisibility.setChecked(false);
+                    }
+                    break;
+                case HANDLE_INITIAL_SCAN:
+                    if (mBluetoothHeadset.getState() == BluetoothHeadset.STATE_ERROR &&
+                            ((Integer)msg.obj).intValue() < 2) {
+                        // Second attempt after another 100ms
+                        sendMessageDelayed(obtainMessage(HANDLE_INITIAL_SCAN, 2), 100);
+                    } else {
+                        resetDeviceListUI();
+                        if (mAutoDiscovery) {
+                            mBluetooth.cancelDiscovery();
+                            mBluetooth.startDiscovery();
+                        }
+                    }
+                    break;
+                case HANDLE_PAIRING_PASSED:
+                    String addr = (String) msg.obj;
+                    pairingDone(addr, true);
+                    break;
+                case HANDLE_PAIRING_FAILED:
+                    String address = (String) msg.obj;
+                    pairingDone(address, false);
+                    String pairName = mBluetooth.getRemoteName(address);
+                    if (pairName == null) {
+                        pairName = address;
+                    }
+                    Toast.makeText(BluetoothSettings.this, 
+                            mRes.getString(R.string.failed_to_pair, pairName),
+                            Toast.LENGTH_SHORT).show();
+                    break;
+                case HANDLE_PAUSE_TIMEOUT:
+                    // Possibility of race condition, but not really harmful
+                    if (!sIsRunning) {
+                        Object[] params = (Object[]) msg.obj;
+                        BluetoothDevice bluetooth = (BluetoothDevice) params[0];
+                        if (bluetooth.isEnabled()) {
+                            if (bluetooth.isDiscovering()) {
+                                bluetooth.cancelDiscovery();
+                            }
+                            if (params[1] != null) {
+                                bluetooth.cancelBondingProcess((String) params[1]);
+                            }
+                            bluetooth.setMode(BluetoothDevice.MODE_CONNECTABLE);
+                        }
+                    }
+                    break;
+            }
+        }
+    };
+
+    private DialogInterface.OnClickListener mDisconnectListener = 
+        new DialogInterface.OnClickListener() {
+        
+            public void onClick(DialogInterface dialog, int which) {
+                if (dialog == mPinDialog) {
+                    if (which == DialogInterface.BUTTON1) {
+                        String pin = mPinEdit.getText().toString();
+                        if (pin != null && pin.length() > 0) {
+                            sendPin(pin);
+                        } else {
+                            sendPin(null);
+                        }
+                    } else {
+                        sendPin(null);
+                    }
+                    mPinDialog = null;
+                    mPinEdit = null;
+                } else {
+                    if (which == DialogInterface.BUTTON1) {
+                        disconnect();
+                    }
+                }
+            }
+    };
+
+    private DialogInterface.OnCancelListener mCancelListener =
+        new DialogInterface.OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+                if (dialog == mPinDialog) {
+                    sendPin(null);
+                }
+                mPinDialog = null;
+                mPinEdit = null;
+            }
+    };
+}
+
diff --git a/src/com/android/settings/BrightnessPreference.java b/src/com/android/settings/BrightnessPreference.java
new file mode 100644
index 0000000..a9851cc
--- /dev/null
+++ b/src/com/android/settings/BrightnessPreference.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.IHardwareService;
+import android.os.ServiceManager;
+import android.preference.SeekBarPreference;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.SeekBar;
+
+import java.util.Map;
+
+public class BrightnessPreference extends SeekBarPreference implements
+        SeekBar.OnSeekBarChangeListener {
+
+    private SeekBar mSeekBar;
+    
+    private int mOldBrightness;
+    
+    // Backlight range is from 0 - 255. Need to make sure that user
+    // doesn't set the backlight to 0 and get stuck
+    private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
+    private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
+
+    public BrightnessPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+
+        mSeekBar = getSeekBar(view);
+        mSeekBar.setOnSeekBarChangeListener(this);
+        mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);
+        try {
+            mOldBrightness = Settings.System.getInt(getContext().getContentResolver(), 
+                Settings.System.SCREEN_BRIGHTNESS);
+        } catch (SettingNotFoundException snfe) {
+            mOldBrightness = MAXIMUM_BACKLIGHT;
+        }
+        mSeekBar.setProgress(mOldBrightness - MINIMUM_BACKLIGHT);
+    }
+
+    public void onProgressChanged(SeekBar seekBar, int progress,
+            boolean fromTouch) {
+        setBrightness(progress + MINIMUM_BACKLIGHT);
+    }
+
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        // NA
+    }
+
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        // NA
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        
+        if (positiveResult) {
+            Settings.System.putInt(getContext().getContentResolver(), 
+                    Settings.System.SCREEN_BRIGHTNESS,
+                    mSeekBar.getProgress() + MINIMUM_BACKLIGHT);
+        } else {
+            setBrightness(mOldBrightness);
+        }
+    }
+    
+    private void setBrightness(int brightness) {
+        try {
+            IHardwareService hardware = IHardwareService.Stub.asInterface(
+                    ServiceManager.getService("hardware"));
+            if (hardware != null) {
+                hardware.setScreenBacklight(brightness);
+            }
+        } catch (RemoteException doe) {
+            
+        }        
+    }
+}
+
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
new file mode 100644
index 0000000..973e655
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.google.android.collect.Lists;
+
+import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+import static com.android.internal.widget.LockPatternView.DisplayMode;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Window;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * If the user has a lock pattern set already, makes them confirm the existing one.
+ *
+ * Then, prompts the user to choose a lock pattern:
+ * - prompts for initial pattern
+ * - asks for confirmation / restart
+ * - saves chosen password when confirmed
+ */
+public class ChooseLockPattern extends Activity implements View.OnClickListener{
+
+    // how long after a confirmation message is shown before moving on
+    static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
+
+    // how long we wait to clear a wrong pattern
+    private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+    private static final int ID_EMPTY_MESSAGE = -1;
+
+
+    protected TextView mHeaderText;
+    protected LockPatternView mLockPatternView;
+    protected TextView mFooterText;
+    private TextView mFooterLeftButton;
+    private TextView mFooterRightButton;
+
+    protected List<LockPatternView.Cell> mChosenPattern = null;
+
+    protected LockPatternUtils mLockPatternUtils;
+
+    /**
+     * The patten used during the help screen to show how to draw a pattern.
+     */
+    private final List<LockPatternView.Cell> mAnimatePattern =
+            Collections.unmodifiableList(
+                Lists.newArrayList(
+                        LockPatternView.Cell.of(0, 0),
+                        LockPatternView.Cell.of(0, 1),
+                        LockPatternView.Cell.of(1, 1),
+                        LockPatternView.Cell.of(2, 1)
+                    ));
+
+
+    /**
+     * The pattern listener that responds according to a user choosing a new
+     * lock pattern.
+     */
+    protected LockPatternView.OnPatternListener mChooseNewLockPatternListener = new LockPatternView.OnPatternListener() {
+
+            public void onPatternStart() {
+                mLockPatternView.removeCallbacks(mClearPatternRunnable);
+                patternInProgress();
+            }
+
+            public void onPatternCleared() {
+                mLockPatternView.removeCallbacks(mClearPatternRunnable);
+            }
+
+            public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+                if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
+                    if (mChosenPattern == null) throw new IllegalStateException("null chosen pattern in stage 'need to confirm");
+                    if (mChosenPattern.equals(pattern)) {
+                        updateStage(Stage.ChoiceConfirmed);
+                    } else {
+                        updateStage(Stage.ConfirmWrong);
+                    }
+                } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
+                    if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
+                        updateStage(Stage.ChoiceTooShort);
+                    } else {
+                        mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
+                        updateStage(Stage.FirstChoiceValid);
+                    }
+                } else {
+                    throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
+                            + "entering the pattern.");
+                }
+            }
+
+            private void patternInProgress() {
+                mHeaderText.setText(R.string.lockpattern_recording_inprogress);
+                mFooterText.setText("");
+                mFooterLeftButton.setEnabled(false);
+                mFooterRightButton.setEnabled(false);
+            }
+     };
+
+
+    /**
+     * The states of the left footer button.
+     */
+    enum LeftButtonMode {
+        Cancel(R.string.cancel, true),
+        CancelDisabled(R.string.cancel, false),
+        Retry(R.string.lockpattern_retry_button_text, true),
+        RetryDisabled(R.string.lockpattern_retry_button_text, false),
+        Gone(ID_EMPTY_MESSAGE, false);
+
+
+        /**
+         * @param text The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        LeftButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+
+        final int text;
+        final boolean enabled;
+    }
+
+    /**
+     * The states of the right button.
+     */
+    enum RightButtonMode {
+        Continue(R.string.lockpattern_continue_button_text, true),
+        ContinueDisabled(R.string.lockpattern_continue_button_text, false),
+        Confirm(R.string.lockpattern_confirm_button_text, true),
+        ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
+        Ok(android.R.string.ok, true);
+
+        /**
+         * @param text The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        RightButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+
+        final int text;
+        final boolean enabled;
+    }
+
+    /**
+     * Keep track internally of where the user is in choosing a pattern.
+     */
+    protected enum Stage {
+
+        Introduction(
+                R.string.lockpattern_recording_intro_header,
+                LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
+                R.string.lockpattern_recording_intro_footer, true),
+        HelpScreen(
+                R.string.lockpattern_settings_help_how_to_record,
+                LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
+        ChoiceTooShort(
+                R.string.lockpattern_recording_incorrect_too_short,
+                LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
+                ID_EMPTY_MESSAGE, true),
+        FirstChoiceValid(
+                R.string.lockpattern_pattern_entered_header,
+                LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
+        NeedToConfirm(
+                R.string.lockpattern_need_to_confirm,
+                LeftButtonMode.CancelDisabled, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ConfirmWrong(
+                R.string.lockpattern_need_to_unlock_wrong,
+                LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ChoiceConfirmed(
+                R.string.lockpattern_pattern_confirmed_header,
+                LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
+
+
+        /**
+         * @param headerMessage The message displayed at the top.
+         * @param leftMode The mode of the left button.
+         * @param rightMode The mode of the right button.
+         * @param footerMessage The footer message.
+         * @param patternEnabled Whether the pattern widget is enabled.
+         */
+        Stage(int headerMessage,
+                LeftButtonMode leftMode,
+                RightButtonMode rightMode,
+                int footerMessage, boolean patternEnabled) {
+            this.headerMessage = headerMessage;
+            this.leftMode = leftMode;
+            this.rightMode = rightMode;
+            this.footerMessage = footerMessage;
+            this.patternEnabled = patternEnabled;
+        }
+
+        final int headerMessage;
+        final LeftButtonMode leftMode;
+        final RightButtonMode rightMode;
+        final int footerMessage;
+        final boolean patternEnabled;
+    }
+
+    private Stage mUiStage = Stage.Introduction;
+
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
+
+    private static final String KEY_UI_STAGE = "uiStage";
+    private static final String KEY_PATTERN_CHOICE = "chosenPattern";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mLockPatternUtils = new LockPatternUtils(getContentResolver());
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setupViews();
+        
+        // make it so unhandled touch events within the unlock screen go to the
+        // lock pattern view.
+        final LinearLayoutWithDefaultTouchRecepient topLayout
+                = (LinearLayoutWithDefaultTouchRecepient) findViewById(
+                R.id.topLayout);
+        topLayout.setDefaultTouchRecepient(mLockPatternView);
+
+        if (savedInstanceState == null) {
+            // first launch
+            updateStage(Stage.Introduction);
+            if (mLockPatternUtils.savedPatternExists()) {
+                confirmPattern();
+            } 
+        } else {
+            // restore from previous state
+            final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
+            if (patternString != null) {
+                mChosenPattern = LockPatternUtils.stringToPattern(patternString);
+            }
+            updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
+        }
+    }
+    
+    /**
+     * Keep all "find view" related stuff confined to this function since in
+     * case someone needs to subclass and customize.
+     */
+    protected void setupViews() {
+        setContentView(R.layout.choose_lock_pattern);
+        
+        mHeaderText = (TextView) findViewById(R.id.headerText);
+
+        mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
+        mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
+
+        mFooterText = (TextView) findViewById(R.id.footerText);
+
+        mFooterLeftButton = (TextView) findViewById(R.id.footerLeftButton);
+        mFooterRightButton = (TextView) findViewById(R.id.footerRightButton);
+
+        mFooterLeftButton.setOnClickListener(this);
+        mFooterRightButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        if (v == mFooterLeftButton) {
+            if (mUiStage.leftMode == LeftButtonMode.Retry) {
+                mChosenPattern = null;
+                mLockPatternView.clearPattern();
+                updateStage(Stage.Introduction);
+            } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
+                finish();
+            } else {
+                throw new IllegalStateException("left footer button pressed, but stage of " +
+                    mUiStage + " doesn't make sense");
+            }
+        } else if (v == mFooterRightButton) {
+
+            if (mUiStage.rightMode == RightButtonMode.Continue) {
+                if (mUiStage != Stage.FirstChoiceValid) {
+                    throw new IllegalStateException("expected ui stage " + Stage.FirstChoiceValid
+                            + " when button is " + RightButtonMode.Continue);
+                }
+                updateStage(Stage.NeedToConfirm);
+            } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
+                if (mUiStage != Stage.ChoiceConfirmed) {
+                    throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
+                            + " when button is " + RightButtonMode.Confirm);
+                }
+                saveChosenPatternAndFinish();
+            } else if (mUiStage.rightMode == RightButtonMode.Ok) {
+                if (mUiStage != Stage.HelpScreen) {
+                    throw new IllegalStateException("Help screen is only mode with ok button, but " +
+                            "stage is " + mUiStage);
+                }
+                mLockPatternView.clearPattern();
+                mLockPatternView.setDisplayMode(DisplayMode.Correct);
+                updateStage(Stage.Introduction);
+            }
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
+            if (mUiStage == Stage.HelpScreen) {
+                updateStage(Stage.Introduction);
+                return true;
+            }
+        }
+        if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
+            updateStage(Stage.HelpScreen);
+            return true;
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+
+    /**
+     * Launch screen to confirm the existing lock pattern.
+     * @see #onActivityResult(int, int, android.content.Intent)
+     */
+    protected void confirmPattern() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
+        startActivityForResult(intent, 55);
+    }
+
+    /**
+     * @see #confirmPattern
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode != 55) {
+            return;
+        }
+
+        if (resultCode != Activity.RESULT_OK) {
+            finish();
+        }
+        updateStage(Stage.Introduction);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
+        if (mChosenPattern != null) {
+            outState.putString(KEY_PATTERN_CHOICE, LockPatternUtils.patternToString(mChosenPattern));
+        }
+    }
+
+
+    /**
+     * Updates the messages and buttons appropriate to what stage the user
+     * is at in choosing a view.  This doesn't handle clearing out the pattern;
+     * the pattern is expected to be in the right state.
+     * @param stage
+     */
+    protected void updateStage(Stage stage) {
+
+        mUiStage = stage;
+
+        // header text, footer text, visibility and 
+        // enabled state all known from the stage
+        if (stage == Stage.ChoiceTooShort) {
+            mHeaderText.setText(
+                    getResources().getString(
+                            stage.headerMessage,
+                            LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
+        } else {
+            mHeaderText.setText(stage.headerMessage);
+        }
+        if (stage.footerMessage == ID_EMPTY_MESSAGE) {
+            mFooterText.setText("");
+        } else {
+            mFooterText.setText(stage.footerMessage);
+        }
+
+        if (stage.leftMode == LeftButtonMode.Gone) {
+            mFooterLeftButton.setVisibility(View.GONE);
+        } else {
+            mFooterLeftButton.setVisibility(View.VISIBLE);
+            mFooterLeftButton.setText(stage.leftMode.text);
+            mFooterLeftButton.setEnabled(stage.leftMode.enabled);
+        }
+
+        mFooterRightButton.setText(stage.rightMode.text);
+        mFooterRightButton.setEnabled(stage.rightMode.enabled);
+
+        // same for whether the patten is enabled
+        if (stage.patternEnabled) {
+            mLockPatternView.enableInput();
+        } else {
+            mLockPatternView.disableInput();
+        }
+
+        // the rest of the stuff varies enough that it is easier just to handle
+        // on a case by case basis.
+        mLockPatternView.setDisplayMode(DisplayMode.Correct);
+
+        switch (mUiStage) {
+            case Introduction:
+                mLockPatternView.clearPattern();
+                break;
+            case HelpScreen:
+                mLockPatternView.setPattern(DisplayMode.Animate, mAnimatePattern);
+                break;
+            case ChoiceTooShort:
+                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
+                postClearPatternRunnable();
+                break;
+            case FirstChoiceValid:
+                break;
+            case NeedToConfirm:
+                mLockPatternView.clearPattern();
+                break;
+            case ConfirmWrong:
+                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
+                postClearPatternRunnable();
+                break;
+            case ChoiceConfirmed:
+                break;
+        }
+    }
+
+
+    // clear the wrong pattern unless they have started a new one
+    // already
+    private void postClearPatternRunnable() {
+        mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
+    }
+
+    private void saveChosenPatternAndFinish() {
+        boolean patternExistedBefore = mLockPatternUtils.savedPatternExists();
+        mLockPatternUtils.saveLockPattern(mChosenPattern);
+
+        // if setting pattern for first time, enable the lock gesture.  otherwise,
+        // keep the user's setting.
+        if (!patternExistedBefore) {
+            mLockPatternUtils.setLockPatternEnabled(true);
+            mLockPatternUtils.setVisiblePatternEnabled(true);
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/settings/ChooseLockPatternExample.java b/src/com/android/settings/ChooseLockPatternExample.java
new file mode 100644
index 0000000..5feba4c
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPatternExample.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageView;
+
+public class ChooseLockPatternExample extends Activity implements View.OnClickListener {
+    private static final long START_DELAY = 1000;
+    protected static final String TAG = "Settings";
+    private View mNextButton;
+    private View mSkipButton;
+    private View mImageView;
+    private AnimationDrawable mAnimation;
+    private Handler mHandler = new Handler();
+    private Runnable mRunnable = new Runnable() {
+        public void run() {
+            startAnimation(mAnimation);
+        }
+    };
+   
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.choose_lock_pattern_example);
+        initViews();
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mHandler.postDelayed(mRunnable, START_DELAY);
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        stopAnimation(mAnimation);
+    }
+    
+    public void onClick(View v) {
+        if (v == mSkipButton) {
+            finish();
+        } else if (v == mNextButton) {
+            stopAnimation(mAnimation);
+            Intent intent = new Intent(this, ChooseLockPattern.class);
+            startActivity(intent);
+            finish();
+        }
+    }
+
+    private void initViews() {
+        mNextButton = findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        
+        mSkipButton = findViewById(R.id.skip_button);
+        mSkipButton.setOnClickListener(this);
+        
+        mImageView = (ImageView) findViewById(R.id.lock_anim);
+        mImageView.setBackgroundResource(R.drawable.lock_anim);
+        mImageView.setOnClickListener(this);
+        mAnimation = (AnimationDrawable) mImageView.getBackground();
+    }
+    
+    protected void startAnimation(final AnimationDrawable animation) {
+        if (animation != null && !animation.isRunning()) {
+            animation.run();
+        }
+    }
+   
+    protected void stopAnimation(final AnimationDrawable animation) {
+        if (animation != null && animation.isRunning()) animation.stop();
+    }
+}
+
diff --git a/src/com/android/settings/ChooseLockPatternTutorial.java b/src/com/android/settings/ChooseLockPatternTutorial.java
new file mode 100644
index 0000000..9687b55
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPatternTutorial.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+public class ChooseLockPatternTutorial extends Activity implements View.OnClickListener {
+    protected View mNextButton;
+    protected View mSkipButton;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Don't show the tutorial if the user has seen it before.
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(getContentResolver());
+        if (savedInstanceState == null && lockPatternUtils.savedPatternExists()) {
+            Intent intent = new Intent();
+            intent.setClassName("com.android.settings", "com.android.settings.ChooseLockPattern");
+            startActivity(intent);
+            finish();
+        } else {
+            initViews();
+        }
+    }
+    
+    private void initViews() {
+        setContentView(R.layout.choose_lock_pattern_tutorial);
+        mNextButton = findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        mSkipButton = findViewById(R.id.skip_button);
+        mSkipButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        if (v == mSkipButton) {
+            finish();
+        } else if (v == mNextButton) {
+            startActivity(new Intent(this, ChooseLockPatternExample.class));
+            finish();
+        }
+    }
+}
+
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
new file mode 100644
index 0000000..c94bbb2
--- /dev/null
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.widget.TextView;
+import android.view.Window;
+
+import java.util.List;
+
+/**
+ * Launch this when you want the user to confirm their lock pattern.
+ *
+ * Sets an activity result of {@link Activity#RESULT_OK} when the user
+ * successfully confirmed their pattern.
+ */
+public class ConfirmLockPattern extends Activity {
+
+    /**
+     * Names of {@link CharSequence} fields within the originating {@link Intent}
+     * that are used to configure the keyguard confirmation view's labeling.
+     * The view will use the system-defined resource strings for any labels that
+     * the caller does not supply.
+     */
+    public static final String HEADER_TEXT = "com.android.settings.ConfirmLockPattern.header";
+    public static final String FOOTER_TEXT = "com.android.settings.ConfirmLockPattern.footer";
+    public static final String HEADER_WRONG_TEXT = "com.android.settings.ConfirmLockPattern.header_wrong";
+    public static final String FOOTER_WRONG_TEXT = "com.android.settings.ConfirmLockPattern.footer_wrong";
+
+    // how long we wait to clear a wrong pattern
+    private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+    private static final String KEY_NUM_WRONG_ATTEMPTS = "num_wrong_attempts";
+
+    private LockPatternView mLockPatternView;
+    private LockPatternUtils mLockPatternUtils;
+    private int mNumWrongConfirmAttempts;
+    private CountDownTimer mCountdownTimer;
+
+    private TextView mHeaderTextView;
+    private TextView mFooterTextView;
+
+    // caller-supplied text for various prompts
+    private CharSequence mHeaderText;
+    private CharSequence mFooterText;
+    private CharSequence mHeaderWrongText;
+    private CharSequence mFooterWrongText;
+
+
+    private enum Stage {
+        NeedToUnlock,
+        NeedToUnlockWrong,
+        LockedOut
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mLockPatternUtils = new LockPatternUtils(getContentResolver());
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.confirm_lock_pattern);
+
+        mHeaderTextView = (TextView) findViewById(R.id.headerText);
+        mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
+        mFooterTextView = (TextView) findViewById(R.id.footerText);
+
+        // make it so unhandled touch events within the unlock screen go to the
+        // lock pattern view.
+        final LinearLayoutWithDefaultTouchRecepient topLayout
+                = (LinearLayoutWithDefaultTouchRecepient) findViewById(
+                R.id.topLayout);
+        topLayout.setDefaultTouchRecepient(mLockPatternView);        
+
+        Intent intent = getIntent();
+        if (intent != null) {
+            mHeaderText = intent.getCharSequenceExtra(HEADER_TEXT);
+            mFooterText = intent.getCharSequenceExtra(FOOTER_TEXT);
+            mHeaderWrongText = intent.getCharSequenceExtra(HEADER_WRONG_TEXT);
+            mFooterWrongText = intent.getCharSequenceExtra(FOOTER_WRONG_TEXT);
+        }
+
+        mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
+        updateStage(Stage.NeedToUnlock);
+
+        if (savedInstanceState != null) {
+            mNumWrongConfirmAttempts = savedInstanceState.getInt(KEY_NUM_WRONG_ATTEMPTS);
+        } else {
+            // on first launch, if no lock pattern is set, then finish with
+            // success (don't want user to get stuck confirming something that
+            // doesn't exist).
+            if (!mLockPatternUtils.savedPatternExists()) {
+                setResult(RESULT_OK);
+                finish();
+            }
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // deliberately not calling super since we are managing this in full
+        outState.putInt(KEY_NUM_WRONG_ATTEMPTS, mNumWrongConfirmAttempts);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        if (mCountdownTimer != null) {
+            mCountdownTimer.cancel();
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // if the user is currently locked out, enforce it.
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        if (deadline != 0) {
+            handleAttemptLockout(deadline);
+        }
+    }
+
+    private void updateStage(Stage stage) {
+
+        switch (stage) {
+            case NeedToUnlock:
+                if (mHeaderText != null) {
+                    mHeaderTextView.setText(mHeaderText);
+                } else {
+                    mHeaderTextView.setText(R.string.lockpattern_need_to_unlock);
+                }
+                if (mFooterText != null) {
+                    mFooterTextView.setText(mFooterText);
+                } else {
+                    mFooterTextView.setText(R.string.lockpattern_need_to_unlock_footer);
+                }
+                
+                mLockPatternView.setEnabled(true);
+                mLockPatternView.enableInput();
+                break;
+            case NeedToUnlockWrong:
+                if (mHeaderWrongText != null) {
+                    mHeaderTextView.setText(mHeaderWrongText);
+                } else {
+                    mHeaderTextView.setText(R.string.lockpattern_need_to_unlock_wrong);
+                }
+                if (mFooterWrongText != null) {
+                    mFooterTextView.setText(mFooterWrongText);
+                } else {
+                    mFooterTextView.setText(R.string.lockpattern_need_to_unlock_wrong_footer);
+                }
+                
+                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
+                mLockPatternView.setEnabled(true);
+                mLockPatternView.enableInput();
+                break;
+            case LockedOut:
+                mLockPatternView.clearPattern();
+                // enabled = false means: disable input, and have the
+                // appearance of being disabled.
+                mLockPatternView.setEnabled(false); // appearance of being disabled
+                break;
+        }
+    }
+
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
+
+    // clear the wrong pattern unless they have started a new one
+    // already
+    private void postClearPatternRunnable() {
+        mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
+    }
+
+    /**
+     * The pattern listener that responds according to a user confirming
+     * an existing lock pattern.
+     */
+    private LockPatternView.OnPatternListener mConfirmExistingLockPatternListener = new LockPatternView.OnPatternListener()  {
+
+        public void onPatternStart() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternCleared() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+            if (mLockPatternUtils.checkPattern(pattern)) {
+                setResult(RESULT_OK);
+                finish();
+            } else {
+                if (pattern.size() >= LockPatternUtils.MIN_LOCK_PATTERN_SIZE &&
+                        ++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+                    long deadline = SystemClock.elapsedRealtime() + LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS;
+                    mLockPatternUtils.setLockoutAttemptDeadline(deadline);
+                    handleAttemptLockout(deadline);
+                } else {
+                    updateStage(Stage.NeedToUnlockWrong);
+                    postClearPatternRunnable();
+                }
+            }
+        }
+    };
+
+
+    private void handleAttemptLockout(long elapsedRealtimeDeadline) {
+        updateStage(Stage.LockedOut);
+        long elapsedRealtime = SystemClock.elapsedRealtime();
+        mCountdownTimer = new CountDownTimer(
+                elapsedRealtimeDeadline - elapsedRealtime,
+                LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS) {
+
+            @Override
+            public void onTick(long millisUntilFinished) {
+                mHeaderTextView.setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
+                final int secondsCountdown = (int) (millisUntilFinished / 1000);
+                mFooterTextView.setText(getString(
+                        R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
+                        secondsCountdown));
+            }
+
+            @Override
+            public void onFinish() {
+                mNumWrongConfirmAttempts = 0;
+                updateStage(Stage.NeedToUnlock);
+            }
+        }.start();
+    }
+}
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
new file mode 100644
index 0000000..ce9dd8c
--- /dev/null
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Dialog;
+import android.app.DatePickerDialog;
+import android.app.TimePickerDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.pim.DateFormat;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.widget.DatePicker;
+import android.widget.TimePicker;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class DateTimeSettings 
+        extends PreferenceActivity 
+        implements OnSharedPreferenceChangeListener,
+                TimePickerDialog.OnTimeSetListener , DatePickerDialog.OnDateSetListener {
+
+    private static final String HOURS_12 = "12";
+    private static final String HOURS_24 = "24";
+    
+    private Calendar mDummyDate;
+    private static final String KEY_DATE_FORMAT = "date_format";
+    private static final String KEY_AUTO_TIME = "auto_time";
+
+    private static final int DIALOG_DATEPICKER = 0;
+    private static final int DIALOG_TIMEPICKER = 1;
+    
+    private CheckBoxPreference mAutoPref;
+    private Preference mTimePref;
+    private Preference mTime24Pref;
+    private Preference mTimeZone;
+    private Preference mDatePref;
+    private ListPreference mDateFormat;
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.date_time_prefs);
+        
+        initUI();        
+    }
+    
+    private void initUI() {
+        boolean autoEnabled = getAutoState();
+
+        mDummyDate = Calendar.getInstance();
+        mDummyDate.set(mDummyDate.get(Calendar.YEAR), 11, 31, 13, 0, 0);
+        
+        mAutoPref = (CheckBoxPreference) findPreference(KEY_AUTO_TIME);
+        mAutoPref.setChecked(autoEnabled);
+        mTimePref = findPreference("time");
+        mTime24Pref = findPreference("24 hour");
+        mTimeZone = findPreference("timezone");
+        mDatePref = findPreference("date");
+        mDateFormat = (ListPreference) findPreference(KEY_DATE_FORMAT);
+        
+        int currentFormatIndex = -1;
+        String [] dateFormats = getResources().getStringArray(R.array.date_format_values);
+        String [] formattedDates = new String[dateFormats.length];
+        String currentFormat = getDateFormat();
+        // Initialize if DATE_FORMAT is not set in the system settings
+        // This can happen after a factory reset (or data wipe)
+        if (currentFormat == null) {
+            currentFormat = getResources().getString(R.string.default_date_format);
+            setDateFormat(currentFormat);
+        }
+        for (int i = 0; i < formattedDates.length; i++) {
+            formattedDates[i] = DateFormat.format(dateFormats[i], mDummyDate).toString();
+            if (currentFormat.equals(dateFormats[i])) currentFormatIndex = i;
+        }
+        
+        mDateFormat.setEntries(formattedDates);
+        mDateFormat.setEntryValues(R.array.date_format_values);
+        mDateFormat.setValue(currentFormat);
+        
+        mTimePref.setEnabled(!autoEnabled);
+        mDatePref.setEnabled(!autoEnabled);
+        mTimeZone.setEnabled(!autoEnabled);
+
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);        
+    }
+
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        ((CheckBoxPreference)mTime24Pref).setChecked(is24Hour());
+
+        // Register for time ticks and other reasons for time change
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_TIME_TICK);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
+        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        registerReceiver(mIntentReceiver, filter, null, null);
+        
+        updateTimeAndDateDisplay();
+    }
+
+    @Override 
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mIntentReceiver);
+    }
+    
+    private void updateTimeAndDateDisplay() {
+        java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(this);
+        Date now = Calendar.getInstance().getTime();
+        Date dummyDate = mDummyDate.getTime();
+        mTimePref.setSummary(DateFormat.getTimeFormat(this).format(now));
+        mTimeZone.setSummary(getTimeZoneText());
+        mDatePref.setSummary(shortDateFormat.format(now));
+        mDateFormat.setSummary(shortDateFormat.format(dummyDate));
+    }
+
+    public void onDateSet(DatePicker view, int year, int month, int day) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.YEAR, year);
+        c.set(Calendar.MONTH, month);
+        c.set(Calendar.DAY_OF_MONTH, day);
+        long when = c.getTimeInMillis();
+
+        if (when / 1000 < Integer.MAX_VALUE) {
+            SystemClock.setCurrentTimeMillis(when);
+        }
+        updateTimeAndDateDisplay();
+    }
+
+    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+        Calendar c = Calendar.getInstance();
+
+        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
+        c.set(Calendar.MINUTE, minute);
+        long when = c.getTimeInMillis();
+
+        if (when / 1000 < Integer.MAX_VALUE) {
+            SystemClock.setCurrentTimeMillis(when);
+        }
+        updateTimeAndDateDisplay();
+        timeUpdated();
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
+        if (key.equals(KEY_DATE_FORMAT)) {
+            String format = preferences.getString(key, 
+                    getResources().getString(R.string.default_date_format));
+            Settings.System.putString(getContentResolver(), 
+                    Settings.System.DATE_FORMAT, format);
+            updateTimeAndDateDisplay();
+        } else if (key.equals(KEY_AUTO_TIME)) {
+            boolean autoEnabled = preferences.getBoolean(key, true);
+            Settings.System.putInt(getContentResolver(), 
+                    Settings.System.AUTO_TIME, 
+                    autoEnabled ? 1 : 0);
+            mTimePref.setEnabled(!autoEnabled);
+            mDatePref.setEnabled(!autoEnabled);
+            mTimeZone.setEnabled(!autoEnabled);
+        }
+    }
+
+    public Dialog onCreateDialog(int id) {
+        Dialog d;
+
+        switch (id) {
+        case DIALOG_DATEPICKER: {
+            final Calendar calendar = Calendar.getInstance();
+            d = new DatePickerDialog(
+                this,
+                this,
+                calendar.get(Calendar.YEAR),
+                calendar.get(Calendar.MONTH),
+                calendar.get(Calendar.DAY_OF_MONTH));
+            d.setTitle(getResources().getString(R.string.date_time_changeDate_text));
+            break;
+        }
+        case DIALOG_TIMEPICKER: {
+            final Calendar calendar = Calendar.getInstance();
+            d = new TimePickerDialog(
+                    this,
+                    this,
+                    calendar.get(Calendar.HOUR_OF_DAY),
+                    calendar.get(Calendar.MINUTE),
+                    DateFormat.is24HourFormat(this));
+            d.setTitle(getResources().getString(R.string.date_time_changeTime_text));
+            break;
+        }
+        default:
+            d = null;
+            break;
+        }
+
+        return d;
+    }
+
+    public void onPrepareDialog(int id, Dialog d) {
+        switch (id) {
+        case DIALOG_DATEPICKER: {
+            DatePickerDialog datePicker = (DatePickerDialog)d;
+            final Calendar calendar = Calendar.getInstance();
+            datePicker.updateDate(
+                    calendar.get(Calendar.YEAR),
+                    calendar.get(Calendar.MONTH),
+                    calendar.get(Calendar.DAY_OF_MONTH));
+            break;
+        }
+        case DIALOG_TIMEPICKER: {
+            TimePickerDialog timePicker = (TimePickerDialog)d;
+            final Calendar calendar = Calendar.getInstance();
+            timePicker.updateTime(
+                    calendar.get(Calendar.HOUR_OF_DAY),
+                    calendar.get(Calendar.MINUTE));
+            break;
+        }
+        default:
+            break;
+        }
+    }
+    
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mDatePref) {
+            showDialog(DIALOG_DATEPICKER);
+        } else if (preference == mTimePref) {
+            showDialog(DIALOG_TIMEPICKER);
+        } else if (preference == mTime24Pref) {
+            set24Hour(((CheckBoxPreference)mTime24Pref).isChecked());
+            updateTimeAndDateDisplay();
+            timeUpdated();
+        } else if (preference == mTimeZone) {
+            Intent intent = new Intent();
+            intent.setClass(this, ZoneList.class);
+            startActivityForResult(intent, 0);
+        }
+        return false;
+    }
+    
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        updateTimeAndDateDisplay();
+    }
+    
+    private void timeUpdated() {
+        Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED);
+        sendBroadcast(timeChanged);
+    }
+    
+    /*  Get & Set values from the system settings  */
+    
+    private boolean is24Hour() {
+        String setting = Settings.System.getString(getContentResolver(),
+                Settings.System.TIME_12_24);
+        return HOURS_24.equals(setting);
+    }
+    
+    private void set24Hour(boolean is24Hour) {
+        Settings.System.putString(getContentResolver(),
+                Settings.System.TIME_12_24,
+                is24Hour? HOURS_24 : HOURS_12);
+    }
+    
+    private String getDateFormat() {
+        return Settings.System.getString(getContentResolver(), 
+                Settings.System.DATE_FORMAT);
+    }
+    
+    private boolean getAutoState() {
+        try {
+            return Settings.System.getInt(getContentResolver(), 
+                Settings.System.AUTO_TIME) > 0;            
+        } catch (SettingNotFoundException snfe) {
+            return true;
+        }
+    }
+
+    private void setDateFormat(String format) {
+        Settings.System.putString(getContentResolver(), Settings.System.DATE_FORMAT, format);        
+    }
+    
+    /*  Helper routines to format timezone */
+    
+    private String getTimeZoneText() {
+        TimeZone    tz = java.util.Calendar.getInstance().getTimeZone();
+        boolean daylight = tz.inDaylightTime(new Date());
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(formatOffset(tz.getRawOffset() +
+                               (daylight ? tz.getDSTSavings() : 0))).
+            append(", ").
+            append(tz.getDisplayName(daylight, TimeZone.LONG));
+
+        return sb.toString();        
+    }
+
+    private char[] formatOffset(int off) {
+        off = off / 1000 / 60;
+
+        char[] buf = new char[9];
+        buf[0] = 'G';
+        buf[1] = 'M';
+        buf[2] = 'T';
+
+        if (off < 0) {
+            buf[3] = '-';
+            off = -off;
+        } else {
+            buf[3] = '+';
+        }
+
+        int hours = off / 60; 
+        int minutes = off % 60;
+
+        buf[4] = (char) ('0' + hours / 10);
+        buf[5] = (char) ('0' + hours % 10);
+
+        buf[6] = ':';
+
+        buf[7] = (char) ('0' + minutes / 10);
+        buf[8] = (char) ('0' + minutes % 10);
+
+        return buf;
+    }
+    
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateTimeAndDateDisplay();
+        }
+    };
+}
diff --git a/src/com/android/settings/DateTimeSettingsSetupWizard.java b/src/com/android/settings/DateTimeSettingsSetupWizard.java
new file mode 100644
index 0000000..8dd970b
--- /dev/null
+++ b/src/com/android/settings/DateTimeSettingsSetupWizard.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.LinearLayout;
+
+public class DateTimeSettingsSetupWizard extends DateTimeSettings implements OnClickListener {
+    private View mNextButton;
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        requestWindowFeature(Window.FEATURE_NO_TITLE); 
+        super.onCreate(icicle);
+        setContentView(R.layout.date_time_settings_setupwizard);
+        mNextButton = findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        setResult(RESULT_OK);
+        finish();
+    }
+}
diff --git a/src/com/android/settings/DebugIntentSender.java b/src/com/android/settings/DebugIntentSender.java
new file mode 100644
index 0000000..9fed947
--- /dev/null
+++ b/src/com/android/settings/DebugIntentSender.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.widget.EditText;
+import android.widget.Button;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.text.TextUtils;
+import android.text.Spannable;
+import android.text.Selection;
+import android.net.Uri;
+
+/**
+ * A simple activity that provides a UI for sending intents
+ */
+public class DebugIntentSender extends Activity {
+    private EditText mIntentField;
+    private EditText mDataField;
+    private EditText mAccountField;
+    private EditText mResourceField;
+    private Button mSendBroadcastButton;
+    private Button mStartActivityButton;
+    private View.OnClickListener mClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if ((v == mSendBroadcastButton) ||
+                       (v == mStartActivityButton)) {
+                String intentAction = mIntentField.getText().toString();
+                String intentData = mDataField.getText().toString();
+                String account = mAccountField.getText().toString();
+                String resource = mResourceField.getText().toString();
+
+                Intent intent = new Intent(intentAction);
+                if (!TextUtils.isEmpty(intentData)) {
+                    intent.setData(Uri.parse(intentData));
+                }
+                intent.putExtra("account", account);
+                intent.putExtra("resource", resource);
+                if (v == mSendBroadcastButton) {
+                    sendBroadcast(intent);
+                } else {
+                    startActivity(intent);
+                }
+
+                setResult(RESULT_OK);
+                finish();
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.intent_sender);
+
+        mIntentField = (EditText) findViewById(R.id.intent);
+        mIntentField.setText(Intent.ACTION_SYNC);
+        Selection.selectAll((Spannable) mIntentField.getText());
+
+        mDataField = (EditText) findViewById(R.id.data);
+        mDataField.setBackgroundResource(android.R.drawable.editbox_background);
+
+        mAccountField = (EditText) findViewById(R.id.account);
+        mResourceField = (EditText) findViewById(R.id.resource);
+
+        mSendBroadcastButton = (Button) findViewById(R.id.sendbroadcast);
+        mSendBroadcastButton.setOnClickListener(mClicked);
+
+        mStartActivityButton = (Button) findViewById(R.id.startactivity);
+        mStartActivityButton.setOnClickListener(mClicked);
+    }
+}
diff --git a/src/com/android/settings/DefaultRingtonePreference.java b/src/com/android/settings/DefaultRingtonePreference.java
new file mode 100644
index 0000000..8eed563
--- /dev/null
+++ b/src/com/android/settings/DefaultRingtonePreference.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.preference.RingtonePreference;
+import android.util.AttributeSet;
+import android.util.Config;
+import android.util.Log;
+
+public class DefaultRingtonePreference extends RingtonePreference {
+    private static final String TAG = "DefaultRingtonePreference";
+    
+    public DefaultRingtonePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
+        super.onPrepareRingtonePickerIntent(ringtonePickerIntent);
+        
+        /*
+         * Since this preference is for choosing the default ringtone, it
+         * doesn't make sense to show a 'Default' item.
+         */
+        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
+        
+        /*
+         * Similarly, 'Silent' shouldn't be shown here. 
+         */
+        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
+    }
+
+    @Override
+    protected void onSaveRingtone(Uri ringtoneUri) {
+        RingtoneManager.setActualDefaultRingtoneUri(getContext(), getRingtoneType(), ringtoneUri);
+    }
+
+    @Override
+    protected Uri onRestoreRingtone() {
+        return RingtoneManager.getActualDefaultRingtoneUri(getContext(), getRingtoneType());
+    }
+    
+}
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
new file mode 100644
index 0000000..02b852b
--- /dev/null
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+/*
+ * Displays preferences for application developers.
+ */
+public class DevelopmentSettings extends PreferenceActivity {
+
+    private static final String ENABLE_ADB = "enable_adb";
+    private static final String KEEP_SCREEN_ON = "keep_screen_on";
+
+    private CheckBoxPreference mEnableAdb;
+    private CheckBoxPreference mKeepScreenOn;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.development_prefs);
+
+        mEnableAdb = (CheckBoxPreference) findPreference(ENABLE_ADB);
+        mKeepScreenOn = (CheckBoxPreference) findPreference(KEEP_SCREEN_ON);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        mEnableAdb.setChecked(Settings.System.getInt(getContentResolver(),
+                Settings.System.ADB_ENABLED, 0) != 0);
+        mKeepScreenOn.setChecked(Settings.System.getInt(getContentResolver(),
+                Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+
+        // Those monkeys kept committing suicide, so we add this property
+        // to disable this functionality
+        if (!TextUtils.isEmpty(SystemProperties.get("ro.monkey"))) {
+            return false;
+        }
+
+        if (preference == mEnableAdb) {
+            Settings.System.putInt(getContentResolver(), Settings.System.ADB_ENABLED, 
+                    mEnableAdb.isChecked() ? 1 : 0);
+        } else if (preference == mKeepScreenOn) {
+            Settings.System.putInt(getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN, 
+                    mKeepScreenOn.isChecked() ? 1 : 0);
+        }
+        
+        return false;
+    }
+}
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
new file mode 100644
index 0000000..58fc91e
--- /dev/null
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.util.Config;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DeviceInfoSettings extends PreferenceActivity {
+
+    private static final String TAG = "DeviceInfoSettings";
+    private static final boolean LOGD = false || Config.LOGD;
+
+    private static final String KEY_CONTAINER = "container";
+    private static final String KEY_TEAM = "team";
+    private static final String KEY_CONTRIBUTORS = "contributors";
+    private static final String KEY_TERMS = "terms";
+    private static final String KEY_LICENSE = "license";
+    private static final String KEY_COPYRIGHT = "copyright";
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.device_info_settings);
+       
+        setSummary("firmware_version", "ro.build.version.release");
+        setSummary("baseband_version", "gsm.version.baseband");
+        setSummary("device_model", "ro.product.model");
+        setSummary("build_number", "ro.build.description");
+        findPreference("kernel_version").setSummary(getFormattedKernelVersion());
+
+        /*
+         * Settings is a generic app and should not contain any device-specific
+         * info.
+         */
+        PreferenceGroup parentPreference = (PreferenceGroup) findPreference(KEY_CONTAINER);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_TERMS,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_LICENSE,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_CONTRIBUTORS,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_COPYRIGHT,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_TEAM,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+    }
+    
+    private void setSummary(String preference, String property) {
+        try {
+            findPreference(preference).setSummary(
+                    SystemProperties.get(property, 
+                            getResources().getString(R.string.device_info_default)));
+        } catch (RuntimeException e) {
+            
+        }
+    }
+
+    private String getFormattedKernelVersion() {
+        String procVersionStr;
+
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader("/proc/version"), 256);
+            try {
+                procVersionStr = reader.readLine();
+            } finally {
+                reader.close();
+            }
+
+            final String PROC_VERSION_REGEX =
+                "\\w+\\s+" + /* ignore: Linux */
+                "\\w+\\s+" + /* ignore: version */
+                "([^\\s]+)\\s+" + /* group 1: 2.6.22-omap1 */
+                "\\(([^\\s@]+(?:@[^\\s.]+)?)[^)]*\\)\\s+" + /* group 2: (xxxxxx@xxxxx.constant) */
+                "\\([^)]+\\)\\s+" + /* ignore: (gcc ..) */
+                "([^\\s]+)\\s+" + /* group 3: #26 */
+                "(?:PREEMPT\\s+)?" + /* ignore: PREEMPT (optional) */
+                "(.+)"; /* group 4: date */
+
+            Pattern p = Pattern.compile(PROC_VERSION_REGEX);
+            Matcher m = p.matcher(procVersionStr);
+
+            if (!m.matches()) {
+                Log.e(TAG, "Regex did not match on /proc/version: " + procVersionStr);
+                return "Unavailable";
+            } else if (m.groupCount() < 4) {
+                Log.e(TAG, "Regex match on /proc/version only returned " + m.groupCount()
+                        + " groups");
+                return "Unavailable";
+            } else {
+                return (new StringBuilder(m.group(1)).append("\n").append(
+                        m.group(2)).append(" ").append(m.group(3)).append("\n")
+                        .append(m.group(4))).toString();
+            }
+        } catch (IOException e) {  
+            Log.e(TAG,
+                "IO Exception when getting kernel version for Device Info screen",
+                e);
+
+            return "Unavailable";
+        }
+    }
+
+}
diff --git a/src/com/android/settings/Display.java b/src/com/android/settings/Display.java
new file mode 100644
index 0000000..f90e0f0
--- /dev/null
+++ b/src/com/android/settings/Display.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+
+public class Display extends Activity implements View.OnClickListener {
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.display);
+
+        mFontSize = (Spinner) findViewById(R.id.fontSize);
+        mFontSize.setOnItemSelectedListener(mFontSizeChanged);
+        String[] states = new String[3];
+        Resources r = getResources();
+        states[0] = r.getString(R.string.small_font);
+        states[1] = r.getString(R.string.medium_font);
+        states[2] = r.getString(R.string.large_font);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, states);
+        adapter.setDropDownViewResource(
+                android.R.layout.simple_spinner_dropdown_item);
+        mFontSize.setAdapter(adapter);
+
+        mPreview = (TextView) findViewById(R.id.preview);
+        mPreview.setText(r.getText(R.string.font_size_preview_text));
+
+        Button save = (Button) findViewById(R.id.save);
+        save.setText(r.getText(R.string.font_size_save));
+        save.setOnClickListener(this);
+
+        mTextSizeTyped = new TypedValue();
+        TypedArray styledAttributes = 
+            obtainStyledAttributes(android.R.styleable.TextView);
+        styledAttributes.getValue(android.R.styleable.TextView_textSize,
+                mTextSizeTyped);
+
+        DisplayMetrics metrics = getResources().getDisplayMetrics();
+        mDisplayMetrics = new DisplayMetrics();
+        mDisplayMetrics.density = metrics.density;
+        mDisplayMetrics.heightPixels = metrics.heightPixels;
+        mDisplayMetrics.scaledDensity = metrics.scaledDensity;
+        mDisplayMetrics.widthPixels = metrics.widthPixels;
+        mDisplayMetrics.xdpi = metrics.xdpi;
+        mDisplayMetrics.ydpi = metrics.ydpi;
+        
+        styledAttributes.recycle();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        try {
+            mCurConfig.updateFrom(
+                ActivityManagerNative.getDefault().getConfiguration());
+        } catch (RemoteException e) {
+        }
+        if (mCurConfig.fontScale < 1) {
+            mFontSize.setSelection(0);
+        } else if (mCurConfig.fontScale > 1) {
+            mFontSize.setSelection(2);
+        } else {
+            mFontSize.setSelection(1);
+        }
+        updateFontScale();
+    }
+
+    private void updateFontScale() {
+        mDisplayMetrics.scaledDensity = mDisplayMetrics.density *
+                mCurConfig.fontScale;
+
+        float size = mTextSizeTyped.getDimension(mDisplayMetrics);
+        mPreview.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
+    }
+
+    public void onClick(View v) {
+        try {
+            ActivityManagerNative.getDefault().updateConfiguration(mCurConfig);
+        } catch (RemoteException e) {
+        }
+        finish();
+    }
+
+    private Spinner.OnItemSelectedListener mFontSizeChanged
+                                    = new Spinner.OnItemSelectedListener() {
+        public void onItemSelected(android.widget.AdapterView av, View v,
+                                    int position, long id) {
+            if (position == 0) {
+                mCurConfig.fontScale = .75f;
+            } else if (position == 2) {
+                mCurConfig.fontScale = 1.25f;
+            } else {
+                mCurConfig.fontScale = 1.0f;
+            }
+
+            updateFontScale();
+        }
+
+        public void onNothingSelected(android.widget.AdapterView av) {
+        }
+    };
+
+    private Spinner mFontSize;
+    private TextView mPreview;
+    private TypedValue mTextSizeTyped;
+    private DisplayMetrics mDisplayMetrics;
+    private Configuration mCurConfig = new Configuration();
+}
diff --git a/src/com/android/settings/EditPinPreference.java b/src/com/android/settings/EditPinPreference.java
new file mode 100644
index 0000000..ee3143c
--- /dev/null
+++ b/src/com/android/settings/EditPinPreference.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.preference.EditTextPreference;
+import android.text.method.DigitsKeyListener;
+import android.text.method.PasswordTransformationMethod;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+
+import java.util.Map;
+
+/**
+ * TODO: Add a soft dialpad for PIN entry.
+ */
+class EditPinPreference extends EditTextPreference {
+
+    private boolean mDialogOpen;
+    
+    interface OnPinEnteredListener {
+        void onPinEntered(EditPinPreference preference, boolean positiveResult);
+    }
+    
+    private OnPinEnteredListener mPinListener;
+    
+    public EditPinPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public EditPinPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+    
+    public void setOnPinEnteredListener(OnPinEnteredListener listener) {
+        mPinListener = listener;
+    }
+    
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+        
+        final EditText editText = (EditText) view.findViewById(android.R.id.edit);
+        
+        if (editText != null) {
+            editText.setSingleLine(true);
+            editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
+            editText.setKeyListener(DigitsKeyListener.getInstance());
+        }
+    }
+
+    public boolean isDialogOpen() {
+        return mDialogOpen;
+    }
+    
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        mDialogOpen = false;
+        if (mPinListener != null) {
+            mPinListener.onPinEntered(this, positiveResult);
+        }
+    }
+    
+    public void showPinDialog() {
+        mDialogOpen = true;
+        showDialog(null);
+    }
+}
diff --git a/src/com/android/settings/InstalledAppDetails.java b/src/com/android/settings/InstalledAppDetails.java
new file mode 100644
index 0000000..712f94d
--- /dev/null
+++ b/src/com/android/settings/InstalledAppDetails.java
@@ -0,0 +1,414 @@
+
+
+/**
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.settings.R;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageStats;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Config;
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
+import android.content.ComponentName;
+import android.view.View;
+import android.widget.AppSecurityPermissions;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Activity to display application information from Settings
+ * 
+ */
+public class InstalledAppDetails extends Activity implements View.OnClickListener, DialogInterface.OnClickListener  {
+    private static final String TAG="InstalledAppDetails";
+    private static final int _UNKNOWN_APP=R.string.unknown;
+   //wait times used for the async package manager api
+    private ApplicationInfo mAppInfo;
+    private Button mUninstallButton;
+    private Button mActivitiesButton;
+    private boolean mSysPackage;
+    private boolean localLOGV=Config.LOGV || true;
+    private TextView mTotalSize;
+    private TextView mAppSize;
+    private TextView mDataSize;
+    PackageStats mSizeInfo;
+    private Button mManageSpaceButton;
+    private PackageManager mPm;
+    private String mBStr, mKbStr, mMbStr;
+    
+    //internal constants used in Handler
+    private static final int CLEAR_USER_DATA = 1;
+    private static final int OP_SUCCESSFUL = 1;
+    private static final int OP_FAILED = 2;
+    private static final int GET_PKG_SIZE = 2;
+    private static final String ATTR_PACKAGE_STATS="PackageStats";
+    
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case CLEAR_USER_DATA:
+                    processClearMsg(msg);
+                    break;
+                case GET_PKG_SIZE:
+                    refreshSizeInfo(msg);
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+    
+    private boolean isSystemPackage() {
+        if ((mAppInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
+            return true;
+        }
+        return false;
+    }
+    
+    class ClearUserDataObserver extends IPackageDataObserver.Stub {
+       public void onRemoveCompleted(final String packageName, final boolean succeeded) {
+           final Message msg = mHandler.obtainMessage(CLEAR_USER_DATA);
+           msg.arg1 = succeeded?OP_SUCCESSFUL:OP_FAILED;
+           mHandler.sendMessage(msg);
+        }
+    }
+    
+    class PkgSizeObserver extends IPackageStatsObserver.Stub {
+        public int idx;
+        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) {
+             Message msg = mHandler.obtainMessage(GET_PKG_SIZE);
+             Bundle data = new Bundle();
+             data.putParcelable(ATTR_PACKAGE_STATS, pStats);
+             msg.setData(data);
+             mHandler.sendMessage(msg);
+            
+         }
+     }
+    
+    private String getSizeStr(long size) {
+        String retStr = "";
+        if(size < 1024) {
+            return String.valueOf(size)+mBStr;
+        }
+        long kb, mb, rem;
+        kb = size >> 10;
+        rem = size - (kb << 10);
+        if(kb < 1024) {
+            if(rem > 512) {
+                kb++;
+            }
+            retStr += String.valueOf(kb)+mKbStr;
+            return retStr;
+        }
+        mb = kb >> 10;
+        if(kb >= 512) {
+            //round off
+            mb++;
+       }
+       retStr += String.valueOf(mb)+ mMbStr;
+       return retStr;
+    }
+    
+    /** Called when the activity is first created. */
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        //get package manager
+        mPm = getPackageManager();
+        //get application's name from intent
+        Intent intent = getIntent();
+        final String packageName = intent.getStringExtra(ManageApplications.APP_PKG_NAME);
+        mSizeInfo = intent.getParcelableExtra(ManageApplications.APP_PKG_SIZE);
+        long total = -1;
+        long code = -1;
+        long data = -1;
+        if(mSizeInfo != null) {
+            total = mSizeInfo.cacheSize+mSizeInfo.codeSize+mSizeInfo.dataSize;
+            code = mSizeInfo.codeSize;
+            data = mSizeInfo.dataSize+mSizeInfo.cacheSize;
+        }
+        String unknownStr = getString(_UNKNOWN_APP);
+        mBStr = getString(R.string.b_text);
+        mKbStr = getString(R.string.kb_text);
+        mMbStr = getString(R.string.mb_text);
+        String totalSizeStr = unknownStr;
+        if(total != -1) {
+            totalSizeStr = getSizeStr(total);
+        }
+        String appSizeStr = unknownStr;
+        if(code != -1) {
+            appSizeStr = getSizeStr(code);
+        }
+        String dataSizeStr = unknownStr;
+        if(data != -1) {
+            dataSizeStr = getSizeStr(data);
+        }
+        if(localLOGV) Log.i(TAG, "packageName:"+packageName+", total="+total+
+                "code="+code+", data="+data);
+        try {
+            mAppInfo = mPm.getApplicationInfo(packageName, 0);
+        } catch (NameNotFoundException e) {
+           Throwable th = e.fillInStackTrace();
+            Log.e(TAG, "Exception when retrieving package:"+packageName, e);
+            displayErrorDialog(R.string.app_not_found_dlg_text, true, true);
+        }
+        setContentView(R.layout.installed_app_details);
+        ((ImageView)findViewById(R.id.app_icon)).setImageDrawable(mPm.
+                getApplicationIcon(mAppInfo));
+        //set application name TODO version
+        CharSequence appName = mPm.getApplicationLabel(mAppInfo);
+        if(appName == null) {
+            appName = getString(_UNKNOWN_APP);
+        }
+        ((TextView)findViewById(R.id.app_name)).setText(appName);
+        CharSequence appDesc = mAppInfo.loadDescription(mPm);
+        if(appDesc != null) {
+            ((TextView)findViewById(R.id.app_description)).setText(appDesc);
+        }
+        //TODO download str and download url
+        //set values on views
+        mTotalSize = (TextView)findViewById(R.id.total_size_text);
+        mTotalSize.setText(totalSizeStr);
+        mAppSize = (TextView)findViewById(R.id.application_size_text);
+        mAppSize.setText(appSizeStr);
+        mDataSize = (TextView)findViewById(R.id.data_size_text);
+        mDataSize.setText(dataSizeStr);
+         
+         mUninstallButton = ((Button)findViewById(R.id.uninstall_button));
+        //determine if app is a system app
+         mSysPackage = isSystemPackage();
+         if(localLOGV) Log.i(TAG, "Is systemPackage "+mSysPackage);
+         int btnText;
+         boolean btnClickable = true;
+         
+         if(mSysPackage) {
+             //app can clear user data
+             if((mAppInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 
+                     == ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) {
+                 mUninstallButton.setText(R.string.clear_user_data_text);
+                 //disable button if data is 0
+                 if(data == 0) {
+                     mUninstallButton.setEnabled(false);
+                 } else {
+                     //enable button
+                     mUninstallButton.setOnClickListener(this);
+                 }
+             } else {
+                 //hide button if diableClearUserData is set
+                 mUninstallButton.setVisibility(View.GONE);
+             }
+         } else {
+             mUninstallButton.setText(R.string.uninstall_text);
+             mUninstallButton.setOnClickListener(this);
+         }
+         //clear activities
+         mActivitiesButton = (Button)findViewById(R.id.clear_activities_button);
+         List<ComponentName> prefActList = new ArrayList<ComponentName>();
+         //intent list cannot be null. so pass empty list
+         List<IntentFilter> intentList = new ArrayList<IntentFilter>();
+         mPm.getPreferredActivities(intentList,  prefActList, packageName);
+         if(localLOGV) Log.i(TAG, "Have "+prefActList.size()+" number of activities in prefered list");
+         TextView autoLaunchView = (TextView)findViewById(R.id.auto_launch);
+         if(prefActList.size() <= 0) {
+             //disable clear activities button
+             autoLaunchView.setText(R.string.auto_launch_disable_text);
+             mActivitiesButton.setEnabled(false);
+         } else {
+             autoLaunchView.setText(R.string.auto_launch_enable_text);
+             mActivitiesButton.setOnClickListener(this);
+         }
+         mManageSpaceButton = (Button)findViewById(R.id.manage_space_button);
+         if(mAppInfo.manageSpaceActivityName != null) {
+             mManageSpaceButton.setVisibility(View.VISIBLE);
+             mManageSpaceButton.setOnClickListener(this);
+         }
+         //security permissions section
+         AppSecurityPermissions asp = new AppSecurityPermissions(this);
+         PackageInfo pkgInfo;
+        try {
+            pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
+        } catch (NameNotFoundException e) {
+            Log.w(TAG, "Couldnt retrieve permissions for package:"+packageName);
+            return;
+        }
+         asp.setSecurityPermissionsView(pkgInfo);
+         LinearLayout securityList = (LinearLayout) findViewById(R.id.security_settings_list);
+         securityList.addView(asp.getPermissionsView());
+    }
+    
+    private void displayErrorDialog(int msgId, final boolean finish, final boolean changed) {
+        //display confirmation dialog
+        new AlertDialog.Builder(this)
+        .setTitle(getString(R.string.app_not_found_dlg_title))
+        .setIcon(R.drawable.ic_dialog_alert)
+        .setMessage(getString(msgId))
+        .setNeutralButton(getString(R.string.dlg_ok), 
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        //force to recompute changed value
+                        setIntentAndFinish(finish, changed);
+                    }
+                }
+        )
+        .show();
+    }
+    
+    private void setIntentAndFinish(boolean finish, boolean appChanged) {
+        if(localLOGV) Log.i(TAG, "appChanged="+appChanged);
+        Intent intent = new Intent();
+        intent.putExtra(ManageApplications.APP_CHG, appChanged);
+        setResult(ManageApplications.RESULT_OK, intent);
+        mUninstallButton.setEnabled(false);
+        if(finish) {
+            finish();
+        }
+    }
+    
+    /*
+     * Private method to handle get size info notification from observer when
+     * the async operation from PackageManager is complete. The current user data
+     * info has to be refreshed in the manage applications screen as well as the current screen.
+     */
+    private void refreshSizeInfo(Message msg) {
+        boolean changed = false;
+        Intent intent = new Intent();
+        PackageStats newPs = msg.getData().getParcelable(ATTR_PACKAGE_STATS);
+        long newTot = newPs.cacheSize+newPs.codeSize+newPs.dataSize;
+        long oldTot = mSizeInfo.cacheSize+mSizeInfo.codeSize+mSizeInfo.dataSize;
+        if(newTot != oldTot) {
+            mTotalSize.setText(getSizeStr(newTot));
+            changed = true;
+        }
+        if(newPs.codeSize != mSizeInfo.codeSize) {
+            mAppSize.setText(getSizeStr(newPs.codeSize));
+            changed = true;
+        }
+        if((newPs.dataSize != mSizeInfo.dataSize) || (newPs.cacheSize != mSizeInfo.cacheSize)) {
+            mDataSize.setText(getSizeStr(newPs.dataSize+newPs.cacheSize));
+            changed = true;
+        }
+        if(changed) {
+            mUninstallButton.setText(R.string.clear_user_data_text);
+            mSizeInfo = newPs;
+            intent.putExtra(ManageApplications.APP_PKG_SIZE, mSizeInfo);
+        }
+        intent.putExtra(ManageApplications.APP_CHG, changed);
+        setResult(ManageApplications.RESULT_OK, intent);
+    }
+    
+    /*
+     * Private method to handle clear message notification from observer when
+     * the async operation from PackageManager is complete
+     */
+    private void processClearMsg(Message msg) {
+        int result = msg.arg1;
+        String packageName = mAppInfo.packageName;
+        if(result == OP_SUCCESSFUL) {
+            Log.i(TAG, "Cleared user data for system package:"+packageName);
+            PkgSizeObserver observer = new PkgSizeObserver();
+            mPm.getPackageSizeInfo(packageName, observer);
+        } else {
+            mUninstallButton.setText(R.string.clear_user_data_text);
+            mUninstallButton.setEnabled(true);
+        }
+    }
+    
+    /*
+     * Private method to initiate clearing user data when the user clicks the clear data 
+     * button for a system package
+     */
+    private  void initiateClearUserDataForSysPkg() {
+        mUninstallButton.setEnabled(false);
+        //invoke uninstall or clear user data based on sysPackage
+        boolean recomputeSizes = false;
+        String packageName = mAppInfo.packageName;
+        Log.i(TAG, "Clearing user data for system package");
+        ClearUserDataObserver observer = new ClearUserDataObserver();
+        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        boolean res = am.clearApplicationUserData(packageName, observer);
+        if(!res) {
+            //doesnt initiate clear. some error. should not happen but just log error for now
+            Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
+            displayErrorDialog(R.string.clear_data_failed, false, false);
+        } else {
+                mUninstallButton.setText(R.string.recompute_size);
+        }
+    }
+    
+    /*
+     * Method implementing functionality of buttons clicked
+     * @see android.view.View.OnClickListener#onClick(android.view.View)
+     */
+    public void onClick(View v) {
+        String packageName = mAppInfo.packageName;
+        if(v == mUninstallButton) {
+            if(mSysPackage) {
+                //display confirmation dialog
+                new AlertDialog.Builder(this)
+                .setTitle(getString(R.string.clear_data_dlg_title))
+                .setIcon(R.drawable.ic_dialog_alert)
+                .setMessage(getString(R.string.clear_data_dlg_text))
+                .setPositiveButton(R.string.dlg_ok, this)
+                .setNegativeButton(R.string.dlg_cancel, this)
+                .show();
+            } else {
+                //create new intent to launch Uninstaller activity
+                Uri packageURI = Uri.parse("package:"+packageName);
+                Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
+                startActivity(uninstallIntent);
+                setIntentAndFinish(true, false);
+            }
+        } else if(v == mActivitiesButton) {
+            mPm.clearPackagePreferredActivities(packageName);
+            mActivitiesButton.setEnabled(false);
+        } else if(v == mManageSpaceButton) {
+            Intent intent = new Intent(Intent.ACTION_DEFAULT);
+            intent.setClassName(mAppInfo.packageName, mAppInfo.manageSpaceActivityName);
+            startActivityForResult(intent, -1);
+        }
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if(which == AlertDialog.BUTTON1) {
+            //invoke uninstall or clear user data based on sysPackage
+            initiateClearUserDataForSysPkg();
+        } else {
+            //cancel do nothing just retain existing screen
+        }
+    }
+}
+
diff --git a/src/com/android/settings/LanguageSettings.java b/src/com/android/settings/LanguageSettings.java
new file mode 100644
index 0000000..2777777
--- /dev/null
+++ b/src/com/android/settings/LanguageSettings.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.ContentResolver;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings.System;
+
+public class LanguageSettings extends PreferenceActivity {
+    
+    private final String[] mSettingsUiKey = {
+            "auto_caps",
+            "auto_replace",
+            "auto_punctuate",
+    };
+    
+    // Note: Order of this array should correspond to the order of the above array
+    private final String[] mSettingsSystemId = {
+            System.TEXT_AUTO_CAPS,
+            System.TEXT_AUTO_REPLACE,
+            System.TEXT_AUTO_PUNCTUATE,
+    };
+
+    // Note: Order of this array should correspond to the order of the above array
+    private final int[] mSettingsDefault = {
+            1,
+            1,
+            1,
+    };
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.language_settings);
+
+        if (getAssets().getLocales().length == 1) {
+            getPreferenceScreen().
+                removePreference(findPreference("language_category"));
+        }
+    
+        ContentResolver resolver = getContentResolver();
+        for (int i = 0; i < mSettingsUiKey.length; i++) {
+            CheckBoxPreference pref = (CheckBoxPreference) findPreference(mSettingsUiKey[i]);
+            pref.setChecked(System.getInt(resolver, mSettingsSystemId[i],
+                                          mSettingsDefault[i]) > 0);
+        }
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        for (int i = 0; i < mSettingsUiKey.length; i++) {
+            if (mSettingsUiKey[i].equals(preference.getKey())) {
+                System.putInt(getContentResolver(), mSettingsSystemId[i], 
+                        ((CheckBoxPreference)preference).isChecked()? 1 : 0);
+                return true;
+            }
+        }
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
+}
diff --git a/src/com/android/settings/LocalePicker.java b/src/com/android/settings/LocalePicker.java
new file mode 100644
index 0000000..46d9b52
--- /dev/null
+++ b/src/com/android/settings/LocalePicker.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.ListActivity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class LocalePicker extends ListActivity {
+    private static final String TAG = "LocalePicker";
+
+    Loc[] mLocales;
+
+    private static class Loc {
+        String label;
+        Locale locale;
+
+        public Loc(String label, Locale locale) {
+            this.label = label;
+            this.locale = locale;
+        }
+
+        @Override
+        public String toString() {
+            return this.label;
+        }
+    }
+
+    int getContentView() {
+        return R.layout.locale_picker;
+    }
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(getContentView());
+
+        String[] locales = getAssets().getLocales();
+        final int N = locales.length;
+        mLocales = new Loc[N];
+        for (int i = 0; i < N; i++) {
+            Locale locale = null;
+            String s = locales[i];
+            int len = s.length();
+            if (len == 0) {
+                locale = new Locale("en", "US");
+            } else if (len == 2) {
+                locale = new Locale(s);
+            } else if (len == 5) {
+                locale = new Locale(s.substring(0, 2), s.substring(3, 5));
+            }
+            String displayName = "";
+            if (locale != null) {
+                displayName = locale.getDisplayName();
+            }
+            if ("zz_ZZ".equals(s)) {
+                displayName = "Pseudo...";
+            }
+
+            mLocales[i] = new Loc(displayName, locale);
+        }
+
+        int layoutId = R.layout.locale_picker_item;
+        int fieldId = R.id.locale;
+        ArrayAdapter<Loc> adapter = new ArrayAdapter<Loc>(this, layoutId, fieldId, mLocales);
+        getListView().setAdapter(adapter);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getListView().requestFocus();
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        try {
+            IActivityManager am = ActivityManagerNative.getDefault();
+            Configuration config = am.getConfiguration();
+
+            Loc loc = mLocales[position];
+            config.locale = loc.locale;
+            final String language = loc.locale.getLanguage();
+            final String region = loc.locale.getCountry();
+
+            am.updateConfiguration(config);
+            
+            // Update the System properties
+            SystemProperties.set("user.language", language);
+            SystemProperties.set("user.region", region);
+            // Write to file for persistence across reboots
+            try {
+                BufferedWriter bw = new BufferedWriter(new java.io.FileWriter(
+                        System.getenv("ANDROID_DATA") + "/locale"));
+                bw.write(language + "_" + region);
+                bw.close();
+            } catch (java.io.IOException ioe) {
+                Log.e(TAG, 
+                        "Unable to persist locale. Error writing to locale file." 
+                        + ioe);
+            }    
+        } catch (RemoteException e) {
+            // Intentionally left blank
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/settings/LocalePickerInSetupWizard.java b/src/com/android/settings/LocalePickerInSetupWizard.java
new file mode 100644
index 0000000..b160e89
--- /dev/null
+++ b/src/com/android/settings/LocalePickerInSetupWizard.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.ListActivity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class LocalePickerInSetupWizard extends LocalePicker {
+    
+    @Override 
+    int getContentView() {
+        return R.layout.locale_picker_in_setupwizard;
+    }
+
+}
diff --git a/src/com/android/settings/ManageApplications.java b/src/com/android/settings/ManageApplications.java
new file mode 100644
index 0000000..8389502
--- /dev/null
+++ b/src/com/android/settings/ManageApplications.java
@@ -0,0 +1,616 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.settings.R;
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageStats;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Activity to pick an application that will be used to display installation information and
+ * options to upgrade/uninstall/delete user data for system applications.
+ *  Initially a compute in progress message is displayed while the application retrieves
+ *  the size information of installed packages which is done asynchronously through a 
+ *  handler. Once the computation is done package resource information is retrieved 
+ *  and then the information is displayed on the screen. All 
+ *  messages are passed through a Handler object.
+ *  Known issue: There could be some ordering issues when installing/uninstalling
+ *  applications when the application list is being scanned.
+ */
+public class ManageApplications extends Activity implements SimpleAdapter.ViewBinder, OnItemClickListener {
+    private static final String TAG = "ManageApplications";
+    //Application prefix information
+    public static final String APP_PKG_PREFIX="com.android.settings.";
+    public static final String APP_PKG_NAME=APP_PKG_PREFIX+"ApplicationPkgName";
+    public static final String APP_PKG_SIZE= APP_PKG_PREFIX+"size";
+    public static final String APP_CHG=APP_PKG_PREFIX+"changed";
+    
+    //constant value that can be used to check return code from sub activity.
+    private static final int INSTALLED_APP_DETAILS = 1;
+     //application attributes passed to sub activity that displays more app info
+    private static final String KEY_APP_NAME = "ApplicationName";
+    private static final String KEY_APP_ICON = "ApplicationIcon";
+    private static final String KEY_APP_DESC = "ApplicationDescription";
+    private static final String KEY_APP_SIZE= "ApplicationSize";
+    //sort order that can be changed through the menu
+    public static final int SORT_ORDER_ALPHA = 0;
+    public static final int SORT_ORDER_SIZE = 1;
+   //key and resource values used in constructing map for SimpleAdapter
+    private static final String sKeys[] = new String[] { KEY_APP_NAME, KEY_APP_ICON, 
+            KEY_APP_DESC, KEY_APP_SIZE};
+    private static final int sResourceIds[] = new int[] { R.id.app_name, R.id.app_icon, 
+            R.id.app_description, R.id.app_size};
+    //List of ApplicationInfo objects for various applications
+    private List<ApplicationInfo> mAppList;
+    //SimpleAdapter used for managing items in the list
+    private SimpleAdapter mAppAdapter;
+    //map used to store size information which is used for displaying size information
+    //in this activity as well as the subactivity. this is to avoid invoking package manager
+    //api to retrieve size information
+    private HashMap<String, PackageStats> mSizeMap;
+    private HashMap<String, Map<String, ?> > mAppAdapterMap;
+    //sort order
+    private int mSortOrder = SORT_ORDER_ALPHA;
+    //log information boolean
+    private boolean localLOGV = Config.LOGV || false;
+    private ApplicationInfo mCurrentPkg;
+    private int mCurrentPkgIdx = 0;
+    private static final int COMPUTE_PKG_SIZE_START = 1;
+    private static final int COMPUTE_PKG_SIZE_DONE = 2;
+    private static final int REMOVE_PKG=3;
+    private static final int REORDER_LIST=4;
+    private static final int ADD_PKG=5;
+    private static final String ATTR_APP_IDX="ApplicationIndex";
+    private static final String ATTR_CHAINED="Chained";
+    private static final String ATTR_PKG_NAME="PackageName";
+    private PkgSizeObserver mObserver;
+    private PackageManager mPm;
+    private PackageIntentReceiver mReceiver;
+    private boolean mDoneIniting = false;
+    private String mKbStr;
+    private String  mMbStr;
+    private String mBStr;
+    
+    /*
+     * Handler class to handle messages for various operations
+     */
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            PackageStats ps;
+            ApplicationInfo info;
+            Bundle data;
+            String pkgName;
+            int idx;
+            int size;
+            boolean chained = false;
+            data = msg.getData();
+            switch (msg.what) {
+            case COMPUTE_PKG_SIZE_START:
+                mDoneIniting = false;
+                //initialize lists
+                mAppList = new ArrayList<ApplicationInfo>();
+                mSizeMap = new HashMap<String, PackageStats>();
+                mAppAdapterMap = new HashMap<String, Map<String, ?> >();
+                //update application list from PackageManager
+                mAppList = mPm.getInstalledApplications(0);
+                if(mAppList.size() == 0) {
+                    return;
+                }
+                mCurrentPkgIdx = 0;
+                mCurrentPkg = mAppList.get(0);
+                if(localLOGV) Log.i(TAG, "Initiating compute sizes for first time");
+                //register receiver
+                mReceiver = new PackageIntentReceiver();
+                mReceiver.registerReceiver();
+                pkgName = mCurrentPkg.packageName;
+                mObserver = new PkgSizeObserver(0);
+                mObserver.invokeGetSizeInfo(pkgName, true);
+                break;
+            case COMPUTE_PKG_SIZE_DONE:
+                ps = mObserver.ps;
+                info = mObserver.appInfo;
+                chained = data.getBoolean(ATTR_CHAINED);
+                if(!mObserver.succeeded) {
+                    if(chained) {
+                        removePackageFromAppList(ps.packageName);
+                    } else {
+                        //do not go to adding phase
+                        break;
+                    }
+                } else {
+                    //insert size value
+                    mSizeMap.put(ps.packageName, ps);
+                    Map<String, Object> entry = createMapEntry(mPm.getApplicationLabel(info), 
+                            mPm.getApplicationIcon(info), 
+                            info.loadDescription(mPm), 
+                            getSizeStr(ps));
+                    mAppAdapterMap.put(ps.packageName, entry);
+                }
+                if(chained) {
+                    //here app list is precomputed
+                    idx = data.getInt(ATTR_APP_IDX);
+                    //increment only if succeded
+                    if(mObserver.succeeded) {
+                        idx++;
+                    }
+                    if(idx <  mAppList.size()) {
+                        pkgName = mAppList.get(idx).packageName;
+                        //increment record index and invoke getSizeInfo for next record
+                        mObserver.invokeGetSizeInfo(pkgName, true);
+                    } else {
+                        sortAppList();
+                        createListFromValues();
+                        mDoneIniting = true;
+                    }
+                } else {
+                    //add app info object as well
+                    mAppList.add(info);
+                    sortAppList();
+                    size = mAppList.size();
+                    int i;
+                    for(i = 0; i < size; i++) {
+                        if(mAppList.get(i).packageName.equalsIgnoreCase(mCurrentPkg.packageName)) {
+                            if(i > mCurrentPkgIdx) {
+                                mCurrentPkgIdx = i;
+                            }
+                            break;
+                        }
+                    }
+                    createListFromValues();
+                }
+                break;
+            case REMOVE_PKG:
+                if(!mDoneIniting) {
+                    //insert message again after some delay
+                    sendMessageToHandler(REMOVE_PKG, data, 10*1000);
+                    break;
+                }
+                pkgName = data.getString(ATTR_PKG_NAME);
+                removePackageFromAppList(pkgName);
+                if(mSizeMap.remove(pkgName) == null) {
+                    Log.i(TAG, "Coudnt remove from size map package:"+pkgName);
+                }
+                if(mAppAdapterMap.remove(pkgName) == null) {
+                    Log.i(TAG, "Coudnt remove from app adapter map package:"+pkgName);
+                }
+                if(mCurrentPkg.packageName.equalsIgnoreCase(pkgName)) {
+                    if(mCurrentPkgIdx == (mAppList.size()-1)) {
+                        mCurrentPkgIdx--;
+                    }
+                    mCurrentPkg = mAppList.get(mCurrentPkgIdx);
+                }
+                createListFromValues();
+                break;
+            case REORDER_LIST:
+                int sortOrder = msg.arg1;
+                if(sortOrder != mSortOrder) {
+                    mSortOrder = sortOrder;
+                    if(localLOGV) Log.i(TAG, "Changing sort order to "+mSortOrder);
+                    sortAppList();
+                    mCurrentPkgIdx  = 0;
+                    mCurrentPkg = mAppList.get(mCurrentPkgIdx);
+                    createListFromValues();
+                }
+                break;
+            case ADD_PKG:
+                pkgName = data.getString(ATTR_PKG_NAME);
+                if(!mDoneIniting) {
+                   //insert message again after some delay
+                    sendMessageToHandler(ADD_PKG, data, 10*1000);
+                    break;
+                }
+                mObserver.invokeGetSizeInfo(pkgName, false);
+                break;
+            default:
+                break;
+            }
+        }
+    };
+    
+    private void removePackageFromAppList(String pkgName) {
+        int size = mAppList.size();
+        for(int i = 0; i < size; i++) {
+            if(mAppList.get(i).packageName.equalsIgnoreCase(pkgName)) {
+                mAppList.remove(i);
+                break;
+            }
+        }
+    }
+    
+    private void clearMessages() {
+        synchronized(mHandler) {
+            mHandler.removeMessages(COMPUTE_PKG_SIZE_START);
+            mHandler.removeMessages(COMPUTE_PKG_SIZE_DONE);
+            mHandler.removeMessages(REMOVE_PKG);
+            mHandler.removeMessages(REORDER_LIST);
+            mHandler.removeMessages(ADD_PKG);
+        }
+    }
+    
+    private void sendMessageToHandler(int msgId, Bundle data, long delayMillis) {
+        synchronized(mHandler) {
+            Message msg = mHandler.obtainMessage(msgId);
+            msg.setData(data);
+            if(delayMillis == 0) {
+                mHandler.sendMessage(msg);
+            } else {
+                mHandler.sendMessageDelayed(msg, delayMillis);
+            }
+        }
+    }
+    
+    private void sendMessageToHandler(int msgId, int arg1) {
+        synchronized(mHandler) {
+            Message msg = mHandler.obtainMessage(msgId);
+            msg.arg1 = arg1;
+            mHandler.sendMessage(msg);
+        }
+    }
+    
+    private void sendMessageToHandler(int msgId) {
+        synchronized(mHandler) {
+            mHandler.sendEmptyMessage(msgId);
+        }
+    }
+    
+    class PkgSizeObserver extends IPackageStatsObserver.Stub {
+        public PackageStats ps;
+        public ApplicationInfo appInfo;
+        public Drawable appIcon;
+        public CharSequence appName;
+        public CharSequence appDesc = "";
+        private int mIdx = 0;
+        private boolean mChained = false;
+        public boolean succeeded;
+        PkgSizeObserver(int i) {
+            mIdx = i;
+        }
+        
+        private void getAppDetails() {
+            try {
+                appInfo = mPm.getApplicationInfo(ps.packageName, 0);
+            } catch (NameNotFoundException e) {
+                return;
+            }
+            appName = appInfo.loadLabel(mPm);
+            appIcon = appInfo.loadIcon(mPm);
+        }
+        
+        public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
+            Bundle data = new Bundle();
+            ps = pStats;
+            succeeded = pSucceeded;
+            if(mChained) {
+                data.putInt(ATTR_APP_IDX, mIdx);
+                if(succeeded) {
+                    mIdx++;
+                }
+            }
+            data.putBoolean(ATTR_CHAINED, mChained);
+            getAppDetails();
+            if(localLOGV) Log.i(TAG, "onGetStatsCompleted::"+appInfo.packageName+", ("+ps.cacheSize+","+
+                    ps.codeSize+", "+ps.dataSize);
+            sendMessageToHandler(COMPUTE_PKG_SIZE_DONE, data, 0);
+        }
+        
+        public void invokeGetSizeInfo(String packageName, boolean chained) {
+             mChained = chained;
+             mPm.getPackageSizeInfo(packageName, this);
+        }
+    }
+    
+    /**
+     * Receives notifications when applications are added/removed.
+     */
+    private class PackageIntentReceiver extends BroadcastReceiver {
+         void registerReceiver() {
+             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+             filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+             filter.addDataScheme("package");
+             ManageApplications.this.registerReceiver(this, filter);
+         }
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String actionStr = intent.getAction();
+            Uri data = intent.getData();
+            String pkgName = data.getEncodedSchemeSpecificPart();
+            if(localLOGV) Log.i(TAG, "action:"+actionStr+", for package:"+pkgName);
+            updatePackageList(actionStr, pkgName);
+        }
+    }
+    
+    private void updatePackageList(String actionStr, String pkgName) {
+        //technically we dont have to invoke handler since onReceive is invoked on
+        //the main thread but doing it here for better clarity
+        if(Intent.ACTION_PACKAGE_ADDED.equalsIgnoreCase(actionStr)) {
+            Bundle data = new Bundle();
+            data.putString(ATTR_PKG_NAME, pkgName);
+            sendMessageToHandler(ADD_PKG, data, 0);
+        } else if(Intent.ACTION_PACKAGE_REMOVED.equalsIgnoreCase(actionStr)) {
+            Bundle data = new Bundle();
+            data.putString(ATTR_PKG_NAME, pkgName);
+            sendMessageToHandler(REMOVE_PKG, data, 0);
+        } else if(Intent.ACTION_PACKAGE_CHANGED.equalsIgnoreCase(actionStr)) {
+            //force adapter to draw the list again. TODO derive from SimpleAdapter
+            //to avoid this
+           
+        }   
+    }
+    
+    /*
+     * Utility method to create an array of map objects from a map of map objects
+     *  for displaying list items to be used in SimpleAdapter.
+     */
+    private void createListFromValues() {
+        findViewById(R.id.center_text).setVisibility(View.GONE);
+        populateAdapterList();
+        mAppAdapter.setViewBinder(this);
+        ListView lv= (ListView) findViewById(android.R.id.list);
+        lv.setOnItemClickListener(this);
+        lv.setAdapter(mAppAdapter);
+        if(mCurrentPkgIdx != -1) {
+            lv.setSelection(mCurrentPkgIdx);
+        }
+    }
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        String action = getIntent().getAction();
+        if(action.equals(Intent.ACTION_MANAGE_PACKAGE_STORAGE)) {
+            mSortOrder = SORT_ORDER_SIZE;
+        }
+        mPm = getPackageManager();
+        //load strings from resources
+        mBStr = getString(R.string.b_text);
+        mKbStr = getString(R.string.kb_text);
+        mMbStr = getString(R.string.mb_text);
+    }
+    
+    @Override
+    public void onStart() {
+        super.onStart();
+        setContentView(R.layout.compute_sizes);
+        //clear all messages related to application list
+        clearMessages();
+        sendMessageToHandler(COMPUTE_PKG_SIZE_START);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        //register receiver here
+        unregisterReceiver(mReceiver);        
+    }
+    
+    public static class AppInfoComparator implements Comparator<ApplicationInfo> {
+        public AppInfoComparator(HashMap<String, PackageStats> pSizeMap) {
+            mSizeMap= pSizeMap;
+        }
+
+        public final int compare(ApplicationInfo a, ApplicationInfo b) {
+            PackageStats aps, bps;
+            aps = mSizeMap.get(a.packageName);
+            bps = mSizeMap.get(b.packageName);
+            if (aps == null && bps == null) {
+                return 0;
+            } else if (aps == null) {
+                return 1;
+            } else if (bps == null) {
+                return -1;
+            }
+            long atotal = aps.dataSize+aps.codeSize+aps.cacheSize;
+            long btotal = bps.dataSize+bps.codeSize+bps.cacheSize;
+            long ret = atotal-btotal;
+            //negate result to sort in descending order
+            if(ret < 0) {
+                return 1;
+            }
+            if(ret == 0) {
+                return 0;
+            }
+            return -1;
+        }
+        private HashMap<String, PackageStats> mSizeMap;
+    }
+
+    /*
+     * Have to extract elements form map and populate a list ot be used by
+     * SimpleAdapter when displaying list elements. The sort order has to follow
+     * the order of elements in mAppList.
+     */
+     private List<Map<String, ?>> createAdapterListFromMap() {
+         //get the index from mAppInfo which gives the correct sort position
+         int imax = mAppList.size();
+         if(localLOGV) Log.i(TAG, "Creating new adapter list");
+         List<Map<String, ?>> adapterList = new ArrayList<Map<String, ?>>();
+         ApplicationInfo tmpInfo;
+         for(int i = 0; i < imax; i++) {
+             tmpInfo = mAppList.get(i);
+             Map<String, Object>newObj = new TreeMap<String, Object>(
+                     mAppAdapterMap.get(tmpInfo.packageName));
+             adapterList.add(newObj);
+         }
+         return adapterList;
+     }
+     
+    private void populateAdapterList() {
+        mAppAdapter = new SimpleAdapter(this, createAdapterListFromMap(),
+                    R.layout.manage_applications_item, sKeys, sResourceIds);
+    }
+    
+    private String getSizeStr(PackageStats ps) {
+        String retStr = "";
+        //insert total size information into map to display in view
+        //at this point its guaranteed that ps is not null. but checking anyway
+        if(ps != null) {
+            long size = ps.cacheSize+ps.codeSize+ps.dataSize;
+            if(size < 1024) {
+                return String.valueOf(size)+mBStr;
+            }
+            long kb, mb, rem;
+            kb = size >> 10;
+            rem = size - (kb << 10);
+            if(kb < 1024) {
+                if(rem > 512) {
+                    kb++;
+                }
+                retStr += String.valueOf(kb)+mKbStr;
+                return retStr;
+            }
+            mb = kb >> 10;
+            if(kb >= 512) {
+                //round off
+                mb++;
+            }
+            retStr += String.valueOf(mb)+ mMbStr;
+            return retStr;
+        } else {
+            Log.w(TAG, "Something fishy, cannot find size info for package:"+ps.packageName);
+        }
+        return retStr;
+    }
+    
+    public void sortAppList() {
+        // Sort application list
+        if(mSortOrder == SORT_ORDER_ALPHA) {
+            Collections.sort(mAppList, new ApplicationInfo.DisplayNameComparator(mPm));
+        } else if(mSortOrder == SORT_ORDER_SIZE) {
+            Collections.sort(mAppList, new AppInfoComparator(mSizeMap));
+        }
+    }
+    
+    private Map<String, Object> createMapEntry(CharSequence appName, 
+            Drawable appIcon, CharSequence appDesc, String sizeStr) {
+        Map<String, Object> map = new TreeMap<String, Object>();
+        map.put(KEY_APP_NAME, appName);
+        //the icon cannot be null. if the application hasnt set it, the default icon is returned.
+        map.put(KEY_APP_ICON, appIcon);
+        if(appDesc == null) {
+            appDesc="";
+        }
+        map.put(KEY_APP_DESC, appDesc);
+        map.put(KEY_APP_SIZE, sizeStr);
+        return map;
+    }
+    
+    private void startApplicationDetailsActivity(ApplicationInfo info, PackageStats ps) {
+        //Create intent to start new activity
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setClass(this, InstalledAppDetails.class);
+        intent.putExtra(APP_PKG_NAME, info.packageName);
+        if(localLOGV) Log.i(TAG, "code="+ps.codeSize+", cache="+ps.cacheSize+", data="+ps.dataSize);
+        intent.putExtra(APP_PKG_SIZE,  ps);
+        if(localLOGV) Log.i(TAG, "Starting sub activity to display info for app:"+info
+                +" with intent:"+intent);
+        //start new activity to display extended information
+        if ((info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
+        }
+        startActivityForResult(intent, INSTALLED_APP_DETAILS);
+    }
+    
+    public boolean setViewValue(View view, Object data, String textRepresentation) {
+        if(data == null) {
+            return false;
+        }
+        int id = view.getId();
+        switch(id) {
+        case R.id.app_name:
+            ((TextView)view).setText((String)data);
+            break;
+        case R.id.app_icon:
+            ((ImageView)view).setImageDrawable((Drawable)data);
+            break;
+        case R.id.app_description:
+            ((TextView)view).setText((String)data);
+            break;
+        case R.id.app_size:
+            ((TextView)view).setText((String)data);
+            break;
+        default:
+                break;
+        }
+        return true;
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, SORT_ORDER_ALPHA, 0, R.string.sort_order_alpha)
+                .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
+        menu.add(0, SORT_ORDER_SIZE, 0, R.string.sort_order_size)
+                .setIcon(android.R.drawable.ic_menu_sort_by_size);
+        return true;
+    }
+    
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        if(mDoneIniting) {
+            menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
+            menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder!= SORT_ORDER_SIZE);
+            return true;
+        } 
+        return false;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int menuId = item.getItemId();
+        sendMessageToHandler(REORDER_LIST, menuId);
+        return true;
+    }
+
+    public void onItemClick(AdapterView<?> parent, View view, int position,
+            long id) {
+        mCurrentPkgIdx=position;
+        ApplicationInfo info = mAppList.get(position);
+        mCurrentPkg = info;        
+        PackageStats ps = mSizeMap.get(info.packageName);
+        startApplicationDetailsActivity(info, ps);
+    }
+}
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
new file mode 100644
index 0000000..38ad608
--- /dev/null
+++ b/src/com/android/settings/MasterClear.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ICheckinService;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Confirm and execute a reset of the device to a clean "just out of the box"
+ * state.  Multiple confirmations are required: first, a general "are you sure
+ * you want to do this?" prompt, followed by a keyguard pattern trace if the user
+ * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
+ * ON THE PHONE" prompt.  If at any time the phone is allowed to go to sleep, is
+ * locked, et cetera, then the confirmation sequence is abandoned.
+ */
+public class MasterClear extends Activity {
+
+    private static final int KEYGUARD_REQUEST = 55;
+
+    private LayoutInflater mInflater;
+    private LockPatternUtils mLockUtils;
+
+    private View mInitialView;
+    private Button mInitiateButton;
+
+    private View mFinalView;
+    private Button mFinalButton;
+
+    /** 
+     * The user has gone through the multiple confirmation, so now we go ahead
+     * and invoke the Checkin Service to reset the device to its factory-default
+     * state (rebooting in the process).
+     */
+    private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
+            public void onClick(View v) {
+                
+                // Those monkeys kept committing suicide, so we add this property
+                // to disable going through with the master clear
+                if (!TextUtils.isEmpty(SystemProperties.get("ro.monkey"))) {
+                    return;
+                }
+                
+                ICheckinService service = 
+                        ICheckinService.Stub.asInterface(ServiceManager.getService("checkin"));
+                if (service != null) {
+                    try {
+                        // This RPC should never return
+                        service.masterClear();
+                    } catch (android.os.RemoteException e) {
+                        // Intentionally blank - there's nothing we can do here
+                        Log.w("MasterClear", "Unable to invoke ICheckinService.masterClear()");
+                    }
+                } else {
+                    Log.w("MasterClear", "Unable to locate ICheckinService");
+                }
+
+                /* If we reach this point, the master clear didn't happen -- the
+                 * service might have been unregistered with the ServiceManager,
+                 * the RPC might have thrown an exception, or for some reason
+                 * the implementation of masterClear() may have returned instead
+                 * of resetting the device.
+                 */
+                new AlertDialog.Builder(MasterClear.this)
+                        .setMessage(getText(R.string.master_clear_failed))
+                        .setPositiveButton(getText(android.R.string.ok), null)
+                        .show();
+            }
+        };
+
+    /**
+     *  Keyguard validation is run using the standard {@link ConfirmLockPattern}
+     * component as a subactivity
+     */
+    private void runKeyguardConfirmation() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.ConfirmLockPattern");
+        // supply header and footer text in the intent
+        intent.putExtra(ConfirmLockPattern.HEADER_TEXT,
+                getText(R.string.master_clear_gesture_prompt));
+        intent.putExtra(ConfirmLockPattern.FOOTER_TEXT,
+                getText(R.string.master_clear_gesture_explanation));
+        startActivityForResult(intent, KEYGUARD_REQUEST);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode != KEYGUARD_REQUEST) {
+            return;
+        }
+
+        // If the user entered a valid keyguard trace, present the final
+        // confirmation prompt; otherwise, go back to the initial state.
+        if (resultCode == Activity.RESULT_OK) {
+            establishFinalConfirmationState();
+        } else {
+            establishInitialState();
+        }
+    }
+
+    /**
+     * If the user clicks to begin the reset sequence, we next require a
+     * keyguard confirmation if the user has currently enabled one.  If there
+     * is no keyguard available, we simply go to the final confirmation prompt.
+     */
+    private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
+            public void onClick(View v) {
+                if (mLockUtils.isLockPatternEnabled()) {
+                    runKeyguardConfirmation();
+                } else {
+                    establishFinalConfirmationState();
+                }
+            }
+        };
+
+    /**
+     * Configure the UI for the final confirmation interaction
+     */
+    private void establishFinalConfirmationState() {
+        if (mFinalView == null) {
+            mFinalView = mInflater.inflate(R.layout.master_clear_final, null);
+            mFinalButton =
+                    (Button) mFinalView.findViewById(R.id.execute_master_clear);
+            mFinalButton.setOnClickListener(mFinalClickListener);
+        }
+
+        setContentView(mFinalView);
+    }
+
+    /**
+     * In its initial state, the activity presents a button for the user to
+     * click in order to initiate a confirmation sequence.  This method is
+     * called from various other points in the code to reset the activity to
+     * this base state.
+     * 
+     * <p>Reinflating views from resources is expensive and prevents us from
+     * caching widget pointers, so we use a single-inflate pattern:  we lazy-
+     * inflate each view, caching all of the widget pointers we'll need at the
+     * time, then simply reuse the inflated views directly whenever we need
+     * to change contents.
+     */
+    private void establishInitialState() {
+        if (mInitialView == null) {
+            mInitialView = mInflater.inflate(R.layout.master_clear_primary, null);
+            mInitiateButton =
+                    (Button) mInitialView.findViewById(R.id.initiate_master_clear);
+            mInitiateButton.setOnClickListener(mInitiateListener);
+        }
+
+        setContentView(mInitialView);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+
+        mInitialView = null;
+        mFinalView = null;
+        mInflater = LayoutInflater.from(this);
+        mLockUtils = new LockPatternUtils(getContentResolver());
+
+        establishInitialState();
+    }
+
+    /** Abandon all progress through the confirmation sequence by returning
+     * to the initial view any time the activity is interrupted (e.g. by
+     * idle timeout).
+     */
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        establishInitialState();
+    }
+
+}
diff --git a/src/com/android/settings/ProgressCategory.java b/src/com/android/settings/ProgressCategory.java
new file mode 100644
index 0000000..15810b3
--- /dev/null
+++ b/src/com/android/settings/ProgressCategory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.preference.PreferenceCategory;
+import android.util.AttributeSet;
+import android.view.View;
+
+import java.util.Map;
+
+public class ProgressCategory extends PreferenceCategory {
+
+    private boolean mProgress = false;
+    
+    public ProgressCategory(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutResource(R.layout.preference_progress_category);
+    }
+    
+    @Override
+    public void onBindView(View view) {
+        super.onBindView(view);
+        View textView = view.findViewById(R.id.scanning_text);
+        View progressBar = view.findViewById(R.id.scanning_progress);
+
+        int visibility = mProgress ? View.VISIBLE : View.INVISIBLE;
+        textView.setVisibility(visibility);
+        progressBar.setVisibility(visibility);
+    }
+    
+    /**
+     * Turn on/off the progress indicator and text on the right.
+     * @param progressOn whether or not the progress should be displayed 
+     */
+    public void setProgress(boolean progressOn) {
+        mProgress = progressOn;
+        notifyChanged();
+    }
+}
+
diff --git a/src/com/android/settings/ProxySelector.java b/src/com/android/settings/ProxySelector.java
new file mode 100644
index 0000000..d320e73
--- /dev/null
+++ b/src/com/android/settings/ProxySelector.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.net.Proxy;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * To start the Proxy Selector activity, create the following intent.
+ *
+ * <code>
+ *      Intent intent = new Intent();
+ *      intent.setClassName("com.android.browser.ProxySelector");
+ *      startActivity(intent);
+ * </code>
+ *
+ * you can add extra options to the intent by using
+ *
+ * <code>
+ *   intent.putExtra(key, value);
+ * </code>
+ *
+ * the extra options are:
+ *
+ * button-label: a string label to display for the okay button
+ * title:        the title of the window
+ * error-text:   If not null, will be used as the label of the error message.
+ */
+public class ProxySelector extends Activity
+{
+    private final static String LOGTAG = "Settings";
+
+    EditText    mHostnameField;
+    EditText    mPortField;
+    Button      mOKButton;
+
+    // Matches blank input, ips, and domain names
+    private static final String HOSTNAME_REGEXP = "^$|^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*$";
+    private static final Pattern HOSTNAME_PATTERN;
+    static {
+        HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
+    }
+
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        if (android.util.Config.LOGV) Log.v(LOGTAG, "[ProxySelector] onStart");
+
+        setContentView(R.layout.proxy);
+        initView();
+        populateFields(false);
+    }
+
+    protected void showError(int error) {
+
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.proxy_error)
+                .setMessage(error)
+                .setPositiveButton(R.string.proxy_error_dismiss, null)
+                .show();
+    }
+
+    void initView() {
+
+        mHostnameField = (EditText)findViewById(R.id.hostname);
+        mHostnameField.setOnFocusChangeListener(mOnFocusChangeHandler);
+
+        mPortField = (EditText)findViewById(R.id.port);
+        mPortField.setOnClickListener(mOKHandler);
+        mPortField.setOnFocusChangeListener(mOnFocusChangeHandler);
+
+        mOKButton = (Button)findViewById(R.id.action);
+        mOKButton.setOnClickListener(mOKHandler);
+
+        Button b = (Button)findViewById(R.id.clear);
+        b.setOnClickListener(mClearHandler);
+
+        b = (Button)findViewById(R.id.defaultView);
+        b.setOnClickListener(mDefaultHandler);
+    }
+
+    void populateFields(boolean useDefault) {
+        String hostname = null;
+        int port = -1;
+        if (useDefault) {
+            // Use the default proxy settings provided by the carrier
+            hostname = Proxy.getDefaultHost();
+            port = Proxy.getDefaultPort();
+        } else {
+            // Use the last setting given by the user
+            hostname = Proxy.getHost(this);
+            port = Proxy.getPort(this);
+        }
+
+        if (hostname == null) {
+            hostname = "";
+        }
+
+        mHostnameField.setText(hostname);
+
+        String portStr = port == -1 ? "" : Integer.toString(port);
+        mPortField.setText(portStr);
+
+        Intent intent = getIntent();
+
+        String buttonLabel = intent.getStringExtra("button-label");
+        if (!TextUtils.isEmpty(buttonLabel)) {
+            mOKButton.setText(buttonLabel);
+        }
+
+        String title = intent.getStringExtra("title");
+        if (!TextUtils.isEmpty(title)) {
+            setTitle(title);
+        }
+    }
+
+    /**
+     * validate syntax of hostname and port entries
+     * @return 0 on success, string resource ID on failure
+     */
+    int validate(String hostname, String port) {
+        Matcher match = HOSTNAME_PATTERN.matcher(hostname);
+
+        if (!match.matches()) return R.string.proxy_error_invalid_host;
+
+        if (hostname.length() > 0 && port.length() == 0) {
+            return R.string.proxy_error_empty_port;
+        }
+
+        if (port.length() > 0) {
+            if (hostname.length() == 0) {
+                return R.string.proxy_error_empty_host_set_port;
+            }
+            int portVal = -1;
+            try {
+                portVal = Integer.parseInt(port);
+            } catch (NumberFormatException ex) {
+                return R.string.proxy_error_invalid_port;
+            }
+            if (portVal <= 0 || portVal > 0xFFFF) {
+                return R.string.proxy_error_invalid_port;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * returns true on success, false if the user must correct something
+     */
+    boolean saveToDb() {
+
+        String hostname = mHostnameField.getText().toString().trim();
+        String portStr = mPortField.getText().toString().trim();
+        int port = -1;
+
+        int result = validate(hostname, portStr);
+        if (result > 0) {
+            showError(result);
+            return false;
+        }
+
+        if (portStr.length() > 0) {
+            try {
+                port = Integer.parseInt(portStr);
+            } catch (NumberFormatException ex) {
+                return false;
+            }
+        }
+
+        // FIXME: The best solution would be to make a better UI that would
+        // disable editing of the text boxes if the user chooses to use the
+        // default settings. i.e. checking a box to always use the default
+        // carrier. http:/b/issue?id=756480
+        // FIXME: This currently will not work if the default host is blank and
+        // the user has cleared the input boxes in order to not use a proxy.
+        // This is a UI problem and can be solved with some better form
+        // controls.
+        // FIXME: If the user types in a proxy that matches the default, should
+        // we keep that setting? Can be fixed with a new UI.
+        ContentResolver res = getContentResolver();
+        if (hostname.equals(Proxy.getDefaultHost())
+                && port == Proxy.getDefaultPort()) {
+            // If the user hit the default button and didn't change any of
+            // the input boxes, treat it as if the user has not specified a
+            // proxy.
+            hostname = null;
+        }
+
+        if (!TextUtils.isEmpty(hostname)) {
+            hostname += ':' + portStr;
+        }
+        Settings.System.putString(res, Settings.System.HTTP_PROXY, hostname);
+        sendBroadcast(new Intent(Proxy.PROXY_CHANGE_ACTION));
+
+        return true;
+    }
+
+    OnClickListener mOKHandler = new OnClickListener() {
+            public void onClick(View v) {
+                if (saveToDb()) {
+                    finish();
+                }
+            }
+        };
+
+    OnClickListener mClearHandler = new OnClickListener() {
+            public void onClick(View v) {
+                mHostnameField.setText("");
+                mPortField.setText("");
+            }
+        };
+
+    OnClickListener mDefaultHandler = new OnClickListener() {
+            public void onClick(View v) {
+                populateFields(true);
+            }
+        };
+
+    OnFocusChangeListener mOnFocusChangeHandler = new OnFocusChangeListener() {
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (hasFocus) {
+                    TextView textView = (TextView) v;
+                    Selection.selectAll((Spannable) textView.getText());
+                }
+            }
+        };
+}
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
new file mode 100644
index 0000000..ad30de7
--- /dev/null
+++ b/src/com/android/settings/RadioInfo.java
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.INetStatService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.pim.DateUtils;
+import android.preference.PreferenceManager;
+import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.gsm.GsmCellLocation;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.EditText;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneStateIntentReceiver;
+import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.gsm.PdpConnection;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.List;
+
+public class RadioInfo extends Activity {
+    private final String TAG = "phone";
+    
+    private static final int EVENT_PHONE_STATE_CHANGED = 100;
+    private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
+    private static final int EVENT_SERVICE_STATE_CHANGED = 300;
+    private static final int EVENT_CFI_CHANGED = 302;
+
+    private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
+    private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
+    private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
+    private static final int EVENT_SET_QXDMLOG_DONE = 1003;
+    private static final int EVENT_SET_CIPHER_DONE = 1004;
+    private static final int EVENT_QUERY_SMSC_DONE = 1005;
+    private static final int EVENT_UPDATE_SMSC_DONE = 1006;
+
+    private static final int MENU_ITEM_SELECT_BAND  = 0;
+    private static final int MENU_ITEM_VIEW_ADN     = 1;
+    private static final int MENU_ITEM_VIEW_FDN     = 2;
+    private static final int MENU_ITEM_VIEW_SDN     = 3;
+    private static final int MENU_ITEM_GET_PDP_LIST = 4;
+    private static final int MENU_ITEM_TOGGLE_DATA  = 5;
+    private static final int MENU_ITEM_TOGGLE_DATA_ON_BOOT = 6;
+
+    private TextView mImei;
+    private TextView mImsi;
+    private TextView number;
+    private TextView callState;
+    private TextView operatorName;
+    private TextView roamingState;
+    private TextView gsmState;
+    private TextView gprsState;
+    private TextView network;
+    private TextView dBm;
+    private TextView mMwi;
+    private TextView mCfi;
+    private TextView mLocation;
+    private TextView mNeighboringCids;
+    private TextView resets;
+    private TextView attempts;
+    private TextView successes;
+    private TextView disconnects;
+    private TextView sentSinceReceived;
+    private TextView sent;
+    private TextView received;
+    private TextView mPingIpAddr;
+    private TextView mPingHostname;
+    private TextView mHttpClientTest;
+    private TextView cipherState;
+    private EditText smsc;
+    private Button radioPowerButton;
+    private Button qxdmLogButton;
+    private Button cipherToggleButton;
+    private Button pingTestButton;
+    private Button updateSmscButton;
+    private Button refreshSmscButton;
+    private Spinner preferredNetworkType;
+
+    private TelephonyManager mTelephonyManager;
+    private Phone phone = null;
+    private PhoneStateIntentReceiver mPhoneStateReceiver;
+    private INetStatService netstat;
+
+    private OemCommands mOem = null;
+    private boolean mQxdmLogEnabled;
+    // The requested cipher state
+    private boolean mCipherOn;
+
+    private String mPingIpAddrResult;
+    private String mPingHostnameResult;
+    private String mHttpClientTestResult;
+    private boolean mMwiValue = false;
+    private boolean mCfiValue = false;
+
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onDataConnectionStateChanged(int state) {
+            updateDataState();
+            updateDataStats();
+            updatePdpList();
+            updateNetworkType();
+        }
+
+        @Override
+        public void onDataActivity(int direction) {
+            updateDataStats2();
+        }
+
+        @Override
+        public void onCellLocationChanged(CellLocation location) {
+            updateLocation(location);
+        }
+
+        @Override
+        public void onMessageWaitingIndicatorChanged(boolean mwi) {
+            mMwiValue = mwi;
+            updateMessageWaiting();
+        }
+
+        @Override
+        public void onCallForwardingIndicatorChanged(boolean cfi) {
+            mCfiValue = cfi;
+            updateCallRedirect();
+        }
+    };
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_PHONE_STATE_CHANGED:
+                    updatePhoneState();
+                    break;
+
+                case EVENT_SIGNAL_STRENGTH_CHANGED:
+                    updateSignalStrength();
+                    break;
+
+                case EVENT_SERVICE_STATE_CHANGED:
+                    updateServiceState();
+                    updatePowerState();
+                    break;
+
+                case EVENT_QUERY_PREFERRED_TYPE_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception == null) {
+                        int type = ((int[])ar.result)[0];
+                        preferredNetworkType.setSelection(type, true);
+                    } else {
+                        preferredNetworkType.setSelection(3, true);
+                    }
+                    break;
+                case EVENT_SET_PREFERRED_TYPE_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        phone.getPreferredNetworkType(
+                                obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
+                    }
+                    break;
+                case EVENT_QUERY_NEIGHBORING_CIDS_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception == null) {
+                        updateNeighboringCids((String[])ar.result);
+                    } else {
+                        mNeighboringCids.setText("unknown");
+                    }
+                    break;
+                case EVENT_SET_QXDMLOG_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception == null) {
+                        mQxdmLogEnabled = !mQxdmLogEnabled;
+                        
+                        updateQxdmState(mQxdmLogEnabled);
+                        displayQxdmEnableResult();
+                    }
+                    break;
+                case EVENT_SET_CIPHER_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception == null) {
+                        setCiphPref(mCipherOn);
+                    }
+                    updateCiphState();
+                    break;
+                case EVENT_QUERY_SMSC_DONE:
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        smsc.setText("refresh error");
+                    } else {
+                        byte[] buf = (byte[]) ar.result;
+                        smsc.setText(new String(buf));
+                    }
+                    break;
+                case EVENT_UPDATE_SMSC_DONE:
+                    updateSmscButton.setEnabled(true);
+                    ar= (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        smsc.setText("update error");
+                    }
+                    break;
+                default:
+                    break;
+
+            }
+        }
+    };
+
+    private class OemCommands {
+
+        public  final int OEM_QXDM_SDLOG_DEFAULT_FILE_SIZE = 32;
+        public  final int OEM_QXDM_SDLOG_DEFAULT_MASK = 0;
+        public  final int OEM_QXDM_SDLOG_DEFAULT_MAX_INDEX = 8;
+
+        final int SIZE_OF_INT = 4;
+        final int OEM_FEATURE_ENABLE = 1;
+        final int OEM_FEATURE_DISABLE = 0;
+        final int OEM_SIMPE_FEAUTURE_LEN = 1;
+
+        final int OEM_QXDM_SDLOG_FUNCTAG = 0x00010000;
+        final int OEM_QXDM_SDLOG_LEN = 4;
+        final int OEM_PS_AUTO_ATTACH_FUNCTAG = 0x00020000;
+        final int OEM_CIPHERING_FUNCTAG = 0x00020001;
+        final int OEM_SMSC_UPDATE_FUNCTAG = 0x00020002;
+        final int OEM_SMSC_QUERY_FUNCTAG = 0x00020003;
+        final int OEM_SMSC_QUERY_LEN = 0;
+        
+        /**
+         * The OEM interface to store QXDM to SD.
+         *
+         * To start/stop logging QXDM logs to SD card, use tag
+         * OEM_RIL_HOOK_QXDM_SD_LOG_SETUP 0x00010000
+         *
+         * "data" is a const oem_ril_hook_qxdm_sdlog_setup_data_st *
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.func_tag
+         * should be OEM_RIL_HOOK_QXDM_SD_LOG_SETUP
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.len
+         * should be "sizeof(unsigned int) * 4"
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->mode
+         * could be 0 for 'stop logging', or 1 for 'start logging'
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_file_size
+         * will assign the size of each log file, and it could be a value between
+         * 1 and 512 (in megabytes, default value is recommended to set as 32).
+         * This value will be ignored when mode == 0.
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_mask will
+         * assign the rule to filter logs, and it is a bitmask (bit0 is for MsgAll,
+         * bit1 is for LogAll, and bit2 is for EventAll) recommended to be set as 0
+         * by default. This value will be ignored when mode == 0.
+         * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_max_fileindex
+         * set the how many logfiles will storted before roll over. This value will
+         * be ignored when mode == 0.
+         *
+         * "response" is NULL
+         *
+         * typedef struct _oem_ril_hook_raw_head_st {
+         *      unsigned int func_tag;
+         *      unsigned int len;
+         * } oem_ril_hook_raw_head_st;
+         *
+         * typedef struct _oem_ril_hook_qxdm_sdlog_setup_data_st {
+         *      oem_ril_hook_raw_head_st head;
+         *      unsigned int mode;
+         *      unsigned int log_file_size;
+         *      unsigned int log_mask;
+         *      unsigned int log_max_fileindex;
+         * } oem_ril_hook_qxdm_sdlog_setup_data_st;
+         *
+         * @param enable set true to start logging QXDM in SD card
+         * @param fileSize is the log file size in MB
+         * @param mask is the log mask to filter
+         * @param maxIndex is the maximum roll-over file number
+         * @return byteArray to use in RIL RAW command
+         */
+        byte[] getQxdmSdlogData(boolean enable, int fileSize, int mask, int maxIndex) {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(bos);
+            try {
+                writeIntLittleEndian(dos, OEM_QXDM_SDLOG_FUNCTAG);
+                writeIntLittleEndian(dos, OEM_QXDM_SDLOG_LEN * SIZE_OF_INT);
+                writeIntLittleEndian(dos, enable ?
+                        OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
+                writeIntLittleEndian(dos, fileSize);
+                writeIntLittleEndian(dos, mask);
+                writeIntLittleEndian(dos, maxIndex);
+            } catch (IOException e) {
+                return null;
+            }
+            return bos.toByteArray();
+        }
+
+        byte[] getSmscQueryData() {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(bos);
+            try {
+                writeIntLittleEndian(dos, OEM_SMSC_QUERY_FUNCTAG);
+                writeIntLittleEndian(dos, OEM_SMSC_QUERY_LEN * SIZE_OF_INT);
+            } catch (IOException e) {
+                return null;
+            }
+            return bos.toByteArray();
+        }
+
+        byte[] getSmscUpdateData(String smsc) {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(bos);
+            try {
+                byte[] smsc_bytes = smsc.getBytes();
+                writeIntLittleEndian(dos, OEM_SMSC_UPDATE_FUNCTAG);
+                writeIntLittleEndian(dos, smsc_bytes.length);
+                dos.write(smsc_bytes);
+            } catch (IOException e) {
+                return null;
+            }
+            return bos.toByteArray();
+        }
+
+        byte[] getPsAutoAttachData(boolean enable) {
+            return getSimpleFeatureData(OEM_PS_AUTO_ATTACH_FUNCTAG, enable);
+        }
+
+        byte[] getCipheringData(boolean enable) {
+            return getSimpleFeatureData(OEM_CIPHERING_FUNCTAG, enable);
+        }
+        
+        private byte[] getSimpleFeatureData(int tag, boolean enable) {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(bos);
+            try {
+                writeIntLittleEndian(dos, tag);
+                writeIntLittleEndian(dos, OEM_SIMPE_FEAUTURE_LEN * SIZE_OF_INT);
+                writeIntLittleEndian(dos, enable ?
+                        OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
+            } catch (IOException e) {
+                return null;
+            }
+            return bos.toByteArray();
+        }
+
+        private void writeIntLittleEndian(DataOutputStream dos, int val)
+                throws IOException {
+            dos.writeByte(val);
+            dos.writeByte(val >> 8);
+            dos.writeByte(val >> 16);
+            dos.writeByte(val >> 24);
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.radio_info);
+
+        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
+        phone = PhoneFactory.getDefaultPhone();
+
+        mImei = (TextView) findViewById(R.id.imei);
+        mImsi = (TextView) findViewById(R.id.imsi);
+        number = (TextView) findViewById(R.id.number);
+        callState = (TextView) findViewById(R.id.call);
+        operatorName = (TextView) findViewById(R.id.operator);
+        roamingState = (TextView) findViewById(R.id.roaming);
+        gsmState = (TextView) findViewById(R.id.gsm);
+        gprsState = (TextView) findViewById(R.id.gprs);
+        network = (TextView) findViewById(R.id.network);
+        dBm = (TextView) findViewById(R.id.dbm);
+        mMwi = (TextView) findViewById(R.id.mwi);
+        mCfi = (TextView) findViewById(R.id.cfi);
+        mLocation = (TextView) findViewById(R.id.location);
+        mNeighboringCids = (TextView) findViewById(R.id.neighboring);
+
+        resets = (TextView) findViewById(R.id.resets);
+        attempts = (TextView) findViewById(R.id.attempts);
+        successes = (TextView) findViewById(R.id.successes);
+        disconnects = (TextView) findViewById(R.id.disconnects);
+        sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
+        sent = (TextView) findViewById(R.id.sent);
+        received = (TextView) findViewById(R.id.received);
+        cipherState = (TextView) findViewById(R.id.ciphState);
+        smsc = (EditText) findViewById(R.id.smsc);
+
+        mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr);
+        mPingHostname = (TextView) findViewById(R.id.pingHostname);
+        mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
+
+        preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
+                android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);        
+        preferredNetworkType.setAdapter(adapter);
+        preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
+
+        radioPowerButton = (Button) findViewById(R.id.radio_power);
+        radioPowerButton.setOnClickListener(mPowerButtonHandler);
+
+        qxdmLogButton = (Button) findViewById(R.id.qxdm_log);
+        qxdmLogButton.setOnClickListener(mQxdmButtonHandler);
+
+        cipherToggleButton = (Button) findViewById(R.id.ciph_toggle);
+        cipherToggleButton.setOnClickListener(mCipherButtonHandler);
+        pingTestButton = (Button) findViewById(R.id.ping_test);
+        pingTestButton.setOnClickListener(mPingButtonHandler);
+        updateSmscButton = (Button) findViewById(R.id.update_smsc);
+        updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
+        refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
+        refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
+        
+        mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
+        mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
+        mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
+        mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED);
+                         
+        updateQxdmState(null);
+        mOem = new OemCommands();
+
+        phone.getPreferredNetworkType(
+                mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
+        phone.getNeighboringCids(
+                mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
+
+        netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
+
+        CellLocation.requestLocationUpdate();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        updatePhoneState();
+        updateSignalStrength();
+        updateMessageWaiting();
+        updateCallRedirect();
+        updateServiceState();
+        updateLocation(mTelephonyManager.getCellLocation());
+        updateDataState();
+        updateDataStats();
+        updateDataStats2();
+        updatePowerState();
+        updateQxdmState(null);
+        updateProperties();
+        updateCiphState();
+
+        Log.i(TAG, "[RadioInfo] onResume: register phone & data intents");
+
+        mPhoneStateReceiver.registerIntent();
+        mTelephonyManager.listen(mPhoneStateListener,
+                  PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+                | PhoneStateListener.LISTEN_DATA_ACTIVITY
+                | PhoneStateListener.LISTEN_CELL_LOCATION
+                | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+                | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        Log.i(TAG, "[RadioInfo] onPause: unregister phone & data intents");
+
+        mPhoneStateReceiver.unregisterIntent();
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label).setOnMenuItemClickListener(mSelectBandCallback)
+                .setAlphabeticShortcut('b');
+        menu.add(1, MENU_ITEM_VIEW_ADN, 0,
+                R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
+        menu.add(1, MENU_ITEM_VIEW_FDN, 0,
+                R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
+        menu.add(1, MENU_ITEM_VIEW_SDN, 0,
+                R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
+        menu.add(1, MENU_ITEM_GET_PDP_LIST,
+                0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
+        menu.add(1, MENU_ITEM_TOGGLE_DATA,
+                0, R.string.radioInfo_menu_disableData).setOnMenuItemClickListener(mToggleData);
+        menu.add(1, MENU_ITEM_TOGGLE_DATA_ON_BOOT,
+                0, R.string.radioInfo_menu_disableDataOnBoot).setOnMenuItemClickListener(mToggleDataOnBoot);
+        return true;
+    }
+
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu)
+    {
+        // Get the TOGGLE DATA menu item in the right state.
+        MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
+        int state = mTelephonyManager.getDataState();
+        boolean visible = true;
+
+        switch (state) {
+            case TelephonyManager.DATA_CONNECTED:
+            case TelephonyManager.DATA_SUSPENDED:
+                item.setTitle(R.string.radioInfo_menu_disableData);
+                break;
+            case TelephonyManager.DATA_DISCONNECTED:
+                item.setTitle(R.string.radioInfo_menu_enableData);
+                break;
+            default:
+                visible = false;
+                break;
+        }
+        item.setVisible(visible);
+
+        // Get the toggle-data-on-boot menu item in the right state.
+        item = menu.findItem(MENU_ITEM_TOGGLE_DATA_ON_BOOT);
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
+        boolean value = sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false);
+        if (value) {
+            item.setTitle(R.string.radioInfo_menu_enableDataOnBoot);
+        } else {
+            item.setTitle(R.string.radioInfo_menu_disableDataOnBoot);
+        }
+        return true;
+    }
+
+    private boolean isRadioOn() {
+        return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+    }
+    
+    private void updatePowerState() {
+    	//log("updatePowerState");
+        String buttonText = isRadioOn() ?
+                            getString(R.string.turn_off_radio) :
+                            getString(R.string.turn_on_radio);
+        radioPowerButton.setText(buttonText);    	
+    }
+
+    private void updateQxdmState(Boolean newQxdmStatus) {
+        SharedPreferences sp = 
+          PreferenceManager.getDefaultSharedPreferences(this.getApplication());
+        mQxdmLogEnabled = sp.getBoolean("qxdmstatus", false);
+        // This is called from onCreate, onResume, and the handler when the status
+        // is updated. 
+        if (newQxdmStatus != null) {
+            SharedPreferences.Editor editor = sp.edit();
+            editor.putBoolean("qxdmstatus", newQxdmStatus);
+            editor.commit();
+            mQxdmLogEnabled = newQxdmStatus;
+        }
+        
+        String buttonText = mQxdmLogEnabled ?
+                            getString(R.string.turn_off_qxdm) :
+                            getString(R.string.turn_on_qxdm);
+        qxdmLogButton.setText(buttonText);
+    }
+
+    private void setCiphPref(boolean value) {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putBoolean(GSMPhone.CIPHERING_KEY, value);
+        editor.commit();
+    }
+
+    private boolean getCiphPref() {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
+        boolean ret = sp.getBoolean(GSMPhone.CIPHERING_KEY, true);
+        return ret;
+    }
+
+    private void updateCiphState() {
+        cipherState.setText(getCiphPref() ? "Ciphering ON" : "Ciphering OFF");
+    }
+
+    private final void
+    updateSignalStrength() {
+        int state =
+                mPhoneStateReceiver.getServiceState().getState();
+        Resources r = getResources();
+
+        if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
+                (ServiceState.STATE_POWER_OFF == state)) {
+            dBm.setText("0");
+        }
+        
+        int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
+        
+        if (-1 == signalDbm) signalDbm = 0;
+
+        int signalAsu = mPhoneStateReceiver.getSignalStrength();
+
+        if (-1 == signalAsu) signalAsu = 0;
+
+        dBm.setText(String.valueOf(signalDbm) + " "
+            + r.getString(R.string.radioInfo_display_dbm) + "   "
+            + String.valueOf(signalAsu) + " "
+            + r.getString(R.string.radioInfo_display_asu));
+    }
+
+    private final void updateLocation(CellLocation location) {
+        GsmCellLocation loc = (GsmCellLocation)location;
+        Resources r = getResources();
+
+        int lac = loc.getLac();
+        int cid = loc.getCid();
+
+        mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
+                          + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
+                          + "   "
+                          + r.getString(R.string.radioInfo_cid) + " = "
+                + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
+    }
+
+    private final void updateNeighboringCids(String[] cids) {
+        if (cids != null && cids.length > 0 && cids[0] != null) {
+            int size = Integer.parseInt(cids[0]);
+            String neiborings;
+            if (size > 0) {
+                neiborings = "{";
+                for (int i=1; i<=size; i++) {
+                    neiborings += cids[i] + ", ";
+                }
+                neiborings += "}";
+            } else {
+                neiborings = "none";
+            }
+            mNeighboringCids.setText(neiborings);
+        } else {
+            mNeighboringCids.setText("unknown");
+        }
+    }
+
+    private final void
+    updateMessageWaiting() {
+        mMwi.setText(String.valueOf(mMwiValue));
+    }
+
+    private final void
+    updateCallRedirect() {
+        mCfi.setText(String.valueOf(mCfiValue));
+    }
+
+
+    private final void
+    updateServiceState() {
+        ServiceState serviceState = mPhoneStateReceiver.getServiceState();
+        int state = serviceState.getState();
+        Resources r = getResources();
+        String display = r.getString(R.string.radioInfo_unknown);
+        
+        switch (state) {
+            case ServiceState.STATE_IN_SERVICE:
+                display = r.getString(R.string.radioInfo_service_in);
+                break;
+            case ServiceState.STATE_OUT_OF_SERVICE:
+            case ServiceState.STATE_EMERGENCY_ONLY:
+                display = r.getString(R.string.radioInfo_service_emergency);
+                break;
+            case ServiceState.STATE_POWER_OFF:
+                display = r.getString(R.string.radioInfo_service_off);
+                break;
+        }
+        
+        gsmState.setText(display);
+        
+        if (serviceState.getRoaming()) {
+            roamingState.setText(R.string.radioInfo_roaming_in);
+        } else {
+            roamingState.setText(R.string.radioInfo_roaming_not);
+        }
+
+        operatorName.setText(serviceState.getOperatorAlphaLong());
+    }
+
+    private final void
+    updatePhoneState() {
+        Phone.State state = mPhoneStateReceiver.getPhoneState();
+        Resources r = getResources();
+        String display = r.getString(R.string.radioInfo_unknown);
+
+        switch (state) {
+            case IDLE:
+                display = r.getString(R.string.radioInfo_phone_idle);
+                break;
+            case RINGING:
+                display = r.getString(R.string.radioInfo_phone_ringing);
+                break;
+            case OFFHOOK:
+                display = r.getString(R.string.radioInfo_phone_offhook);
+                break;
+        }
+
+        callState.setText(display);
+    }
+
+    private final void
+    updateDataState() {
+        int state = mTelephonyManager.getDataState();
+        Resources r = getResources();
+        String display = r.getString(R.string.radioInfo_unknown);
+
+        switch (state) {
+            case TelephonyManager.DATA_CONNECTED:
+                display = r.getString(R.string.radioInfo_data_connected);
+                break;
+            case TelephonyManager.DATA_CONNECTING:
+                display = r.getString(R.string.radioInfo_data_connecting);
+                break;
+            case TelephonyManager.DATA_DISCONNECTED:
+                display = r.getString(R.string.radioInfo_data_disconnected);
+                break;
+            case TelephonyManager.DATA_SUSPENDED:
+                display = r.getString(R.string.radioInfo_data_suspended);
+                break;
+        }
+        
+        gprsState.setText(display);
+    }
+
+    private final void updateNetworkType() {
+        Resources r = getResources();
+        String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
+                r.getString(R.string.radioInfo_unknown));
+
+        network.setText(display);
+    }
+
+    private final void
+    updateProperties() {
+        String s;
+        Resources r = getResources();
+
+        s = phone.getDeviceId();
+        if (s == null) s = r.getString(R.string.radioInfo_unknown); 
+        mImei.setText(s);
+        
+        s = phone.getSubscriberId();
+        if (s == null) s = r.getString(R.string.radioInfo_unknown); 
+        mImsi.setText(s);
+
+        s = phone.getLine1Number();
+        if (s == null) s = r.getString(R.string.radioInfo_unknown); 
+        number.setText(s);
+    }
+
+    private final void updateDataStats() {
+        String s;
+
+        s = SystemProperties.get("net.gsm.radio-reset", "0");
+        resets.setText(s);
+
+        s = SystemProperties.get("net.gsm.attempt-gprs", "0");
+        attempts.setText(s);
+
+        s = SystemProperties.get("net.gsm.succeed-gprs", "0");
+        successes.setText(s);
+
+        //s = SystemProperties.get("net.gsm.disconnect", "0");
+        //disconnects.setText(s);
+
+        s = SystemProperties.get("net.ppp.reset-by-timeout", "0");
+        sentSinceReceived.setText(s);
+    }
+
+    private final void updateDataStats2() {
+        Resources r = getResources();
+
+        try {
+            int txPackets = netstat.getTxPackets();
+            int rxPackets = netstat.getRxPackets();
+            int txBytes   = netstat.getTxBytes();
+            int rxBytes   = netstat.getRxBytes();
+    
+            String packets = r.getString(R.string.radioInfo_display_packets);
+            String bytes   = r.getString(R.string.radioInfo_display_bytes);
+    
+            sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
+            received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Ping a IP address.
+     */
+    private final void pingIpAddr() {
+        try {
+            // This is hardcoded IP addr. This is for testing purposes.
+            // We would need to get rid of this before release.
+            String ipAddress = "74.125.47.104";
+            Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress);
+            int status = p.waitFor();
+            if (status == 0) {
+                mPingIpAddrResult = "Pass";
+            } else {
+                mPingIpAddrResult = "Fail: IP addr not reachable";
+            }
+        } catch (IOException e) {
+            mPingIpAddrResult = "Fail: IOException";
+        } catch (InterruptedException e) {
+            mPingIpAddrResult = "Fail: InterruptedException";
+        }
+    }
+
+    /**
+     *  Ping a host name
+     */
+    private final void pingHostname() {
+        try {
+            Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com"); 
+            int status = p.waitFor();
+            if (status == 0) {
+                mPingHostnameResult = "Pass";
+            } else {
+                mPingHostnameResult = "Fail: Host unreachable";
+            }
+        } catch (UnknownHostException e) {
+            mPingHostnameResult = "Fail: Unknown Host";
+        } catch (IOException e) {
+            mPingHostnameResult= "Fail: IOException";
+        } catch (InterruptedException e) {
+            mPingHostnameResult = "Fail: InterruptedException";
+        }
+    }
+
+    /**
+     * This function checks for basic functionality of HTTP Client.
+     */
+    private void httpClientTest() {
+        HttpClient client = new DefaultHttpClient();
+        try {
+            HttpGet request = new HttpGet("http://www.google.com");
+            HttpResponse response = client.execute(request);
+            if (response.getStatusLine().getStatusCode() == 200) {
+                mHttpClientTestResult = "Pass";
+            } else {
+                mHttpClientTestResult = "Fail: Code: " + String.valueOf(response);
+            }
+            request.abort();
+        } catch (IOException e) {
+            mHttpClientTestResult = "Fail: IOException";
+        }
+    }
+
+    private void refreshSmsc() {
+        byte[] data = mOem.getSmscQueryData();
+        if (data == null) return;
+        phone.invokeOemRilRequestRaw(data,
+                mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
+    }
+
+    private final void updatePingState() {
+        final Handler handler = new Handler();
+        // Set all to unknown since the threads will take a few secs to update.
+        mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown);
+        mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown);
+        mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
+
+        mPingIpAddr.setText(mPingIpAddrResult);
+        mPingHostname.setText(mPingHostnameResult);
+        mHttpClientTest.setText(mHttpClientTestResult);
+
+        final Runnable updatePingResults = new Runnable() {
+            public void run() {
+                mPingIpAddr.setText(mPingIpAddrResult);
+                mPingHostname.setText(mPingHostnameResult);
+                mHttpClientTest.setText(mHttpClientTestResult);
+            }
+        };
+        Thread ipAddr = new Thread() {
+            @Override
+            public void run() {
+                pingIpAddr();
+                handler.post(updatePingResults);
+            }
+        };
+        ipAddr.start();
+
+        Thread hostname = new Thread() {
+            @Override
+            public void run() {
+                pingHostname();
+                handler.post(updatePingResults);
+            }
+        };
+        hostname.start();
+
+        Thread httpClient = new Thread() {
+            @Override
+            public void run() {
+                httpClientTest();
+                handler.post(updatePingResults);
+            }
+        };
+        httpClient.start();
+    }
+
+    private final void updatePdpList() {
+        StringBuilder sb = new StringBuilder("========DATA=======\n");
+
+        List<PdpConnection> pdps = phone.getCurrentPdpList();
+
+        for (PdpConnection pdp : pdps) {
+            sb.append("    State: ").append(pdp.getState().toString()).append("\n");
+            if (pdp.getState().isActive()) {
+                long timeElapsed =
+                    (System.currentTimeMillis() - pdp.getConnectionTime())/1000;
+                sb.append("    connected at ")
+                  .append(DateUtils.timeString(pdp.getConnectionTime()))
+                  .append(" and elapsed ")
+                  .append(DateUtils.formatElapsedTime(timeElapsed))
+                  .append("\n    to ")
+                  .append(pdp.getApn().toString())
+                  .append("\ninterface: ")
+                  .append(phone.getInterfaceName(phone.getActiveApn()))
+                  .append("\naddress: ")
+                  .append(phone.getIpAddress(phone.getActiveApn()))
+                  .append("\ngateway: ")
+                  .append(phone.getGateway(phone.getActiveApn()));
+                String[] dns = phone.getDnsServers(phone.getActiveApn()); 
+                sb.append("\ndns: ").append(dns[0]).append(", ").append(dns[1]);
+            } else if (pdp.getState().isInactive()) {
+                sb.append("    disconnected with last try at ")
+                  .append(DateUtils.timeString(pdp.getLastFailTime()))
+                  .append("\n    fail because ")
+                  .append(pdp.getLastFailCause().toString());
+            } else {
+                sb.append("    is connecting to ")
+                  .append(pdp.getApn().toString());
+            }
+            sb.append("\n===================");
+        }
+
+
+        disconnects.setText(sb.toString());
+    }
+
+    private void displayQxdmEnableResult() {
+        String status = mQxdmLogEnabled ? "Start QXDM Log" : "Stop QXDM Log";
+
+        DialogInterface mProgressPanel = new AlertDialog.
+                Builder(this).setMessage(status).show();
+
+        mHandler.postDelayed(
+                new Runnable() {
+                    public void run() {
+                        finish();
+                    }
+                }, 2000);
+    }
+
+    private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            // XXX We need to specify the component here because if we don't
+            // the activity manager will try to resolve the type by calling
+            // the content provider, which causes it to be loaded in a process
+            // other than the Dialer process, which causes a lot of stuff to
+            // break.
+            intent.setClassName("com.android.phone",
+                    "com.android.phone.SimContacts");
+            startActivity(intent);
+            return true;
+        }
+    };
+
+    private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            // XXX We need to specify the component here because if we don't
+            // the activity manager will try to resolve the type by calling
+            // the content provider, which causes it to be loaded in a process
+            // other than the Dialer process, which causes a lot of stuff to
+            // break.
+            intent.setClassName("com.android.phone",
+                    "com.android.phone.FdnList");
+            startActivity(intent);
+            return true;
+        }
+    };
+
+    private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            Intent intent = new Intent(
+                Intent.ACTION_VIEW, Uri.parse("content://sim/sdn"));
+            // XXX We need to specify the component here because if we don't
+            // the activity manager will try to resolve the type by calling
+            // the content provider, which causes it to be loaded in a process
+            // other than the Dialer process, which causes a lot of stuff to
+            // break.
+            intent.setClassName("com.android.phone",
+                    "com.android.phone.ADNList");
+            startActivity(intent);
+            return true;
+        }
+    };
+
+    private void toggleDataDisabledOnBoot() {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
+        SharedPreferences.Editor editor = sp.edit();
+        boolean value = sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false);
+        editor.putBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, !value);
+        byte[] data = mOem.getPsAutoAttachData(value);
+        if (data == null) {
+            // don't commit
+            return;
+        }
+
+        editor.commit();
+        phone.invokeOemRilRequestRaw(data, null);
+    }
+
+    private MenuItem.OnMenuItemClickListener mToggleDataOnBoot = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            toggleDataDisabledOnBoot();
+            return true;
+        }
+    };
+    
+    private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            int state = mTelephonyManager.getDataState();
+            switch (state) {
+                case TelephonyManager.DATA_CONNECTED:
+                    phone.disableDataConnectivity();
+                    break;
+                case TelephonyManager.DATA_DISCONNECTED:
+                    phone.enableDataConnectivity();
+                    break;
+                default:
+                    // do nothing
+                    break;
+            }
+            return true;
+        }
+    };
+
+    private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            phone.getPdpContextList(null);
+            return true;
+        }
+    };
+
+    private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
+        public boolean onMenuItemClick(MenuItem item) {
+            Intent intent = new Intent();
+            intent.setClass(RadioInfo.this, BandMode.class);
+            startActivity(intent);
+            return true;
+        }
+    };
+
+    OnClickListener mPowerButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            //log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
+            phone.setRadioPower(!isRadioOn());
+        }
+    };
+
+    OnClickListener mCipherButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            mCipherOn = !getCiphPref();
+            byte[] data = mOem.getCipheringData(mCipherOn);
+            
+            if (data == null)
+                return;
+
+            cipherState.setText("Setting...");
+            phone.invokeOemRilRequestRaw(data,
+                    mHandler.obtainMessage(EVENT_SET_CIPHER_DONE));
+        }
+    };
+    
+    OnClickListener mPingButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            updatePingState();
+        }
+    };
+
+    OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            updateSmscButton.setEnabled(false);
+            byte[] data = mOem.getSmscUpdateData(smsc.getText().toString());
+            if (data == null) return;
+            phone.invokeOemRilRequestRaw(data,
+                    mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
+        }
+    };
+
+    OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            refreshSmsc();
+        }
+    };
+
+    OnClickListener mQxdmButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            byte[] data = mOem.getQxdmSdlogData(
+                    !mQxdmLogEnabled,
+                    mOem.OEM_QXDM_SDLOG_DEFAULT_FILE_SIZE,
+                    mOem.OEM_QXDM_SDLOG_DEFAULT_MASK,
+                    mOem.OEM_QXDM_SDLOG_DEFAULT_MAX_INDEX);
+
+            if (data == null)
+                return;
+
+            phone.invokeOemRilRequestRaw(data,
+                    mHandler.obtainMessage(EVENT_SET_QXDMLOG_DONE));
+        }
+    };
+
+    AdapterView.OnItemSelectedListener
+            mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() {
+        public void onItemSelected(AdapterView parent, View v, int pos, long id) {
+            Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
+            if (pos>=0 && pos<=2) {
+                phone.setPreferredNetworkType(pos, msg);
+            }
+        }
+
+        public void onNothingSelected(AdapterView parent) {
+        }
+    };
+
+    private String[] mPreferredNetworkLabels = {
+            "WCDMA preferred", "GSM only", "WCDMA only", "Unknown"};
+}
diff --git a/src/com/android/settings/SdCardErrorReceiver.java b/src/com/android/settings/SdCardErrorReceiver.java
new file mode 100644
index 0000000..ba35a3c
--- /dev/null
+++ b/src/com/android/settings/SdCardErrorReceiver.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.util.Log;
+import android.widget.Toast;
+
+
+/**
+ * Glue class: connects AlarmAlert IntentReceiver to AlarmAlert
+ * activity.  Passes through Alarm ID.
+ */
+public class SdCardErrorReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "SdCardErrorReceiver";
+
+    @Override public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        final int duration = 3500;
+        if (action.equals(Intent.ACTION_MEDIA_BAD_REMOVAL)) {
+            Toast.makeText(context, R.string.sdcard_removal_alert_title, duration).show();
+        } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTABLE)) {
+            Toast.makeText(context, R.string.sdcard_unmountable_alert_title, duration).show();
+        } else {
+            Log.e(TAG, "unknown intent");
+        }
+    }
+}
diff --git a/src/com/android/settings/SdCardIntentReceiver.java b/src/com/android/settings/SdCardIntentReceiver.java
new file mode 100644
index 0000000..9648ec1
--- /dev/null
+++ b/src/com/android/settings/SdCardIntentReceiver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.util.Config;
+import android.util.Log;
+
+/**
+ * 
+ */
+public class SdCardIntentReceiver extends BroadcastReceiver {
+
+    private static final int SDCARD_STATUS = 1;
+    private static final String TAG = "SdCardIntentReceiver";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        NotificationManager nm = (NotificationManager) context
+                .getSystemService(Context.NOTIFICATION_SERVICE);
+        String action = intent.getAction();
+        if (Config.LOGD) Log.d(TAG, "onReceiveIntent " + action);
+
+        if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
+            nm.cancel(SDCARD_STATUS);
+
+            Intent statusIntent = new Intent(Intent.ACTION_MAIN, null);
+            statusIntent.setClass(context, SdCardSettings.class);
+            nm.notify(SDCARD_STATUS, new Notification(context,
+                    android.R.drawable.stat_notify_sdcard,
+                    null,
+                    System.currentTimeMillis(),
+                    context.getText(R.string.sdcard_setting),
+                    null,
+                    statusIntent));
+        } else if (action.equals(Intent.ACTION_MEDIA_REMOVED)) {
+            nm.cancel(SDCARD_STATUS);
+        } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) {
+            nm.cancel(SDCARD_STATUS);
+
+            Intent statusIntent = new Intent(Intent.ACTION_MAIN, null);
+            statusIntent.setClass(context, SdCardSettings.class);
+            nm.notify(SDCARD_STATUS, new Notification(context,
+                    android.R.drawable.stat_notify_sdcard_usb,
+                    null,
+                    System.currentTimeMillis(),
+                    "SD Card",
+                    null,
+                    statusIntent));
+        }
+    }
+}
diff --git a/src/com/android/settings/SdCardSettings.java b/src/com/android/settings/SdCardSettings.java
new file mode 100644
index 0000000..d10166a
--- /dev/null
+++ b/src/com/android/settings/SdCardSettings.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.Environment;
+import android.os.IMountService;
+import android.os.ServiceManager;
+import android.os.StatFs;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.TextView;
+
+import java.io.File;
+
+
+public class SdCardSettings extends Activity
+{
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.sdcard_settings_screen);
+
+        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+
+        mRemovedLayout = findViewById(R.id.removed);
+        mMountedLayout = findViewById(R.id.mounted);
+        mUnmountedLayout = findViewById(R.id.unmounted);
+        mScanningLayout = findViewById(R.id.scanning);
+        mSharedLayout = findViewById(R.id.shared);
+        mBadRemovalLayout = findViewById(R.id.bad_removal);
+        mReadOnlyStatus = findViewById(R.id.read_only);
+
+        mMassStorage = (CheckBox)findViewById(R.id.mass_storage);
+        mMassStorage.setOnClickListener(mMassStorageListener);
+
+        Button unmountButton = (Button)findViewById(R.id.sdcard_unmount);
+        unmountButton.setOnClickListener(mUnmountButtonHandler);
+
+        mTotalSize = (TextView)findViewById(R.id.total);
+        mUsedSize = (TextView)findViewById(R.id.used);
+        mAvailableSize = (TextView)findViewById(R.id.available);
+
+        // install an intent filter to receive SD card related events.
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_REMOVED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SHARED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
+        intentFilter.addDataScheme("file");
+        registerReceiver(mReceiver, intentFilter);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        update();
+    }
+
+    private void setLayout(View layout) {
+        mRemovedLayout.setVisibility(layout == mRemovedLayout ? View.VISIBLE : View.GONE);
+        mMountedLayout.setVisibility(layout == mMountedLayout ? View.VISIBLE : View.GONE);
+        mUnmountedLayout.setVisibility(layout == mUnmountedLayout ? View.VISIBLE : View.GONE);
+        mScanningLayout.setVisibility(layout == mScanningLayout ? View.VISIBLE : View.GONE);
+        mSharedLayout.setVisibility(layout == mSharedLayout ? View.VISIBLE : View.GONE);
+        mBadRemovalLayout.setVisibility(layout == mBadRemovalLayout ? View.VISIBLE : View.GONE);
+    }
+
+    private void update() {
+        try {
+            mMassStorage.setChecked(mMountService.getMassStorageEnabled());
+        } catch (RemoteException ex) {
+        }
+
+        String scanVolume = null; // this no longer exists: SystemProperties.get(MediaScanner.CURRENT_VOLUME_PROPERTY, "");
+        boolean scanning = "external".equals(scanVolume);
+
+        if (scanning) {
+            setLayout(mScanningLayout);
+        } else {
+            String status = Environment.getExternalStorageState();
+            boolean readOnly = false;
+
+            if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
+                status = Environment.MEDIA_MOUNTED;
+                readOnly = true;
+            }
+
+            if (status.equals(Environment.MEDIA_MOUNTED)) {
+                try {
+                    File path = Environment.getExternalStorageDirectory();
+                    StatFs stat = new StatFs(path.getPath());
+                    long blockSize = stat.getBlockSize();
+                    long totalBlocks = stat.getBlockCount();
+                    long availableBlocks = stat.getAvailableBlocks();
+
+                    mTotalSize.setText(formatSize(totalBlocks * blockSize));
+                    mUsedSize.setText(formatSize((totalBlocks - availableBlocks) * blockSize));
+                    mAvailableSize.setText(formatSize(availableBlocks * blockSize));
+                } catch (IllegalArgumentException e) {
+                    // this can occur if the SD card is removed, but we haven't received the
+                    // ACTION_MEDIA_REMOVED Intent yet.
+                    status = Environment.MEDIA_REMOVED;
+                }
+
+                mReadOnlyStatus.setVisibility(readOnly ? View.VISIBLE : View.GONE);
+                setLayout(mMountedLayout);
+            } else if (status.equals(Environment.MEDIA_UNMOUNTED)) {
+                setLayout(mUnmountedLayout);
+            } else if (status.equals(Environment.MEDIA_REMOVED)) {
+                setLayout(mRemovedLayout);
+            } else if (status.equals(Environment.MEDIA_SHARED)) {
+                setLayout(mSharedLayout);
+            } else if (status.equals(Environment.MEDIA_BAD_REMOVAL)) {
+                setLayout(mBadRemovalLayout);
+            }
+        }
+    }
+
+    private String formatSize(long size) {
+        String suffix = null;
+
+        // add K or M suffix if size is greater than 1K or 1M
+        if (size >= 1024) {
+            suffix = "K";
+            size /= 1024;
+            if (size >= 1024) {
+                suffix = "M";
+                size /= 1024;
+            }
+        }
+
+        StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
+
+        int commaOffset = resultBuffer.length() - 3;
+        while (commaOffset > 0) {
+            resultBuffer.insert(commaOffset, ',');
+            commaOffset -= 3;
+        }
+
+        if (suffix != null)
+            resultBuffer.append(suffix);
+        return resultBuffer.toString();
+    }
+
+    OnClickListener mMassStorageListener = new OnClickListener() {
+        public void onClick(View v) {
+            try {
+                mMountService.setMassStorageEnabled(mMassStorage.isChecked());
+            } catch (RemoteException ex) {
+            }
+        }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            update();
+        }
+    };
+
+    OnClickListener mUnmountButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            try {
+                mMountService.unmountMedia(Environment.getExternalStorageDirectory().toString());
+            } catch (RemoteException ex) {
+            }
+        }
+    };
+
+
+    private int         mStatus;
+    private IMountService   mMountService;
+
+    private CheckBox    mMassStorage;
+
+    private TextView    mTotalSize;
+    private TextView    mUsedSize;
+    private TextView    mAvailableSize;
+
+    private View        mRemovedLayout;
+    private View        mMountedLayout;
+    private View        mUnmountedLayout;
+    private View        mScanningLayout;
+    private View        mSharedLayout;
+    private View        mBadRemovalLayout;
+    private View        mReadOnlyStatus;
+}
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
new file mode 100644
index 0000000..c1a509a
--- /dev/null
+++ b/src/com/android/settings/SecuritySettings.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.util.Config;
+import android.util.Log;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Gesture lock pattern settings.
+ */
+public class SecuritySettings extends PreferenceActivity
+    implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+    // Lock Settings
+    
+    private static final String KEY_LOCK_ENABLED = "lockenabled";
+    private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
+    private static final int CONFIRM_PATTERN_REQUEST_CODE = 55;
+
+    private LockPatternUtils mLockPatternUtils;
+    private CheckBoxPreference mLockEnabled;
+    private CheckBoxPreference mVisiblePattern;
+    private Preference mChoosePattern;
+
+    private CheckBoxPreference mShowPassword;
+    
+    // Location Settings
+    
+    private static final String LOCATION_NETWORK = "location_network";
+    private static final String LOCATION_GPS = "location_gps";
+
+    private CheckBoxPreference mNetwork;
+    private CheckBoxPreference mGps;
+    private LocationManager mLocationManager;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.security_settings);
+
+        mLockPatternUtils = new LockPatternUtils(getContentResolver());
+
+        createPreferenceHierarchy();
+        
+        // Get the available location providers
+        mLocationManager = (LocationManager)
+            getSystemService(Context.LOCATION_SERVICE);
+
+        mNetwork = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_NETWORK);
+        mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS);
+        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+        updateToggles();
+    }
+
+    private PreferenceScreen createPreferenceHierarchy() {
+        // Root
+        PreferenceScreen root = this.getPreferenceScreen();
+
+        // Inline preferences
+        PreferenceCategory inlinePrefCat = new PreferenceCategory(this);
+        inlinePrefCat.setTitle(R.string.lock_settings_title);
+        root.addPreference(inlinePrefCat);
+
+        // autolock toggle
+        mLockEnabled = new LockEnabledPref(this);
+        mLockEnabled.setTitle(R.string.lockpattern_settings_enable_title);
+        mLockEnabled.setSummary(R.string.lockpattern_settings_enable_summary);
+        mLockEnabled.setKey(KEY_LOCK_ENABLED);
+        inlinePrefCat.addPreference(mLockEnabled);
+
+        // visible pattern
+        mVisiblePattern = new CheckBoxPreference(this);
+        mVisiblePattern.setKey(KEY_VISIBLE_PATTERN);
+        mVisiblePattern.setTitle(R.string.lockpattern_settings_enable_visible_pattern_title);
+        inlinePrefCat.addPreference(mVisiblePattern);
+
+        // change pattern lock
+        Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                    "com.android.settings.ChooseLockPatternTutorial");
+        mChoosePattern = getPreferenceManager().createPreferenceScreen(this);
+        mChoosePattern.setIntent(intent);
+        inlinePrefCat.addPreference(mChoosePattern);
+        
+        PreferenceScreen simLockPreferences = getPreferenceManager()
+                .createPreferenceScreen(this);
+        simLockPreferences.setTitle(R.string.sim_lock_settings_category);
+        // Intent to launch SIM lock settings
+        intent = new Intent();
+        intent.setClassName("com.android.settings", "com.android.settings.SimLockSettings");
+        simLockPreferences.setIntent(intent);
+        
+        PreferenceCategory simLockCat = new PreferenceCategory(this);
+        simLockCat.setTitle(R.string.sim_lock_settings_title);
+        root.addPreference(simLockCat);
+        simLockCat.addPreference(simLockPreferences);
+
+        // Passwords
+        PreferenceCategory passwordsCat = new PreferenceCategory(this);
+        passwordsCat.setTitle(R.string.security_passwords_title);
+        root.addPreference(passwordsCat);
+        
+        CheckBoxPreference showPassword = mShowPassword = new CheckBoxPreference(this);
+        showPassword.setKey("show_password");
+        showPassword.setTitle(R.string.show_password);
+        showPassword.setSummary(R.string.show_password_summary);
+        showPassword.setPersistent(false);
+        passwordsCat.addPreference(showPassword);
+        
+        return root;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        boolean patternExists = mLockPatternUtils.savedPatternExists();
+        mLockEnabled.setEnabled(patternExists);
+        mVisiblePattern.setEnabled(patternExists);
+
+        mLockEnabled.setChecked(mLockPatternUtils.isLockPatternEnabled());
+        mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled());
+
+        int chooseStringRes = mLockPatternUtils.savedPatternExists() ?
+                R.string.lockpattern_settings_change_lock_pattern :
+                R.string.lockpattern_settings_choose_lock_pattern;
+        mChoosePattern.setTitle(chooseStringRes);
+        
+        mShowPassword
+                .setChecked(Settings.System.getInt(getContentResolver(),
+                Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+            Preference preference) {
+        final String key = preference.getKey();
+
+        if (KEY_LOCK_ENABLED.equals(key)) {
+            mLockPatternUtils.setLockPatternEnabled(isToggled(preference));
+        } else if (KEY_VISIBLE_PATTERN.equals(key)) {
+            mLockPatternUtils.setVisiblePatternEnabled(isToggled(preference));
+        } else if (preference == mShowPassword) {
+            Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
+                    mShowPassword.isChecked() ? 1 : 0);
+        }
+        
+        return false;
+    }
+
+    /*
+     * Creates toggles for each available location provider
+     */
+    private void updateToggles() {
+        String providers = getAllowedProviders();
+        mNetwork.setChecked(providers.contains(LocationManager.NETWORK_PROVIDER));
+        mGps.setChecked(providers.contains(LocationManager.GPS_PROVIDER));
+    }
+
+    private void updateProviders() {
+        String preferredProviders = "";
+        if (mNetwork.isChecked()) {
+            preferredProviders += LocationManager.NETWORK_PROVIDER;
+        }
+        if (mGps.isChecked()) {
+            preferredProviders += "," + LocationManager.GPS_PROVIDER;
+        }
+        setProviders(preferredProviders);
+    }
+
+    private void setProviders(String providers) {
+        // Update the system setting LOCATION_PROVIDERS_ALLOWED
+        Settings.System.putString(getContentResolver(),
+                Settings.System.LOCATION_PROVIDERS_ALLOWED, providers);
+        if (Config.LOGV) {
+            Log.v("Location Accuracy", "Setting LOCATION_PROVIDERS_ALLOWED = " + providers);
+        }
+        // Inform the location manager about the changes
+        mLocationManager.updateProviders();
+    }
+
+    /**
+     * @return string containing a list of providers that have been enabled for use
+     */
+    private String getAllowedProviders() {
+        String allowedProviders =
+            Settings.System.getString(getContentResolver(),
+                Settings.System.LOCATION_PROVIDERS_ALLOWED);
+        if (allowedProviders == null) {
+            allowedProviders = "";
+        }
+        return allowedProviders;
+    }
+
+    public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
+        if (LOCATION_NETWORK.equals(key) || LOCATION_GPS.equals(key)) {
+            updateProviders();
+        }
+    }
+
+    private boolean isToggled(Preference pref) {
+        return ((CheckBoxPreference) pref).isChecked();
+    }
+
+
+    /**
+     * For the user to disable keyguard, we first make them verify their
+     * existing pattern.
+     */
+    private class LockEnabledPref extends CheckBoxPreference {
+
+        public LockEnabledPref(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onClick() {
+            if (isChecked() && mLockPatternUtils.savedPatternExists()) {
+                confirmPatternThenDisable();
+            } else {
+                super.onClick();
+            }
+        }
+    }
+
+    /**
+     * Launch screen to confirm the existing lock pattern.
+     * @see #onActivityResult(int, int, android.content.Intent)
+     */
+    private void confirmPatternThenDisable() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
+        startActivityForResult(intent, CONFIRM_PATTERN_REQUEST_CODE);
+    }
+
+    /**
+     * @see #confirmPatternThenDisable
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode != CONFIRM_PATTERN_REQUEST_CODE) {
+            return;
+        }
+
+        if (resultCode == Activity.RESULT_OK) {
+            mLockPatternUtils.setLockPatternEnabled(false);                
+        }
+    }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
new file mode 100644
index 0000000..9f98ab2
--- /dev/null
+++ b/src/com/android/settings/Settings.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.provider.Settings.System;
+
+public class Settings extends PreferenceActivity {
+
+    private static final String KEY_PARENT = "parent";
+    private static final String KEY_CALL_SETTINGS = "call_settings";
+    private static final String KEY_SYNC_SETTINGS = "sync_settings";
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.settings);
+        
+        PreferenceGroup parent = (PreferenceGroup) findPreference(KEY_PARENT);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parent, KEY_SYNC_SETTINGS, 0);
+    }
+    
+    @Override
+    protected void onResume() {
+        findPreference(KEY_CALL_SETTINGS).setEnabled(!isAirplaneMode());
+        super.onResume();
+    }
+
+    private boolean isAirplaneMode() {
+        return System.getInt(getContentResolver(), 
+                              System.AIRPLANE_MODE_ON, 0) > 0;
+    }   
+
+}
diff --git a/src/com/android/settings/SettingsLicenseActivity.java b/src/com/android/settings/SettingsLicenseActivity.java
new file mode 100644
index 0000000..82eadca
--- /dev/null
+++ b/src/com/android/settings/SettingsLicenseActivity.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Toast;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * The "dialog" that shows from "License" in the Settings app.
+ */
+public class SettingsLicenseActivity extends AlertActivity {
+
+    private static final String TAG = "SettingsLicenseActivity";
+    private static final boolean LOGV = false || Config.LOGV;
+    
+    private static final String DEFAULT_LICENSE_PATH = "/system/etc/NOTICE.html";
+    private static final String PROPERTY_LICENSE_PATH = "ro.config.license_path";
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        String fileName = SystemProperties.get(PROPERTY_LICENSE_PATH, DEFAULT_LICENSE_PATH);
+        if (TextUtils.isEmpty(fileName)) {
+            Log.e(TAG, "The system property for the license file is empty.");
+            showErrorAndFinish();
+            return;
+        }
+
+        FileReader fileReader = null;
+        StringBuilder data = null;
+        try {
+            data = new StringBuilder(2048); 
+            char tmp[] = new char[2048];
+            int numRead;
+            fileReader = new FileReader(fileName);
+            while ((numRead = fileReader.read(tmp)) >= 0) {
+                data.append(tmp, 0, numRead);
+            }
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "License HTML file not found at " + fileName, e);
+            showErrorAndFinish();
+            return;
+        } catch (IOException e) {
+            Log.e(TAG, "Error reading license HTML file at " + fileName, e);
+            showErrorAndFinish();
+            return;
+        } finally {
+            try {
+                if (fileReader != null) {
+                    fileReader.close();
+                }
+            } catch (IOException e) {
+            }
+        }
+    
+        if (TextUtils.isEmpty(data)) {
+            Log.e(TAG, "License HTML is empty (from " + fileName + ")");
+            showErrorAndFinish();
+            return;
+        }
+        
+        WebView webView = new WebView(this);
+
+        if (LOGV) Log.v(TAG, "Started encode at " + System.currentTimeMillis());
+        // Need to encode to base64 for WebView to load the contents properly
+        String dataStr;
+        try {
+            byte[] base64Bytes = Base64.encodeBase64(data.toString().getBytes("ISO8859_1"));
+            dataStr = new String(base64Bytes);
+        } catch (UnsupportedEncodingException e) {
+            Log.e(TAG, "Could not convert to base64", e);
+            showErrorAndFinish();
+            return;
+        }
+        if (LOGV) Log.v(TAG, "Ended encode at " + System.currentTimeMillis());
+        if (LOGV) {
+            Log.v(TAG, "Started test decode at " + System.currentTimeMillis());
+            Base64.decodeBase64(dataStr.getBytes());
+            Log.v(TAG, "Ended decode at " + System.currentTimeMillis());
+        }
+
+        
+        // Begin the loading.  This will be done in a separate thread in WebView.
+        webView.loadData(dataStr, "text/html", "base64");
+        webView.setWebViewClient(new WebViewClient() {
+            @Override
+            public void onPageFinished(WebView view, String url) {
+                // Change from 'Loading...' to the real title
+                mAlert.setTitle(getString(R.string.settings_license_activity_title));
+            }
+        });
+        
+        final AlertController.AlertParams p = mAlertParams;
+        p.mTitle = getString(R.string.settings_license_activity_loading);
+        p.mView = webView;
+        p.mForceInverseBackground = true;
+        setupAlert();
+    }
+
+    private void showErrorAndFinish() {
+        Toast.makeText(this, R.string.settings_license_activity_unavailable, Toast.LENGTH_LONG)
+                .show();
+        finish();
+    }
+    
+}
diff --git a/src/com/android/settings/SimLockSettings.java b/src/com/android/settings/SimLockSettings.java
new file mode 100644
index 0000000..286e3d6
--- /dev/null
+++ b/src/com/android/settings/SimLockSettings.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceScreen;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import android.widget.Toast;
+
+/**
+ * Implements the preference screen to enable/disable SIM lock and
+ * also the dialogs to change the SIM PIN. In the former case, enabling/disabling
+ * the SIM lock will prompt the user for the current PIN.
+ * In the Change PIN case, it prompts the user for old pin, new pin and new pin
+ * again before attempting to change it. Calls the SimCard interface to execute
+ * these operations.
+ *
+ */
+public class SimLockSettings extends PreferenceActivity 
+        implements EditPinPreference.OnPinEnteredListener {
+
+    private static final int OFF_MODE = 0;
+    // State when enabling/disabling SIM lock
+    private static final int SIM_LOCK_MODE = 1;
+    // State when entering the old pin
+    private static final int SIM_OLD_MODE = 2;
+    // State when entering the new pin - first time
+    private static final int SIM_NEW_MODE = 3;
+    // State when entering the new pin - second time
+    private static final int SIM_REENTER_MODE = 4;
+    
+    // Keys in xml file
+    private static final String PIN_DIALOG = "sim_pin";
+    private static final String PIN_TOGGLE = "sim_toggle";
+    // Keys in icicle
+    private static final String DIALOG_STATE = "dialogState";
+    private static final String DIALOG_PIN = "dialogPin";
+    private static final String DIALOG_ERROR = "dialogError";
+    private static final String ENABLE_TO_STATE = "enableState";
+    
+    private static final int MIN_PIN_LENGTH = 4;
+    private static final int MAX_PIN_LENGTH = 8;
+    // Which dialog to show next when popped up
+    private int mDialogState = OFF_MODE;
+    
+    private String mPin;
+    private String mOldPin;
+    private String mNewPin;
+    private String mError;
+    // Are we trying to enable or disable SIM lock?
+    private boolean mToState;
+    
+    private Phone mPhone;
+    
+    private EditPinPreference mPinDialog;
+    private CheckBoxPreference mPinToggle;
+    
+    private Resources mRes;
+
+    // For async handler to identify request type
+    private static final int ENABLE_SIM_PIN_COMPLETE = 100;
+    private static final int CHANGE_SIM_PIN_COMPLETE = 101;
+
+    // For replies from SimCard interface
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case ENABLE_SIM_PIN_COMPLETE:
+                    simLockChanged(ar.exception == null);
+                    break;
+                case CHANGE_SIM_PIN_COMPLETE:
+                    simPinChanged(ar.exception == null);
+                    break;
+            }
+
+            return;
+        }
+    };
+    
+    // For top-level settings screen to query
+    static boolean isSimLockEnabled() {
+        return PhoneFactory.getDefaultPhone().getSimCard().getSimLockEnabled();
+    }
+    
+    static String getSummary(Context context) {
+        Resources res = context.getResources();
+        String summary = isSimLockEnabled() 
+                ? res.getString(R.string.sim_lock_on) 
+                : res.getString(R.string.sim_lock_off);
+        return summary;
+    }
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    
+        addPreferencesFromResource(R.xml.sim_lock_settings);
+        
+        mPinDialog = (EditPinPreference) findPreference(PIN_DIALOG);
+        mPinToggle = (CheckBoxPreference) findPreference(PIN_TOGGLE);
+        if (savedInstanceState != null && savedInstanceState.containsKey(DIALOG_STATE)) {
+            mDialogState = savedInstanceState.getInt(DIALOG_STATE);
+            mPin = savedInstanceState.getString(DIALOG_PIN);
+            mError = savedInstanceState.getString(DIALOG_ERROR);
+            mToState = savedInstanceState.getBoolean(ENABLE_TO_STATE);
+        }
+
+        mPinDialog.setOnPinEnteredListener(this);
+        
+        // Don't need any changes to be remembered
+        getPreferenceScreen().setPersistent(false);
+        
+        mPhone = PhoneFactory.getDefaultPhone();
+        mRes = getResources();
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        mPinToggle.setChecked(mPhone.getSimCard().getSimLockEnabled());
+        
+        if (mDialogState != OFF_MODE) {
+            showPinDialog();
+        } else {
+            // Prep for standard click on "Change PIN"
+            resetDialogState();
+        }
+    }
+    
+    @Override
+    protected void onSaveInstanceState(Bundle out) {
+        // Need to store this state for slider open/close
+        // There is one case where the dialog is popped up by the preference
+        // framework. In that case, let the preference framework store the
+        // dialog state. In other cases, where this activity manually launches
+        // the dialog, store the state of the dialog.
+        if (mPinDialog.isDialogOpen()) {
+            out.putInt(DIALOG_STATE, mDialogState);
+            out.putString(DIALOG_PIN, mPinDialog.getEditText().getText().toString());
+            out.putString(DIALOG_ERROR, mError);
+            out.putBoolean(ENABLE_TO_STATE, mToState);
+        } else {
+            super.onSaveInstanceState(out);
+        }
+    }
+
+    private void showPinDialog() {
+        if (mDialogState == OFF_MODE) {
+            return;
+        }
+        setDialogValues();
+        
+        mPinDialog.showPinDialog();
+    }
+    
+    private void setDialogValues() {
+        mPinDialog.setText(mPin);
+        String message = "";
+        switch (mDialogState) {
+            case SIM_LOCK_MODE:
+                message = mRes.getString(R.string.sim_enter_pin);
+                mPinDialog.setDialogTitle(mToState 
+                        ? mRes.getString(R.string.sim_enable_sim_lock)
+                        : mRes.getString(R.string.sim_disable_sim_lock));
+                break;
+            case SIM_OLD_MODE:
+                message = mRes.getString(R.string.sim_enter_old);
+                mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin));
+                break;
+            case SIM_NEW_MODE:
+                message = mRes.getString(R.string.sim_enter_new);
+                mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin));
+                break;
+            case SIM_REENTER_MODE:
+                message = mRes.getString(R.string.sim_reenter_new);
+                mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin));
+                break;
+        }
+        if (mError != null) {
+            message = mError + "\n" + message;
+            mError = null;
+        }
+        mPinDialog.setDialogMessage(message);
+    }
+
+    public void onPinEntered(EditPinPreference preference, boolean positiveResult) {
+        if (!positiveResult) {
+            resetDialogState();
+            return;
+        }
+        
+        mPin = preference.getText();
+        if (!reasonablePin(mPin)) {
+            // inject error message and display dialog again
+            mError = mRes.getString(R.string.sim_bad_pin);
+            showPinDialog();
+            return;
+        }
+        switch (mDialogState) {
+            case SIM_LOCK_MODE:
+                tryChangeSimLockState();
+                break;
+            case SIM_OLD_MODE:
+                mOldPin = mPin;
+                mDialogState = SIM_NEW_MODE;
+                mError = null;
+                mPin = null;
+                showPinDialog();
+                break;
+            case SIM_NEW_MODE:
+                mNewPin = mPin;
+                mDialogState = SIM_REENTER_MODE;
+                mPin = null;
+                showPinDialog();
+                break;
+            case SIM_REENTER_MODE:
+                if (!mPin.equals(mNewPin)) {
+                    mError = mRes.getString(R.string.sim_pins_dont_match);
+                    mDialogState = SIM_NEW_MODE;
+                    mPin = null;
+                    showPinDialog();
+                } else {
+                    mError = null;
+                    tryChangePin();
+                }
+                break;
+        }
+    }
+    
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mPinToggle) {
+            // Get the new, preferred state
+            mToState = mPinToggle.isChecked();
+            // Flip it back and pop up pin dialog  
+            mPinToggle.setChecked(!mToState);  
+            mDialogState = SIM_LOCK_MODE;
+            showPinDialog();
+        }
+        return true;
+    }
+    
+    private void tryChangeSimLockState() {
+        // Try to change sim lock. If it succeeds, toggle the lock state and 
+        // reset dialog state. Else inject error message and show dialog again.
+        Message callback = Message.obtain(mHandler, ENABLE_SIM_PIN_COMPLETE);
+        mPhone.getSimCard().setSimLockEnabled(mToState, mPin, callback);
+
+    }
+    
+    private void simLockChanged(boolean success) {
+        if (success) {
+            mPinToggle.setChecked(mToState);
+        } else {
+            // TODO: I18N
+            Toast.makeText(this, mRes.getString(R.string.sim_lock_failed), Toast.LENGTH_SHORT)
+                    .show();
+        }
+        resetDialogState();
+    }
+
+    private void simPinChanged(boolean success) {
+        if (!success) {
+         // TODO: I18N
+            Toast.makeText(this, mRes.getString(R.string.sim_change_failed), 
+                    Toast.LENGTH_SHORT)
+                    .show();
+        } else {
+            Toast.makeText(this, mRes.getString(R.string.sim_change_succeeded), 
+                    Toast.LENGTH_SHORT)
+                    .show();
+
+        }
+        resetDialogState();
+    }
+
+    private void tryChangePin() {
+        Message callback = Message.obtain(mHandler, CHANGE_SIM_PIN_COMPLETE);
+        mPhone.getSimCard().changeSimLockPassword(mOldPin,
+                mNewPin, callback);
+    }
+    
+    private boolean reasonablePin(String pin) {
+        if (pin == null || pin.length() < MIN_PIN_LENGTH || pin.length() > MAX_PIN_LENGTH) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+ 
+    private void resetDialogState() {
+        mError = null;
+        mDialogState = SIM_OLD_MODE; // Default for when Change PIN is clicked
+        mPin = "";
+        setDialogValues();
+    }
+}
diff --git a/src/com/android/settings/SoundAndDisplaySettings.java b/src/com/android/settings/SoundAndDisplaySettings.java
new file mode 100644
index 0000000..887fb8f
--- /dev/null
+++ b/src/com/android/settings/SoundAndDisplaySettings.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.Log;
+
+public class SoundAndDisplaySettings extends PreferenceActivity implements
+        Preference.OnPreferenceChangeListener {
+    private static final String TAG = "SoundAndDisplaysSettings";
+
+    /** If there is no setting in the provider, use this. */
+    private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
+    
+    private static final String KEY_SILENT = "silent";
+    private static final String KEY_VIBRATE = "vibrate";
+    private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
+    private static final String KEY_DTMF_TONE = "dtmf_tone";
+    private static final String KEY_SOUND_EFFECTS = "sound_effects";
+    
+    private CheckBoxPreference mSilent;
+    private CheckBoxPreference mVibrate;
+    private CheckBoxPreference mDtmfTone;
+    private CheckBoxPreference mSoundEffects;
+    
+    private AudioManager mAudioManager;
+    
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            
+            int ringerMode = intent
+                    .getIntExtra(AudioManager.EXTRA_RINGER_MODE, AudioManager.RINGER_MODE_NORMAL);
+            boolean isSilentMode = ringerMode != AudioManager.RINGER_MODE_NORMAL;
+            
+            if (mSilent.isChecked() != isSilentMode) {
+                mSilent.setChecked(isSilentMode);
+            }
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ContentResolver resolver = getContentResolver();
+        
+        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        
+        addPreferencesFromResource(R.xml.sound_and_display_settings);
+        
+        mSilent = (CheckBoxPreference) findPreference(KEY_SILENT);
+        mVibrate = (CheckBoxPreference) findPreference(KEY_VIBRATE);
+        mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE);
+        mDtmfTone.setPersistent(false);
+        mDtmfTone.setChecked(Settings.System.getInt(resolver,
+                Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0);
+        mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS);
+        mSoundEffects.setPersistent(false);
+        mSoundEffects.setChecked(Settings.System.getInt(resolver,
+                Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0);
+        
+        ListPreference screenTimeoutPreference =
+            (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
+        screenTimeoutPreference.setValue(String.valueOf(Settings.System.getInt(
+                getContentResolver(), SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE)));
+        screenTimeoutPreference.setOnPreferenceChangeListener(this);
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        updateState(true);
+        
+        IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+        registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        unregisterReceiver(mReceiver);
+    }
+
+    private void updateState(boolean force) {
+        final boolean silent = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
+        final boolean phoneVibrate = mAudioManager
+                .getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER)
+                        == AudioManager.VIBRATE_SETTING_ON;
+        
+        if (silent != mSilent.isChecked() || force) {
+            mSilent.setChecked(silent);
+        }
+        
+        if (phoneVibrate != mVibrate.isChecked() || force) {
+            mVibrate.setChecked(phoneVibrate);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+
+        if (preference == mSilent) {
+            final boolean silent = mSilent.isChecked();
+            mAudioManager.setRingerMode(silent ? AudioManager.RINGER_MODE_SILENT
+                    : AudioManager.RINGER_MODE_NORMAL);
+            
+        } else if (preference == mVibrate) {
+            final boolean vibrate = mVibrate.isChecked();
+            mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
+                    vibrate ? AudioManager.VIBRATE_SETTING_ON
+                            : AudioManager.VIBRATE_SETTING_OFF);
+        } else if (preference == mDtmfTone) {
+            Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
+                    mDtmfTone.isChecked() ? 1 : 0);
+            
+        } else if (preference == mSoundEffects) {
+            if (mSoundEffects.isChecked()) {
+                mAudioManager.loadSoundEffects();
+            } else {
+                mAudioManager.unloadSoundEffects();
+            }
+            Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
+                    mSoundEffects.isChecked() ? 1 : 0);
+        }
+        return true;
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (KEY_SCREEN_TIMEOUT.equals(preference.getKey())) {
+            int value = Integer.parseInt((String) objValue);
+            try {
+                Settings.System.putInt(getContentResolver(), 
+                        SCREEN_OFF_TIMEOUT, value);
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "could not persist screen timeout setting", e);
+            }
+        }
+        
+        return true;
+    }
+
+}
diff --git a/src/com/android/settings/TestingSettings.java b/src/com/android/settings/TestingSettings.java
new file mode 100644
index 0000000..3994560
--- /dev/null
+++ b/src/com/android/settings/TestingSettings.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class TestingSettings extends PreferenceActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.testing_settings);
+    }
+
+}
diff --git a/src/com/android/settings/TestingSettingsBroadcastReceiver.java b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
new file mode 100644
index 0000000..c6cd7e1
--- /dev/null
+++ b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
@@ -0,0 +1,28 @@
+package com.android.settings;
+
+import android.provider.Telephony;
+import static android.provider.Telephony.Intents.SECRET_CODE_ACTION;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.util.Config;
+import android.util.Log;
+import android.view.KeyEvent;
+
+
+public class TestingSettingsBroadcastReceiver extends BroadcastReceiver {
+  
+    public TestingSettingsBroadcastReceiver() {
+    }
+    
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent.getAction().equals(SECRET_CODE_ACTION)) {
+            Intent i = new Intent(Intent.ACTION_MAIN);
+            i.setClass(context, TestingSettings.class);
+            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(i);
+        }
+    }
+}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
new file mode 100644
index 0000000..a23272b
--- /dev/null
+++ b/src/com/android/settings/Utils.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * 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 com.android.settings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+
+import java.util.List;
+
+public class Utils {
+
+    /**
+     * Set the preference's title to the matching activity's label.
+     */
+    public static final int UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY = 1;
+
+    /**
+     * Finds a matching activity for a preference's intent. If a matching
+     * activity is not found, it will remove the preference.
+     * 
+     * @param context The context.
+     * @param parentPreferenceGroup The preference group that contains the
+     *            preference whose intent is being resolved.
+     * @param preferenceKey The key of the preference whose intent is being
+     *            resolved.
+     * @param flags 0 or one or more of
+     *            {@link #UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY}
+     *            .
+     * @return Whether an activity was found. If false, the preference was
+     *         removed.
+     */
+    public static boolean updatePreferenceToSpecificActivityOrRemove(Context context,
+            PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) {
+        
+        Preference preference = parentPreferenceGroup.findPreference(preferenceKey);
+        if (preference == null) {
+            return false;
+        }
+        
+        Intent intent = preference.getIntent();
+        if (intent != null) {
+            // Find the activity that is in the system image
+            PackageManager pm = context.getPackageManager();
+            List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
+            int listSize = list.size();
+            for (int i = 0; i < listSize; i++) {
+                ResolveInfo resolveInfo = list.get(i);
+                if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+                        != 0) {
+                    
+                    // Replace the intent with this specific activity
+                    preference.setIntent(new Intent().setClassName(
+                            resolveInfo.activityInfo.packageName,
+                            resolveInfo.activityInfo.name));
+
+                    if ((flags & UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY) != 0) {
+                        // Set the preference title to the activity's label
+                        preference.setTitle(resolveInfo.loadLabel(pm));
+                    }
+                    
+                    return true;
+                }
+            }
+        }
+
+        // Did not find a matching activity, so remove the preference
+        parentPreferenceGroup.removePreference(preference);
+        
+        return true;
+    }
+    
+}
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
new file mode 100644
index 0000000..18b30bd
--- /dev/null
+++ b/src/com/android/settings/WirelessSettings.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import com.android.settings.wifi.WifiEnabler;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
+import android.bluetooth.IBluetoothDeviceCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.widget.Toast;
+
+public class WirelessSettings extends PreferenceActivity {
+
+    private static final String KEY_TOGGLE_AIRPLANE = "toggle_airplane";
+    private static final String KEY_TOGGLE_BLUETOOTH = "toggle_bluetooth";
+    private static final String KEY_TOGGLE_WIFI = "toggle_wifi";
+
+    private WifiEnabler mWifiEnabler;
+    private AirplaneModeEnabler mAirplaneModeEnabler;
+    
+    private CheckBoxPreference mToggleBluetooth;
+    
+    private IntentFilter mIntentFilter;
+    
+    private static final int EVENT_FAILED_BT_ENABLE = 1;
+    private static final int EVENT_PASSED_BT_ENABLE = 2;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.wireless_settings);
+
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(BluetoothIntent.ENABLED_ACTION);
+        mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
+
+        initToggles();
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        refreshToggles();
+        registerReceiver(mReceiver, mIntentFilter);       
+        
+        mWifiEnabler.resume();
+        mAirplaneModeEnabler.resume();
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mReceiver);
+
+        mWifiEnabler.pause();
+        mAirplaneModeEnabler.pause();
+    }
+    
+    private void initToggles() {
+        
+        mWifiEnabler = new WifiEnabler(
+                this,
+                (WifiManager) getSystemService(WIFI_SERVICE),
+                (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI));
+        
+        mAirplaneModeEnabler = new AirplaneModeEnabler(
+                this,
+                (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE));
+        
+        mToggleBluetooth = (CheckBoxPreference) findPreference(KEY_TOGGLE_BLUETOOTH);
+        mToggleBluetooth.setPersistent(false);
+    }
+    
+    private void refreshToggles() {
+        mToggleBluetooth.setChecked(isBluetoothEnabled());
+        mToggleBluetooth.setEnabled(true);
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mToggleBluetooth) {
+            setBluetoothEnabled(mToggleBluetooth.isChecked());
+            return true;
+        }
+        
+        return false;
+    }
+
+    private boolean isBluetoothEnabled() {
+        BluetoothDevice device = (BluetoothDevice)getSystemService(BLUETOOTH_SERVICE);
+        if (device != null) {
+            return device.isEnabled();
+        } else {
+            return false;
+        }
+    }
+    
+    private void setBluetoothEnabled(boolean enabled) {
+        try {
+            BluetoothDevice device = (BluetoothDevice)getSystemService(BLUETOOTH_SERVICE);
+            if (enabled) {
+                // Turn it off until intent or callback is delivered
+                mToggleBluetooth.setChecked(false);
+                if (device.enable(mBtCallback)) {
+                    mToggleBluetooth.setSummary(R.string.bluetooth_enabling);
+                    mToggleBluetooth.setEnabled(false);
+                }
+            } else {
+                if (device.disable()) {
+                    Settings.System.putInt(getContentResolver(),
+                            Settings.System.BLUETOOTH_ON, 0);
+                } else {
+                    // Unusual situation, that you can't turn off bluetooth
+                    mToggleBluetooth.setChecked(true);
+                }
+            }
+        } catch (NullPointerException e) {
+            // TODO: 1071858
+            mToggleBluetooth.setChecked(false);
+            mToggleBluetooth.setEnabled(false);
+        }
+    }
+
+    private IBluetoothDeviceCallback mBtCallback = new IBluetoothDeviceCallback.Stub() {
+        
+        public void onEnableResult(int res) {
+            switch (res) {
+            case BluetoothDevice.RESULT_FAILURE:
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_FAILED_BT_ENABLE, 0));
+                break;
+            case BluetoothDevice.RESULT_SUCCESS:
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_PASSED_BT_ENABLE, 0));
+                break;
+            }
+        }
+        
+        public void onCreateBondingResult(String device, int res) {
+            // Don't care
+        }
+        public void onGetRemoteServiceChannelResult(String address, int channel) { }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
+                updateBtStatus(true);
+            } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
+                mToggleBluetooth.setChecked(false);
+            }
+        }
+    };
+
+    private void updateBtStatus(boolean enabled) {
+        mToggleBluetooth.setChecked(enabled);
+        mToggleBluetooth.setEnabled(true);
+        mToggleBluetooth.setSummary(R.string.bluetooth_quick_toggle_summary);
+        if (enabled) {
+            Settings.System.putInt(getContentResolver(),
+                Settings.System.BLUETOOTH_ON, 1);
+        }
+    }
+    
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_PASSED_BT_ENABLE:
+                    updateBtStatus(true);
+                    break;
+                case EVENT_FAILED_BT_ENABLE:
+                    updateBtStatus(false);
+                    Toast.makeText(WirelessSettings.this, 
+                            getResources().getString(R.string.bluetooth_failed_to_enable),
+                            Toast.LENGTH_SHORT).show();
+
+                    break;
+            }
+        }
+    };
+}
diff --git a/src/com/android/settings/ZoneList.java b/src/com/android/settings/ZoneList.java
new file mode 100644
index 0000000..a2ec1ef
--- /dev/null
+++ b/src/com/android/settings/ZoneList.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.AlarmManager;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * This activity displays a list of time zones that match a filter string
+ * such as "Africa", "Europe", etc. Choosing an item from the list will set
+ * the time zone. Pressing Back without choosing from the list will not 
+ * result in a change in the time zone setting.
+ */
+public class ZoneList extends ListActivity {
+    
+    private static final String TAG = "ZoneList";
+    private static final String KEY_ID = "id";
+    private static final String KEY_DISPLAYNAME = "name";
+    private static final String KEY_GMT = "gmt";
+    private static final String KEY_OFFSET = "offset";
+    private static final String XMLTAG_TIMEZONE = "timezone";
+
+    private static final int HOURS_1 = 60 * 60000;
+    private static final int HOURS_24 = 24 * HOURS_1;
+    private static final int HOURS_HALF = HOURS_1 / 2;
+    
+    private static final int MENU_TIMEZONE = Menu.FIRST+1;
+    private static final int MENU_ALPHABETICAL = Menu.FIRST;
+
+    // Initial focus position
+    private int mDefault;
+    
+    private boolean mSortedByTimezone;
+
+    private SimpleAdapter mTimezoneSortedAdapter;
+    private SimpleAdapter mAlphabeticalAdapter;
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        String[] from = new String[] {KEY_DISPLAYNAME, KEY_GMT};
+        int[] to = new int[] {android.R.id.text1, android.R.id.text2};
+
+        MyComparator comparator = new MyComparator(KEY_OFFSET);
+        
+        List<HashMap> timezoneSortedList = getZones();
+        Collections.sort(timezoneSortedList, comparator);
+        mTimezoneSortedAdapter = new SimpleAdapter(this,
+                (List) timezoneSortedList,
+                android.R.layout.simple_list_item_2,
+                from,
+                to);
+
+        List<HashMap> alphabeticalList = new ArrayList<HashMap>(timezoneSortedList);
+        comparator.setSortingKey(KEY_DISPLAYNAME);
+        Collections.sort(alphabeticalList, comparator);
+        mAlphabeticalAdapter = new SimpleAdapter(this,
+                (List) alphabeticalList,
+                android.R.layout.simple_list_item_2,
+                from,
+                to);
+        
+        // Sets the adapter
+        setSorting(true);
+        
+        // If current timezone is in this list, move focus to it
+        setSelection(mDefault);
+        
+        // Assume user may press Back
+        setResult(RESULT_CANCELED);
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, MENU_ALPHABETICAL, 0, R.string.zone_list_menu_sort_alphabetically)
+            .setIcon(R.drawable.ic_menu_sort_alphabetically);
+        menu.add(0, MENU_TIMEZONE, 0, R.string.zone_list_menu_sort_by_timezone)
+            .setIcon(R.drawable.ic_menu_3d_globe);
+        
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+     
+        if (mSortedByTimezone) {
+            menu.findItem(MENU_TIMEZONE).setVisible(false);
+            menu.findItem(MENU_ALPHABETICAL).setVisible(true);
+        } else {
+            menu.findItem(MENU_TIMEZONE).setVisible(true);
+            menu.findItem(MENU_ALPHABETICAL).setVisible(false);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+
+            case MENU_TIMEZONE:
+                setSorting(true);
+                return true;
+                
+            case MENU_ALPHABETICAL:
+                setSorting(false);
+                return true;
+                
+            default:
+                return false;
+        }
+    }
+
+    private void setSorting(boolean timezone) {
+        setListAdapter(timezone ? mTimezoneSortedAdapter : mAlphabeticalAdapter);
+        mSortedByTimezone = timezone;
+    }
+    
+    private List<HashMap> getZones() {
+        List<HashMap> myData = new ArrayList<HashMap>();
+        long date = Calendar.getInstance().getTimeInMillis();
+        try {
+            XmlResourceParser xrp = getResources().getXml(R.xml.timezones);
+            while (xrp.next() != XmlResourceParser.START_TAG)
+                ;
+            xrp.next();
+            while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+                while (xrp.getEventType() != XmlResourceParser.START_TAG) {
+                    if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
+                        return myData;
+                    }
+                    xrp.next();
+                }
+                if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
+                    String id = xrp.getAttributeValue(0);
+                    String displayName = xrp.nextText();
+                    addItem(myData, id, displayName, date);
+                }
+                while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+                    xrp.next();
+                }
+                xrp.next();
+            }
+            xrp.close();
+        } catch (XmlPullParserException xppe) {
+            Log.e(TAG, "Ill-formatted timezones.xml file");
+        } catch (java.io.IOException ioe) {
+            Log.e(TAG, "Unable to read timezones.xml file");
+        }
+
+        return myData;
+    }
+
+    protected void addItem(List<HashMap> myData, String id, String displayName, 
+            long date) {
+        HashMap map = new HashMap();
+        map.put(KEY_ID, id);
+        map.put(KEY_DISPLAYNAME, displayName);
+        TimeZone tz = TimeZone.getTimeZone(id);
+        int offset = tz.getOffset(date);
+        int p = Math.abs(offset);
+        StringBuilder name = new StringBuilder();
+        name.append("GMT");
+        
+        if (offset < 0) {
+            name.append('-');
+        } else {
+            name.append('+');
+        }
+        
+        name.append(p / (HOURS_1));
+        name.append(':');
+
+        int min = p / 60000;
+        min %= 60;
+
+        if (min < 10) {
+            name.append('0');
+        }
+        name.append(min);
+        
+        map.put(KEY_GMT, name.toString());
+        map.put(KEY_OFFSET, offset);
+        
+        if (id.equals(TimeZone.getDefault().getID())) {
+            mDefault = myData.size();
+        }
+        
+        myData.add(map);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Map map = (Map) l.getItemAtPosition(position);
+        // Update the system timezone value
+        AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+        alarm.setTimeZone((String) map.get(KEY_ID));
+        setResult(RESULT_OK);
+        finish();
+    }
+    
+    private static class MyComparator implements Comparator<HashMap> {
+        private String mSortingKey; 
+        
+        public MyComparator(String sortingKey) {
+            mSortingKey = sortingKey;
+        }
+        
+        public void setSortingKey(String sortingKey) {
+            mSortingKey = sortingKey;
+        }
+        
+        public int compare(HashMap map1, HashMap map2) {
+            Object value1 = map1.get(mSortingKey);
+            Object value2 = map2.get(mSortingKey);
+
+            /* 
+             * This should never happen, but just in-case, put non-comparable
+             * items at the end.
+             */
+            if (!isComparable(value1)) {
+                return isComparable(value2) ? 1 : 0;
+            } else if (!isComparable(value2)) {
+                return -1;
+            }
+            
+            return ((Comparable) value1).compareTo(value2);
+        }
+        
+        private boolean isComparable(Object value) {
+            return (value != null) && (value instanceof Comparable); 
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/ZonePicker.java b/src/com/android/settings/ZonePicker.java
new file mode 100644
index 0000000..def5036
--- /dev/null
+++ b/src/com/android/settings/ZonePicker.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * 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 com.android.settings;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ZonePicker extends ListActivity {
+
+    private ArrayAdapter<CharSequence> mFilterAdapter;
+    
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mFilterAdapter = ArrayAdapter.createFromResource(this,
+                R.array.timezone_filters, android.R.layout.simple_list_item_1);
+        setListAdapter(mFilterAdapter);
+    }
+    
+    protected void addItem(List<Map> data, String name, String zone) {
+        HashMap temp = new HashMap();
+        temp.put("title", name);
+        temp.put("zone", zone);
+        data.add(temp);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        String filter = (String) mFilterAdapter.getItem(position);
+        // If All is chosen, reset the filter
+        if (filter.equals("All")) {
+            filter = null;
+        }
+        Intent zoneList = new Intent();
+        zoneList.setClass(this, ZoneList.class);
+        zoneList.putExtra("filter", filter);
+        
+        startActivityForResult(zoneList, 0);
+    }
+    
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        // If subactivity has resulted in a timezone selection, close this act.
+        if (resultCode == RESULT_OK) {
+            finish();
+        }
+    }    
+}
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
new file mode 100644
index 0000000..8a3cb8b
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings.deviceinfo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.Environment;
+import android.os.IMountService;
+import android.os.ServiceManager;
+import android.os.StatFs;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+
+import com.android.settings.R;
+
+import java.io.File;
+import java.text.DecimalFormat;
+
+public class Memory extends PreferenceActivity {
+
+    private static final String MEMORY_SD_SIZE = "memory_sd_size";
+
+    private static final String MEMORY_SD_AVAIL = "memory_sd_avail";
+
+    private static final String MEMORY_SD_UNMOUNT = "memory_sd_unmount";
+
+    private Resources mRes;
+
+    private Preference mSdSize;
+    private Preference mSdAvail;
+    private Preference mSdUnmount;
+    
+    private IMountService   mMountService;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.device_info_memory);
+
+        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        
+        mRes = getResources();
+        mSdSize = findPreference(MEMORY_SD_SIZE);
+        mSdAvail = findPreference(MEMORY_SD_AVAIL);
+        mSdUnmount = findPreference(MEMORY_SD_UNMOUNT);
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_REMOVED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SHARED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
+        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
+        intentFilter.addDataScheme("file");
+        registerReceiver(mReceiver, intentFilter);
+
+        updateMemoryStatus();
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        unregisterReceiver(mReceiver);
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mSdUnmount) {
+            unmount();
+            return true;
+        }
+        
+        return false;
+    }
+     
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateMemoryStatus();
+        }
+    };
+
+    private void unmount() {
+        try {
+            mMountService.unmountMedia(Environment.getExternalStorageDirectory().toString());
+        } catch (RemoteException ex) {
+            // Failed for some reason, try to update UI to actual state
+            updateMemoryStatus();
+        }
+    }
+    
+    private void updateMemoryStatus() {
+        String status = Environment.getExternalStorageState();
+        String readOnly = "";
+        if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
+            status = Environment.MEDIA_MOUNTED;
+            readOnly = mRes.getString(R.string.read_only);
+        }
+ 
+        if (status.equals(Environment.MEDIA_MOUNTED)) {
+            try {
+                File path = Environment.getExternalStorageDirectory();
+                StatFs stat = new StatFs(path.getPath());
+                long blockSize = stat.getBlockSize();
+                long totalBlocks = stat.getBlockCount();
+                long availableBlocks = stat.getAvailableBlocks();
+                
+                mSdSize.setSummary(formatSize(totalBlocks * blockSize));
+                mSdAvail.setSummary(formatSize(availableBlocks * blockSize) + readOnly);
+                mSdUnmount.setEnabled(true);
+            } catch (IllegalArgumentException e) {
+                // this can occur if the SD card is removed, but we haven't received the 
+                // ACTION_MEDIA_REMOVED Intent yet.
+                status = Environment.MEDIA_REMOVED;
+            }
+            
+        } else {
+            mSdSize.setSummary(mRes.getString(R.string.sd_unavailable));
+            mSdAvail.setSummary(mRes.getString(R.string.sd_unavailable));
+            mSdUnmount.setEnabled(false);
+        }
+
+        File path = Environment.getDataDirectory();
+        StatFs stat = new StatFs(path.getPath());
+        long blockSize = stat.getBlockSize();
+        long availableBlocks = stat.getAvailableBlocks();
+        findPreference("memory_internal_avail").setSummary(formatSize(availableBlocks * blockSize));
+    }
+    
+    private String formatSize(long size) {
+        String suffix = null;
+        
+        // add KB or MB suffix if size is greater than 1K or 1M
+        if (size >= 1024) {
+            suffix = " KB";
+            size /= 1024;
+            if (size >= 1024) {
+                suffix = " MB";
+                size /= 1024;
+            }
+        }
+        
+        DecimalFormat formatter = new DecimalFormat();
+        formatter.setGroupingSize(3);
+        String result = formatter.format(size);
+                
+        if (suffix != null)
+            result = result + suffix;
+        return result;
+    }
+    
+}
diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java
new file mode 100644
index 0000000..a56e607
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings.deviceinfo;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneStateIntentReceiver;
+import com.android.internal.telephony.TelephonyProperties;
+import com.android.settings.R;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Display the following information
+ * # Phone Number
+ * # Network
+ * # Roaming
+ * # IMEI
+ * # IMSI
+ * # Network type
+ * # Signal Strength
+ * # Battery Strength  : TODO
+ * # Uptime
+ * # Awake Time
+ * # XMPP/buzz/tickle status : TODO
+ *
+ */
+public class Status extends PreferenceActivity {
+
+    private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
+    private static final String KEY_BT_ADDRESS = "bt_address";
+    private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
+    private static final int EVENT_SERVICE_STATE_CHANGED = 300;
+    
+    private static final int EVENT_FIX_UPTIME = 500;
+
+    private TelephonyManager mTelephonyManager;
+    private Phone mPhone = null;
+    private PhoneStateIntentReceiver mPhoneStateReceiver;
+    private Resources mRes;
+    private Preference mSignalStrength;
+    private Preference mUptime;
+    private Preference mAwakeTime;
+
+    private static String sUnknown;
+    
+    private Preference mBatteryStatus;
+    private Preference mBatteryLevel;
+
+    private Handler mHandler;
+
+    private static class MyHandler extends Handler {
+        private WeakReference<Status> mStatus;
+
+        public MyHandler(Status activity) {
+            mStatus = new WeakReference<Status>(activity);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Status status = mStatus.get();
+            if (status == null) {
+                return;
+            }
+
+            switch (msg.what) {
+                case EVENT_SIGNAL_STRENGTH_CHANGED:
+                    status.updateSignalStrength();
+                    break;
+
+                case EVENT_SERVICE_STATE_CHANGED:
+                    ServiceState serviceState = status.mPhoneStateReceiver.getServiceState();
+                    status.updateServiceState(serviceState);
+                    break;
+
+                case EVENT_FIX_UPTIME:
+                    status.updateTimes();
+                    sendMessageDelayed(obtainMessage(EVENT_FIX_UPTIME), 1000);
+                    break;
+            }
+        }
+    }
+
+    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
+        
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+
+                int level = intent.getIntExtra("level", 0);
+                int scale = intent.getIntExtra("scale", 100);
+                
+                mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%");
+                
+                int plugType = intent.getIntExtra("plugged", 0);
+                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
+                String statusString;
+                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
+                    statusString = getString(R.string.battery_info_status_charging);
+                    if (plugType > 0) {
+                        statusString = statusString + " " + getString(
+                                (plugType == BatteryManager.BATTERY_PLUGGED_AC)
+                                        ? R.string.battery_info_status_charging_ac
+                                        : R.string.battery_info_status_charging_usb);
+                    }
+                } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+                    statusString = getString(R.string.battery_info_status_discharging);
+                } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
+                    statusString = getString(R.string.battery_info_status_not_charging);
+                } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
+                    statusString = getString(R.string.battery_info_status_full);
+                } else {
+                    statusString = getString(R.string.battery_info_status_unknown);
+                }
+                mBatteryStatus.setSummary(statusString);
+            }
+        }
+    };
+
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onDataConnectionStateChanged(int state) {
+            updateDataState();
+            updateNetworkType();
+        }
+    };
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mHandler = new MyHandler(this);
+        
+        mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
+
+        addPreferencesFromResource(R.xml.device_info_status);
+        mBatteryLevel = findPreference("battery_level");
+        mBatteryStatus = findPreference("battery_status");
+        
+        mRes = getResources();
+        if (sUnknown == null) {
+            sUnknown = mRes.getString(R.string.device_info_default);
+        }
+        
+        mPhone = PhoneFactory.getDefaultPhone();
+        mSignalStrength = findPreference("signal_strength");
+        mUptime = findPreference("up_time");
+        mAwakeTime = findPreference("awake_time");
+        
+        setSummaryText("imei", mPhone.getDeviceId());
+        setSummaryText("imei_sv",
+                ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
+                        .getDeviceSoftwareVersion());
+        setSummaryText("imsi", mPhone.getSubscriberId());
+        setSummaryText("number", mPhone.getLine1Number());
+
+        mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
+        mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
+        mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
+        
+        setWifiStatus();
+        setBtStatus();
+    }   
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        mPhoneStateReceiver.registerIntent();
+        registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+        
+        updateSignalStrength();
+        updateServiceState(mPhone.getServiceState());
+        updateDataState();
+        
+        mTelephonyManager.listen(mPhoneStateListener,
+                  PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_FIX_UPTIME), 0);
+    }
+    
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        mPhoneStateReceiver.unregisterIntent();
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+        unregisterReceiver(mBatteryInfoReceiver);
+        mHandler.removeMessages(EVENT_FIX_UPTIME);
+    }
+
+    /**
+     * @param preference The key for the Preference item
+     * @param property The system property to fetch
+     * @param alt The default value, if the property doesn't exist
+     */
+    private void setSummary(String preference, String property, String alt) {
+        try {
+            findPreference(preference).setSummary(
+                    SystemProperties.get(property, alt));
+        } catch (RuntimeException e) {
+            
+        }
+    }
+
+    private void setSummaryText(String preference, String text) {
+        if (text != null) {
+            findPreference(preference).setSummary(text);
+        }
+    }
+    
+    private void updateNetworkType() {
+        // Whether EDGE, UMTS, etc...
+        setSummary("network_type", TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, sUnknown);
+    }
+    
+    private void updateDataState() {
+        int state = mTelephonyManager.getDataState();
+        String display = mRes.getString(R.string.radioInfo_unknown);
+
+        switch (state) {
+            case TelephonyManager.DATA_CONNECTED:
+                display = mRes.getString(R.string.radioInfo_data_connected);
+                break;
+            case TelephonyManager.DATA_SUSPENDED:
+                display = mRes.getString(R.string.radioInfo_data_suspended);
+                break;
+            case TelephonyManager.DATA_CONNECTING:
+                display = mRes.getString(R.string.radioInfo_data_connecting);
+                break;
+            case TelephonyManager.DATA_DISCONNECTED:
+                display = mRes.getString(R.string.radioInfo_data_disconnected);
+                break;
+        }
+        
+        setSummaryText("data_state", display);
+    }
+
+    private void updateServiceState(ServiceState serviceState) {
+        int state = serviceState.getState();
+        String display = mRes.getString(R.string.radioInfo_unknown);
+        
+        switch (state) {
+            case ServiceState.STATE_IN_SERVICE:
+                display = mRes.getString(R.string.radioInfo_service_in);
+                break;
+            case ServiceState.STATE_OUT_OF_SERVICE:
+            case ServiceState.STATE_EMERGENCY_ONLY:
+                display = mRes.getString(R.string.radioInfo_service_out);
+                break;
+            case ServiceState.STATE_POWER_OFF:
+                display = mRes.getString(R.string.radioInfo_service_off);
+                break;
+        }
+        
+        setSummaryText("service_state", display);
+        
+        if (serviceState.getRoaming()) {
+            setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_in));
+        } else {
+            setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_not));
+        }
+        setSummaryText("operator_name", serviceState.getOperatorAlphaLong());
+    }
+    
+    void updateSignalStrength() {
+        int state =
+                mPhoneStateReceiver.getServiceState().getState();
+        Resources r = getResources();
+
+        if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
+                (ServiceState.STATE_POWER_OFF == state)) {
+            mSignalStrength.setSummary("0");
+        }
+        
+        int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
+        
+        if (-1 == signalDbm) signalDbm = 0;
+
+        int signalAsu = mPhoneStateReceiver.getSignalStrength();
+
+        if (-1 == signalAsu) signalAsu = 0;
+
+        mSignalStrength.setSummary(String.valueOf(signalDbm) + " "
+                    + r.getString(R.string.radioInfo_display_dbm) + "   "
+                    + String.valueOf(signalAsu) + " "
+                    + r.getString(R.string.radioInfo_display_asu));
+    }
+    
+    private void setWifiStatus() {
+        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+
+        Preference wifiMacAddressPref = findPreference(KEY_WIFI_MAC_ADDRESS);
+        String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
+        wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 
+                : getString(R.string.status_unavailable));
+    }
+
+    private void setBtStatus() {
+        BluetoothDevice bluetooth = (BluetoothDevice) getSystemService(BLUETOOTH_SERVICE);
+        Preference btAddressPref = findPreference(KEY_BT_ADDRESS);
+
+        if (bluetooth == null) {
+            // device not BT capable
+            getPreferenceScreen().removePreference(btAddressPref);
+        } else {
+            String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null;
+            btAddressPref.setSummary(!TextUtils.isEmpty(address) ? address
+                    : getString(R.string.status_unavailable));
+        }
+    }
+
+    void updateTimes() {
+        long at = SystemClock.uptimeMillis() / 1000;
+        long ut = SystemClock.elapsedRealtime() / 1000;
+        long st = ut - at;
+
+        if (ut == 0) {
+            ut = 1;
+        }
+
+        mUptime.setSummary(convert(ut));
+        mAwakeTime.setSummary(convert(at) + " (" + (((1000 * at / ut) + 5) / 10) + "%)");
+    }
+    
+    private String pad(int n) {
+        if (n >= 10) {
+            return String.valueOf(n);
+        } else {
+            return "0" + String.valueOf(n);
+        }
+    }
+
+    private String convert(long t) {
+        int s = (int)(t % 60);
+        int m = (int)((t / 60) % 60);
+        int h = (int)((t / 3600));
+
+        return h + ":" + pad(m) + ":" + pad(s);
+    }
+}
diff --git a/src/com/android/settings/quicklaunch/BookmarkPicker.java b/src/com/android/settings/quicklaunch/BookmarkPicker.java
new file mode 100644
index 0000000..5c5ab40
--- /dev/null
+++ b/src/com/android/settings/quicklaunch/BookmarkPicker.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.quicklaunch;
+
+import com.android.settings.R;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Activity to pick a bookmark that will be returned to the caller.
+ * <p>
+ * Currently, bookmarks are either:
+ * <li> Activities that are in the launcher
+ * <li> Activities that are within an app that is capable of being launched with
+ * the {@link Intent#ACTION_CREATE_SHORTCUT}.
+ */
+public class BookmarkPicker extends ListActivity implements SimpleAdapter.ViewBinder {
+
+    private static final String TAG = "BookmarkPicker";
+
+    /** Extra in the returned intent from this activity. */
+    public static final String EXTRA_TITLE = "com.android.settings.quicklaunch.TITLE";
+    
+    /** Extra that should be provided, and will be returned. */
+    public static final String EXTRA_SHORTCUT = "com.android.settings.quicklaunch.SHORTCUT";
+
+    /**
+     * The request code for the screen to create a bookmark that is WITHIN an
+     * application. For example, Gmail can return a bookmark for the inbox
+     * folder.
+     */
+    private static final int REQUEST_CREATE_SHORTCUT = 1;
+
+    /** Intent used to get all the activities that are launch-able */
+    private static Intent sLaunchIntent;
+    /** Intent used to get all the activities that are {@link #REQUEST_CREATE_SHORTCUT}-able */
+    private static Intent sShortcutIntent;
+    
+    /**
+     * List of ResolveInfo for activities that we can bookmark (either directly
+     * to the activity, or by launching the activity and it returning a bookmark
+     * WITHIN that application).
+     */
+    private List<ResolveInfo> mResolveList;
+    
+    // List adapter stuff
+    private static final String KEY_TITLE = "TITLE";
+    private static final String KEY_RESOLVE_INFO = "RESOLVE_INFO";
+    private static final String sKeys[] = new String[] { KEY_TITLE, KEY_RESOLVE_INFO };
+    private static final int sResourceIds[] = new int[] { R.id.title, R.id.icon };
+    private SimpleAdapter mMyAdapter;
+
+    /** Display those activities that are launch-able */
+    private static final int DISPLAY_MODE_LAUNCH = 0;
+    /** Display those activities that are able to have bookmarks WITHIN the application */
+    private static final int DISPLAY_MODE_SHORTCUT = 1;
+    private int mDisplayMode = DISPLAY_MODE_LAUNCH;
+    
+    private Handler mUiHandler = new Handler();
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        updateListAndAdapter();
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, DISPLAY_MODE_LAUNCH, 0, R.string.quick_launch_display_mode_applications)
+                .setIcon(R.drawable.ic_menu_archive);
+        menu.add(0, DISPLAY_MODE_SHORTCUT, 0, R.string.quick_launch_display_mode_shortcuts)
+                .setIcon(R.drawable.ic_menu_goto);
+        return true;
+    }
+    
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(DISPLAY_MODE_LAUNCH).setVisible(mDisplayMode != DISPLAY_MODE_LAUNCH);
+        menu.findItem(DISPLAY_MODE_SHORTCUT).setVisible(mDisplayMode != DISPLAY_MODE_SHORTCUT);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        
+        switch (item.getItemId()) {
+
+            case DISPLAY_MODE_LAUNCH: 
+                mDisplayMode = DISPLAY_MODE_LAUNCH;
+                break;
+            
+            case DISPLAY_MODE_SHORTCUT:
+                mDisplayMode = DISPLAY_MODE_SHORTCUT;
+                break;
+            
+            default:
+                return false;
+        }
+        
+        updateListAndAdapter();
+        return true;
+    }
+
+    private void ensureIntents() {
+        if (sLaunchIntent == null) {
+            sLaunchIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
+            sShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+        }
+    }
+
+    /**
+     * This should be called from the UI thread.
+     */
+    private void updateListAndAdapter() {
+        // Get the activities in a separate thread
+        new Thread("data updater") {
+            @Override
+            public void run() {
+                synchronized (BookmarkPicker.this) {
+                    /*
+                     * Don't touch any of the lists that are being used by the
+                     * adapter in this thread!
+                     */
+                    ArrayList<ResolveInfo> newResolveList = new ArrayList<ResolveInfo>();
+                    ArrayList<Map<String, ?>> newAdapterList = new ArrayList<Map<String, ?>>();
+
+                    fillResolveList(newResolveList);
+                    Collections.sort(newResolveList,
+                            new ResolveInfo.DisplayNameComparator(getPackageManager()));
+                    
+                    fillAdapterList(newAdapterList, newResolveList);
+                    
+                    updateAdapterToUseNewLists(newAdapterList, newResolveList);
+                }
+            }
+        }.start();  
+    }
+    
+    private void updateAdapterToUseNewLists(final ArrayList<Map<String, ?>> newAdapterList,
+            final ArrayList<ResolveInfo> newResolveList) {
+        // Post this back on the UI thread
+        mUiHandler.post(new Runnable() {
+            public void run() {
+                /*
+                 * SimpleAdapter does not support changing the lists after it
+                 * has been created. We just create a new instance.
+                 */
+                mMyAdapter = createResolveAdapter(newAdapterList);
+                mResolveList = newResolveList;
+                setListAdapter(mMyAdapter);
+            }
+        });
+    }
+    
+    /**
+     * Gets all activities matching our current display mode.
+     * 
+     * @param list The list to fill.
+     */
+    private void fillResolveList(List<ResolveInfo> list) {
+        ensureIntents();
+        PackageManager pm = getPackageManager();
+        list.clear();
+        
+        if (mDisplayMode == DISPLAY_MODE_LAUNCH) {
+            list.addAll(pm.queryIntentActivities(sLaunchIntent, 0));
+        } else if (mDisplayMode == DISPLAY_MODE_SHORTCUT) {
+            list.addAll(pm.queryIntentActivities(sShortcutIntent, 0)); 
+        }
+    }
+    
+    private SimpleAdapter createResolveAdapter(List<Map<String, ?>> list) {
+        SimpleAdapter adapter = new SimpleAdapter(this, list,
+                R.layout.bookmark_picker_item, sKeys, sResourceIds);
+        adapter.setViewBinder(this);
+        return adapter;
+    }
+
+    private void fillAdapterList(List<Map<String, ?>> list,
+            List<ResolveInfo> resolveList) {
+        list.clear();
+        int resolveListSize = resolveList.size();
+        for (int i = 0; i < resolveListSize; i++) {
+            ResolveInfo info = resolveList.get(i);
+            /*
+             * Simple adapter craziness. For each item, we need to create a map
+             * from a key to its value (the value can be any object--the view
+             * binder will take care of filling the View with a representation
+             * of that object).
+             */
+            Map<String, Object> map = new TreeMap<String, Object>();
+            map.put(KEY_TITLE, getResolveInfoTitle(info));
+            map.put(KEY_RESOLVE_INFO, info);
+            list.add(map);
+        }
+    }
+
+    /** Get the title for a resolve info. */
+    private String getResolveInfoTitle(ResolveInfo info) {
+        CharSequence label = info.loadLabel(getPackageManager());
+        if (label == null) label = info.activityInfo.name;
+        return label != null ? label.toString() : null;
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        if (position >= mResolveList.size()) return;
+
+        ResolveInfo info = mResolveList.get(position);
+        
+        switch (mDisplayMode) {
+
+            case DISPLAY_MODE_LAUNCH: 
+                // We can go ahead and return the clicked info's intent
+                Intent intent = getIntentForResolveInfo(info, Intent.ACTION_MAIN);
+                intent.addCategory(Intent.CATEGORY_LAUNCHER);
+                finish(intent, getResolveInfoTitle(info));
+                break;
+
+            case DISPLAY_MODE_SHORTCUT:
+                // Start the shortcut activity so the user can pick the actual intent
+                // (example: Gmail's shortcut activity shows a list of mailboxes)
+                startShortcutActivity(info);
+                break;
+        }
+        
+    }
+    
+    private static Intent getIntentForResolveInfo(ResolveInfo info, String action) {
+        Intent intent = new Intent(action);
+        ActivityInfo ai = info.activityInfo;
+        intent.setClassName(ai.packageName, ai.name);
+        return intent;
+    }
+
+    /**
+     * Starts an activity to get a shortcut.
+     * <p>
+     * For example, Gmail has an activity that lists the available labels. It
+     * returns a shortcut intent for going directly to this label.
+     */
+    private void startShortcutActivity(ResolveInfo info) {
+        Intent intent = getIntentForResolveInfo(info, Intent.ACTION_CREATE_SHORTCUT);
+        startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
+        
+        // Will get a callback to onActivityResult
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != RESULT_OK) {
+            return;
+        }
+        
+        switch (requestCode) {
+            
+            case REQUEST_CREATE_SHORTCUT:
+                if (data != null) {
+                    finish((Intent) data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT),
+                            data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
+                }
+                break;
+                
+            default:
+                super.onActivityResult(requestCode, resultCode, data);
+                break;
+        }
+    }
+    
+    /**
+     * Finishes the activity and returns the given data.
+     */
+    private void finish(Intent intent, String title) {
+        // Give back what was given to us (it will have the shortcut, for example)
+        intent.putExtras(getIntent());
+        // Put our information
+        intent.putExtra(EXTRA_TITLE, title);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean setViewValue(View view, Object data, String textRepresentation) {
+        if (view.getId() == R.id.icon) {
+            Drawable icon = ((ResolveInfo) data).loadIcon(getPackageManager());
+            if (icon != null) {
+                ((ImageView) view).setImageDrawable(icon);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/quicklaunch/QuickLaunchSettings.java b/src/com/android/settings/quicklaunch/QuickLaunchSettings.java
new file mode 100644
index 0000000..1b9dff4
--- /dev/null
+++ b/src/com/android/settings/quicklaunch/QuickLaunchSettings.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 com.android.settings.quicklaunch;
+
+import com.android.settings.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.Settings.Bookmarks;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.AdapterView;
+
+/**
+ * Settings activity for quick launch.
+ * <p>
+ * Shows a list of possible shortcuts, the current application each is bound to,
+ * and allows choosing a new bookmark for a shortcut.
+ */
+public class QuickLaunchSettings extends PreferenceActivity implements
+        AdapterView.OnItemLongClickListener, DialogInterface.OnClickListener {
+
+    private static final String TAG = "QuickLaunchSettings";
+
+    private static final String KEY_SHORTCUT_CATEGORY = "shortcut_category";
+
+    private static final int DIALOG_CLEAR_SHORTCUT = 0;
+
+    private static final int REQUEST_PICK_BOOKMARK = 1;
+
+    private static final int COLUMN_SHORTCUT = 0;
+    private static final int COLUMN_TITLE = 1;
+    private static final String[] sProjection = new String[] {
+            Bookmarks.SHORTCUT, Bookmarks.TITLE
+    };
+    private static final String sShortcutSelection = Bookmarks.SHORTCUT + "=?";
+    
+    private Handler mUiHandler = new Handler();
+    
+    private static final String DEFAULT_BOOKMARK_FOLDER = "@default";
+    /** Cursor for Bookmarks provider. */
+    private Cursor mBookmarksCursor;
+    /** Listens for changes to Bookmarks provider. */
+    private BookmarksObserver mBookmarksObserver;
+    /** Used to keep track of which shortcuts have bookmarks. */
+    private SparseBooleanArray mBookmarkedShortcuts;
+    
+    /** Preference category to hold the shortcut preferences. */
+    private PreferenceCategory mShortcutCategory;
+    /** Mapping of a shortcut to its preference. */
+    private SparseArray<ShortcutPreference> mShortcutToPreference;
+
+    /** The bookmark title of the shortcut that is being cleared. */
+    private CharSequence mClearDialogBookmarkTitle;
+    private static final String CLEAR_DIALOG_BOOKMARK_TITLE = "CLEAR_DIALOG_BOOKMARK_TITLE";
+    /** The shortcut that is being cleared. */
+    private char mClearDialogShortcut;
+    private static final String CLEAR_DIALOG_SHORTCUT = "CLEAR_DIALOG_SHORTCUT";
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.quick_launch_settings);
+        
+        mShortcutCategory = (PreferenceCategory) findPreference(KEY_SHORTCUT_CATEGORY);
+        mShortcutToPreference = new SparseArray<ShortcutPreference>();
+        mBookmarksObserver = new BookmarksObserver(mUiHandler);
+        initShortcutPreferences();
+        mBookmarksCursor = managedQuery(Bookmarks.CONTENT_URI, sProjection, null, null);
+        getListView().setOnItemLongClickListener(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        getContentResolver().registerContentObserver(Bookmarks.CONTENT_URI, true,
+                mBookmarksObserver);
+        refreshShortcuts();
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        getContentResolver().unregisterContentObserver(mBookmarksObserver);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        
+        // Restore the clear dialog's info
+        mClearDialogBookmarkTitle = state.getString(CLEAR_DIALOG_BOOKMARK_TITLE);
+        mClearDialogShortcut = (char) state.getInt(CLEAR_DIALOG_SHORTCUT, 0);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        
+        // Save the clear dialog's info
+        outState.putCharSequence(CLEAR_DIALOG_BOOKMARK_TITLE, mClearDialogBookmarkTitle);
+        outState.putInt(CLEAR_DIALOG_SHORTCUT, mClearDialogShortcut);
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+            
+            case DIALOG_CLEAR_SHORTCUT: {
+                // Create the dialog for clearing a shortcut
+                return new AlertDialog.Builder(this)
+                        .setTitle(getString(R.string.quick_launch_clear_dialog_title))
+                        .setIcon(R.drawable.ic_dialog_alert)
+                        .setMessage(getString(R.string.quick_launch_clear_dialog_message,
+                                mClearDialogShortcut, mClearDialogBookmarkTitle))
+                        .setPositiveButton(R.string.quick_launch_clear_ok_button, this)
+                        .setNegativeButton(R.string.quick_launch_clear_cancel_button, this)
+                        .create();
+            }
+        }
+        
+        return super.onCreateDialog(id);
+    }
+    
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        switch (id) {
+            
+            case DIALOG_CLEAR_SHORTCUT: {
+                AlertDialog alertDialog = (AlertDialog) dialog;
+                alertDialog.setMessage(getString(R.string.quick_launch_clear_dialog_message,
+                        mClearDialogShortcut, mClearDialogBookmarkTitle));
+            }
+        }
+    }
+
+    private void showClearDialog(ShortcutPreference pref) {
+
+        if (!pref.hasBookmark()) return;
+        
+        mClearDialogBookmarkTitle = pref.getTitle();
+        mClearDialogShortcut = pref.getShortcut();
+        showDialog(DIALOG_CLEAR_SHORTCUT);
+    }
+    
+    public void onClick(DialogInterface dialog, int which) {
+        if (mClearDialogShortcut > 0 && which == AlertDialog.BUTTON1) {
+            // Clear the shortcut
+            clearShortcut(mClearDialogShortcut);
+        }
+        mClearDialogBookmarkTitle = null;
+        mClearDialogShortcut = 0;
+    }
+
+    private void clearShortcut(char shortcut) {
+        getContentResolver().delete(Bookmarks.CONTENT_URI, sShortcutSelection,
+                new String[] { String.valueOf((int) shortcut) });
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (!(preference instanceof ShortcutPreference)) return false;
+
+        // Open the screen to pick a bookmark for this shortcut
+        ShortcutPreference pref = (ShortcutPreference) preference;
+        Intent intent = new Intent(this, BookmarkPicker.class);
+        intent.putExtra(BookmarkPicker.EXTRA_SHORTCUT, pref.getShortcut());
+        startActivityForResult(intent, REQUEST_PICK_BOOKMARK);
+        
+        return true;
+    }
+
+    public boolean onItemLongClick(AdapterView parent, View view, int position, long id) {
+        
+        // Open the clear shortcut dialog
+        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(position);
+        if (!(pref instanceof ShortcutPreference)) return false;
+        showClearDialog((ShortcutPreference) pref);
+        return true;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != RESULT_OK) {
+            return;
+        }
+
+        if (requestCode == REQUEST_PICK_BOOKMARK) {
+            
+            // Returned from the 'pick bookmark for this shortcut' screen
+            if (data == null) {
+                Log.w(TAG, "Result from bookmark picker does not have an intent.");
+                return;
+            }
+            
+            String title = data.getStringExtra(BookmarkPicker.EXTRA_TITLE);
+            char shortcut = data.getCharExtra(BookmarkPicker.EXTRA_SHORTCUT, (char) 0);
+            updateShortcut(shortcut, title, data);
+            
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
+
+    private void updateShortcut(char shortcut, String title, Intent intent) {
+        
+        // Update the bookmark for a shortcut
+        Bookmarks.add(getContentResolver(), intent, title.toString(), DEFAULT_BOOKMARK_FOLDER,
+                shortcut, 0);
+    }
+    
+    private ShortcutPreference getOrCreatePreference(char shortcut) {
+        ShortcutPreference pref = mShortcutToPreference.get(shortcut);
+        if (pref != null) {
+            return pref;
+        } else {
+            Log.w(TAG, "Unknown shortcut '" + shortcut + "', creating preference anyway");
+            return createPreference(shortcut);
+        }
+    }
+    
+    private ShortcutPreference createPreference(char shortcut) {
+        ShortcutPreference pref = new ShortcutPreference(QuickLaunchSettings.this, shortcut);
+        mShortcutCategory.addPreference(pref);
+        mShortcutToPreference.put(shortcut, pref);
+        return pref;
+    }
+
+    private void initShortcutPreferences() {
+        
+        /** Whether the shortcut has been seen already.  The array index is the shortcut. */
+        SparseBooleanArray shortcutSeen = new SparseBooleanArray();
+        KeyCharacterMap keyMap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
+
+        // Go through all the key codes and create a preference for the appropriate keys
+        for (int keyCode = KeyEvent.MAX_KEYCODE - 1; keyCode >= 0; keyCode--) {
+            // Get the label for the primary char on the key that produces this key code
+            char shortcut = (char) Character.toLowerCase(keyMap.getDisplayLabel(keyCode));
+            if (shortcut == 0 || shortcutSeen.get(shortcut, false)) continue;
+            // TODO: need a to tell if the current keyboard can produce this key code, for now
+            // only allow the letter or digits
+            if (!Character.isLetterOrDigit(shortcut)) continue;
+            shortcutSeen.put(shortcut, true);
+            
+            createPreference(shortcut);
+        }
+    }
+    
+    private synchronized void refreshShortcuts() {
+        Cursor c = mBookmarksCursor;
+        if (c == null) {
+            // Haven't finished querying yet
+            return;
+        }
+        
+        if (!c.requery()) {
+            Log.e(TAG, "Could not requery cursor when refreshing shortcuts.");
+            return;
+        }
+        
+        /**
+         * We use the previous bookmarked shortcuts array to filter out those
+         * shortcuts that had bookmarks before this method call, and don't after
+         * (so we can set the preferences to be without bookmarks).
+         */
+        SparseBooleanArray noLongerBookmarkedShortcuts = mBookmarkedShortcuts;
+        SparseBooleanArray newBookmarkedShortcuts = new SparseBooleanArray(); 
+        while (c.moveToNext()) {
+            char shortcut = Character.toLowerCase((char) c.getInt(COLUMN_SHORTCUT));
+            if (shortcut == 0) continue;
+            
+            ShortcutPreference pref = getOrCreatePreference(shortcut);
+            pref.setTitle(c.getString(COLUMN_TITLE));
+            pref.setSummary(getString(R.string.quick_launch_shortcut,
+                    String.valueOf(shortcut)));
+            pref.setHasBookmark(true);
+            
+            newBookmarkedShortcuts.put(shortcut, true);
+            if (noLongerBookmarkedShortcuts != null) {
+                // After this loop, the shortcuts with value true in this array
+                // will no longer have bookmarks
+                noLongerBookmarkedShortcuts.put(shortcut, false);
+            }
+        }
+        
+        if (noLongerBookmarkedShortcuts != null) {
+            for (int i = noLongerBookmarkedShortcuts.size() - 1; i >= 0; i--) {
+                if (noLongerBookmarkedShortcuts.valueAt(i)) {
+                    // True, so there is no longer a bookmark for this shortcut
+                    char shortcut = (char) noLongerBookmarkedShortcuts.keyAt(i);
+                    ShortcutPreference pref = mShortcutToPreference.get(shortcut);
+                    if (pref != null) {
+                        pref.setHasBookmark(false);
+                    }
+                }
+            }
+        }
+        
+        mBookmarkedShortcuts = newBookmarkedShortcuts;
+        
+        c.deactivate();
+    }
+
+    private class BookmarksObserver extends ContentObserver {
+
+        public BookmarksObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            
+            refreshShortcuts();
+        }
+    }
+}
diff --git a/src/com/android/settings/quicklaunch/ShortcutPreference.java b/src/com/android/settings/quicklaunch/ShortcutPreference.java
new file mode 100644
index 0000000..92efdeb
--- /dev/null
+++ b/src/com/android/settings/quicklaunch/ShortcutPreference.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.quicklaunch;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.preference.Preference;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Preference type for a shortcut in {@link QuickLaunchSettings}.
+ */
+public class ShortcutPreference extends Preference implements Comparable<Preference> {
+
+    private static Object sStaticVarsLock = new Object();
+    
+    // These static fields are used across all instances of ShortcutPreference.
+    // There will be many ShortcutPreference instances (~36 for US).
+    private static String STRING_ASSIGN_APPLICATION;
+    private static String STRING_NO_SHORTCUT;
+
+    private static int sDimAlpha;
+    private static ColorStateList sRegularTitleColor;
+    private static ColorStateList sDimTitleColor;
+    private static ColorStateList sRegularSummaryColor;
+    private static ColorStateList sDimSummaryColor;
+    
+    private char mShortcut;
+    private boolean mHasBookmark;
+    
+    public ShortcutPreference(Context context, char shortcut) {
+        super(context);
+
+        synchronized (sStaticVarsLock) {
+            // Init statics. This should only happen for the first ShortcutPreference created,
+            // the rest will already have them initialized.
+            if (STRING_ASSIGN_APPLICATION == null) {
+                STRING_ASSIGN_APPLICATION = context.getString(R.string.quick_launch_assign_application);
+                STRING_NO_SHORTCUT = context.getString(R.string.quick_launch_no_shortcut);
+    
+                TypedValue outValue = new TypedValue();
+                context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
+                sDimAlpha = (int) (outValue.getFloat() * 255);
+            }
+        }
+        
+        mShortcut = shortcut;
+
+        setWidgetLayoutResource(R.layout.preference_widget_shortcut);
+    }
+
+    public char getShortcut() {
+        return mShortcut;
+    }
+
+    public void setShortcut(char shortcut) {
+        if (shortcut != mShortcut) {
+            mShortcut = shortcut;
+            notifyChanged();
+        }
+    }
+
+    public boolean hasBookmark() {
+        return mHasBookmark;
+    }
+
+    public void setHasBookmark(boolean hasBookmark) {
+        if (hasBookmark != mHasBookmark) {
+            mHasBookmark = hasBookmark;
+            notifyChanged();
+        }
+    }
+
+    @Override
+    public CharSequence getTitle() {
+        return mHasBookmark ? super.getTitle() : STRING_ASSIGN_APPLICATION;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return mHasBookmark ? super.getSummary() : STRING_NO_SHORTCUT;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        
+        TextView shortcutView = (TextView) view.findViewById(R.id.shortcut);
+        if (shortcutView != null) {
+            shortcutView.setText(String.valueOf(mShortcut));
+        }
+    
+        TextView titleView = (TextView) view.findViewById(android.R.id.title);
+
+        synchronized (sStaticVarsLock) {
+            if (sRegularTitleColor == null) {
+                sRegularTitleColor = titleView.getTextColors();
+                sDimTitleColor = sRegularTitleColor.withAlpha(sDimAlpha);
+            }
+        }
+        
+        ColorStateList color = mHasBookmark ? sRegularTitleColor : sDimTitleColor;
+        if (color != null) {
+            titleView.setTextColor(color);
+        }
+        
+        TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
+
+        synchronized (sStaticVarsLock) {
+            if (sRegularSummaryColor == null) {
+                sRegularSummaryColor = summaryView.getTextColors();
+                sDimSummaryColor = sRegularSummaryColor.withAlpha(sDimAlpha);
+            }
+        }
+        
+        color = mHasBookmark ? sRegularSummaryColor : sDimSummaryColor;
+        if (color != null) {
+            summaryView.setTextColor(color);
+        }
+        
+    }
+
+    public int compareTo(Preference another) {
+        if (!(another instanceof ShortcutPreference)) return super.compareTo(another);
+
+        // Letters before digits
+        char other = ((ShortcutPreference) another).mShortcut;
+        if (Character.isDigit(mShortcut) && Character.isLetter(other)) return 1;
+        else if (Character.isDigit(other) && Character.isLetter(mShortcut)) return -1;
+        else return mShortcut - other;
+    }
+    
+}
diff --git a/src/com/android/settings/wifi/AccessPointDialog.java b/src/com/android/settings/wifi/AccessPointDialog.java
new file mode 100644
index 0000000..95e469f
--- /dev/null
+++ b/src/com/android/settings/wifi/AccessPointDialog.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.R;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.text.method.PasswordTransformationMethod;
+import android.text.method.TransformationMethod;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TableLayout;
+import android.widget.TextView;
+
+public class AccessPointDialog extends AlertDialog implements DialogInterface.OnClickListener,
+        AdapterView.OnItemSelectedListener, View.OnClickListener {
+
+    private static final String TAG = "AccessPointDialog";
+    private static final String INSTANCE_KEY_ACCESS_POINT_STATE =
+            "com.android.settings.wifi.AccessPointDialog:accessPointState";
+    private static final String INSTANCE_KEY_MODE =
+            "com.android.settings.wifi.AccessPointDialog:mode";
+    private static final String INSTANCE_KEY_CUSTOM_TITLE =
+            "com.android.settings.wifi.AccessPointDialog:customTitle";
+    private static final String INSTANCE_KEY_AUTO_SECURITY_ALLOWED =
+            "com.android.settings.wifi.AccessPointDialog:autoSecurityAllowed";
+    
+    private static final int POSITIVE_BUTTON = BUTTON1;
+    private static final int NEGATIVE_BUTTON = BUTTON2;
+    private static final int NEUTRAL_BUTTON = BUTTON3;
+    
+    /** The dialog should show info connectivity functionality */
+    public static final int MODE_INFO = 0;
+    /** The dialog should configure the detailed AP properties */
+    public static final int MODE_CONFIGURE = 1;
+    /** The dialog should have the password field and connect/cancel */
+    public static final int MODE_RETRY_PASSWORD = 2;
+    
+    // These should be matched with the XML. Both arrays in XML depend on this
+    // ordering!
+    private static final int SECURITY_AUTO = 0;
+    private static final int SECURITY_NONE = 1;
+    private static final int SECURITY_WEP = 2;
+    private static final int SECURITY_WPA_PERSONAL = 3;
+    private static final int SECURITY_WPA2_PERSONAL = 4;
+
+    private static final int[] WEP_TYPE_VALUES = {
+            AccessPointState.WEP_PASSWORD_AUTO, AccessPointState.WEP_PASSWORD_ASCII,
+            AccessPointState.WEP_PASSWORD_HEX
+    };
+    
+    // Button positions, default to impossible values
+    private int mConnectButtonPos = Integer.MAX_VALUE; 
+    private int mForgetButtonPos = Integer.MAX_VALUE;
+    private int mSaveButtonPos = Integer.MAX_VALUE;
+
+    // Client configurable items. Generally, these should be saved in instance state
+    private int mMode = MODE_INFO;
+    private boolean mAutoSecurityAllowed = true;
+    private CharSequence mCustomTitle;
+    // This does not need to be saved in instance state.
+    private WifiLayer mWifiLayer;
+    private AccessPointState mState;
+    
+    // General views
+    private View mView;
+    private TextView mPasswordText;
+    private EditText mPasswordEdit;
+    private CheckBox mShowPasswordCheckBox;
+    
+    // Info-specific views
+    private ViewGroup mTable;
+    
+    // Configure-specific views
+    private EditText mSsidEdit;
+    private Spinner mSecuritySpinner;
+    private Spinner mWepTypeSpinner;
+    
+    public AccessPointDialog(Context context, WifiLayer wifiLayer) {
+        super(context);
+
+        mWifiLayer = wifiLayer;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        onLayout();
+        onFill();
+
+        super.onCreate(savedInstanceState);
+    }
+    
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        // Set to a class loader that can find AccessPointState
+        savedInstanceState.setClassLoader(getClass().getClassLoader());
+        
+        mState = savedInstanceState.getParcelable(INSTANCE_KEY_ACCESS_POINT_STATE);
+        mState.setContext(getContext());
+        
+        mMode = savedInstanceState.getInt(INSTANCE_KEY_MODE, mMode);
+        mAutoSecurityAllowed = savedInstanceState.getBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED,
+                mAutoSecurityAllowed);
+        mCustomTitle = savedInstanceState.getCharSequence(INSTANCE_KEY_CUSTOM_TITLE);
+        if (mCustomTitle != null) {
+            setTitle(mCustomTitle);
+        }
+
+        // This is called last since it depends on the above values 
+        super.onRestoreInstanceState(savedInstanceState);
+        
+        if (mShowPasswordCheckBox != null) {
+            // Restore the show-password-state on the edit text
+            setShowPassword(mShowPasswordCheckBox.isChecked());
+        }
+    }
+
+    @Override
+    public Bundle onSaveInstanceState() {
+        Bundle bundle = super.onSaveInstanceState();
+        bundle.putParcelable(INSTANCE_KEY_ACCESS_POINT_STATE, mState);
+        bundle.putInt(INSTANCE_KEY_MODE, mMode);
+        bundle.putBoolean(INSTANCE_KEY_AUTO_SECURITY_ALLOWED, mAutoSecurityAllowed);
+        bundle.putCharSequence(INSTANCE_KEY_CUSTOM_TITLE, mCustomTitle);
+        return bundle;
+    }
+
+    /**
+     * Sets state to show in this dialog.
+     * 
+     * @param state The state.
+     */
+    public void setState(AccessPointState state) {
+        mState = state;
+    }
+
+    /**
+     * Sets the dialog mode.
+     * @param mode One of {@link #MODE_CONFIGURE} or {@link #MODE_INFO}
+     */
+    public void setMode(int mode) {
+        mMode = mode;
+    }
+
+    public void setAutoSecurityAllowed(boolean autoSecurityAllowed) {
+        mAutoSecurityAllowed = autoSecurityAllowed;
+    }
+
+    @Override
+    public void setTitle(CharSequence title) {
+        super.setTitle(title);
+        mCustomTitle = title;
+    }
+
+    @Override
+    public void setTitle(int titleId) {
+        setTitle(getContext().getString(titleId));
+    }
+
+    /** Called after flags are set, the dialog's layout/etc should be set up here */
+    private void onLayout() {
+        final Context context = getContext();
+        final String ssid = mState.getHumanReadableSsid();
+        
+        int positiveButtonResId = 0;
+        int negativeButtonResId = R.string.cancel;
+        int neutralButtonResId = 0;
+
+        if (mCustomTitle == null) {
+            // Generic title is the SSID
+            // We don't want to trigger this as a custom title, so call super's
+            super.setTitle(ssid);
+        }
+        setInverseBackgroundForced(true);
+
+        boolean defaultPasswordVisibility = true;
+        
+        if (mMode == MODE_CONFIGURE) {
+            setLayout(R.layout.wifi_ap_configure);
+
+            positiveButtonResId = R.string.wifi_save_config;
+            mSaveButtonPos = POSITIVE_BUTTON;
+            
+        } else if (mMode == MODE_INFO) {
+            setLayout(R.layout.wifi_ap_info);
+
+            if (mState.isConnectable()) {
+                if (mCustomTitle == null) {
+                    // We don't want to trigger this as a custom title, so call super's
+                    super.setTitle(context.getString(R.string.connect_to_blank, ssid));
+                }
+                positiveButtonResId = R.string.connect;
+                mConnectButtonPos = POSITIVE_BUTTON;
+            }
+
+            if (mState.isForgetable()) {
+                if (positiveButtonResId == 0) {
+                    positiveButtonResId = R.string.forget_network;
+                    mForgetButtonPos = POSITIVE_BUTTON;
+                } else {
+                    neutralButtonResId = R.string.forget_network;
+                    mForgetButtonPos = NEUTRAL_BUTTON;
+                }
+            }
+        } else if (mMode == MODE_RETRY_PASSWORD) {
+            setLayout(R.layout.wifi_ap_retry_password);
+            
+            positiveButtonResId = R.string.connect;
+            mConnectButtonPos = POSITIVE_BUTTON;
+            
+            setGenericPasswordVisible(true);
+            defaultPasswordVisibility = false;
+        }
+
+        if (defaultPasswordVisibility) {
+            if (!mState.configured && mState.seen && mState.hasSecurity()) {
+                setGenericPasswordVisible(true);
+            } else {
+                setGenericPasswordVisible(false);
+            }
+        }
+        
+        setButtons(positiveButtonResId, negativeButtonResId, neutralButtonResId);
+    }
+
+    /** Called when we need to set our member variables to point to the views. */
+    private void onReferenceViews(View view) {
+        mPasswordText = (TextView) view.findViewById(R.id.password_text);
+        mPasswordEdit = (EditText) view.findViewById(R.id.password_edit);
+        
+        mShowPasswordCheckBox = (CheckBox) view.findViewById(R.id.show_password_checkbox);
+        if (mShowPasswordCheckBox != null) {
+            mShowPasswordCheckBox.setOnClickListener(this);
+        }
+        
+        if (mMode == MODE_CONFIGURE) {
+            mSsidEdit = (EditText) view.findViewById(R.id.ssid_edit);
+            mSecuritySpinner = (Spinner) view.findViewById(R.id.security_spinner);
+            mSecuritySpinner.setOnItemSelectedListener(this);
+            setSecuritySpinnerAdapter();
+            mWepTypeSpinner = (Spinner) view.findViewById(R.id.wep_type_spinner);
+            
+        } else if (mMode == MODE_INFO) {
+            mTable = (ViewGroup) view.findViewById(R.id.table);
+        }
+        
+    }
+    
+    private void setSecuritySpinnerAdapter() {
+        Context context = getContext();
+        int arrayResId = mAutoSecurityAllowed ? R.array.wifi_security_entries
+                : R.array.wifi_security_without_auto_entries;         
+
+        ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context,
+                android.R.layout.simple_spinner_item,
+                context.getResources().getStringArray(arrayResId));
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mSecuritySpinner.setAdapter(adapter);
+    }
+    
+    /** Called when the widgets are in-place waiting to be filled with data */
+    private void onFill() {
+
+        // Appears in the order added
+        if (mMode == MODE_INFO) {
+            if (mState.primary) {
+                addInfoRow(R.string.wifi_status, mState.getSummarizedStatus());
+                addInfoRow(R.string.wifi_link_speed, mState.linkSpeed + WifiInfo.LINK_SPEED_UNITS);
+            }
+    
+            if (mState.seen) {
+                addInfoRow(R.string.signal, getSignalResId(mState.signal));
+            }
+            
+            if (mState.security != null) {
+                addInfoRow(R.string.security, mState.getHumanReadableSecurity());
+            }
+    
+            if (mState.primary && mState.ipAddress != 0) {
+                addInfoRow(R.string.ip_address, ipAddressToString(mState.ipAddress));
+            }
+            
+        } else if (mMode == MODE_CONFIGURE) {
+            String ssid = mState.getHumanReadableSsid();
+            if (!TextUtils.isEmpty(ssid)) {
+                mSsidEdit.setText(ssid);
+            }
+            
+            mPasswordEdit.setHint(R.string.wifi_password_unchanged);
+        }
+
+        updatePasswordCaption(mState.security);
+    }
+
+    private void updatePasswordCaption(String security) {
+        
+        if (mPasswordText != null && security != null
+                && security.equals(AccessPointState.WEP)) {
+            mPasswordText.setText(R.string.please_type_hex_key);
+        } else {
+            mPasswordText.setText(R.string.please_type_passphrase);
+        }
+    }
+    
+    private void addInfoRow(int nameResId, String value) {
+        View rowView = getLayoutInflater().inflate(R.layout.wifi_ap_info_row, mTable, false);
+        ((TextView) rowView.findViewById(R.id.name)).setText(nameResId);
+        ((TextView) rowView.findViewById(R.id.value)).setText(value);
+        mTable.addView(rowView);
+    }
+        
+    private void addInfoRow(int nameResId, int valueResId) {
+        addInfoRow(nameResId, getContext().getString(valueResId));
+    }
+    
+    private void setButtons(int positiveResId, int negativeResId, int neutralResId) {
+        final Context context = getContext();
+        
+        if (positiveResId > 0) {
+            setButton(context.getString(positiveResId), this);
+        }
+        
+        if (negativeResId > 0) {
+            setButton2(context.getString(negativeResId), this);
+        }
+
+        if (neutralResId > 0) {
+            setButton3(context.getString(neutralResId), this);
+        }
+    }
+    
+    private void setLayout(int layoutResId) {
+        setView(mView = getLayoutInflater().inflate(layoutResId, null));
+        onReferenceViews(mView);
+    }
+    
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == mForgetButtonPos) {
+            handleForget();
+        } else if (which == mConnectButtonPos) {
+            handleConnect();
+        } else if (which == mSaveButtonPos) {
+            handleSave();
+        }
+    }
+    
+    private void handleForget() {
+        if (!replaceStateWithWifiLayerInstance()) return;
+        mWifiLayer.forgetNetwork(mState);
+    }
+    
+    private void handleConnect() {
+        if (!replaceStateWithWifiLayerInstance()) {
+            Log.w(TAG, "Assuming connecting to a new network.");
+        }
+        
+        /*
+         * If the network is secured and they haven't entered a password, popup
+         * an error. Allow empty passwords if the state already has a password
+         * set (since in that scenario, an empty password means keep the old
+         * password).
+         */
+        String password = getEnteredPassword();
+        boolean passwordIsEmpty = TextUtils.isEmpty(password);
+        
+        /*
+         * When 'retry password', they can not enter a blank password. In any
+         * other mode, we let them enter a blank password if the state already
+         * has a password.
+         */
+        if (passwordIsEmpty && (!mState.hasPassword() || mMode == MODE_RETRY_PASSWORD)
+                && (mState.security != null) && !mState.security.equals(AccessPointState.OPEN)) {
+            new AlertDialog.Builder(getContext())
+                    .setTitle(R.string.error_title)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(R.string.wifi_password_incorrect_error)
+                    .setPositiveButton(android.R.string.ok, null)
+                    .show();
+            return;
+        }
+        
+        if (!passwordIsEmpty) { 
+            mState.setPassword(password);
+        }
+        
+        mWifiLayer.connectToNetwork(mState);            
+    }
+    
+    private void handleSave() {
+        replaceStateWithWifiLayerInstance();
+
+        String ssid = mSsidEdit.getText().toString();
+        String password = mPasswordEdit.getText().toString();
+        
+        mState.setSsid(ssid);
+        
+        int securityType = getSecurityTypeFromSpinner();
+        
+        if (!TextUtils.isEmpty(password)) {
+            switch (securityType) {
+             
+                case SECURITY_WPA_PERSONAL: {
+                    mState.setSecurity(AccessPointState.WPA);
+                    mState.setPassword(password);
+                    break;
+                }
+                    
+                case SECURITY_WPA2_PERSONAL: {
+                    mState.setSecurity(AccessPointState.WPA2);
+                    mState.setPassword(password);
+                    break;
+                }
+                
+                case SECURITY_AUTO: {
+                    mState.setPassword(password);
+                    break;
+                }
+                    
+                case SECURITY_WEP: {
+                    mState.setSecurity(AccessPointState.WEP);
+                    mState.setPassword(password,
+                            WEP_TYPE_VALUES[mWepTypeSpinner.getSelectedItemPosition()]);
+                    break;
+                }
+                
+            }
+        } else {
+            mState.setSecurity(AccessPointState.OPEN);
+        }
+        
+        if (securityType == SECURITY_NONE) {
+            mState.setSecurity(AccessPointState.OPEN);
+        }
+            
+        if (!mWifiLayer.saveNetwork(mState)) {
+            return;
+        }
+        
+        // Connect right away if they've touched it
+        if (!mWifiLayer.connectToNetwork(mState)) {
+            return;
+        }
+        
+    }
+    
+    /**
+     * Replaces our {@link #mState} with the equal WifiLayer instance.  This is useful after
+     * we unparceled the state previously and before we are calling methods on {@link #mWifiLayer}.
+     * 
+     * @return Whether WifiLayer was able to find an equal state in its set.
+     */
+    private boolean replaceStateWithWifiLayerInstance() {
+        AccessPointState state = mWifiLayer.getWifiLayerApInstance(mState);
+        if (state == null) {
+            return false;
+        }
+        
+        mState = state;
+        return true;
+    }
+    
+    private int getSecurityTypeFromSpinner() {
+        int position = mSecuritySpinner.getSelectedItemPosition();
+        // If there is no AUTO choice, the position needs 1 added to get
+        // to the proper spinner position -> security constants mapping
+        return mAutoSecurityAllowed ? position : position + 1;
+    }
+    
+    private String getEnteredPassword() {
+        return mPasswordEdit != null ? mPasswordEdit.getText().toString() : null;
+    }
+    
+    /**
+     * Call the one you want to hide first.
+     */
+    private void setWepVisible(boolean visible) {
+        setGenericPasswordVisible(visible);
+        int visibility = visible ? View.VISIBLE : View.GONE;
+        mWepTypeSpinner.setVisibility(visibility);
+    }
+    
+    /**
+     * @see #setWepVisible(boolean)
+     */
+    private void setGenericPasswordVisible(boolean visible) {
+        int visibility = visible ? View.VISIBLE : View.GONE;
+        mPasswordText.setVisibility(visibility);
+        mPasswordEdit.setVisibility(visibility);
+        mShowPasswordCheckBox.setVisibility(visibility);
+    }
+    
+    public void onItemSelected(AdapterView parent, View view, int position, long id) {
+        if (parent == mSecuritySpinner) {
+            handleSecurityChange(getSecurityTypeFromSpinner());
+        }
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+
+    private void handleSecurityChange(int security) {
+        
+        switch (security) {
+            
+            case SECURITY_NONE: {
+                setWepVisible(false);
+                setGenericPasswordVisible(false);
+                break;
+            }
+            
+            case SECURITY_WEP: {
+                setGenericPasswordVisible(false);
+                setWepVisible(true);
+                updatePasswordCaption(AccessPointState.WEP);
+                break;
+            }
+            
+            case SECURITY_AUTO: {
+                setWepVisible(false);
+                setGenericPasswordVisible(mState.hasSecurity());
+                // Shows the generic 'wireless password'
+                updatePasswordCaption(AccessPointState.WPA);
+                break;
+            }
+            
+            case SECURITY_WPA_PERSONAL:
+            case SECURITY_WPA2_PERSONAL: {
+                setWepVisible(false);
+                setGenericPasswordVisible(true);
+                // Both WPA and WPA2 show the same caption, so either is ok
+                updatePasswordCaption(AccessPointState.WPA);
+                break;
+            }
+        }
+    }
+
+    private static int getSignalResId(int signal) {
+        switch (WifiManager.calculateSignalLevel(signal, 4)) {
+            case 0: {
+                return R.string.wifi_signal_0;
+            }
+            case 1: {
+                return R.string.wifi_signal_1;
+            }
+            case 2: {
+                return R.string.wifi_signal_2;
+            }
+            case 3: {
+                return R.string.wifi_signal_3;
+            }
+        }
+        
+        return 0;
+    }
+    
+    private static String ipAddressToString(int addr) {
+        StringBuffer buf = new StringBuffer();
+        buf.append(addr  & 0xff).append('.').
+            append((addr >>>= 8) & 0xff).append('.').
+            append((addr >>>= 8) & 0xff).append('.').
+            append((addr >>>= 8) & 0xff);
+        return buf.toString();
+    }
+
+    public void onClick(View v) {
+        if (v == mShowPasswordCheckBox) {
+            setShowPassword(mShowPasswordCheckBox.isChecked());
+        }
+    }
+    
+    private void setShowPassword(boolean showPassword) {
+        if (mPasswordEdit != null) {
+            // Toggle password
+            mPasswordEdit.setTransformationMethod(
+                    showPassword ?
+                            null :
+                            PasswordTransformationMethod.getInstance());
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/wifi/AccessPointPreference.java b/src/com/android/settings/wifi/AccessPointPreference.java
new file mode 100644
index 0000000..10e0947
--- /dev/null
+++ b/src/com/android/settings/wifi/AccessPointPreference.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.R;
+
+import android.net.wifi.WifiManager;
+import android.preference.Preference;
+import android.view.View;
+import android.widget.ImageView;
+
+public class AccessPointPreference extends Preference implements
+        AccessPointState.AccessPointStateCallback {
+    
+    // UI states
+    private static final int[] STATE_ENCRYPTED = { R.attr.state_encrypted };
+    private static final int[] STATE_EMPTY = { };
+    
+    // Signal strength indicator
+    private static final int UI_SIGNAL_LEVELS = 4;
+
+    private WifiSettings mWifiSettings;
+    
+    private AccessPointState mState;
+
+    public AccessPointPreference(WifiSettings wifiSettings, AccessPointState state) {
+        super(wifiSettings, null);
+        
+        mWifiSettings = wifiSettings;
+        mState = state;
+        
+        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
+        
+        state.setCallback(this);
+        
+        refresh();
+    }
+    
+    public void refresh() {
+        setTitle(mState.getHumanReadableSsid());
+        setSummary(mState.getSummarizedStatus());
+
+        notifyChanged();
+    }
+    
+    public void refreshAccessPointState() {
+        refresh();
+        
+        // The ordering of access points could have changed due to the state change, so
+        // re-evaluate ordering
+        notifyHierarchyChanged();
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        ImageView signal = (ImageView) view.findViewById(R.id.signal);
+        if (mState.seen) {
+            signal.setImageResource(R.drawable.wifi_signal);
+            signal.setImageState(mState.hasSecurity() ? STATE_ENCRYPTED : STATE_EMPTY, true);
+            signal.setImageLevel(getUiSignalLevel());
+        } else {
+            signal.setImageDrawable(null);
+        }
+    }
+
+    private int getUiSignalLevel() {
+        return mState != null ? WifiManager.calculateSignalLevel(mState.signal, UI_SIGNAL_LEVELS)
+                : 0; 
+    }
+
+    /**
+     * Returns the {@link AccessPointState} associated with this preference.
+     * @return The {@link AccessPointState}.
+     */
+    public AccessPointState getAccessPointState() {
+        return mState;
+    }
+    
+    @Override
+    public int compareTo(Preference another) {
+        if (!(another instanceof AccessPointPreference)) {
+            // Let normal preferences go before us.
+            // NOTE: we should only be compared to Preference in our
+            //       category.
+            return 1;
+        }
+        
+        return mState.compareTo(((AccessPointPreference) another).mState);
+    }
+    
+}
+
diff --git a/src/com/android/settings/wifi/AccessPointState.java b/src/com/android/settings/wifi/AccessPointState.java
new file mode 100644
index 0000000..8dabbd1
--- /dev/null
+++ b/src/com/android/settings/wifi/AccessPointState.java
@@ -0,0 +1,869 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiConfiguration.AuthAlgorithm;
+import android.net.wifi.WifiConfiguration.GroupCipher;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.PairwiseCipher;
+import android.net.wifi.WifiConfiguration.Protocol;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+public final class AccessPointState implements Comparable<AccessPointState>, Parcelable {
+
+    private static final String TAG = "AccessPointState";
+    
+    // Constants used for different security types
+    public static final String WPA2 = "WPA2";
+    public static final String WPA = "WPA";
+    public static final String WEP = "WEP";
+    public static final String OPEN = "Open";
+
+    /** String present in capabilities if the scan result is ad-hoc */
+    private static final String ADHOC_CAPABILITY = "[IBSS]";
+    /** String present in capabilities if the scan result is enterprise secured */
+    private static final String ENTERPRISE_CAPABILITY = "-EAP-";
+    
+    // Localized strings for different security types
+    private static String LOCALIZED_WPA2;
+    private static String LOCALIZED_WPA;
+    private static String LOCALIZED_WEP;
+    private static String LOCALIZED_OPEN;
+    private static String LOCALIZED_UNKNOWN;
+    private static String LOCALIZED_VERBOSE_WPA2;
+    private static String LOCALIZED_VERBOSE_WPA;
+    private static String LOCALIZED_VERBOSE_WEP;
+    private static String LOCALIZED_VERBOSE_OPEN;
+
+    
+    // Localized strings for various messages
+    private static String SUMMARY_NOT_IN_RANGE;
+    private static String SUMMARY_REMEMBERED;
+    private static String SUMMARY_CONNECTION_FAILED;
+    
+    public static final String BSSID_ANY = "any";
+    public static final int NETWORK_ID_NOT_SET = -1;
+    /** This should be used with care! */
+    static final int NETWORK_ID_ANY = -2;
+    
+    public static final int MATCH_NONE = 0;
+    public static final int MATCH_WEAK = 1;
+    public static final int MATCH_STRONG = 2;
+    public static final int MATCH_EXACT = 3;
+    
+    // Don't set these directly, use the setters.
+    public int networkId;
+    public int priority;
+    public boolean hiddenSsid;
+    public int linkSpeed;
+    public int ipAddress;
+    public String bssid;
+    public String ssid;
+    public int signal;
+    public boolean primary;
+    public boolean seen;
+    public boolean configured;
+    public NetworkInfo.DetailedState status;
+    public String security;
+    public boolean disabled;
+    
+    /**
+     * Use this for sorting based on signal strength. It is a heavily-damped
+     * time-averaged weighted signal.
+     */
+    private float signalForSorting = Float.MIN_VALUE;
+    
+    private static final float DAMPING_FACTOR = 0.2f;
+    
+    /**
+     * This will be a user entered password, and NOT taken from wpa_supplicant
+     * (since it would give us *)
+     */
+    private String mPassword; 
+    private boolean mConfigHadPassword;
+    
+    public static final int WEP_PASSWORD_AUTO = 0;
+    public static final int WEP_PASSWORD_ASCII = 1;
+    public static final int WEP_PASSWORD_HEX = 2;
+    private int mWepPasswordType;
+    
+    private Context mContext;
+
+    /**
+     * If > 0, don't refresh (changes are being batched), use
+     * {@link #blockRefresh()} and {@link #unblockRefresh()} only.
+     */
+    private int mBlockRefresh;
+    /**
+     * This will be set by {@link #requestRefresh} and shouldn't be written to
+     * elsewhere.
+     */
+    private boolean mNeedsRefresh;    
+    
+    private AccessPointStateCallback mCallback;
+    
+    private StringBuilder mSummaryBuilder = new StringBuilder();
+    
+    interface AccessPointStateCallback {
+        void refreshAccessPointState();
+    }
+    
+    public AccessPointState(Context context) {
+        this();
+        
+        setContext(context);
+    }
+
+    private AccessPointState() {
+        bssid = BSSID_ANY;
+        ssid = "";
+        networkId = NETWORK_ID_NOT_SET;
+        hiddenSsid = false;
+    }
+
+    void setContext(Context context) {
+        mContext = context;
+        setStrings();
+    }
+
+    private void setStrings() {
+        final Context c = mContext;
+
+        if (SUMMARY_NOT_IN_RANGE == null && c != null) {
+            SUMMARY_NOT_IN_RANGE = c.getString(R.string.summary_not_in_range);
+            SUMMARY_REMEMBERED = c.getString(R.string.summary_remembered);
+            SUMMARY_CONNECTION_FAILED = c.getString(R.string.summary_connection_failed);
+            
+            LOCALIZED_OPEN = c.getString(R.string.wifi_security_open);
+            LOCALIZED_WEP = c.getString(R.string.wifi_security_wep);
+            LOCALIZED_WPA = c.getString(R.string.wifi_security_wpa);
+            LOCALIZED_WPA2 = c.getString(R.string.wifi_security_wpa2);
+
+            LOCALIZED_VERBOSE_OPEN = c.getString(R.string.wifi_security_verbose_open);
+            LOCALIZED_VERBOSE_WEP = c.getString(R.string.wifi_security_verbose_wep);
+            LOCALIZED_VERBOSE_WPA = c.getString(R.string.wifi_security_verbose_wpa);
+            LOCALIZED_VERBOSE_WPA2 = c.getString(R.string.wifi_security_verbose_wpa2);
+
+            LOCALIZED_UNKNOWN = c.getString(R.string.wifi_security_unknown);
+        }
+    }
+    
+    public void setNetworkId(int networkId) {
+        this.networkId = networkId;
+    }
+    
+    public void setBssid(String bssid) {
+        if (bssid != null) {
+            // If the BSSID is a wildcard, do NOT let a specific BSSID replace it
+            if (!this.bssid.equals(BSSID_ANY)) {
+                this.bssid = bssid;
+            }
+        }
+    }
+
+    private String getWpaSupplicantBssid() {
+        return bssid.equals(BSSID_ANY) ? null : bssid;
+    }
+    
+    public static String convertToQuotedString(String string) {
+        if (TextUtils.isEmpty(string)) {
+            return "";
+        }
+        
+        final int lastPos = string.length() - 1;
+        if (lastPos < 0 || (string.charAt(0) == '"' && string.charAt(lastPos) == '"')) {
+            return string;
+        }
+        
+        return "\"" + string + "\"";
+    }
+    
+    public void setPrimary(boolean primary) {
+        if (this.primary != primary) {
+            this.primary = primary;
+            requestRefresh();
+        }
+    }
+    
+    public void setSeen(boolean seen) {
+        if (this.seen != seen) {
+            this.seen = seen;
+            requestRefresh();
+        }
+    }
+    
+    public void setDisabled(boolean disabled) {
+        if (this.disabled != disabled) {
+            this.disabled = disabled;
+            requestRefresh();
+        }
+    }
+    
+    public void setSignal(int signal) {
+
+        if (signalForSorting == Float.MIN_VALUE) {
+            signalForSorting = signal;
+        } else {
+            signalForSorting = (DAMPING_FACTOR * signal) + ((1-DAMPING_FACTOR) * signalForSorting);
+        }
+
+        if (this.signal != signal) {
+            this.signal = signal;
+            requestRefresh();
+        }
+    }
+    
+    public String getHumanReadableSsid() {
+        if (TextUtils.isEmpty(ssid)) {
+            return "";
+        }
+        
+        final int lastPos = ssid.length() - 1;
+        if (ssid.charAt(0) == '"' && ssid.charAt(lastPos) == '"') {
+            return ssid.substring(1, lastPos);
+        }
+        
+        return ssid;
+    }
+    
+    public void setSsid(String ssid) {
+        if (ssid != null) {
+            this.ssid = convertToQuotedString(ssid);
+            requestRefresh();
+        }
+    }
+    
+    public void setPriority(int priority) {
+        if (this.priority != priority) {
+            this.priority = priority;
+            requestRefresh();
+        }
+    }
+
+    public void setHiddenSsid(boolean hiddenSsid) {
+        if (this.hiddenSsid != hiddenSsid) {
+            this.hiddenSsid = hiddenSsid;
+            requestRefresh();
+        }
+    }
+
+    public void setLinkSpeed(int linkSpeed) {
+        if (this.linkSpeed != linkSpeed) {
+            this.linkSpeed = linkSpeed;
+            requestRefresh();
+        }
+    }
+    
+    public void setIpAddress(int address) {
+        if (ipAddress != address) {
+            ipAddress = address;
+            requestRefresh();
+        }
+    }
+    
+    public void setConfigured(boolean configured) {
+        if (this.configured != configured) {
+            this.configured = configured;
+            requestRefresh();
+        }
+    }
+    
+    public void setStatus(NetworkInfo.DetailedState status) {
+        if (this.status != status) {
+            this.status = status;
+            requestRefresh();
+        }
+    }
+    
+    public void setSecurity(String security) {
+        if (TextUtils.isEmpty(this.security) || !this.security.equals(security)) {
+            this.security = security;
+            requestRefresh();
+        }
+    }
+
+    public boolean hasSecurity() {
+        return security != null && !security.contains(OPEN);
+    }
+    
+    public String getHumanReadableSecurity() {
+        if (security.equals(OPEN)) return LOCALIZED_OPEN;
+        else if (security.equals(WEP)) return LOCALIZED_WEP;
+        else if (security.equals(WPA)) return LOCALIZED_WPA;
+        else if (security.equals(WPA2)) return LOCALIZED_WPA2;
+        
+        return LOCALIZED_UNKNOWN;
+    }
+    
+    public void updateFromScanResult(ScanResult scanResult) {
+        blockRefresh();
+        
+        // We don't keep specific AP BSSIDs and instead leave that as wildcard
+        
+        setSeen(true);
+        setSsid(scanResult.SSID);
+        if (networkId == NETWORK_ID_NOT_SET) {
+            // Since ScanResults don't cross-reference network ID, we set it as a wildcard
+            setNetworkId(NETWORK_ID_ANY);
+        }
+        setSignal(scanResult.level);
+        setSecurity(getScanResultSecurity(scanResult));
+        unblockRefresh();
+    }
+    
+    /**
+     * @return The security of a given {@link ScanResult}.
+     */
+    public static String getScanResultSecurity(ScanResult scanResult) {
+        final String cap = scanResult.capabilities;
+        final String[] securityModes = { WEP, WPA, WPA2 }; 
+        for (int i = securityModes.length - 1; i >= 0; i--) {
+            if (cap.contains(securityModes[i])) {
+                return securityModes[i];
+            }
+        }
+        
+        return OPEN;
+    }
+    
+    /**
+     * @return Whether the given ScanResult represents an adhoc network.
+     */
+    public static boolean isAdhoc(ScanResult scanResult) {
+        return scanResult.capabilities.contains(ADHOC_CAPABILITY);
+    }
+    
+    /**
+     * @return Whether the given ScanResult has enterprise security.
+     */
+    public static boolean isEnterprise(ScanResult scanResult) {
+        return scanResult.capabilities.contains(ENTERPRISE_CAPABILITY);
+    }
+    
+    public void updateFromWifiConfiguration(WifiConfiguration wifiConfig) {
+        if (wifiConfig != null) {
+            blockRefresh();
+            setBssid(wifiConfig.BSSID);
+            setNetworkId(wifiConfig.networkId);
+            setPriority(wifiConfig.priority);
+            setHiddenSsid(wifiConfig.hiddenSSID);
+            setSsid(wifiConfig.SSID);
+            setConfigured(true);
+            setDisabled(wifiConfig.status == WifiConfiguration.Status.DISABLED);
+            parseWifiConfigurationSecurity(wifiConfig);
+            unblockRefresh();
+        }
+    }
+    
+    public void setPassword(String password) {
+        setPassword(password, WEP_PASSWORD_AUTO);
+    }
+    
+    public void setPassword(String password, int wepPasswordType) {
+        mPassword = password;
+        mWepPasswordType = wepPasswordType;
+    }
+    
+    public boolean hasPassword() {
+        return !TextUtils.isEmpty(mPassword) || mConfigHadPassword; 
+    }
+    
+    private static boolean hasPassword(WifiConfiguration wifiConfig) {
+        return !TextUtils.isEmpty(wifiConfig.preSharedKey)
+                || !TextUtils.isEmpty(wifiConfig.wepKeys[0])
+                || !TextUtils.isEmpty(wifiConfig.wepKeys[1])
+                || !TextUtils.isEmpty(wifiConfig.wepKeys[2])
+                || !TextUtils.isEmpty(wifiConfig.wepKeys[3]);        
+    }
+    
+    private void parseWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
+        setSecurity(getWifiConfigurationSecurity(wifiConfig));
+        mConfigHadPassword = hasPassword(wifiConfig);
+    }
+    
+    /**
+     * @return The security of a given {@link WifiConfiguration}.
+     */
+    public static String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
+
+        if (wifiConfig.allowedKeyManagement.get(KeyMgmt.NONE)) {
+            // If we never set group ciphers, wpa_supplicant puts all of them.
+            // For open, we don't set group ciphers.
+            // For WEP, we specifically only set WEP40 and WEP104, so CCMP
+            // and TKIP should not be there.
+            if (!wifiConfig.allowedGroupCiphers.get(GroupCipher.CCMP)
+                    && (wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP40)
+                            || wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP104))) {
+                return WEP;
+            } else {
+                return OPEN;
+            }
+        } else if (wifiConfig.allowedProtocols.get(Protocol.RSN)) {
+            return WPA2;
+        } else if (wifiConfig.allowedProtocols.get(Protocol.WPA)) {
+            return WPA;
+        } else {
+            Log.w(TAG, "Unknown security type from WifiConfiguration, falling back on open.");
+            return OPEN;
+        }
+    }
+    
+    public void updateFromWifiInfo(WifiInfo wifiInfo, NetworkInfo.DetailedState state) {
+        if (wifiInfo != null) {
+            blockRefresh();
+            setBssid(wifiInfo.getBSSID());
+            setLinkSpeed(wifiInfo.getLinkSpeed());
+            setNetworkId(wifiInfo.getNetworkId());
+            setIpAddress(wifiInfo.getIpAddress());
+            setSsid(wifiInfo.getSSID());
+            if (state != null) {
+                setStatus(state);
+            }
+            setHiddenSsid(wifiInfo.getHiddenSSID());
+            unblockRefresh();
+        }
+    }
+    
+    /**
+     * @return Whether this AP can be connected to at the moment.
+     */
+    public boolean isConnectable() {
+        return !primary && seen;
+    }
+
+    /**
+     * @return Whether this AP can be forgotten at the moment.
+     */
+    public boolean isForgetable() {
+        return configured;
+    }
+    
+    /**
+     * Updates the state as if it were never configured.
+     * <p>
+     * Note: This will not pass the forget call to the Wi-Fi API.
+     */
+    public void forget() {
+        blockRefresh();
+        setConfigured(false);
+        setNetworkId(NETWORK_ID_NOT_SET);
+        setPrimary(false);
+        setStatus(null);
+        setDisabled(false);
+        unblockRefresh();
+    }
+    
+    public void updateWifiConfiguration(WifiConfiguration config) {
+        config.BSSID = getWpaSupplicantBssid();
+        config.priority = priority;
+        config.hiddenSSID = hiddenSsid;
+        config.SSID = convertToQuotedString(ssid);
+        
+        setupSecurity(config);
+    }
+    
+    private void setupSecurity(WifiConfiguration config) {
+        config.allowedAuthAlgorithms.clear();
+        config.allowedGroupCiphers.clear();
+        config.allowedKeyManagement.clear();
+        config.allowedPairwiseCiphers.clear();
+        config.allowedProtocols.clear();
+        
+        if (TextUtils.isEmpty(security)) {
+            security = OPEN;
+            Log.w(TAG, "Empty security, assuming open");
+        }
+        
+        if (security.equals(WEP)) {
+            
+            // If password is empty, it should be left untouched
+            if (!TextUtils.isEmpty(mPassword)) {
+                if (mWepPasswordType == WEP_PASSWORD_AUTO) {
+                    if (isHexWepKey(mPassword)) {
+                        config.wepKeys[0] = mPassword;
+                    } else {
+                        config.wepKeys[0] = convertToQuotedString(mPassword);
+                    }
+                } else {
+                    config.wepKeys[0] = mWepPasswordType == WEP_PASSWORD_ASCII
+                            ? convertToQuotedString(mPassword)
+                            : mPassword;
+                }
+            }
+            
+            config.wepTxKeyIndex = 0;
+            
+            config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
+            config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
+
+            config.allowedKeyManagement.set(KeyMgmt.NONE);
+            
+            config.allowedGroupCiphers.set(GroupCipher.WEP40);
+            config.allowedGroupCiphers.set(GroupCipher.WEP104);
+            
+        } else if (security.equals(WPA) || security.equals(WPA2)){
+            config.allowedGroupCiphers.set(GroupCipher.TKIP);
+            config.allowedGroupCiphers.set(GroupCipher.CCMP);
+            
+            config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+            
+            config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
+            config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);
+
+            config.allowedProtocols.set(security.equals(WPA2) ? Protocol.RSN : Protocol.WPA);
+            
+            // If password is empty, it should be left untouched
+            if (!TextUtils.isEmpty(mPassword)) {
+                config.preSharedKey = convertToQuotedString(mPassword);
+            }
+            
+        } else if (security.equals(OPEN)) {
+            config.allowedKeyManagement.set(KeyMgmt.NONE);
+        }
+    }
+    
+    private static boolean isHexWepKey(String wepKey) {
+        final int len = wepKey.length();
+        
+        // WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
+        if (len != 10 && len != 26 && len != 58) {
+            return false;
+        }
+        
+        for (int i = len - 1; i >= 0; i--) {
+            final char c = wepKey.charAt(i);
+            if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    public void setCallback(AccessPointStateCallback callback) {
+        mCallback = callback;
+    }
+    
+    void blockRefresh() {
+        mBlockRefresh++;
+    }
+    
+    void unblockRefresh() {
+        if (--mBlockRefresh == 0 && mNeedsRefresh) {
+            requestRefresh();
+        }
+    }
+    
+    private void requestRefresh() {
+        if (mBlockRefresh > 0) {
+            mNeedsRefresh = true;
+            return;
+        }
+        
+        if (mCallback != null) {
+            mCallback.refreshAccessPointState();
+        }
+        
+        mNeedsRefresh = false;
+    }
+    
+    /**
+     * {@inheritDoc}
+     * @see #hashCode()
+     * @see #equals(Object)
+     */
+    public int matches(int otherNetworkId, String otherBssid, String otherSsid,
+            String otherSecurity) {
+        
+        // Whenever this method is touched, please ensure #equals and #hashCode
+        // still work with the changes here!
+        
+        if (otherSsid == null) {
+            if (WifiLayer.LOGV) {
+                Log.w(TAG, "BSSID: " + otherBssid + ", SSID: " + otherSsid);
+            }
+            return MATCH_NONE;
+        }
+
+        /*
+         * If we both have 'security' set, it must match (an open network still
+         * has 'security' set to OPEN)
+         */
+        if (security != null && otherSecurity != null) {
+            if (!security.equals(otherSecurity)) {
+                return MATCH_NONE;
+            }
+        }
+        
+        // WifiConfiguration gives an empty bssid as a BSSID wildcard
+        if (TextUtils.isEmpty(otherBssid)) {
+            otherBssid = AccessPointState.BSSID_ANY;
+        }
+
+        final boolean networkIdMatches = networkId == otherNetworkId;
+        if (!networkIdMatches && networkId != NETWORK_ID_ANY && otherNetworkId != NETWORK_ID_ANY) {
+            // Network IDs don't match (e.g., 1 & 2 or unset & 1) and neither is a wildcard
+            return MATCH_NONE;
+        }
+        
+        if (networkIdMatches && otherNetworkId != NETWORK_ID_NOT_SET
+                && otherNetworkId != NETWORK_ID_ANY) {
+            // Network ID matches (they're set to the same ID)
+            return MATCH_EXACT;
+        }
+        
+        // So now, network IDs aren't set or at least one is a wildcard 
+        
+        final boolean bssidMatches = bssid.equals(otherBssid);
+        final boolean otherBssidIsWildcard = otherBssid.equals(BSSID_ANY);
+        if (bssidMatches && !otherBssidIsWildcard) {
+            // BSSID matches (and neither is a wildcard)
+            return MATCH_STRONG;
+        }
+
+        if (!bssidMatches && !bssid.equals(BSSID_ANY) && !otherBssidIsWildcard) {
+            // BSSIDs don't match (e.g., 00:24:21:21:42:12 & 42:12:44:21:22:52)
+            // and neither is a wildcard
+            return MATCH_NONE;
+        }
+        
+        // So now, BSSIDs are both wildcards
+        
+        final boolean ssidMatches = ssid.equals(otherSsid); 
+        if (ssidMatches) {
+            // SSID matches
+            return MATCH_WEAK;
+        }
+
+        return MATCH_NONE;
+    }
+    
+    /**
+     * {@inheritDoc}
+     * @see #matches(int, String, String)
+     * @see #equals(Object)
+     */
+    @Override
+    public int hashCode() {
+        // Two equal() objects must have same hashCode.
+        // With Wi-Fi, the broadest match is if two SSIDs are the same.  The finer-grained matches
+        // imply this (for example, the same network IDs means the same WifiConfiguration which
+        // means the same SSID).
+        // See #matches for the exact matching algorithm we use.
+        return ssid != null ? ssid.hashCode() : 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see #matches(int, String, String)
+     * @see #hashCode()
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!o.getClass().equals(getClass())) {
+            return false;
+        }
+        
+        final AccessPointState other = (AccessPointState) o;
+
+        // To see which conditions cause two AccessPointStates to be equal, see
+        // where #matches returns MATCH_WEAK or greater.
+        
+        return matches(other.networkId, other.bssid, other.ssid, other.security) >= MATCH_WEAK;
+    }
+
+    public int matchesWifiConfiguration(WifiConfiguration wifiConfig) {
+        String security = getWifiConfigurationSecurity(wifiConfig);
+        return matches(wifiConfig.networkId, wifiConfig.BSSID, wifiConfig.SSID, security);
+    }
+    
+    String getSummarizedStatus() {
+        StringBuilder sb = mSummaryBuilder;
+        sb.delete(0, sb.length());
+        
+        if (primary && status != null) {
+            buildSummary(sb, WifiStatus.getPrintable(mContext, status), true);
+            
+        } else if (!seen) {
+            buildSummary(sb, SUMMARY_NOT_IN_RANGE, true);
+
+            // Remembered comes second in this case
+            if (!primary && configured) {
+                buildSummary(sb, SUMMARY_REMEMBERED, true);
+            }
+            
+        } else {
+            if (configured && disabled) {
+                // The connection failure overrides all in this case
+                return SUMMARY_CONNECTION_FAILED;
+            }
+
+            // Remembered comes first in this case
+            if (!primary && configured) {
+                buildSummary(sb, SUMMARY_REMEMBERED, true);
+            }
+            
+            // If it is seen (and not the primary), show the security type
+            String verboseSecurity = getVerboseSecurity();
+            if (verboseSecurity != null) {
+                buildSummary(sb, verboseSecurity, true);
+            }
+        }
+        
+        return sb.toString();
+    }
+    
+    private String getVerboseSecurity() {
+        if (WEP.equals(security)) {
+            return LOCALIZED_VERBOSE_WEP;
+        } else if (WPA.equals(security)) {
+            return LOCALIZED_VERBOSE_WPA;
+        } else if (WPA2.equals(security)) {
+            return LOCALIZED_VERBOSE_WPA2;
+        } else if (OPEN.equals(security)) {
+            return LOCALIZED_VERBOSE_OPEN;
+        } else {
+            return null;
+        }
+    }
+    
+    private void buildSummary(StringBuilder sb, String string, boolean autoLowerCaseFirstLetter) {
+        if (sb.length() == 0) {
+            sb.append(string);
+        } else {
+            sb.append(", ");
+            if (autoLowerCaseFirstLetter) {
+                // Convert first letter to lowercase
+                sb.append(Character.toLowerCase(string.charAt(0))).append(string, 1,
+                        string.length());
+            } else {
+                sb.append(string);
+            }
+        }
+    }
+    
+    public int compareTo(AccessPointState other) {
+        // This ranks the states for displaying in the AP list, not for
+        // connecting to (wpa_supplicant does that using the WifiConfiguration's
+        // priority field).
+        
+        // Clarity > efficiency, of this logic:
+        int comparison;
+        
+        // Primary
+        comparison = (other.primary ? 1 : 0) - (primary ? 1 : 0);
+        if (comparison != 0) return comparison;
+        
+        // Currently seen (similar to, but not always the same as within range)
+        comparison = (other.seen ? 1 : 0) - (seen ? 1 : 0);
+        if (comparison != 0) return comparison;
+
+        // Configured
+        comparison = (other.configured ? 1 : 0) - (configured ? 1 : 0);
+        if (comparison != 0) return comparison;
+
+        if (!configured) {
+            // Neither are configured
+
+            // Open network
+            comparison = (hasSecurity() ? 1 : 0) - (other.hasSecurity() ? 1 : 0);
+            if (comparison != 0) return comparison;
+        }
+
+        // Signal strength
+        comparison = (int) (other.signalForSorting - signalForSorting);
+        if (comparison != 0) return comparison;
+
+        // Alphabetical
+        return ssid.compareToIgnoreCase(other.ssid);
+    }
+
+    public String toString() {
+        return ssid + " (" + bssid + ", " + networkId + ", " + super.toString() + ")";
+    }
+    
+    /** Implement the Parcelable interface */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(bssid);
+        dest.writeInt(configured ? 1 : 0);
+        dest.writeInt(ipAddress);
+        dest.writeInt(linkSpeed);
+        dest.writeInt(networkId);
+        dest.writeInt(primary ? 1 : 0);
+        dest.writeInt(priority);
+        dest.writeInt(hiddenSsid ? 1 : 0);
+        dest.writeString(security);
+        dest.writeInt(seen ? 1 : 0);
+        dest.writeInt(disabled ? 1 : 0);
+        dest.writeInt(signal);
+        dest.writeString(ssid);
+        dest.writeString(status != null ? status.toString() : null);
+        dest.writeString(mPassword);
+        dest.writeInt(mConfigHadPassword ? 1 : 0);
+        dest.writeInt(mWepPasswordType);
+    }
+
+    /** Implement the Parcelable interface */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    public static final Creator<AccessPointState> CREATOR =
+        new Creator<AccessPointState>() {
+            public AccessPointState createFromParcel(Parcel in) {
+                AccessPointState state = new AccessPointState();
+                state.bssid = in.readString();
+                state.configured = in.readInt() == 1;
+                state.ipAddress = in.readInt();
+                state.linkSpeed = in.readInt();
+                state.networkId = in.readInt();
+                state.primary = in.readInt() == 1;
+                state.priority = in.readInt();
+                state.hiddenSsid = in.readInt() == 1;
+                state.security = in.readString();
+                state.seen = in.readInt() == 1;
+                state.disabled = in.readInt() == 1;
+                state.signal = in.readInt();
+                state.ssid = in.readString();
+                String statusStr = in.readString();
+                if (statusStr != null) {
+                    state.status = NetworkInfo.DetailedState.valueOf(statusStr);
+                }
+                state.mPassword = in.readString();
+                state.mConfigHadPassword = in.readInt() == 1;
+                state.mWepPasswordType = in.readInt();
+                return state;
+            }
+
+            public AccessPointState[] newArray(int size) {
+                return new AccessPointState[size];
+            }
+        };
+
+        
+}
diff --git a/src/com/android/settings/wifi/IpSettings.java b/src/com/android/settings/wifi/IpSettings.java
new file mode 100644
index 0000000..592e8da
--- /dev/null
+++ b/src/com/android/settings/wifi/IpSettings.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.R;
+
+import android.content.ContentResolver;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.provider.Settings.System;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+public class IpSettings extends PreferenceActivity implements Preference.OnPreferenceChangeListener {
+
+    private static final String KEY_USE_STATIC_IP = "use_static_ip";
+
+    private String[] mSettingNames = {
+            System.WIFI_STATIC_IP, System.WIFI_STATIC_GATEWAY, System.WIFI_STATIC_NETMASK,
+            System.WIFI_STATIC_DNS1, System.WIFI_STATIC_DNS2
+    };
+    
+    private String[] mPreferenceKeys = {
+            "ip_address", "gateway", "netmask", "dns1", "dns2"
+    };
+    
+    private CheckBoxPreference mUseStaticIpCheckBox;
+    
+    private static final int MENU_ITEM_SAVE = Menu.FIRST;
+    private static final int MENU_ITEM_CANCEL = Menu.FIRST + 1;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        addPreferencesFromResource(R.xml.ip_settings);
+        
+        mUseStaticIpCheckBox = (CheckBoxPreference) findPreference(KEY_USE_STATIC_IP);
+
+        for (int i = 0; i < mPreferenceKeys.length; i++) {
+            Preference preference = findPreference(mPreferenceKeys[i]);
+            preference.setOnPreferenceChangeListener(this);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        updateUi();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+    
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            updateSettingsProvider();
+        }
+    
+        return super.onKeyDown(keyCode, event);
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        String value = (String) newValue;
+        
+        if (!isIpAddress(value)) {
+            Toast.makeText(this, R.string.wifi_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
+            return false;
+        }
+        
+        preference.setSummary(value);
+        return true;
+    }
+
+    private boolean isIpAddress(String value) {
+        
+        int start = 0;
+        int end = value.indexOf('.');
+        int numBlocks = 0;
+        
+        while (start < value.length()) {
+            
+            if (end == -1) {
+                end = value.length();
+            }
+
+            try {
+                int block = Integer.parseInt(value.substring(start, end));
+                if ((block > 255) || (block < 0)) {
+                    return false;
+                }
+            } catch (NumberFormatException e) {
+                return false;
+            }
+            
+            numBlocks++;
+            
+            start = end + 1;
+            end = value.indexOf('.', start);
+        }
+        
+        return numBlocks == 4;
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        
+        menu.add(0, MENU_ITEM_SAVE, 0, R.string.wifi_ip_settings_menu_save)
+                .setIcon(android.R.drawable.ic_menu_save);
+
+        menu.add(0, MENU_ITEM_CANCEL, 0, R.string.wifi_ip_settings_menu_cancel)
+                .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        switch (item.getItemId()) {
+        
+            case MENU_ITEM_SAVE:
+                updateSettingsProvider();
+                finish();
+                return true;
+                
+            case MENU_ITEM_CANCEL:
+                finish();
+                return true;
+        }
+        
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void updateUi() {
+        ContentResolver contentResolver = getContentResolver();
+        
+        mUseStaticIpCheckBox.setChecked(System.getInt(contentResolver,
+                System.WIFI_USE_STATIC_IP, 0) != 0);
+        
+        for (int i = 0; i < mSettingNames.length; i++) {
+            EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
+            String settingValue = System.getString(contentResolver, mSettingNames[i]);
+            preference.setText(settingValue);
+            preference.setSummary(settingValue);
+        }
+    }
+    
+    private void updateSettingsProvider() {
+        ContentResolver contentResolver = getContentResolver();
+
+        System.putInt(contentResolver, System.WIFI_USE_STATIC_IP,
+                mUseStaticIpCheckBox.isChecked() ? 1 : 0);
+        
+        for (int i = 0; i < mSettingNames.length; i++) {
+            EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
+            System.putString(contentResolver, mSettingNames[i], preference.getText());
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
new file mode 100644
index 0000000..88cfe06
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
+
+import com.android.settings.R;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.preference.Preference;
+import android.preference.CheckBoxPreference;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+
+public class WifiEnabler implements Preference.OnPreferenceChangeListener {
+    
+    private static final boolean LOCAL_LOGD = Config.LOGD || WifiLayer.LOGV;
+    private static final String TAG = "SettingsWifiEnabler";
+    
+    private final Context mContext; 
+    private final WifiManager mWifiManager;
+    private final CheckBoxPreference mWifiCheckBoxPref;
+    private final CharSequence mOriginalSummary;
+    
+    private final IntentFilter mWifiStateFilter;
+    private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                handleWifiStateChanged(
+                        intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN),
+                        intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE,
+                                WIFI_STATE_UNKNOWN));
+            } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                handleNetworkStateChanged(
+                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO));
+            }
+        }
+    };
+    
+    public WifiEnabler(Context context, WifiManager wifiManager,
+            CheckBoxPreference wifiCheckBoxPreference) {
+        mContext = context;
+        mWifiCheckBoxPref = wifiCheckBoxPreference;
+        mWifiManager = wifiManager;
+        
+        mOriginalSummary = wifiCheckBoxPreference.getSummary();
+        wifiCheckBoxPreference.setPersistent(false);
+        
+        mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+    }
+
+    public void resume() {
+        int state = mWifiManager.getWifiState();
+        // This is the widget enabled state, not the preference toggled state
+        mWifiCheckBoxPref.setEnabled(state == WIFI_STATE_ENABLED || state == WIFI_STATE_DISABLED
+                || state == WIFI_STATE_UNKNOWN);
+
+        mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter);
+        mWifiCheckBoxPref.setOnPreferenceChangeListener(this);
+    }
+    
+    public void pause() {
+        mContext.unregisterReceiver(mWifiStateReceiver);
+        mWifiCheckBoxPref.setOnPreferenceChangeListener(null);
+    }
+    
+    public boolean onPreferenceChange(Preference preference, Object value) {
+        // Turn on/off Wi-Fi
+        setWifiEnabled((Boolean) value);
+        
+        // Don't update UI to opposite state until we're sure
+        return false;
+    }
+    
+    private void setWifiEnabled(final boolean enable) {
+        // Disable button
+        mWifiCheckBoxPref.setEnabled(false);
+        
+        if (!mWifiManager.setWifiEnabled(enable)) {
+            mWifiCheckBoxPref.setSummary(enable ? R.string.error_starting : R.string.error_stopping);
+        }
+    }
+    
+    private void handleWifiStateChanged(int wifiState, int previousWifiState) {
+
+        if (LOCAL_LOGD) {
+            Log.d(TAG, "Received wifi state changed from "
+                    + getHumanReadableWifiState(previousWifiState) + " to "
+                    + getHumanReadableWifiState(wifiState));
+        }
+        
+        if (wifiState == WIFI_STATE_DISABLED || wifiState == WIFI_STATE_ENABLED) {
+            mWifiCheckBoxPref.setChecked(wifiState == WIFI_STATE_ENABLED);
+            mWifiCheckBoxPref
+                    .setSummary(wifiState == WIFI_STATE_DISABLED ? mOriginalSummary : null);
+            
+            mWifiCheckBoxPref.setEnabled(isEnabledByDependency());
+            
+        } else if (wifiState == WIFI_STATE_DISABLING || wifiState == WIFI_STATE_ENABLING) {
+            mWifiCheckBoxPref.setSummary(wifiState == WIFI_STATE_ENABLING ? R.string.wifi_starting
+                    : R.string.wifi_stopping);
+            
+        } else if (wifiState == WIFI_STATE_UNKNOWN) {
+            int message = R.string.wifi_error;
+            if (previousWifiState == WIFI_STATE_ENABLING) message = R.string.error_starting;
+            else if (previousWifiState == WIFI_STATE_DISABLING) message = R.string.error_stopping;
+            
+            mWifiCheckBoxPref.setChecked(false);
+            mWifiCheckBoxPref.setSummary(message);
+            mWifiCheckBoxPref.setEnabled(true);
+        }
+    }
+
+    private void handleNetworkStateChanged(NetworkInfo networkInfo) {
+
+        if (LOCAL_LOGD) {
+            Log.d(TAG, "Received network state changed to " + networkInfo);
+        }
+        
+        if (mWifiManager.isWifiEnabled()) {
+            String summary = WifiStatus.getStatus(mContext, 
+                    mWifiManager.getConnectionInfo().getSSID(), networkInfo.getDetailedState());
+            mWifiCheckBoxPref.setSummary(summary);
+        }
+    }
+
+    private boolean isEnabledByDependency() {
+        Preference dep = getDependencyPreference();
+        if (dep == null) {
+            return true;
+        }
+        
+        return !dep.shouldDisableDependents();
+    }
+    
+    private Preference getDependencyPreference() {
+        String depKey = mWifiCheckBoxPref.getDependency();
+        if (TextUtils.isEmpty(depKey)) {
+            return null;
+        }
+        
+        return mWifiCheckBoxPref.getPreferenceManager().findPreference(depKey);
+    }
+    
+    private static String getHumanReadableWifiState(int wifiState) {
+        switch (wifiState) {
+            case WIFI_STATE_DISABLED:
+                return "Disabled";
+            case WIFI_STATE_DISABLING:
+                return "Disabling";
+            case WIFI_STATE_ENABLED:
+                return "Enabled";
+            case WIFI_STATE_ENABLING:
+                return "Enabling";
+            case WIFI_STATE_UNKNOWN:
+                return "Unknown";
+            default:
+                return "Some other state!";    
+        }
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiLayer.java b/src/com/android/settings/wifi/WifiLayer.java
new file mode 100644
index 0000000..b29fd92
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiLayer.java
@@ -0,0 +1,1302 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+
+import com.android.settings.R;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkInfo.State;
+import android.net.wifi.ScanResult;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Helper class for abstracting Wi-Fi.
+ * <p>
+ * Client must call {@link #onCreate()}, {@link #onCreatedCallback()},
+ * {@link #onPause()}, {@link #onResume()}.
+ */
+public class WifiLayer {
+    
+    private static final String TAG = "SettingsWifiLayer";
+    static final boolean LOGV = false || Config.LOGV;
+    
+    //============================
+    // Other member variables
+    //============================
+    
+    private Context mContext;
+    private Callback mCallback;
+
+    static final int MESSAGE_ATTEMPT_SCAN = 1;
+    private Handler mHandler = new MyHandler();
+    
+    //============================
+    // Wifi member variables
+    //============================
+    
+    private WifiManager mWifiManager;
+    private IntentFilter mIntentFilter;
+    private List<AccessPointState> mApScanList = new ArrayList<AccessPointState>();
+    private List<AccessPointState> mApOtherList = new ArrayList<AccessPointState>();
+    private AccessPointState mCurrentPrimaryAp;
+    
+    /** The last access point that we were authenticating with. */
+    private AccessPointState mLastAuthenticatingAp;
+    
+    /** The delay between scans when we're continually scanning. */
+    private static final int CONTINUOUS_SCAN_DELAY_MS = 6000; 
+    /** On failure, the maximum retries for scanning. */
+    private static final int SCAN_MAX_RETRY = 5;
+    /** On failure, the delay between each scan retry. */
+    private static final int SCAN_RETRY_DELAY_MS = 1000;
+    /** On failure, the number of retries so far. */
+    private int mScanRetryCount = 0;
+    /**
+     * Whether we're currently obtaining an address. Continuous scanning will be
+     * disabled in this state.
+     */
+    private boolean mIsObtainingAddress;
+
+    /**
+     * See {@link Settings.System#WIFI_NUM_OPEN_NETWORKS_KEPT}.
+     */
+    private int WIFI_NUM_OPEN_NETWORKS_KEPT;
+    /**
+     * Once the highest priority exceeds this value, all networks will be
+     * wrapped around starting at 0. This is so another client of the Wi-Fi
+     * API can have access points that aren't managed by us. (If the other
+     * client wants lower-priority access points than ours, it can use negative
+     * priority.)
+     */
+    private static final int HIGHEST_PRIORITY_MAX_VALUE = 99999;
+    /**
+     * Never access directly, only the related methods should.
+     */
+    private int mNextHighestPriority;
+    
+    /**
+     * This is used to track when the user wants to connect to a specific AP. We
+     * disable all other APs, set this to true, and let wpa_supplicant connect.
+     * Once we get a network state change, we re-enable the rest of them.
+     */
+    private boolean mReenableApsOnNetworkStateChange = false;
+
+    /**
+     * The current supplicant state, as broadcasted.
+     */
+    private SupplicantState mCurrentSupplicantState;
+    
+    //============================
+    // Inner classes
+    //============================
+    
+    interface Callback {
+        void onError(int messageResId);
+        
+        /**
+         * Called when an AP is added or removed.
+         * 
+         * @param ap The AP.
+         * @param added {@code true} if added, {@code false} if removed.
+         */
+        void onAccessPointSetChanged(AccessPointState ap, boolean added);
+        
+        /**
+         * Called when the scanning status changes.
+         * 
+         * @param started {@code true} if the scanning just started,
+         *            {@code false} if it just ended.
+         */
+        void onScanningStatusChanged(boolean started);
+
+        /**
+         * Called when the access points should be enabled or disabled. This is
+         * called from both wpa_supplicant being connected/disconnected and Wi-Fi
+         * being enabled/disabled.
+         * 
+         * @param enabled {@code true} if they should be enabled, {@code false}
+         *            if they should be disabled.
+         */
+        void onAccessPointsStateChanged(boolean enabled);   
+        
+        /**
+         * Called when there is trouble authenticating and the retry-password
+         * dialog should be shown.
+         * 
+         * @param ap The access point.
+         */
+        void onRetryPassword(AccessPointState ap);
+    }
+    
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                handleNetworkStateChanged(
+                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
+                        intent.getStringExtra(WifiManager.EXTRA_BSSID));
+            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                handleScanResultsAvailable();
+            } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
+                handleSupplicantConnectionChanged(
+                        intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false));
+            } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
+                handleSupplicantStateChanged(
+                        (SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE),
+                        intent.hasExtra(WifiManager.EXTRA_SUPPLICANT_ERROR),
+                        intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0));
+            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                        WifiManager.WIFI_STATE_UNKNOWN));
+            } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+                handleSignalChanged(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0));
+            } else if (action.equals(WifiManager.NETWORK_IDS_CHANGED_ACTION)) {
+                handleNetworkIdsChanged();
+            }
+        }
+    };
+    
+    /**
+     * If using this class, make sure to call the callbacks of this class, such
+     * as {@link #onCreate()}, {@link #onCreatedCallback()},
+     * {@link #onPause()}, {@link #onResume()}.
+     * 
+     * @param context The context.
+     * @param callback The interface that will be invoked when events from this
+     *            class are generated.
+     */
+    public WifiLayer(Context context, Callback callback) {
+        mContext = context;
+        mCallback = callback;
+    }
+    
+    //============================
+    // Lifecycle
+    //============================
+
+    /**
+     * The client MUST call this.
+     * <p>
+     * This shouldn't have any dependency on the callback.
+     */
+    public void onCreate() {
+        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
+        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
+        
+        WIFI_NUM_OPEN_NETWORKS_KEPT = Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.WIFI_NUM_OPEN_NETWORKS_KEPT, 10);
+    }
+    
+    /**
+     * The client MUST call this.
+     * <p>
+     * Callback is ready, this can do whatever it wants with it.
+     */
+    public void onCreatedCallback() {
+        if (isWifiEnabled()) {
+            refreshAll(false);
+        }
+    }
+    
+    /**
+     * The client MUST call this.
+     * 
+     * @see android.app.Activity#onResume
+     */
+    public void onResume() {
+        mContext.registerReceiver(mReceiver, mIntentFilter);
+        
+        if (isWifiEnabled()) {
+            // Kick start the continual scan
+            queueContinuousScan();
+        }
+    }
+
+    /**
+     * The client MUST call this.
+     * 
+     * @see android.app.Activity#onPause
+     */
+    public void onPause() {
+        mContext.unregisterReceiver(mReceiver);
+        
+        attemptReenableAllAps();
+        
+        removeFutureScans();
+    }
+    
+    //============================
+    // "Public" API
+    //============================
+
+    /**
+     * Returns an AccessPointState instance (that we track locally in WifiLayer)
+     * for the given state. First, we check if we track the given instance. If
+     * not, we find an equal AccessPointState instance that we track.
+     * 
+     * @param state An AccessPointState instance that does not necessarily have
+     *            to be one that this WifiLayer class tracks. For example, it
+     *            could be the result of unparceling.
+     * @return An AccessPointState instance that this WifiLayer class tracks.
+     */
+    public AccessPointState getWifiLayerApInstance(AccessPointState state) {
+        synchronized (this) {
+            
+            if (hasApInstanceLocked(state)) {
+                return state;
+            }
+            
+            return findApLocked(state.networkId, state.bssid, state.ssid, state.security);
+        }
+    }
+    
+    /**
+     * Connects to the network, and creates the Wi-Fi API config if necessary.
+     * 
+     * @param state The state of the network to connect to. This MUST be an
+     *            instance that was given to you by this class. If you
+     *            constructed the instance yourself (for example, after
+     *            unparceling it), you should use
+     *            {@link #getWifiLayerApInstance(AccessPointState)}.
+     * @return Whether the operation was successful.
+     */
+    public boolean connectToNetwork(AccessPointState state) {
+        if (LOGV) {
+            Log.v(TAG, "Connecting to " + state);
+        }
+        
+        // Need WifiConfiguration for the AP
+        WifiConfiguration config = findConfiguredNetwork(state);
+
+        if (LOGV) {
+            Log.v(TAG, " Found configured network " + config);
+        }
+        
+        if (config == null) {
+            /*
+             * Connecting for the first time, need to create it. We will enable
+             * and save it below (when we set priority).
+             */
+            config = addConfiguration(state, 0);
+
+            if (config == null) {
+                Log.e(TAG, "Config is still null, even after attempting to add it.");
+                error(R.string.error_connecting);
+                return false;
+            }
+
+            /*
+             * We could reload the configured networks, but instead just
+             * shortcut and add this state to our list in memory.
+             */
+            ensureTrackingState(state);
+        } else {
+            // Make sure the configuration has the latest from the state
+            state.updateWifiConfiguration(config);
+        }
+
+        // Enable this network before we save to storage
+        if (!managerEnableNetwork(state, false)) {
+            Log.e(TAG, "Could not enable network ID " + state.networkId);
+            error(R.string.error_connecting);
+            return false;
+        }
+        
+        /*
+         * Give it highest priority, this could cause a network ID change, so do
+         * it after any modifications to the network we're connecting to
+         */
+        setHighestPriorityStateAndSave(state, config);
+        
+        /*
+         * We force supplicant to connect to this network by disabling the
+         * others. We do this AFTER we save above so this disabled flag isn't
+         * persisted.
+         */
+        mReenableApsOnNetworkStateChange = true;
+        if (!managerEnableNetwork(state, true)) {
+            Log.e(TAG, "Could not enable network ID " + state.networkId);
+            error(R.string.error_connecting);
+            return false;
+        }
+
+        if (LOGV) {
+            Log.v(TAG, " Enabled network " + state.networkId);
+        }
+
+        if (mCurrentSupplicantState == SupplicantState.DISCONNECTED ||
+                mCurrentSupplicantState == SupplicantState.SCANNING) {
+            mWifiManager.reconnect();
+        }
+        
+        // Check for too many configured open networks
+        if (!state.hasSecurity()) {
+            checkForExcessOpenNetworks();
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Saves a network, and creates the Wi-Fi API config if necessary.
+     * 
+     * @param state The state of the network to save. If you constructed the
+     *            instance yourself (for example, after unparceling it), you
+     *            should use {@link #getWifiLayerApInstance(AccessPointState)}.
+     * @return Whether the operation was successful.
+     */
+    public boolean saveNetwork(AccessPointState state) {
+        WifiConfiguration config = findConfiguredNetwork(state);
+        
+        if (config == null) {
+            // if the user is adding a new network, assume that it is hidden
+            state.setHiddenSsid(true);
+
+            config = addConfiguration(state, ADD_CONFIGURATION_ENABLE);
+
+            if (config == null) {
+                Log.e(TAG, "Could not save configuration, call to addConfiguration failed.");
+                error(R.string.error_saving);
+                return false;
+            }
+            
+        } else {
+            state.updateWifiConfiguration(config);
+            if (mWifiManager.updateNetwork(config) == -1) {
+                Log.e(TAG, "Could not update configuration, call to WifiManager failed.");
+                error(R.string.error_saving);
+                return false;
+            }
+        }
+        
+        // Successfully added network, go ahead and persist
+        if (!managerSaveConfiguration()) {
+            Log.e(TAG, "Could not save configuration, call to WifiManager failed.");
+            error(R.string.error_saving);
+            return false;
+        }
+        
+        /*
+         * We could reload the configured networks, but instead just shortcut
+         * and add this state to our list in memory
+         */
+        ensureTrackingState(state);
+        
+        return true;
+    }
+    
+    /**
+     * Forgets a network.
+     * 
+     * @param state The state of the network to forget. If you constructed the
+     *            instance yourself (for example, after unparceling it), you
+     *            should use {@link #getWifiLayerApInstance(AccessPointState)}.
+     * @return Whether the operation was succesful.
+     */
+    public boolean forgetNetwork(AccessPointState state) {
+        if (!state.configured) {
+            Log.w(TAG, "Inconsistent state:  Forgetting a network that is not configured.");
+            return true;
+        }
+        
+        int oldNetworkId = state.networkId;
+        state.forget();
+        
+        if (!state.seen) {
+            // If it is not seen, it should be removed from the UI
+            removeApFromUi(state);
+        }
+                    
+        synchronized (this) {
+            mApOtherList.remove(state);
+            // It should not be removed from the scan list, since if it was
+            // there that means it's still seen
+        }
+
+        if (!mWifiManager.removeNetwork(oldNetworkId)) {
+            Log.e(TAG, "Removing network " + state.ssid + " (network ID " + oldNetworkId +
+                    ") failed.");
+            return false;
+        }
+        
+        if (!managerSaveConfiguration()) {
+            error(R.string.error_saving);
+            return false;
+        }
+
+        return true;
+    }
+    
+    /**
+     * This ensures this class is tracking the given state. This means it is in
+     * our list of access points, either in the scanned list or in the
+     * remembered list.
+     * 
+     * @param state The state that will be checked for tracking, and if not
+     *            tracking will be added to the remembered list in memory.
+     */
+    private void ensureTrackingState(AccessPointState state) {
+        synchronized (this) {
+            if (hasApInstanceLocked(state)) {
+                return;
+            }
+            
+            mApOtherList.add(state);
+        }
+    }
+    
+    /**
+     * Attempts to scan networks.  This has a retry mechanism.
+     */
+    public void attemptScan() {
+        
+        // Remove any future scans since we're scanning right now
+        removeFutureScans();
+        
+        if (!mWifiManager.isWifiEnabled()) return;
+        
+        if (!mWifiManager.startScan()) {
+            postAttemptScan();
+        } else {
+            mScanRetryCount = 0;
+        }
+    }
+
+    private void queueContinuousScan() {
+        mHandler.removeMessages(MESSAGE_ATTEMPT_SCAN);
+        
+        if (!mIsObtainingAddress) {
+            // Don't do continuous scan while in obtaining IP state
+            mHandler.sendEmptyMessageDelayed(MESSAGE_ATTEMPT_SCAN, CONTINUOUS_SCAN_DELAY_MS);
+        }
+    }
+    
+    private void removeFutureScans() {
+        mHandler.removeMessages(MESSAGE_ATTEMPT_SCAN);
+    }
+    
+    public boolean isWifiEnabled() {
+        return mWifiManager.isWifiEnabled();
+    }
+    
+    public void error(int messageResId) {
+        Log.e(TAG, mContext.getResources().getString(messageResId));
+        
+        if (mCallback != null) {
+            mCallback.onError(messageResId);
+        }
+    }
+    
+    //============================
+    // Wifi logic
+    //============================
+
+    private void refreshAll(boolean attemptScan) {
+        loadConfiguredAccessPoints();
+        refreshStatus();
+        
+        if (attemptScan) {
+            attemptScan();
+        }
+    }
+    
+    private void postAttemptScan() {
+        onScanningStarted();
+
+        if (++mScanRetryCount < SCAN_MAX_RETRY) {
+            // Just in case, remove previous ones first
+            removeFutureScans();
+            mHandler.sendEmptyMessageDelayed(MESSAGE_ATTEMPT_SCAN, SCAN_RETRY_DELAY_MS);
+        } else {
+            // Show an error once we run out of attempts
+            error(R.string.error_scanning);
+            onScanningEnded();
+        }
+    }
+    
+    private void onScanningStarted() {
+        if (mCallback != null) {
+            mCallback.onScanningStatusChanged(true);
+        }
+    }
+    
+    private void onScanningEnded() {
+        queueContinuousScan();
+        
+        if (mCallback != null) {
+            mCallback.onScanningStatusChanged(false);
+        }
+    }
+    
+    private void clearApLists() {
+        List<AccessPointState> accessPoints = new ArrayList<AccessPointState>();
+        
+        synchronized(this) {
+            // Clear the logic's list of access points
+            accessPoints.addAll(mApScanList);
+            accessPoints.addAll(mApOtherList);
+            mApScanList.clear();
+            mApOtherList.clear();
+        }
+        
+        for (int i = accessPoints.size() - 1; i >= 0; i--) {
+            removeApFromUi(accessPoints.get(i));
+        }
+    }
+    
+    private boolean managerSaveConfiguration() {
+        boolean retValue = mWifiManager.saveConfiguration();
+        
+        /*
+         * We need to assume the network IDs have changed, so handle this. Note:
+         * we also have a receiver on the broadcast intent in case another wifi
+         * framework client caused the change. In this case, we will handle the
+         * possible network ID change twice (but it's not too costly).
+         */
+        handleNetworkIdsChanged();
+        
+        return retValue;
+    }
+    
+    private boolean managerEnableNetwork(AccessPointState state, boolean disableOthers) {
+        if (!mWifiManager.enableNetwork(state.networkId, disableOthers)) {
+            return false;
+        }
+        
+        // Enabling was successful, make sure the state is not disabled
+        state.setDisabled(false);
+        
+        return true;
+    }
+    
+    private static final int ADD_CONFIGURATION_ENABLE = 1;
+    private static final int ADD_CONFIGURATION_SAVE = 2;
+    private WifiConfiguration addConfiguration(AccessPointState state, int flags) {
+        // Create and add
+        WifiConfiguration config = new WifiConfiguration();
+        
+        state.updateWifiConfiguration(config);
+        
+        final int networkId = mWifiManager.addNetwork(config);
+        if (networkId == -1) {
+            return null;
+        }
+        
+        state.setNetworkId(networkId);
+        state.setConfigured(true);
+        
+        // If we should, then enable it, since it comes disabled by default
+        if ((flags & ADD_CONFIGURATION_ENABLE) != 0
+                && !managerEnableNetwork(state, false)) {
+            return null;
+        }
+
+        // If we should, then save it
+        if ((flags & ADD_CONFIGURATION_SAVE) != 0 && !managerSaveConfiguration()) {
+            return null;
+        }
+
+        if (mCallback != null) {
+            mCallback.onAccessPointSetChanged(state, true);
+        }
+
+        return config;
+    }
+    
+    private WifiConfiguration findConfiguredNetwork(AccessPointState state) {
+        final List<WifiConfiguration> wifiConfigs = getConfiguredNetworks();
+        
+        for (int i = wifiConfigs.size() - 1; i >= 0; i--) {
+            final WifiConfiguration wifiConfig = wifiConfigs.get(i); 
+            if (state.matchesWifiConfiguration(wifiConfig) >= AccessPointState.MATCH_WEAK) {
+                return wifiConfig;
+            }
+        }
+        
+        return null;
+    }
+    
+    private List<WifiConfiguration> getConfiguredNetworks() {
+        final List<WifiConfiguration> wifiConfigs = mWifiManager.getConfiguredNetworks();
+        return wifiConfigs;
+    }
+    
+    /**
+     * Must call while holding the lock for the list, which is usually the
+     * WifiLayer instance.
+     */
+    private static AccessPointState findApLocked(List<AccessPointState> list, int networkId,
+            String bssid, String ssid, String security) {
+        AccessPointState ap;
+        for (int i = list.size() - 1; i >= 0; i--) {
+            ap = list.get(i);
+            if (ap.matches(networkId, bssid, ssid, security) >= AccessPointState.MATCH_WEAK) {
+                return ap;
+            }
+        }
+
+        return null;
+    }
+    
+    /**
+     * Must call while holding the lock for the lists, which is usually this
+     * WifiLayer instance.
+     */
+    private AccessPointState findApLocked(int networkId, String bssid, String ssid,
+            String security) {
+        AccessPointState ap = findApLocked(mApScanList, networkId, bssid, ssid, security);
+        if (ap == null) {
+            ap = findApLocked(mApOtherList, networkId, bssid, ssid, security);
+        }
+        return ap;
+    }
+
+    /**
+     * Returns whether we have the exact instance of the access point state
+     * given. This is useful in cases where an AccessPointState has been
+     * parceled by the client and the client is attempting to use it to
+     * connect/forget/save.
+     * <p>
+     * Must call while holding the lock for the lists, which is usually this
+     * WifiLayer instance.
+     */
+    private boolean hasApInstanceLocked(AccessPointState state) {
+        
+        for (int i = mApScanList.size() - 1; i >= 0; i--) {
+            if (mApScanList.get(i) == state) {
+                return true;
+            }
+        }
+
+        for (int i = mApOtherList.size() - 1; i >= 0; i--) {
+            if (mApOtherList.get(i) == state) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    private void loadConfiguredAccessPoints() {
+        final List<WifiConfiguration> configs = getConfiguredNetworks();
+        
+        for (int i = configs.size() - 1; i >= 0; i--) {
+            final WifiConfiguration config = configs.get(i);
+            
+            AccessPointState ap;
+            synchronized(this) {
+                ap = findApLocked(config.networkId, config.BSSID, config.SSID,
+                        AccessPointState.getWifiConfigurationSecurity(config));
+                
+                if (ap != null) {
+                    // We already know about this one
+                    continue;
+                }
+    
+                ap = new AccessPointState(mContext);
+                ap.updateFromWifiConfiguration(config);
+                if (LOGV) Log.v(TAG, "Created " + ap + " in loadConfiguredAccessPoints");
+                mApOtherList.add(ap);
+            }
+
+            // Make sure our next highest priority is greater than this
+            checkNextHighestPriority(ap.priority);
+            
+            if (mCallback != null) {
+                mCallback.onAccessPointSetChanged(ap, true);
+            }
+        }
+    }
+
+    private AccessPointState getCurrentAp() {
+        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        
+        String ssid = wifiInfo.getSSID();
+        if (ssid != null) {
+            /*
+             * We pass null for security since we have a network ID (i.e., it's
+             * not a wildcard), and rely on it matching.
+             */
+            return findApLocked(wifiInfo.getNetworkId(), wifiInfo.getBSSID(), ssid, null);
+        } else {
+            return null;
+        }
+    }
+    
+    private void setPrimaryAp(AccessPointState ap) {
+        synchronized (this) {
+            // Unset other
+            if (mCurrentPrimaryAp != null) {
+                mCurrentPrimaryAp.setPrimary(false);
+            }
+
+            mCurrentPrimaryAp = ap;
+        }
+
+        if (ap != null) {
+            ap.setPrimary(true);
+        }
+    }
+
+    private void attemptReenableAllAps() {
+        if (mReenableApsOnNetworkStateChange) {
+            mReenableApsOnNetworkStateChange = false;
+            enableAllAps();
+        }
+    }
+    
+    private void enableAllAps() {
+        synchronized(this) {
+            if (LOGV) {
+                Log.v(TAG, " Enabling all APs");
+            }
+            
+            enableApsLocked(mApOtherList);
+            enableApsLocked(mApScanList);
+        }
+    }
+    
+    private void enableApsLocked(List<AccessPointState> apList) {
+        for (int i = apList.size() - 1; i >= 0; i--) {
+            AccessPointState state = apList.get(i);
+            int networkId = state.networkId;
+            if (networkId != AccessPointState.NETWORK_ID_NOT_SET &&
+                    networkId != AccessPointState.NETWORK_ID_ANY) {
+                managerEnableNetwork(state, false);
+            }
+        }
+    }
+    
+    private void removeApFromUi(AccessPointState ap) {
+        if (mCallback != null) {
+            mCallback.onAccessPointSetChanged(ap, false);
+        }
+    }
+    
+    /**
+     * Sets the access point state to the highest priority.
+     * <p>
+     * If you have a list of configured networks from WifiManager, you probably
+     * shouldn't call this until you're done traversing the list.
+     * 
+     * @param state The state to set as the highest priority.
+     * @param reusableConfiguration An optional WifiConfiguration that will be
+     *            given to the WifiManager as updated data for the network ID.
+     *            This will be filled with the new priority.
+     * @return Whether the operation was successful.
+     */
+    private boolean setHighestPriorityStateAndSave(AccessPointState state,
+            WifiConfiguration reusableConfiguration) {
+
+        if (!isConsideredForHighestPriority(state)) {
+            Log.e(TAG,
+                    "Could not set highest priority on state because state is not being considered.");
+            return false;
+        }
+        
+        if (reusableConfiguration == null) {
+            reusableConfiguration = new WifiConfiguration();
+        }
+        
+        int oldPriority = reusableConfiguration.priority;
+        reusableConfiguration.priority = getNextHighestPriority();
+        reusableConfiguration.networkId = state.networkId;
+        
+        if (mWifiManager.updateNetwork(reusableConfiguration) == -1) {
+            // Rollback priority
+            reusableConfiguration.priority = oldPriority;
+            Log.e(TAG,
+                    "Could not set highest priority on state because updating the supplicant network failed.");
+            return false;
+        }
+
+        if (!managerSaveConfiguration()) {
+            reusableConfiguration.priority = oldPriority;
+            Log.e(TAG,
+                    "Could not set highest priority on state because saving config failed.");
+            return false;
+        }
+        
+        state.priority = reusableConfiguration.priority;
+        
+        if (LOGV) {
+            Log.v(TAG, " Set highest priority to "
+                    + state.priority + " from " + oldPriority);
+        }
+        
+        return true;
+    }
+
+    /**
+     * Makes sure the next highest priority is larger than the given priority.
+     */
+    private void checkNextHighestPriority(int priority) {
+        if (priority > HIGHEST_PRIORITY_MAX_VALUE || priority < 0) {
+            // This is a priority that we aren't managing
+            return;
+        }
+        
+        if (mNextHighestPriority <= priority) {
+            mNextHighestPriority = priority + 1;
+        }
+    }
+
+    /**
+     * Checks if there are too many open networks, and removes the excess ones.
+     */
+    private void checkForExcessOpenNetworks() {
+        synchronized(this) {
+            ArrayList<AccessPointState> allAps = getApsSortedByPriorityLocked();
+
+            // Walk from highest to lowest priority
+            int openConfiguredCount = 0;
+            for (int i = allAps.size() - 1; i >= 0; i--) {
+                AccessPointState state = allAps.get(i);
+                if (state.configured && !state.hasSecurity()) {
+                    openConfiguredCount++;
+                    if (openConfiguredCount > WIFI_NUM_OPEN_NETWORKS_KEPT) {
+                        // Remove this network
+                        forgetNetwork(state);
+                    }
+                }
+            }
+        }
+    }
+    
+    private boolean isConsideredForHighestPriority(AccessPointState state) {
+        return state.configured && state.networkId != AccessPointState.NETWORK_ID_ANY &&
+                state.networkId != AccessPointState.NETWORK_ID_NOT_SET;
+    }
+    
+    /**
+     * Gets the next highest priority. If this value is larger than the max,
+     * shift all the priorities so the lowest starts at 0.
+     * <p>
+     * Only
+     * {@link #setHighestPriorityStateAndSave(AccessPointState, WifiConfiguration)}
+     * should call this.
+     * 
+     * @return The next highest priority to use.
+     */
+    private int getNextHighestPriority() {
+        if (mNextHighestPriority > HIGHEST_PRIORITY_MAX_VALUE) {
+            shiftPriorities();
+        }
+        
+        return mNextHighestPriority++;
+    }
+
+    /**
+     * Shift all the priorities so the lowest starts at 0.
+     * 
+     * @return Whether the operation was successful.
+     */
+    private boolean shiftPriorities() {
+        synchronized(this) {
+
+            ArrayList<AccessPointState> allAps = getApsSortedByPriorityLocked();
+
+            // Re-usable WifiConfiguration for setting priority
+            WifiConfiguration updatePriorityConfig = new WifiConfiguration();
+            
+            // Set new priorities
+            mNextHighestPriority = 0;
+            int size = allAps.size();
+            for (int i = 0; i < size; i++) {
+                AccessPointState state = allAps.get(i);
+                
+                if (!isConsideredForHighestPriority(state)) {
+                    continue;
+                }
+                
+                if (!setHighestPriorityStateAndSave(state, updatePriorityConfig)) {
+                    Log.e(TAG,
+                            "Could not shift priorities because setting the new priority failed.");
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+    }
+
+    private ArrayList<AccessPointState> getApsSortedByPriorityLocked() {
+        // Get all of the access points we have
+        ArrayList<AccessPointState> allAps = new ArrayList<AccessPointState>(mApScanList.size()
+                + mApOtherList.size());
+        allAps.addAll(mApScanList);
+        allAps.addAll(mApOtherList);
+        
+        // Sort them based on priority
+        Collections.sort(allAps, new Comparator<AccessPointState>() {
+            public int compare(AccessPointState object1, AccessPointState object2) {
+                return object1.priority - object2.priority;
+            }
+        });
+
+        return allAps;
+    }
+    
+    //============================
+    // Status related
+    //============================
+
+    private void refreshStatus() {
+        refreshStatus(null, null);
+    }
+    
+    private void refreshStatus(AccessPointState ap, NetworkInfo.DetailedState detailedState) {
+        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        if (detailedState == null) {
+            detailedState = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
+        }
+
+        if (ap == null && WifiStatus.isLiveConnection(detailedState)) {
+            /*
+             * We pass null for security since we have a network ID (i.e., it's
+             * not a wildcard), and rely on it matching.
+             */
+            ap = findApLocked(wifiInfo.getNetworkId(), wifiInfo.getBSSID(), wifiInfo
+                    .getSSID(), null);
+        }
+
+        if (ap != null) {
+            ap.blockRefresh();
+
+            // Let the AP get the latest info from the WifiInfo 
+            ap.updateFromWifiInfo(wifiInfo, detailedState);
+
+            // The detailed state from the Intent has more states than the WifiInfo's detailed
+            // state can have (for example, DHCP completion).  Set the status using
+            // the Intent's detailed state.
+            ap.setStatus(detailedState);
+            ap.unblockRefresh();
+        }
+    }
+    
+    //============================
+    // Wifi callbacks
+    //============================
+    
+    private void handleNetworkStateChanged(NetworkInfo info, String bssid) {
+        final AccessPointState ap = getCurrentAp();
+        NetworkInfo.DetailedState detailedState = info.getDetailedState(); 
+
+        if (LOGV) {
+            Log.v(TAG, "State change received " + info.toString() + ", or "
+                    + detailedState + " on " + bssid + " matched to " + ap);
+        }
+
+        handleDisablingScanWhileObtainingAddress(detailedState);
+        
+        // This will update the AP with its new info
+        refreshStatus(ap, detailedState);
+        
+        boolean isDisconnected = info.getState().equals(State.DISCONNECTED);
+        if (ap != null && info.isConnectedOrConnecting()) {
+            setPrimaryAp(ap);
+
+            if (LOGV) {
+                Log.v(TAG, " Updated " + ap + " to be primary");
+            }
+            
+        } else if (isDisconnected) {
+            
+            /*
+             * When we drop off a network (for example, the router is powered
+             * down when we were connected), we received a DISCONNECT event
+             * without a BSSID. We should not have a primary AP anymore.
+             */
+            setPrimaryAp(null);
+            
+            if (LOGV) {
+                Log.v(TAG, " Cleared primary");
+            }
+            
+        } else if (detailedState.equals(DetailedState.FAILED)) {
+
+            /*
+             * Doh, failed for whatever reason. Unset the primary AP, but set
+             * failed status on the AP that failed.
+             */
+            setPrimaryAp(null);
+            ap.setStatus(DetailedState.FAILED);
+            
+            // Bring up error dialog
+            error(R.string.wifi_generic_connection_error);
+            
+        } else if (LOGV) {
+            Log.v(TAG, " Did not update any AP to primary, could have updated "
+                    + ap + " but we aren't connected or connecting");
+        }
+
+        if ((ap != null) && (info.isConnected()
+                    || (detailedState == DetailedState.OBTAINING_IPADDR))) {
+            /*
+             * Sometimes the scan results do not contain the AP even though it's
+             * clearly connected. This may be because we do passive background
+             * scanning that isn't as 'strong' as active scanning, so even
+             * though a network is nearby, it won't be seen by the passive
+             * scanning. If we are connected (or obtaining IP) then we know it
+             * is seen.
+             */
+            ap.setSeen(true);
+        }
+
+        attemptReenableAllAps();
+    }
+
+    private void handleDisablingScanWhileObtainingAddress(DetailedState detailedState) {
+        
+        if (detailedState == DetailedState.OBTAINING_IPADDR) {
+            mIsObtainingAddress = true;
+
+            // We will not scan while obtaining an IP address
+            removeFutureScans();
+            
+        } else {
+            mIsObtainingAddress = false;
+            
+            // Start continuous scan
+            queueContinuousScan();
+        }
+    }
+    
+    private void handleScanResultsAvailable() {
+        synchronized(this) {
+            // In the end, we'll moved the ones no longer seen into the mApOtherList
+            List<AccessPointState> oldScanList = mApScanList;
+            List<AccessPointState> newScanList =
+                    new ArrayList<AccessPointState>(oldScanList.size());
+
+            List<ScanResult> list = mWifiManager.getScanResults();
+            if (list != null) {
+                for (int i = list.size() - 1; i >= 0; i--) {
+                    final ScanResult scanResult = list.get(i);
+                    
+                    if (LOGV) {
+//                        Log.v(TAG, "    " + scanResult);
+                    }
+                    
+                    if (scanResult == null) {
+                        continue;
+                    }
+                    
+                    /*
+                     * Ignore adhoc, enterprise-secured, or hidden networks.
+                     * Hidden networks show up with empty SSID.
+                     */
+                    if (AccessPointState.isAdhoc(scanResult)
+                            || AccessPointState.isEnterprise(scanResult)
+                            || TextUtils.isEmpty(scanResult.SSID)) {
+                        continue;
+                    }
+                    
+                    final String ssid = AccessPointState.convertToQuotedString(scanResult.SSID);
+                    String security = AccessPointState.getScanResultSecurity(scanResult);
+                    
+                    // See if this AP is part of a group of APs (e.g., any large
+                    // wifi network has many APs, we'll only show one) that we've
+                    // seen in this scan
+                    AccessPointState ap = findApLocked(newScanList, AccessPointState.NETWORK_ID_ANY,
+                                                 AccessPointState.BSSID_ANY, ssid, security);
+
+                    // Yup, we've seen this network.
+                    if (ap != null) {
+                        // Use the better signal
+                        if (WifiManager.compareSignalLevel(scanResult.level, ap.signal) > 0) {
+                            ap.setSignal(scanResult.level);
+                        }
+                        
+                        if (LOGV) {
+//                            Log.v(TAG, "         Already seen, continuing..");
+                        }
+                        
+                        continue;
+                    }
+
+                    // Find the AP in either our old scan list, or our non-seen
+                    // configured networks list
+                    ap = findApLocked(AccessPointState.NETWORK_ID_ANY, AccessPointState.BSSID_ANY,
+                                ssid, security);
+
+                    if (ap != null) {
+                        // Remove the AP from both (no harm if one doesn't contain it)
+                        oldScanList.remove(ap);
+                        mApOtherList.remove(ap);
+                    } else {
+                        ap = new AccessPointState(mContext);
+//                        if (LOGV) Log.v(TAG, "Created " + ap);
+                    }
+
+                    // Give it the latest state
+                    ap.updateFromScanResult(scanResult);
+
+                    if (mCallback != null) {
+                        mCallback.onAccessPointSetChanged(ap, true);
+                    }
+
+                    newScanList.add(ap);
+                }
+            }
+            
+            // oldScanList contains the ones no longer seen
+            List<AccessPointState> otherList = mApOtherList;
+            for (int i = oldScanList.size() - 1; i >= 0; i--) {
+                final AccessPointState ap = oldScanList.get(i);
+                
+                if (ap.configured) {
+                    
+                    // Keep it around, since it is configured
+                    ap.setSeen(false);
+                    otherList.add(ap);
+                    
+                } else {
+                    
+                    // Remove it since it is not configured and not seen
+                    removeApFromUi(ap);
+                }
+            }
+            
+            mApScanList = newScanList;
+        }
+
+        onScanningEnded();
+    }
+    
+    private void handleSupplicantConnectionChanged(boolean connected) {
+        if (mCallback != null) {
+            mCallback.onAccessPointsStateChanged(connected);
+        }
+        
+        if (connected) {
+            refreshAll(true);
+        }
+    }
+
+    private void handleWifiStateChanged(int wifiState) {
+        
+        if (wifiState == WIFI_STATE_ENABLED) {
+            loadConfiguredAccessPoints();
+            attemptScan();
+
+        } else if (wifiState == WIFI_STATE_DISABLED) {
+            removeFutureScans();
+            if (LOGV) Log.v(TAG, "Clearing AP lists because wifi is disabled");
+            clearApLists();
+        }
+        
+        if (mCallback != null) {
+            mCallback.onAccessPointsStateChanged(wifiState == WIFI_STATE_ENABLED);
+        }
+    }
+    
+    private void handleSignalChanged(int rssi) {
+        
+        if (mCurrentPrimaryAp != null) {
+            mCurrentPrimaryAp.setSignal(rssi);
+        }
+    }
+
+    private void handleSupplicantStateChanged(SupplicantState state, boolean hasError, int error) {
+        mCurrentSupplicantState = state;
+        
+        if (SupplicantState.FOUR_WAY_HANDSHAKE.equals(state)) {
+            mLastAuthenticatingAp = getCurrentAp();
+        }
+        
+        if (hasError) {
+            handleSupplicantStateError(error);
+        }
+    }
+    
+    private void handleSupplicantStateError(int supplicantError) {
+        if (supplicantError == WifiManager.ERROR_AUTHENTICATING) {
+            if (mCallback != null) {
+                if (mLastAuthenticatingAp != null) {
+                    mCallback.onRetryPassword(mLastAuthenticatingAp);
+                }
+            }
+        }
+    }
+    
+    private void handleNetworkIdsChanged() {
+        synchronized (this) {
+            final List<WifiConfiguration> configs = getConfiguredNetworks();
+            
+            for (int i = configs.size() - 1; i >= 0; i--) {
+                final WifiConfiguration config = configs.get(i);
+                
+                AccessPointState ap;
+                // Since network IDs have changed, we can't use it to find our previous AP state
+                ap = findApLocked(AccessPointState.NETWORK_ID_ANY, config.BSSID, config.SSID,
+                        AccessPointState.getWifiConfigurationSecurity(config));
+                
+                if (ap == null) {
+                    continue;
+                }
+
+                ap.setNetworkId(config.networkId);
+            }
+        }
+    }
+    
+    private class MyHandler extends Handler {
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_ATTEMPT_SCAN:
+                    attemptScan();
+                    break;
+            }
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
new file mode 100644
index 0000000..ceb995b
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.ProgressCategory;
+import com.android.settings.R;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * Settings screen for WiFi. This will be launched from the main system settings.
+ */
+public class WifiSettings extends PreferenceActivity implements WifiLayer.Callback,
+        DialogInterface.OnDismissListener {
+
+    private static final String TAG = "WifiSettings";
+    
+    //============================
+    // Preference/activity member variables
+    //============================
+    
+    private static final String INSTANCE_KEY_DIALOG_BUNDLE =
+            "com.android.settings.wifi.WifiSettings:dialogBundle";
+    /*
+     * We don't use Activity's dialog management because AlertDialog isn't fully
+     * able to change many of its features after it's been created, and the
+     * dialog management only creates once.
+     */
+    private Dialog mDialog;
+    
+    private static final String KEY_ADD_OTHER_NETWORK = "add_other_network";
+
+    private static final int CONTEXT_MENU_ID_CONNECT = Menu.FIRST;
+    private static final int CONTEXT_MENU_ID_FORGET = Menu.FIRST + 1;
+    private static final int CONTEXT_MENU_ID_CHANGE_PASSWORD = Menu.FIRST + 2;
+
+    private static final int MENU_ID_SCAN = Menu.FIRST; 
+    private static final int MENU_ID_ADVANCED = Menu.FIRST + 1; 
+    
+    private static final String KEY_WIFI_ENABLED = "wifi_enabled";
+    private static final String KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED =
+            "open_network_notifications_enabled";
+    private static final String KEY_ACCESS_POINTS = "access_points";
+    
+    private ProgressCategory mApCategory;
+    private CheckBoxPreference mWifiEnabled;
+    private WifiEnabler mWifiEnabler;
+    private CheckBoxPreference mOpenNetworkNotificationsEnabled; 
+    private Preference mAddOtherNetwork;
+    
+    private WeakHashMap<AccessPointState, AccessPointPreference> mAps;
+    
+    //============================
+    // Wifi member variables
+    //============================
+    
+    private WifiLayer mWifiLayer;
+        
+    //============================
+    // Activity lifecycle
+    //============================
+    
+    public WifiSettings() {
+        mAps = new WeakHashMap<AccessPointState, AccessPointPreference>();
+        mWifiLayer = new WifiLayer(this, this);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        onCreatePreferences();
+        mWifiLayer.onCreate();
+
+        onCreatedWifi();
+        mWifiLayer.onCreatedCallback();
+    }
+    
+    /**
+     * Shouldn't have any dependency on the wifi layer.
+     */
+    private void onCreatePreferences() {
+        addPreferencesFromResource(R.xml.wifi_settings);
+        
+        final PreferenceScreen preferenceScreen = getPreferenceScreen();
+        
+        mApCategory = (ProgressCategory) preferenceScreen.findPreference(KEY_ACCESS_POINTS);
+        // We don't want the ordering to be the order preferences are added,
+        // instead we want*:
+        //   1) preferred, visible APs
+        //   2) visible APs
+        //   3) preferred, APs out of range
+        //   * this ordering logic is in AccessPointPreference's compareTo
+        mApCategory.setOrderingAsAdded(false);
+        
+        mWifiEnabled = (CheckBoxPreference) preferenceScreen.findPreference(KEY_WIFI_ENABLED);
+        mWifiEnabler = new WifiEnabler(this, (WifiManager) getSystemService(WIFI_SERVICE),
+                mWifiEnabled);
+        
+        mOpenNetworkNotificationsEnabled = (CheckBoxPreference) preferenceScreen
+                .findPreference(KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED);
+        mOpenNetworkNotificationsEnabled.setChecked(Settings.System.getInt(getContentResolver(),
+                Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);        
+        
+        mAddOtherNetwork = preferenceScreen.findPreference(KEY_ADD_OTHER_NETWORK);
+        
+        registerForContextMenu(getListView());
+    }
+
+    private void onCreatedWifi() {
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mWifiLayer.onResume();
+        mWifiEnabler.resume();
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mWifiLayer.onPause();
+        mWifiEnabler.pause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        
+        if (mDialog != null) {
+            mDialog.dismiss();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        
+        menu.add(0, MENU_ID_SCAN, 0, R.string.scan_wifi)
+            .setIcon(R.drawable.ic_menu_scan_network);
+        
+        menu.add(0, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
+            .setIcon(R.drawable.ic_menu_manage);
+        
+        return true;
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        super.onOptionsItemSelected(item);
+        
+        switch (item.getItemId()) {
+
+            case MENU_ID_SCAN:
+                mWifiLayer.attemptScan();
+                return true;
+                
+            case MENU_ID_ADVANCED:
+                Intent intent = new Intent(this, IpSettings.class);
+                startActivity(intent);
+                return true;
+                
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        
+        if (mDialog != null) {
+            Bundle dialogBundle = mDialog.onSaveInstanceState();
+            outState.putBundle(INSTANCE_KEY_DIALOG_BUNDLE, dialogBundle);
+        }
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        
+        Bundle dialogBundle = state.getBundle(INSTANCE_KEY_DIALOG_BUNDLE);
+        if (dialogBundle != null) {
+            mDialog = new AccessPointDialog(this, mWifiLayer);
+            mDialog.onRestoreInstanceState(dialogBundle);
+            showDialog(mDialog);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void onDismiss(DialogInterface dialog) {
+        if (dialog == mDialog) {
+            mDialog = null;
+        }
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        super.onCreateContextMenu(menu, v, menuInfo);
+     
+        AccessPointState state = getStateFromMenuInfo(menuInfo);
+        if (state == null) {
+            return;
+        }
+     
+        menu.setHeaderTitle(state.getHumanReadableSsid());
+        
+        if (state.isConnectable()) {
+            menu.add(0, CONTEXT_MENU_ID_CONNECT, 0, R.string.wifi_context_menu_connect);
+        }
+        
+        if (state.isForgetable()) {
+            menu.add(0, CONTEXT_MENU_ID_FORGET, 1, R.string.wifi_context_menu_forget);
+            
+            if (state.hasPassword()) {
+                menu.add(0, CONTEXT_MENU_ID_CHANGE_PASSWORD, 2,
+                        R.string.wifi_context_menu_change_password);
+            }
+        }
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        
+        AccessPointState state = getStateFromMenuInfo(item.getMenuInfo());
+        if (state == null) {
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            
+            case CONTEXT_MENU_ID_CONNECT:
+                connectToNetwork(state);
+                return true;
+                
+            case CONTEXT_MENU_ID_FORGET:
+                mWifiLayer.forgetNetwork(state);
+                return true;
+                
+            case CONTEXT_MENU_ID_CHANGE_PASSWORD:
+                showAccessPointDialog(state, AccessPointDialog.MODE_CONFIGURE);
+                return true;
+                
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Decides what needs to happen to connect to a particular access point. If
+     * it is secured and doesn't already have a password, it will bring up a
+     * password box. Otherwise it will just connect.
+     */
+    private void connectToNetwork(AccessPointState state) {
+        if (state.hasSecurity() && !state.hasPassword()) {
+            showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
+        } else {
+            mWifiLayer.connectToNetwork(state);
+        }
+    }
+    
+    private AccessPointState getStateFromMenuInfo(ContextMenuInfo menuInfo) {
+        if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) {
+            return null;
+        }
+        
+        AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
+        Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem(
+                adapterMenuInfo.position);
+        if (pref == null || !(pref instanceof AccessPointPreference)) {
+            return null;
+        }
+
+        return ((AccessPointPreference) pref).getAccessPointState();
+    }
+    
+    //============================
+    // Preference callbacks
+    //============================
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        super.onPreferenceTreeClick(preferenceScreen, preference);
+
+        if (preference == mAddOtherNetwork) {
+            showAddOtherNetworkDialog();
+        } else if (preference == mOpenNetworkNotificationsEnabled) {
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+                    mOpenNetworkNotificationsEnabled.isChecked() ? 1 : 0);
+        } else if (preference instanceof AccessPointPreference) {
+            AccessPointState state = ((AccessPointPreference) preference).getAccessPointState();
+            showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
+        }
+        
+        return false;
+    }
+    
+    //============================
+    // Wifi-related
+    //============================
+
+    public WifiLayer getWifiLayer() {
+        return mWifiLayer;
+    }
+
+    private void showAddOtherNetworkDialog() {
+        AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer);
+        dialog.setState(new AccessPointState(this));
+        dialog.setMode(AccessPointDialog.MODE_CONFIGURE);
+        dialog.setTitle(R.string.wifi_add_other_network);
+        dialog.setAutoSecurityAllowed(false);
+        showDialog(dialog);
+    }
+    
+    public void showAccessPointDialog(AccessPointState state, int mode) {
+        AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer);
+        dialog.setMode(mode);
+        dialog.setState(state);
+        showDialog(dialog);
+    }
+
+    private void showDialog(Dialog dialog) {
+        // Have only one dialog open at a time
+        if (mDialog != null) {
+            mDialog.dismiss();
+        }
+        
+        mDialog = dialog;
+        dialog.setOnDismissListener(this);
+        if (dialog != null) {
+            dialog.show();
+        }
+    }
+    
+    //============================
+    // Wifi callbacks
+    //============================
+
+    public void onError(int messageResId) {
+        Toast.makeText(this, messageResId, Toast.LENGTH_LONG).show();
+    }
+
+    public void onScanningStatusChanged(boolean started) {
+        mApCategory.setProgress(started);
+    }    
+
+    public void onAccessPointSetChanged(AccessPointState ap, boolean added) {
+
+        AccessPointPreference pref = mAps.get(ap);
+        
+        if (WifiLayer.LOGV) {
+            Log.v(TAG, "onAccessPointSetChanged with " + ap + " and "
+                    + (added ? "added" : "removed") + ", found pref " + pref);
+        }
+        
+        if (added) {
+            
+            if (pref == null) {
+                pref = new AccessPointPreference(this, ap);
+                mAps.put(ap, pref);
+            } else {
+                pref.setEnabled(true);
+            }
+            
+            mApCategory.addPreference(pref);
+            
+        } else {
+
+            mAps.remove(ap);
+            
+            if (pref != null) {
+                mApCategory.removePreference(pref);
+            }
+            
+        }
+    }
+
+    public void onAccessPointsStateChanged(boolean enabled) {
+        if (enabled) {
+            mApCategory.setEnabled(true);
+        } else {
+            mApCategory.removeAll();
+            mAps.clear();
+        }
+
+        mAddOtherNetwork.setEnabled(enabled);
+    }
+
+    public void onRetryPassword(AccessPointState ap) {
+
+        if ((mDialog != null) && mDialog.isShowing()) {
+            // If we're already showing a dialog, ignore this request
+            return;
+        }
+        
+        showAccessPointDialog(ap, AccessPointDialog.MODE_RETRY_PASSWORD);
+    }
+    
+}
diff --git a/src/com/android/settings/wifi/WifiStatus.java b/src/com/android/settings/wifi/WifiStatus.java
new file mode 100644
index 0000000..d4b6431
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiStatus.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 com.android.settings.wifi;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.text.TextUtils;
+
+public class WifiStatus {
+
+    // e.g., "Connecting"
+    public static String sScanning;
+    public static String sConnecting;
+    public static String sAuthenticating;
+    public static String sObtainingIp;
+    public static String sConnected;
+    public static String sDisconnecting;
+    public static String sDisconnected;
+    public static String sFailed;    
+
+    // e.g., "Connecting to %1$s"
+    public static String sScanningFragment;
+    public static String sConnectingFragment;
+    public static String sAuthenticatingFragment;
+    public static String sObtainingIpFragment;
+    public static String sConnectedFragment;
+    public static String sDisconnectingFragment;
+    public static String sDisconnectedFragment;
+    public static String sFailedFragment;    
+
+    private static void fillStrings(Context context) {
+        sScanning = context.getString(R.string.status_scanning);
+        sConnecting = context.getString(R.string.status_connecting);
+        sAuthenticating = context.getString(R.string.status_authenticating);
+        sObtainingIp = context.getString(R.string.status_obtaining_ip);
+        sConnected = context.getString(R.string.status_connected);
+        sDisconnecting = context.getString(R.string.status_disconnecting);
+        sDisconnected = context.getString(R.string.status_disconnected);
+        sFailed = context.getString(R.string.status_failed);
+
+        sScanningFragment = context.getString(R.string.fragment_status_scanning);
+        sConnectingFragment = context.getString(R.string.fragment_status_connecting);
+        sAuthenticatingFragment = context.getString(R.string.fragment_status_authenticating);
+        sObtainingIpFragment = context.getString(R.string.fragment_status_obtaining_ip);
+        sConnectedFragment = context.getString(R.string.fragment_status_connected);
+        sDisconnectingFragment = context.getString(R.string.fragment_status_disconnecting);
+        sDisconnectedFragment = context.getString(R.string.fragment_status_disconnected);
+        sFailedFragment = context.getString(R.string.fragment_status_failed);
+    }
+    
+    public static String getStatus(Context context, String ssid,
+            NetworkInfo.DetailedState detailedState) {
+        
+        if (!TextUtils.isEmpty(ssid) && isLiveConnection(detailedState)) {
+            return getPrintableFragment(context, detailedState, ssid);
+        } else {
+            return getPrintable(context, detailedState);
+        }
+    }
+    
+    public static boolean isLiveConnection(NetworkInfo.DetailedState detailedState) {
+        return detailedState != NetworkInfo.DetailedState.DISCONNECTED
+                && detailedState != NetworkInfo.DetailedState.FAILED
+                && detailedState != NetworkInfo.DetailedState.IDLE
+                && detailedState != NetworkInfo.DetailedState.SCANNING;
+    }
+    
+    public static String getPrintable(Context context,
+            NetworkInfo.DetailedState detailedState) {
+        
+        if (sScanning == null) {
+            fillStrings(context);
+        }
+        
+        switch (detailedState) {
+            case AUTHENTICATING:
+                return sAuthenticating;
+            case CONNECTED:
+                return sConnected;
+            case CONNECTING:
+                return sConnecting;
+            case DISCONNECTED:
+                return sDisconnected;
+            case DISCONNECTING:
+                return sDisconnecting;
+            case FAILED:
+                return sFailed;
+            case OBTAINING_IPADDR:
+                return sObtainingIp;
+            case SCANNING:
+                return sScanning;
+            default:
+                return null;
+        }
+    }
+    
+    public static String getPrintableFragment(Context context,
+            NetworkInfo.DetailedState detailedState, String apName) {
+        
+        if (sScanningFragment == null) {
+            fillStrings(context);
+        }
+
+        String fragment = null;
+        switch (detailedState) {
+            case AUTHENTICATING:
+                fragment = sAuthenticatingFragment;
+                break;
+            case CONNECTED:
+                fragment = sConnectedFragment;
+                break;
+            case CONNECTING:
+                fragment = sConnectingFragment;
+                break;
+            case DISCONNECTED:
+                fragment = sDisconnectedFragment;
+                break;
+            case DISCONNECTING:
+                fragment = sDisconnectingFragment;
+                break;
+            case FAILED:
+                fragment = sFailedFragment;
+                break;
+            case OBTAINING_IPADDR:
+                fragment = sObtainingIpFragment;
+                break;
+            case SCANNING:
+                fragment = sScanningFragment;
+                break;
+        }
+        
+        return String.format(fragment, apName);
+    }
+    
+}
