diff --git a/src/com/android/settings/ActivityPicker.java b/src/com/android/settings/ActivityPicker.java
new file mode 100644
index 0000000..47e005f
--- /dev/null
+++ b/src/com/android/settings/ActivityPicker.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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.app.LauncherActivity;
+import android.content.Intent;
+import android.os.Parcelable;
+import android.view.View;
+import android.widget.ListView;
+
+/**
+ * Displays a list of all activities matching the incoming {@link Intent.EXTRA_INTENT}
+ * query, along with any applicable icons. 
+ */
+public class ActivityPicker extends LauncherActivity {
+    
+    @Override
+    protected Intent getTargetIntent() {
+        Intent intent = this.getIntent();
+        Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
+        targetIntent.addCategory(Intent.CATEGORY_DEFAULT);
+        
+        // Use a custom title for this dialog, if provided
+        if (intent.hasExtra(Intent.EXTRA_TITLE)) {
+            String title = intent.getStringExtra(Intent.EXTRA_TITLE);
+            setTitle(title);
+        }
+        
+        Parcelable parcel = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+        if (parcel instanceof Intent) {
+            targetIntent = (Intent) parcel;
+        }
+        
+        return targetIntent;
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Intent intent = intentForPosition(position);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+}
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
new file mode 100644
index 0000000..f105712
--- /dev/null
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -0,0 +1,118 @@
+/*
+ * 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(mContext));
+
+        mPhoneStateReceiver.registerIntent();
+        mCheckBoxPref.setOnPreferenceChangeListener(this);
+    }
+    
+    public void pause() {
+        mPhoneStateReceiver.unregisterIntent();
+        mCheckBoxPref.setOnPreferenceChangeListener(null);
+    }
+    
+    static boolean isAirplaneModeOn(Context context) {
+        return Settings.System.getInt(context.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 airplaneModeEnabled = serviceState.getState() == ServiceState.STATE_POWER_OFF;
+        mCheckBoxPref.setChecked(airplaneModeEnabled);
+        mCheckBoxPref.setSummary(airplaneModeEnabled ? null : 
+                mContext.getString(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..f1fa2ef
--- /dev/null
+++ b/src/com/android/settings/ApnEditor.java
@@ -0,0 +1,403 @@
+/*
+ * 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 String mCurMnc;
+    private String mCurMcc;
+    
+    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);
+                    mCurMnc = mnc;
+                    mCurMcc = mcc;
+                }
+            }
+        }
+        
+        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);
+        
+        if (mCurMnc != null && mCurMcc != null) {
+            if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) {
+                values.put(Telephony.Carriers.CURRENT, 1);
+            }
+        }
+        
+        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..87e3412
--- /dev/null
+++ b/src/com/android/settings/ApnSettings.java
@@ -0,0 +1,229 @@
+/*
+ * 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.ProgressDialog;
+import android.content.ContentResolver;
+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.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.provider.Telephony;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+public class ApnSettings extends PreferenceActivity {
+
+    public static final String EXTRA_POSITION = "position";
+    public static final String RESTORE_CARRIERS_URI =
+        "content://telephony/carriers/restore";
+
+    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 static final int MENU_RESTORE = Menu.FIRST + 1;
+
+    private static final int EVENT_RESTORE_DEFAULTAPN_START = 1;
+    private static final int EVENT_RESTORE_DEFAULTAPN_COMPLETE = 2;
+
+    private static final int DIALOG_RESTORE_DEFAULTAPN = 1001;
+
+    private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI);
+
+    private static boolean mRestoreDefaultApnMode;
+
+    private RestoreApnUiHandler mRestoreApnUiHandler;
+    private RestoreApnProcessHandler mRestoreApnProcessHandler;
+
+    private Cursor mCursor;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.apn_settings);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (!mRestoreDefaultApnMode) {
+            fillList();
+        } else {
+            showDialog(DIALOG_RESTORE_DEFAULTAPN);
+        }
+    }
+
+    private void fillList() {
+        mCursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] {
+                "_id", "name", "apn"}, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+
+        PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
+        apnList.removeAll();
+
+        mCursor.moveToFirst();
+        while (!mCursor.isAfterLast()) {
+            String name = mCursor.getString(NAME_INDEX);
+            String apn = mCursor.getString(APN_INDEX);
+
+            if (name != null && apn != null && TextUtils.getTrimmedLength(name) > 0
+                    && TextUtils.getTrimmedLength(apn) > 0) {
+                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);
+        menu.add(0, MENU_RESTORE, 0,
+                getResources().getString(R.string.menu_restore))
+                .setIcon(android.R.drawable.ic_menu_upload);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_NEW:
+            addNewApn();
+            return true;
+
+        case MENU_RESTORE:
+            restoreDefaultApn();
+            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;
+    }
+
+    private boolean restoreDefaultApn() {
+        showDialog(DIALOG_RESTORE_DEFAULTAPN);
+        mRestoreDefaultApnMode = true;
+
+        if (mRestoreApnUiHandler == null) {
+            mRestoreApnUiHandler = new RestoreApnUiHandler();
+        }
+
+        if (mRestoreApnProcessHandler == null) {
+            HandlerThread restoreDefaultApnThread = new HandlerThread(
+                    "Restore default APN Handler: Process Thread");
+            restoreDefaultApnThread.start();
+            mRestoreApnProcessHandler = new RestoreApnProcessHandler(
+                    restoreDefaultApnThread.getLooper(), mRestoreApnUiHandler);
+        }
+
+        mRestoreApnProcessHandler
+                .sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_START);
+        return true;
+    }
+
+    private class RestoreApnUiHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_RESTORE_DEFAULTAPN_COMPLETE:
+                    fillList();
+                    getPreferenceScreen().setEnabled(true);
+                    mRestoreDefaultApnMode = false;
+                    dismissDialog(DIALOG_RESTORE_DEFAULTAPN);
+                    Toast.makeText(
+                        ApnSettings.this,
+                        getResources().getString(
+                                R.string.restore_default_apn_completed),
+                        Toast.LENGTH_LONG).show();
+                    break;
+            }
+        }
+    }
+
+    private class RestoreApnProcessHandler extends Handler {
+        private Handler mRestoreApnUiHandler;
+
+        public RestoreApnProcessHandler(Looper looper, Handler restoreApnUiHandler) {
+            super(looper);
+            this.mRestoreApnUiHandler = restoreApnUiHandler;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_RESTORE_DEFAULTAPN_START:
+                    ContentResolver resolver = getContentResolver();
+                    resolver.delete(DEFAULTAPN_URI, null, null);                    
+                    mRestoreApnUiHandler
+                        .sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_COMPLETE);
+                    break;
+            }
+        }
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        if (id == DIALOG_RESTORE_DEFAULTAPN) {
+            ProgressDialog dialog = new ProgressDialog(this);
+            dialog.setMessage(getResources().getString(R.string.restore_default_apn));
+            dialog.setCancelable(false);
+            return dialog;
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        if (id == DIALOG_RESTORE_DEFAULTAPN) {
+            getPreferenceScreen().setEnabled(false);
+        }
+    }
+}
diff --git a/src/com/android/settings/ApplicationSettings.java b/src/com/android/settings/ApplicationSettings.java
new file mode 100644
index 0000000..85fe11f
--- /dev/null
+++ b/src/com/android/settings/ApplicationSettings.java
@@ -0,0 +1,98 @@
+/*
+ * 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.content.res.Configuration;
+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 static final String KEY_QUICK_LAUNCH = "quick_launch";
+
+    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());
+
+        if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_NOKEYS) {
+            // No hard keyboard, remove the setting for quick launch
+            Preference quickLaunchSetting = findPreference(KEY_QUICK_LAUNCH);
+            getPreferenceScreen().removePreference(quickLaunchSetting);
+        }
+    }
+
+    @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.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 
+                                enabled ? 1 : 0);
+    }
+    
+    private boolean isNonMarketAppsAllowed() {
+        return Settings.Secure.getInt(getContentResolver(), 
+                                      Settings.Secure.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..f9962fa
--- /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.text.format.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() / 1000;
+                long awakeTimePluggedIn = mBatteryStats.getAwakeTimePlugged() / 1000;
+                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/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..47fc07f
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -0,0 +1,497 @@
+/*
+ * 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{
+
+    /**
+     * Used by the choose lock pattern wizard to indicate the wizard is
+     * finished, and each activity in the wizard should finish.
+     * <p>
+     * Previously, each activity in the wizard would finish itself after
+     * starting the next activity. However, this leads to broken 'Back'
+     * behavior. So, now an activity does not finish itself until it gets this
+     * result.
+     */
+    static final int RESULT_FINISHED = RESULT_FIRST_USER;
+    
+    // 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);
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());        
+
+        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) {
+                // They are canceling the entire wizard
+                setResult(RESULT_FINISHED);
+                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) {
+            setResult(RESULT_FINISHED);
+            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);
+        }
+        
+        setResult(RESULT_FINISHED);
+        finish();
+    }
+}
diff --git a/src/com/android/settings/ChooseLockPatternExample.java b/src/com/android/settings/ChooseLockPatternExample.java
new file mode 100644
index 0000000..77517b9
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPatternExample.java
@@ -0,0 +1,104 @@
+/*
+ * 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 int REQUESTCODE_CHOOSE = 1;
+    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) {
+            // Canceling, so finish all
+            setResult(ChooseLockPattern.RESULT_FINISHED);
+            finish();
+        } else if (v == mNextButton) {
+            stopAnimation(mAnimation);
+            Intent intent = new Intent(this, ChooseLockPattern.class);
+            startActivityForResult(intent, REQUESTCODE_CHOOSE);
+        }
+    }
+    
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUESTCODE_CHOOSE && resultCode == ChooseLockPattern.RESULT_FINISHED) {
+            setResult(resultCode);
+            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..a0a878a
--- /dev/null
+++ b/src/com/android/settings/ChooseLockPatternTutorial.java
@@ -0,0 +1,75 @@
+/*
+ * 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 {
+    private static final int REQUESTCODE_EXAMPLE = 1;
+    
+    private View mNextButton;
+    private 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) {
+            // Canceling, so finish all
+            setResult(ChooseLockPattern.RESULT_FINISHED);
+            finish();
+        } else if (v == mNextButton) {
+            startActivityForResult(new Intent(this, ChooseLockPatternExample.class),
+                    REQUESTCODE_EXAMPLE);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUESTCODE_EXAMPLE && resultCode == ChooseLockPattern.RESULT_FINISHED) {
+            setResult(resultCode);
+            finish();
+        }
+    }
+    
+}
+
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
new file mode 100644
index 0000000..44baccc
--- /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.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+        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_PATTERN_REGISTER_FAIL &&
+                        ++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    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..e78215a
--- /dev/null
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -0,0 +1,366 @@
+/*
+ * 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.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.text.format.DateFormat;
+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);
+        }
+    }
+
+    @Override
+    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;
+    }
+
+    @Override
+    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;
+        }
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mDatePref) {
+            showDialog(DIALOG_DATEPICKER);
+        } else if (preference == mTimePref) {
+            // The 24-hour mode may have changed, so recreate the dialog
+            removeDialog(DIALOG_TIMEPICKER);
+            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() {
+        return DateFormat.is24HourFormat(this);
+    }
+    
+    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..155f085
--- /dev/null
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -0,0 +1,88 @@
+/*
+ * 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.BatteryManager;
+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 static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
+
+    private CheckBoxPreference mEnableAdb;
+    private CheckBoxPreference mKeepScreenOn;
+    private CheckBoxPreference mAllowMockLocation;
+
+    @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);
+        mAllowMockLocation = (CheckBoxPreference) findPreference(ALLOW_MOCK_LOCATION);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        mEnableAdb.setChecked(Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ADB_ENABLED, 0) != 0);
+        mKeepScreenOn.setChecked(Settings.System.getInt(getContentResolver(),
+                Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
+        mAllowMockLocation.setChecked(Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ALLOW_MOCK_LOCATION, 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.Secure.putInt(getContentResolver(), Settings.Secure.ADB_ENABLED, 
+                    mEnableAdb.isChecked() ? 1 : 0);
+        } else if (preference == mKeepScreenOn) {
+            Settings.System.putInt(getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN, 
+                    mKeepScreenOn.isChecked() ? 
+                    (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
+        } else if (preference == mAllowMockLocation) {
+            Settings.Secure.putInt(getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION,
+                    mAllowMockLocation.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..be01f7d
--- /dev/null
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -0,0 +1,153 @@
+/*
+ * 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.Build;
+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";
+    private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
+    
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.device_info_settings);
+       
+        setStringSummary("firmware_version", Build.VERSION.RELEASE);
+        setValueSummary("baseband_version", "gsm.version.baseband");
+        setStringSummary("device_model", Build.MODEL);
+        setStringSummary("build_number", Build.DISPLAY);
+        findPreference("kernel_version").setSummary(getFormattedKernelVersion());
+
+        /*
+         * Settings is a generic app and should not contain any device-specific
+         * info.
+         */
+        
+        // These are contained in the "container" preference group
+        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_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);
+        
+        // These are contained by the root preference screen
+        parentPreference = getPreferenceScreen();
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference,
+                KEY_SYSTEM_UPDATE_SETTINGS,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+        Utils.updatePreferenceToSpecificActivityOrRemove(this, parentPreference, KEY_CONTRIBUTORS,
+                Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
+    }
+    
+    private void setStringSummary(String preference, String value) {
+        try {
+            findPreference(preference).setSummary(value);
+        } catch (RuntimeException e) {
+            findPreference(preference).setSummary(
+                getResources().getString(R.string.device_info_default));
+        }
+    }
+    
+    private void setValueSummary(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/GadgetPickActivity.java b/src/com/android/settings/GadgetPickActivity.java
new file mode 100644
index 0000000..840a6a5
--- /dev/null
+++ b/src/com/android/settings/GadgetPickActivity.java
@@ -0,0 +1,131 @@
+/*
+ * 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.LauncherActivity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.gadget.GadgetProviderInfo;
+import android.gadget.GadgetManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.util.Log;
+
+import java.text.Collator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class GadgetPickActivity extends LauncherActivity
+{
+    private static final String TAG = "GadgetPickActivity";
+
+    GadgetManager mGadgetManager;
+    int mGadgetId;
+    
+    public GadgetPickActivity() {
+        mGadgetManager = GadgetManager.getInstance(this);
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        Bundle extras = getIntent().getExtras();
+        mGadgetId = extras.getInt(GadgetManager.EXTRA_GADGET_ID);
+
+        setResultData(RESULT_CANCELED);
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id)
+    {
+        Intent intent = intentForPosition(position);
+        int result;
+        try {
+            mGadgetManager.bindGadgetId(mGadgetId, intent.getComponent());
+            result = RESULT_OK;
+        } catch (IllegalArgumentException e) {
+            // This is thrown if they're already bound, or otherwise somehow
+            // bogus.  Set the result to canceled, and exit.  The app *should*
+            // clean up at this point.  We could pass the error along, but
+            // it's not clear that that's useful -- the gadget will simply not
+            // appear.
+            result = RESULT_CANCELED;
+        }
+        setResultData(result);
+        finish();
+    }
+    
+    @Override
+    public List<ListItem> makeListItems() {
+        List<GadgetProviderInfo> installed = mGadgetManager.getInstalledProviders();
+        PackageManager pm = getPackageManager();
+
+        Drawable defaultIcon = null;
+        IconResizer resizer = new IconResizer();
+
+        ArrayList<ListItem> result = new ArrayList();
+        final int N = installed.size();
+        for (int i=0; i<N; i++) {
+            GadgetProviderInfo info = installed.get(i);
+
+            LauncherActivity.ListItem item = new LauncherActivity.ListItem();
+            item.packageName = info.provider.getPackageName();
+            item.className = info.provider.getClassName();
+            
+            item.label = info.label;
+            if (info.icon != 0) {
+                Drawable d = pm.getDrawable( item.packageName, info.icon, null);
+                if (d != null) {
+                    item.icon = resizer.createIconThumbnail(d);
+                } else {
+                    Log.w(TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon)
+                            + " for package: " + item.packageName);
+                }
+            }
+            if (item.icon == null) {
+                // (including error case above)
+                if (defaultIcon == null) {
+                    // TODO: Load standard icon.
+                }
+                item.icon = defaultIcon;
+            }
+            
+            result.add(item);
+        }
+
+        Collections.sort(result, new Comparator<ListItem>() {
+                Collator mCollator = Collator.getInstance();
+                public int compare(ListItem lhs, ListItem rhs) {
+                    return mCollator.compare(lhs.label, rhs.label);
+                }
+            });
+        return result;
+    }
+
+    void setResultData(int code) {
+        Intent result = new Intent();
+        result.putExtra(GadgetManager.EXTRA_GADGET_ID, mGadgetId);
+        setResult(code, result);
+    }
+}
+
diff --git a/src/com/android/settings/InputMethodsSettings.java b/src/com/android/settings/InputMethodsSettings.java
new file mode 100644
index 0000000..51b770d
--- /dev/null
+++ b/src/com/android/settings/InputMethodsSettings.java
@@ -0,0 +1,191 @@
+/*
+ * 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 java.util.HashSet;
+import java.util.List;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.RemoteException;
+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;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+/*
+ * Displays preferences for input methods.
+ */
+public class InputMethodsSettings extends PreferenceActivity {
+    private List<InputMethodInfo> mInputMethodProperties;
+
+    final TextUtils.SimpleStringSplitter mStringColonSplitter
+            = new TextUtils.SimpleStringSplitter(':');
+    
+    private String mLastInputMethodId;
+    private String mLastTickedInputMethodId;
+
+    static public String getInputMethodIdFromKey(String key) {
+        return key;
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.input_methods_prefs);
+
+        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+        mInputMethodProperties = imm.getInputMethodList();
+
+        mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
+            Settings.Secure.DEFAULT_INPUT_METHOD);
+
+        int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
+                .size());
+        for (int i = 0; i < N; ++i) {
+            InputMethodInfo property = mInputMethodProperties.get(i);
+            String prefKey = property.getId();
+
+            CharSequence label = property.loadLabel(getPackageManager());
+            
+            // Add a check box.
+            CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
+            chkbxPref.setKey(prefKey);
+            chkbxPref.setTitle(label);
+            getPreferenceScreen().addPreference(chkbxPref);
+
+            // If setting activity is available, add a setting screen entry.
+            if (null != property.getSettingsActivity()) {
+                PreferenceScreen prefScreen = new PreferenceScreen(this, null);
+                prefScreen.setKey(property.getSettingsActivity());
+                prefScreen.setTitle(getResources().getString(
+                        R.string.input_methods_settings_label_format, label));
+                getPreferenceScreen().addPreference(prefScreen);
+            }
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        final HashSet<String> enabled = new HashSet<String>();
+        String enabledStr = Settings.Secure.getString(getContentResolver(),
+                Settings.Secure.ENABLED_INPUT_METHODS);
+        if (enabledStr != null) {
+            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+            splitter.setString(enabledStr);
+            while (splitter.hasNext()) {
+                enabled.add(splitter.next());
+            }
+        }
+        
+        // Update the statuses of the Check Boxes.
+        int N = mInputMethodProperties.size();
+        for (int i = 0; i < N; ++i) {
+            final String id = mInputMethodProperties.get(i).getId();
+            CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
+                    .get(i).getId());
+            pref.setChecked(enabled.contains(id));
+        }
+        mLastTickedInputMethodId = null;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        StringBuilder builder = new StringBuilder(256);
+        
+        boolean haveLastInputMethod = false;
+        
+        int firstEnabled = -1;
+        int N = mInputMethodProperties.size();
+        for (int i = 0; i < N; ++i) {
+            final String id = mInputMethodProperties.get(i).getId();
+            CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
+            boolean hasIt = id.equals(mLastInputMethodId);
+            if (pref.isChecked()) {
+                if (builder.length() > 0) builder.append(':');
+                builder.append(id);
+                if (firstEnabled < 0) {
+                    firstEnabled = i;
+                }
+                if (hasIt) haveLastInputMethod = true;
+            } else if (hasIt) {
+                mLastInputMethodId = mLastTickedInputMethodId;
+            }
+        }
+
+        // If the last input method is unset, set it as the first enabled one.
+        if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) {
+            if (firstEnabled >= 0) {
+                mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
+            } else {
+                mLastInputMethodId = null;
+            }
+        }
+        
+        Settings.Secure.putString(getContentResolver(),
+            Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
+        Settings.Secure.putString(getContentResolver(),
+            Settings.Secure.DEFAULT_INPUT_METHOD, mLastInputMethodId);
+    }
+
+    @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 instanceof CheckBoxPreference) {
+            CheckBoxPreference chkPref = (CheckBoxPreference) preference;
+            String id = getInputMethodIdFromKey(chkPref.getKey());
+            if (chkPref.isChecked()) {
+                mLastTickedInputMethodId = id;
+            } else if (id.equals(mLastTickedInputMethodId)) {
+                mLastTickedInputMethodId = null;
+            }
+        } else if (preference instanceof PreferenceScreen) {
+            if (preference.getIntent() == null) {
+                PreferenceScreen pref = (PreferenceScreen) preference;
+                String activityName = pref.getKey();
+                String packageName = activityName.substring(0, activityName
+                        .lastIndexOf("."));
+                if (activityName.length() > 0) {
+                    Intent i = new Intent(Intent.ACTION_MAIN);
+                    i.setClassName(packageName, activityName);
+                    startActivity(i);
+                }
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/src/com/android/settings/InstalledAppDetails.java b/src/com/android/settings/InstalledAppDetails.java
new file mode 100644
index 0000000..327874b
--- /dev/null
+++ b/src/com/android/settings/InstalledAppDetails.java
@@ -0,0 +1,478 @@
+
+
+/**
+ * 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.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.text.format.Formatter;
+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. This activity presents
+ * extended information associated with a package like code, data, total size, permissions
+ * used by the application and also the set of default launchable activities.
+ * For system applications, an option to clear user data is displayed only if data size is > 0.
+ * System applications that do not want clear user data do not have this option.
+ * For non-system applications, there is no option to clear data. Instead there is an option to
+ * uninstall the application.
+ */
+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;
+    private ApplicationInfo mAppInfo;
+    private Button mAppButton;
+    private Button mActivitiesButton;
+    private boolean mCanUninstall;
+    private boolean localLOGV=Config.LOGV || false;
+    private TextView mAppSnippetSize;
+    private TextView mTotalSize;
+    private TextView mAppSize;
+    private TextView mDataSize;
+    private PkgSizeObserver mSizeObserver;
+    private ClearUserDataObserver mClearDataObserver;
+    // Views related to cache info
+    private View mCachePanel;
+    private TextView mCacheSize;
+    private Button mClearCacheButton;
+    private ClearCacheObserver mClearCacheObserver;
+    private Button mForceStopButton;
+    
+    PackageStats mSizeInfo;
+    private Button mManageSpaceButton;
+    private PackageManager mPm;
+    
+    //internal constants used in Handler
+    private static final int OP_SUCCESSFUL = 1;
+    private static final int OP_FAILED = 2;
+    private static final int CLEAR_USER_DATA = 1;
+    private static final int GET_PKG_SIZE = 2;
+    private static final int CLEAR_CACHE = 3;
+    private static final String ATTR_PACKAGE_STATS="PackageStats";
+    
+    // invalid size value used initially and also when size retrieval through PackageManager
+    // fails for whatever reason
+    private static final int SIZE_INVALID = -1;
+    
+    // Resource strings
+    private CharSequence mInvalidSizeStr;
+    private CharSequence mComputingStr;
+    private CharSequence mAppButtonText;
+    
+    // Possible btn states
+    private enum AppButtonStates {
+        CLEAR_DATA,
+        UNINSTALL,
+        NONE
+    } 
+    private AppButtonStates mAppButtonState;
+    
+    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;
+                case CLEAR_CACHE:
+                    // Refresh size info
+                    mPm.getPackageSizeInfo(mAppInfo.packageName, mSizeObserver);
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+    
+    private boolean isUninstallable() {
+        if (((mAppInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) && 
+                ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0)) {
+            return false;
+        }
+        return true;
+    }
+    
+    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);
+            
+         }
+     }
+    
+    class ClearCacheObserver extends IPackageDataObserver.Stub {
+        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
+            final Message msg = mHandler.obtainMessage(CLEAR_CACHE);
+            msg.arg1 = succeeded?OP_SUCCESSFUL:OP_FAILED;
+            mHandler.sendMessage(msg);
+         }
+     }
+    
+    private String getSizeStr(long size) {
+        if (size == SIZE_INVALID) {
+            return mInvalidSizeStr.toString();
+        }
+        return Formatter.formatFileSize(this, size);
+    }
+    
+    private void setAppBtnState() {
+        boolean visible = false;
+        if(mCanUninstall) {
+            //app can clear user data
+            if((mAppInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 
+                    == ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) {
+                mAppButtonText = getText(R.string.clear_user_data_text);
+               mAppButtonState = AppButtonStates.CLEAR_DATA;
+               visible = true;
+            } else {
+                //hide button if diableClearUserData is set
+                visible = false;
+                mAppButtonState = AppButtonStates.NONE;
+            }
+        } else {
+            visible = true;
+            mAppButtonState = AppButtonStates.UNINSTALL;
+            mAppButtonText = getText(R.string.uninstall_text);
+        }
+        if(visible) {
+            mAppButton.setText(mAppButtonText);
+            mAppButton.setVisibility(View.VISIBLE);
+        } else {
+            mAppButton.setVisibility(View.GONE);
+        }
+    }
+    
+    /** 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);
+        mComputingStr = getText(R.string.computing_size);
+        // Try retrieving package stats again
+        CharSequence totalSizeStr, appSizeStr, dataSizeStr;
+        totalSizeStr = appSizeStr = dataSizeStr = mComputingStr;
+        if(localLOGV) Log.i(TAG, "Have to compute package sizes");
+        mSizeObserver = new PkgSizeObserver();
+        mPm.getPackageSizeInfo(packageName, mSizeObserver);
+
+        try {
+            mAppInfo = mPm.getApplicationInfo(packageName, 
+                    PackageManager.GET_UNINSTALLED_PACKAGES);
+        } catch (NameNotFoundException e) {
+            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(mAppInfo.loadIcon(mPm));
+        //set application name TODO version
+        CharSequence appName = mAppInfo.loadLabel(mPm);
+        if(appName == null) {
+            appName = getString(_UNKNOWN_APP);
+        }
+        ((TextView)findViewById(R.id.app_name)).setText(appName);
+        mAppSnippetSize = ((TextView)findViewById(R.id.app_size));
+        mAppSnippetSize.setText(totalSizeStr);
+        //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);
+         
+         mAppButton = ((Button)findViewById(R.id.uninstall_button));
+        //determine if app is a system app
+         mCanUninstall = !isUninstallable();
+         if(localLOGV) Log.i(TAG, "Is systemPackage "+mCanUninstall);
+         setAppBtnState();
+         mManageSpaceButton = (Button)findViewById(R.id.manage_space_button);
+         if(mAppInfo.manageSpaceActivityName != null) {
+             mManageSpaceButton.setVisibility(View.VISIBLE);
+             mManageSpaceButton.setOnClickListener(this);
+         }
+         
+         // Cache section
+         mCachePanel = findViewById(R.id.cache_panel);
+         mCacheSize = (TextView) findViewById(R.id.cache_size_text);
+         mCacheSize.setText(mComputingStr);
+         mClearCacheButton = (Button) findViewById(R.id.clear_cache_button);
+         mForceStopButton = (Button) findViewById(R.id.force_stop_button);
+         mForceStopButton.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);
+         }
+         
+         // security permissions section
+         LinearLayout permsView = (LinearLayout) findViewById(R.id.permissions_section);
+         AppSecurityPermissions asp = new AppSecurityPermissions(this, packageName);
+         if(asp.getPermissionCount() > 0) {
+             permsView.setVisibility(View.VISIBLE);
+             // Make the security sections header visible
+             LinearLayout securityList = (LinearLayout) permsView.findViewById(
+                     R.id.security_settings_list);
+             securityList.addView(asp.getPermissionsView());
+         } else {
+             permsView.setVisibility(View.GONE);
+         }
+    }
+    
+    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(android.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);
+        mAppButton.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;
+        PackageStats newPs = msg.getData().getParcelable(ATTR_PACKAGE_STATS);
+        long newTot = newPs.cacheSize+newPs.codeSize+newPs.dataSize;
+        if(mSizeInfo == null) {
+            mSizeInfo = newPs;
+            String str = getSizeStr(newTot);
+            mTotalSize.setText(str);
+            mAppSnippetSize.setText(str);
+            mAppSize.setText(getSizeStr(newPs.codeSize));
+            mDataSize.setText(getSizeStr(newPs.dataSize));
+            mCacheSize.setText(getSizeStr(newPs.cacheSize));
+        } else {
+            long oldTot = mSizeInfo.cacheSize+mSizeInfo.codeSize+mSizeInfo.dataSize;
+            if(newTot != oldTot) {
+                String str = getSizeStr(newTot);
+                mTotalSize.setText(str);
+                mAppSnippetSize.setText(str);
+                changed = true;
+            }
+            if(newPs.codeSize != mSizeInfo.codeSize) {
+                mAppSize.setText(getSizeStr(newPs.codeSize));
+                changed = true;
+            }
+            if(newPs.dataSize != mSizeInfo.dataSize) {
+                mDataSize.setText(getSizeStr(newPs.dataSize));
+                changed = true;
+            }
+            if(newPs.cacheSize != mSizeInfo.cacheSize) {
+                mCacheSize.setText(getSizeStr(newPs.cacheSize));
+                changed = true;
+            }
+            if(changed) {
+                mSizeInfo = newPs;
+            }
+        }
+        
+        long data = mSizeInfo.dataSize;
+        // Disable button if data is 0
+        if(mAppButtonState != AppButtonStates.NONE){
+            mAppButton.setText(mAppButtonText);
+            if((mAppButtonState == AppButtonStates.CLEAR_DATA) && (data == 0)) {
+                mAppButton.setEnabled(false);
+            } else {
+                mAppButton.setEnabled(true);
+                mAppButton.setOnClickListener(this);
+            }            
+        }
+        refreshCacheInfo(newPs.cacheSize);
+    }
+    
+    private void refreshCacheInfo(long cacheSize) {
+        // Set cache info
+        mCacheSize.setText(getSizeStr(cacheSize));
+        if (cacheSize <= 0) {
+            mClearCacheButton.setEnabled(false);
+        } else {
+            mClearCacheButton.setOnClickListener(this);
+        }
+    }
+    
+    /*
+     * 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);
+            mPm.getPackageSizeInfo(packageName, mSizeObserver);
+        } else {
+            mAppButton.setText(R.string.clear_user_data_text);
+            mAppButton.setEnabled(true);
+        }
+    }
+    
+    /*
+     * Private method to initiate clearing user data when the user clicks the clear data 
+     * button for a system package
+     */
+    private  void initiateClearUserDataForSysPkg() {
+        mAppButton.setEnabled(false);
+        //invoke uninstall or clear user data based on sysPackage
+        String packageName = mAppInfo.packageName;
+        Log.i(TAG, "Clearing user data for system package");
+        if(mClearDataObserver == null) {
+            mClearDataObserver = new ClearUserDataObserver();
+        }
+        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
+        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 {
+                mAppButton.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 == mAppButton) {
+            if(mCanUninstall) {
+                //display confirmation dialog
+                new AlertDialog.Builder(this)
+                .setTitle(getString(R.string.clear_data_dlg_title))
+                .setIcon(android.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, true);
+            }
+        } 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);
+        } else if (v == mClearCacheButton) {
+            // Lazy initialization of observer
+            if (mClearCacheObserver == null) {
+                mClearCacheObserver = new ClearCacheObserver();
+            }
+            mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver);
+        } else if (v == mForceStopButton) {
+            ActivityManager am = (ActivityManager)getSystemService(
+                    Context.ACTIVITY_SERVICE);
+            am.restartPackage(packageName);
+        }
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if(which == AlertDialog.BUTTON_POSITIVE) {
+            //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..8463d26
--- /dev/null
+++ b/src/com/android/settings/LanguageSettings.java
@@ -0,0 +1,247 @@
+/*
+ * 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.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.provider.Settings.System;
+import android.text.TextUtils;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.HashSet;
+import java.util.List;
+
+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,
+    };
+    
+    private List<InputMethodInfo> mInputMethodProperties;
+
+    final TextUtils.SimpleStringSplitter mStringColonSplitter
+            = new TextUtils.SimpleStringSplitter(':');
+    
+    private String mLastInputMethodId;
+    private String mLastTickedInputMethodId;
+
+    static public String getInputMethodIdFromKey(String key) {
+        return key;
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.language_settings);
+
+        if (getAssets().getLocales().length == 1) {
+            getPreferenceScreen().
+                removePreference(findPreference("language_category"));
+        }
+    
+        Configuration config = getResources().getConfiguration();
+        if (config.keyboard != Configuration.KEYBOARD_QWERTY) {
+            getPreferenceScreen().removePreference(
+                    getPreferenceScreen().findPreference("hardkeyboard_category"));
+        } else {
+            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);
+            }
+        }
+
+        onCreateIMM();
+    }
+    
+    private void onCreateIMM() {
+        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+        mInputMethodProperties = imm.getInputMethodList();
+
+        mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
+            Settings.Secure.DEFAULT_INPUT_METHOD);
+        
+        PreferenceGroup textCategory = (PreferenceGroup) findPreference("text_category");
+        
+        int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
+                .size());
+        for (int i = 0; i < N; ++i) {
+            InputMethodInfo property = mInputMethodProperties.get(i);
+            String prefKey = property.getId();
+
+            CharSequence label = property.loadLabel(getPackageManager());
+            
+            // Add a check box.
+            CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
+            chkbxPref.setKey(prefKey);
+            chkbxPref.setTitle(label);
+            textCategory.addPreference(chkbxPref);
+
+            // If setting activity is available, add a setting screen entry.
+            if (null != property.getSettingsActivity()) {
+                PreferenceScreen prefScreen = new PreferenceScreen(this, null);
+                prefScreen.setKey(property.getSettingsActivity());
+                CharSequence settingsLabel = getResources().getString(
+                        R.string.input_methods_settings_label_format, label);
+                prefScreen.setTitle(settingsLabel);
+                textCategory.addPreference(prefScreen);
+            }
+        }
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        final HashSet<String> enabled = new HashSet<String>();
+        String enabledStr = Settings.Secure.getString(getContentResolver(),
+                Settings.Secure.ENABLED_INPUT_METHODS);
+        if (enabledStr != null) {
+            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+            splitter.setString(enabledStr);
+            while (splitter.hasNext()) {
+                enabled.add(splitter.next());
+            }
+        }
+        
+        // Update the statuses of the Check Boxes.
+        int N = mInputMethodProperties.size();
+        for (int i = 0; i < N; ++i) {
+            final String id = mInputMethodProperties.get(i).getId();
+            CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
+                    .get(i).getId());
+            pref.setChecked(enabled.contains(id));
+        }
+        mLastTickedInputMethodId = null;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        StringBuilder builder = new StringBuilder(256);
+        
+        boolean haveLastInputMethod = false;
+        
+        int firstEnabled = -1;
+        int N = mInputMethodProperties.size();
+        for (int i = 0; i < N; ++i) {
+            final String id = mInputMethodProperties.get(i).getId();
+            CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
+            boolean hasIt = id.equals(mLastInputMethodId);
+            if (pref.isChecked()) {
+                if (builder.length() > 0) builder.append(':');
+                builder.append(id);
+                if (firstEnabled < 0) {
+                    firstEnabled = i;
+                }
+                if (hasIt) haveLastInputMethod = true;
+            } else if (hasIt) {
+                mLastInputMethodId = mLastTickedInputMethodId;
+            }
+        }
+
+        // If the last input method is unset, set it as the first enabled one.
+        if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) {
+            if (firstEnabled >= 0) {
+                mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
+            } else {
+                mLastInputMethodId = null;
+            }
+        }
+        
+        Settings.Secure.putString(getContentResolver(),
+            Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
+        Settings.Secure.putString(getContentResolver(),
+            Settings.Secure.DEFAULT_INPUT_METHOD, mLastInputMethodId);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+
+        // Physical keyboard stuff
+        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;
+            }
+        }
+
+        // Input Method stuff
+        // 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 instanceof CheckBoxPreference) {
+            CheckBoxPreference chkPref = (CheckBoxPreference) preference;
+            String id = getInputMethodIdFromKey(chkPref.getKey());
+            if (chkPref.isChecked()) {
+                mLastTickedInputMethodId = id;
+            } else if (id.equals(mLastTickedInputMethodId)) {
+                mLastTickedInputMethodId = null;
+            }
+        } else if (preference instanceof PreferenceScreen) {
+            if (preference.getIntent() == null) {
+                PreferenceScreen pref = (PreferenceScreen) preference;
+                String activityName = pref.getKey();
+                String packageName = activityName.substring(0, activityName
+                        .lastIndexOf("."));
+                if (activityName.length() > 0) {
+                    Intent i = new Intent(Intent.ACTION_MAIN);
+                    i.setClassName(packageName, activityName);
+                    startActivity(i);
+                }
+            }
+        }
+
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
+}
diff --git a/src/com/android/settings/LauncherGadgetBinder.java b/src/com/android/settings/LauncherGadgetBinder.java
new file mode 100644
index 0000000..f7b5a61
--- /dev/null
+++ b/src/com/android/settings/LauncherGadgetBinder.java
@@ -0,0 +1,225 @@
+/*
+ * 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.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.gadget.GadgetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class LauncherGadgetBinder extends Activity {
+    private static final String TAG = "LauncherGadgetBinder";
+    private static final boolean LOGD = true;
+    
+    static final String AUTHORITY = "com.android.launcher.settings";
+    static final String TABLE_FAVORITES = "favorites";
+    
+    static final String EXTRA_BIND_SOURCES = "com.android.launcher.settings.bindsources";
+    static final String EXTRA_BIND_TARGETS = "com.android.launcher.settings.bindtargets";
+
+    static final String EXTRA_GADGET_BITMAPS = "com.android.camera.gadgetbitmaps";
+    
+    /**
+     * {@link ContentProvider} constants pulled over from Launcher
+     */
+    static final class LauncherProvider implements BaseColumns {
+        static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_FAVORITES);
+
+        static final String ITEM_TYPE = "itemType";
+        static final String GADGET_ID = "gadgetId";
+        static final String ICON = "icon";
+
+        static final int ITEM_TYPE_GADGET = 4;
+        static final int ITEM_TYPE_WIDGET_CLOCK = 1000;
+        static final int ITEM_TYPE_WIDGET_SEARCH = 1001;
+        static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002;
+    }
+    
+    static final String[] BIND_PROJECTION = new String[] {
+        LauncherProvider._ID,
+        LauncherProvider.ITEM_TYPE,
+        LauncherProvider.GADGET_ID,
+        LauncherProvider.ICON,
+    };
+    
+    static final int INDEX_ID = 0;
+    static final int INDEX_ITEM_TYPE = 1;
+    static final int INDEX_GADGET_ID = 2;
+    static final int INDEX_ICON = 3;
+    
+    static final ComponentName BIND_PHOTO_GADGET = new ComponentName("com.android.camera",
+            "com.android.camera.PhotoGadgetBind");
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        finish();
+
+        // This helper reaches into the Launcher database and binds any unlinked
+        // gadgets. If will remove any items that can't be bound successfully.
+        // We protect this binder at the manifest level by asserting the caller
+        // has the Launcher WRITE_SETTINGS permission.
+        
+        final Intent intent = getIntent();
+        final Bundle extras = intent.getExtras();
+        
+        int[] bindSources = null;
+        ArrayList<ComponentName> bindTargets = null;
+        Exception exception = null;
+
+        try {
+            bindSources = extras.getIntArray(EXTRA_BIND_SOURCES);
+            bindTargets = intent.getParcelableArrayListExtra(EXTRA_BIND_TARGETS);
+        } catch (ClassCastException ex) {
+            exception = ex;
+        }
+        
+        if (exception != null || bindSources == null || bindTargets == null ||
+                bindSources.length != bindTargets.size()) {
+            Log.w(TAG, "Problem reading incoming bind request, or invalid request", exception);
+            return;
+        }
+        
+        final String selectWhere = buildOrWhereString(LauncherProvider.ITEM_TYPE, bindSources);
+        
+        final ContentResolver resolver = getContentResolver();
+        final GadgetManager gadgetManager = GadgetManager.getInstance(this);
+        
+        boolean foundPhotoGadgets = false;
+        final ArrayList<Integer> photoGadgetIds = new ArrayList<Integer>();
+        final ArrayList<Bitmap> photoBitmaps = new ArrayList<Bitmap>();
+        
+        Cursor c = null;
+        
+        try {
+            c = resolver.query(LauncherProvider.CONTENT_URI,
+                    BIND_PROJECTION, selectWhere, null, null);
+            
+            if (LOGD) Log.d(TAG, "found bind cursor count="+c.getCount());
+            
+            final ContentValues values = new ContentValues();
+            while (c != null && c.moveToNext()) {
+                long favoriteId = c.getLong(INDEX_ID);
+                int itemType = c.getInt(INDEX_ITEM_TYPE);
+                int gadgetId = c.getInt(INDEX_GADGET_ID);
+                byte[] iconData = c.getBlob(INDEX_ICON);
+                
+                // Find the binding target for this type
+                ComponentName targetGadget = null;
+                for (int i = 0; i < bindSources.length; i++) {
+                    if (bindSources[i] == itemType) {
+                        targetGadget = bindTargets.get(i);
+                        break;
+                    }
+                }
+                
+                if (LOGD) Log.d(TAG, "found matching targetGadget="+targetGadget.toString()+" for favoriteId="+favoriteId);
+                
+                boolean bindSuccess = false;
+                try {
+                    gadgetManager.bindGadgetId(gadgetId, targetGadget);
+                    bindSuccess = true;
+                } catch (RuntimeException ex) {
+                    Log.w(TAG, "Problem binding gadget", ex);
+                }
+                
+                // Handle special case of photo gadget by loading bitmap and
+                // preparing for later binding
+                if (bindSuccess && iconData != null &&
+                        itemType == LauncherProvider.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
+                    Bitmap bitmap = BitmapFactory.decodeByteArray(iconData, 0, iconData.length);
+                    
+                    photoGadgetIds.add(gadgetId);
+                    photoBitmaps.add(bitmap);
+                    foundPhotoGadgets = true;
+                }
+
+                if (LOGD) Log.d(TAG, "after finished, success="+bindSuccess);
+
+                // Depending on success, update launcher or remove item
+                Uri favoritesUri = ContentUris.withAppendedId(LauncherProvider.CONTENT_URI, favoriteId);
+                if (bindSuccess) {
+                    values.clear();
+                    values.put(LauncherProvider.ITEM_TYPE, LauncherProvider.ITEM_TYPE_GADGET);
+                    values.putNull(LauncherProvider.ICON);
+                    resolver.update(favoritesUri, values, null, null);
+                } else {
+                    resolver.delete(favoritesUri, null, null);
+                }
+                    
+            }
+        } catch (SQLException ex) {
+            Log.w(TAG, "Problem while binding gadgetIds for Launcher", ex);
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+        
+        if (foundPhotoGadgets) {
+            // Convert gadgetIds into int[]
+            final int N = photoGadgetIds.size();
+            final int[] photoGadgetIdsArray = new int[N];
+            for (int i = 0; i < N; i++) {
+                photoGadgetIdsArray[i] = photoGadgetIds.get(i);
+            }
+            
+            // Launch intent over to handle bitmap binding, but we don't need to
+            // wait around for the result.
+            final Intent bindIntent = new Intent();
+            bindIntent.setComponent(BIND_PHOTO_GADGET);
+            
+            final Bundle bindExtras = new Bundle();
+            bindExtras.putIntArray(GadgetManager.EXTRA_GADGET_IDS, photoGadgetIdsArray);
+            bindExtras.putParcelableArrayList(EXTRA_GADGET_BITMAPS, photoBitmaps);
+            bindIntent.putExtras(bindExtras);
+            
+            startActivity(bindIntent);
+        }
+        
+        if (LOGD) Log.d(TAG, "completely finished with binding for Launcher");
+    }
+    
+    /**
+     * Build a query string that will match any row where the column matches
+     * anything in the values list.
+     */
+    static String buildOrWhereString(String column, int[] values) {
+        StringBuilder selectWhere = new StringBuilder();
+        for (int i = values.length - 1; i >= 0; i--) {
+            selectWhere.append(column).append("=").append(values[i]);
+            if (i > 0) {
+                selectWhere.append(" OR ");
+            }
+        }
+        return selectWhere.toString();
+    }
+    
+}
diff --git a/src/com/android/settings/LocalePicker.java b/src/com/android/settings/LocalePicker.java
new file mode 100644
index 0000000..386d7e0
--- /dev/null
+++ b/src/com/android/settings/LocalePicker.java
@@ -0,0 +1,153 @@
+/*
+ * 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();
+        Arrays.sort(locales);
+
+        final int origSize = locales.length;
+        Loc[] preprocess = new Loc[origSize];
+        int finalSize = 0;
+        for (int i = 0 ; i < origSize; i++ ) {
+            String s = locales[i];
+            int len = s.length();
+            if (len == 2) {
+                Locale l = new Locale(s);
+                preprocess[finalSize++] = new Loc(toTitleCase(l.getDisplayLanguage()), l);
+            } else if (len == 5) {
+                String language = s.substring(0, 2);
+                String country = s.substring(3, 5);
+                Locale l = new Locale(language, country);
+
+                if (finalSize == 0) {
+                    preprocess[finalSize++] = new Loc(toTitleCase(l.getDisplayLanguage()), l);
+                } else {
+                    // check previous entry:
+                    //  same lang and no country -> overwrite it with a lang-only name
+                    //  same lang and a country -> upgrade to full name and 
+                    //    insert ours with full name
+                    //  diff lang -> insert ours with lang-only name
+                    if (preprocess[finalSize-1].locale.getLanguage().equals(language)) {
+                       String prevCountry = preprocess[finalSize-1].locale.getCountry();
+                       if (prevCountry.length() == 0) {
+                            preprocess[finalSize-1].locale = l;
+                            preprocess[finalSize-1].label = toTitleCase(l.getDisplayLanguage());
+                        } else {
+                            preprocess[finalSize-1].label = toTitleCase(preprocess[finalSize-1].locale.getDisplayName());
+                            preprocess[finalSize++] = new Loc(toTitleCase(l.getDisplayName()), l);
+                        }
+                    } else {
+                        String displayName;
+                        if (s.equals("zz_ZZ")) {
+                            displayName = "Pseudo...";
+                        } else {
+                            displayName = toTitleCase(l.getDisplayLanguage());
+                        }
+                        preprocess[finalSize++] = new Loc(displayName, l);
+                    }
+                }
+            }
+        }
+        mLocales = new Loc[finalSize];
+        for (int i = 0; i < finalSize ; i++) {
+            mLocales[i] = preprocess[i];
+        }
+        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);
+    }
+
+    private static String toTitleCase(String s) {
+        if (s.length() == 0) {
+            return s;
+        }
+
+        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+    }
+
+    @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;
+
+            // indicate this isn't some passing default - the user wants this remembered
+            config.userSetLocale = true;
+
+            am.updateConfiguration(config);
+        } 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..74957ed
--- /dev/null
+++ b/src/com/android/settings/ManageApplications.java
@@ -0,0 +1,1307 @@
+/*
+ * 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.ActivityManager;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+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.IPackageStatsObserver;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageStats;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.format.Formatter;
+import android.util.Config;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Activity to pick an application that will be used to display installation information and
+ * options to uninstall/delete user data for system applications. This activity
+ * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
+ * intent.
+ *  Initially a compute in progress message is displayed while the application retrieves
+ *  the list of application information from the PackageManager. The size information
+ *  for each package is refreshed to the screen. The resource(app description and
+ *  icon) information for each package is not available yet, so some default values for size
+ *  icon and descriptions are used initially. Later the resource information for each 
+ *  application is retrieved and dynamically updated on the screen.
+ *  A Broadcast receiver registers for package additions or deletions when the activity is
+ *  in focus. If the user installs or deletes packages when the activity has focus, the receiver
+ *  gets notified and proceeds to add/delete these packages from the list on the screen.
+ *  This is an unlikely scenario but could happen. The entire list gets created every time
+ *  the activity's onStart gets invoked. This is to avoid having the receiver for the entire
+ *  life cycle of the application.
+ *  The applications can be sorted either alphabetically or 
+ *  based on size(descending). If this activity gets launched under low memory
+ *  situations(A low memory notification dispatches intent 
+ *  ACTION_MANAGE_PACKAGE_STORAGE) the list is sorted per size.
+ *  If the user selects an application, extended info(like size, uninstall/clear data options,
+ *  permissions info etc.,) is displayed via the InstalledAppDetails activity.
+ */
+public class ManageApplications extends ListActivity implements
+        OnItemClickListener, DialogInterface.OnCancelListener,
+        DialogInterface.OnClickListener {
+    // TAG for this activity
+    private static final String TAG = "ManageApplications";
+    
+    // Log information boolean
+    private boolean localLOGV = Config.LOGV || false;
+    
+    // attributes used as keys when passing values to InstalledAppDetails activity
+    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_CHG = APP_PKG_PREFIX+"changed";
+    
+    // attribute name used in receiver for tagging names of added/deleted packages
+    private static final String ATTR_PKG_NAME="PackageName";
+    private static final String ATTR_APP_PKG_STATS="ApplicationPackageStats";
+    
+    // constant value that can be used to check return code from sub activity.
+    private static final int INSTALLED_APP_DETAILS = 1;
+    
+    // sort order that can be changed through the menu can be sorted alphabetically
+    // or size(descending)
+    private static final int MENU_OPTIONS_BASE = 0;
+    public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 0;
+    public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 1;
+    // Filter options used for displayed list of applications
+    public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 2;
+    public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 3;
+    public static final int FILTER_APPS_RUNNING = MENU_OPTIONS_BASE + 4;
+    public static final int FILTER_OPTIONS = MENU_OPTIONS_BASE + 5;
+    // Alert Dialog presented to user to find out the filter option
+    AlertDialog mAlertDlg;
+    // sort order
+    private int mSortOrder = SORT_ORDER_ALPHA;
+    // Filter value
+    int mFilterApps = FILTER_APPS_ALL;
+    
+    // Custom Adapter used for managing items in the list
+    private AppInfoAdapter mAppInfoAdapter;
+    
+    // messages posted to the handler
+    private static final int HANDLER_MESSAGE_BASE = 0;
+    private static final int INIT_PKG_INFO = HANDLER_MESSAGE_BASE+1;
+    private static final int COMPUTE_PKG_SIZE_DONE = HANDLER_MESSAGE_BASE+2;
+    private static final int REMOVE_PKG = HANDLER_MESSAGE_BASE+3;
+    private static final int REORDER_LIST = HANDLER_MESSAGE_BASE+4;
+    private static final int ADD_PKG_START = HANDLER_MESSAGE_BASE+5;
+    private static final int ADD_PKG_DONE = HANDLER_MESSAGE_BASE+6;
+    private static final int REFRESH_ICONS = HANDLER_MESSAGE_BASE+7;
+    private static final int NEXT_LOAD_STEP = HANDLER_MESSAGE_BASE+8;
+    
+    // observer object used for computing pkg sizes
+    private PkgSizeObserver mObserver;
+    // local handle to PackageManager
+    private PackageManager mPm;
+    // Broadcast Receiver object that receives notifications for added/deleted
+    // packages
+    private PackageIntentReceiver mReceiver;
+    // atomic variable used to track if computing pkg sizes is in progress. should be volatile?
+    
+    private boolean mComputeSizes = false;
+    // default icon thats used when displaying applications initially before resource info is
+    // retrieved
+    private Drawable mDefaultAppIcon;
+    
+    // temporary dialog displayed while the application info loads
+    private static final int DLG_BASE = 0;
+    private static final int DLG_LOADING = DLG_BASE + 1;
+    
+    // compute index used to track the application size computations
+    private int mComputeIndex;
+    
+    // Size resource used for packages whose size computation failed for some reason
+    private CharSequence mInvalidSizeStr;
+    private CharSequence mComputingSizeStr;
+    
+    // map used to store list of added and removed packages. Immutable Boolean
+    // variables indicate if a package has been added or removed. If a package is
+    // added or deleted multiple times a single entry with the latest operation will
+    // be recorded in the map.
+    private Map<String, Boolean> mAddRemoveMap;
+    
+    // layout inflater object used to inflate views
+    private LayoutInflater mInflater;
+    
+    // invalid size value used initially and also when size retrieval through PackageManager
+    // fails for whatever reason
+    private static final int SIZE_INVALID = -1;
+    
+    // debug boolean variable to test delays from PackageManager API's
+    private boolean DEBUG_PKG_DELAY = false;
+    
+    // Thread to load resources
+    ResourceLoaderThread mResourceThread;
+    
+    String mCurrentPkgName;
+    
+    //TODO implement a cache system
+    private Map<String, AppInfo> mAppPropCache;
+    
+    // empty message displayed when list is empty
+    private TextView mEmptyView;
+    
+    // Boolean variables indicating state
+    private boolean mLoadLabels = false;
+    private boolean mSizesFirst = false;
+    // ListView used to display list
+    private ListView mListView;
+    // State variables used to figure out menu options and also
+    // initiate the first computation and loading of resources
+    private boolean mJustCreated = true;
+    private boolean mFirst = false;
+    
+    /*
+     * Handler class to handle messages for various operations
+     * Most of the operations that effect Application related data
+     * are posted as messages to the handler to avoid synchronization
+     * when accessing these structures.
+     * When the size retrieval gets kicked off for the first time, a COMPUTE_PKG_SIZE_START
+     * message is posted to the handler which invokes the getSizeInfo for the pkg at index 0
+     * When the PackageManager's asynchronous call back through
+     * PkgSizeObserver.onGetStatsCompleted gets invoked, the application resources like
+     * label, description, icon etc., is loaded in the same thread and these values are
+     * set on the observer. The observer then posts a COMPUTE_PKG_SIZE_DONE message
+     * to the handler. This information is updated on the AppInfoAdapter associated with
+     * the list view of this activity and size info retrieval is initiated for the next package as 
+     * indicated by mComputeIndex
+     * When a package gets added while the activity has focus, the PkgSizeObserver posts
+     * ADD_PKG_START message to the handler.  If the computation is not in progress, the size
+     * is retrieved for the newly added package through the observer object and the newly
+     * installed app info is updated on the screen. If the computation is still in progress
+     * the package is added to an internal structure and action deferred till the computation
+     * is done for all the packages. 
+     * When a package gets deleted, REMOVE_PKG is posted to the handler
+     *  if computation is not in progress(as indicated by
+     * mDoneIniting), the package is deleted from the displayed list of apps. If computation is
+     * still in progress the package is added to an internal structure and action deferred till
+     * the computation is done for all packages.
+     * When the sizes of all packages is computed, the newly
+     * added or removed packages are processed in order.
+     * If the user changes the order in  which these applications are viewed by hitting the
+     * menu key, REORDER_LIST message is posted to the handler. this sorts the list
+     * of items based on the sort order.
+     */
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            PackageStats ps;
+            ApplicationInfo info;
+            Bundle data;
+            String pkgName = null;
+            AppInfo appInfo;
+            data = msg.getData();
+            if(data != null) {
+                pkgName = data.getString(ATTR_PKG_NAME);
+            }
+            switch (msg.what) {
+            case INIT_PKG_INFO:
+                if(localLOGV) Log.i(TAG, "Message INIT_PKG_INFO");
+                // Retrieve the package list and init some structures
+                initAppList(mFilterApps);
+                mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
+                break;
+            case COMPUTE_PKG_SIZE_DONE:
+                if(localLOGV) Log.i(TAG, "Message COMPUTE_PKG_SIZE_DONE");
+                if(pkgName == null) {
+                     Log.w(TAG, "Ignoring message");
+                     break;
+                }
+                ps = data.getParcelable(ATTR_APP_PKG_STATS);
+                if(ps == null) {
+                    Log.i(TAG, "Invalid package stats for package:"+pkgName);
+                } else {
+                    int pkgId = mAppInfoAdapter.getIndex(pkgName);
+                    if(mComputeIndex != pkgId) {
+                        //spurious call from stale observer
+                        Log.w(TAG, "Stale call back from PkgSizeObserver");
+                        break;
+                    }
+                    mAppInfoAdapter.updateAppSize(pkgName, ps);
+                }
+                mComputeIndex++;
+                if (mComputeIndex < mAppInfoAdapter.getCount()) {
+                    // initiate compute package size for next pkg in list
+                    mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(
+                            mComputeIndex), 
+                            COMPUTE_PKG_SIZE_DONE);
+                } else {
+                    // check for added/removed packages
+                    Set<String> keys =  mAddRemoveMap.keySet();
+                    Iterator<String> iter = keys.iterator();
+                    List<String> removeList = new ArrayList<String>();
+                    boolean added = false;
+                    boolean removed = false;
+                    while (iter.hasNext()) {
+                        String key = iter.next();
+                        if (mAddRemoveMap.get(key) == Boolean.TRUE) {
+                            // add
+                            try {
+                                info = mPm.getApplicationInfo(key, 0);
+                                mAppInfoAdapter.addApplicationInfo(info);
+                                added = true;
+                            } catch (NameNotFoundException e) {
+                                Log.w(TAG, "Invalid added package:"+key+" Ignoring entry");
+                            }   
+                        } else {
+                            // remove
+                            removeList.add(key);
+                            removed = true;
+                        }
+                    }
+                    // remove uninstalled packages from list
+                    if (removed) {
+                        mAppInfoAdapter.removeFromList(removeList);
+                    }
+                    // handle newly installed packages
+                    if (added) {
+                        mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(
+                                mComputeIndex), 
+                                COMPUTE_PKG_SIZE_DONE);
+                    } else {
+                        // end computation here
+                        mComputeSizes = true;
+                        mFirst = true;
+                        mAppInfoAdapter.sortList(mSortOrder);
+                        mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
+                    }
+                }
+                break;
+            case REMOVE_PKG:
+                if(localLOGV) Log.i(TAG, "Message REMOVE_PKG");
+                if(pkgName == null) {
+                    Log.w(TAG, "Ignoring message:REMOVE_PKG for null pkgName");
+                    break;
+                }
+                if (!mComputeSizes) {
+                    Boolean currB = mAddRemoveMap.get(pkgName);
+                    if (currB == null || (currB.equals(Boolean.TRUE))) {
+                        mAddRemoveMap.put(pkgName, Boolean.FALSE);
+                    }
+                    break;
+                }
+                List<String> pkgList = new ArrayList<String>();
+                pkgList.add(pkgName);
+                mAppInfoAdapter.removeFromList(pkgList);
+                break;
+            case REORDER_LIST:
+                if(localLOGV) Log.i(TAG, "Message REORDER_LIST");
+                int menuOption = msg.arg1;
+                if((menuOption == SORT_ORDER_ALPHA) || 
+                        (menuOption == SORT_ORDER_SIZE)) {
+                    // Option to sort list
+                    if (menuOption != mSortOrder) {
+                        mSortOrder = menuOption;
+                        if (localLOGV) Log.i(TAG, "Changing sort order to "+mSortOrder);
+                        mAppInfoAdapter.sortList(mSortOrder);
+                    }
+                } else if(menuOption != mFilterApps) {
+                    // Option to filter list
+                    mFilterApps = menuOption;
+                    boolean ret = mAppInfoAdapter.resetAppList(mFilterApps, 
+                            getInstalledApps(mFilterApps));
+                    if(!ret) {
+                        // Reset cache
+                        mAppPropCache = null;
+                        mFilterApps = FILTER_APPS_ALL;
+                        mHandler.sendEmptyMessage(INIT_PKG_INFO);
+                        sendMessageToHandler(REORDER_LIST, menuOption);
+                    }
+                }
+                break;
+            case ADD_PKG_START:
+                if(localLOGV) Log.i(TAG, "Message ADD_PKG_START");
+                if(pkgName == null) {
+                    Log.w(TAG, "Ignoring message:ADD_PKG_START for null pkgName");
+                    break;
+                }
+                if (!mComputeSizes) {
+                    Boolean currB = mAddRemoveMap.get(pkgName);
+                    if (currB == null || (currB.equals(Boolean.FALSE))) {
+                        mAddRemoveMap.put(pkgName, Boolean.TRUE);
+                    }
+                    break;
+                }
+                try {
+                        info = mPm.getApplicationInfo(pkgName, 0);
+                    } catch (NameNotFoundException e) {
+                        Log.w(TAG, "Couldnt find application info for:"+pkgName);
+                        break;
+                    }
+                mObserver.invokeGetSizeInfo(info, ADD_PKG_DONE);
+                break;
+            case ADD_PKG_DONE:
+                if(localLOGV) Log.i(TAG, "Message COMPUTE_PKG_SIZE_DONE");
+                if(pkgName == null) {
+                    Log.w(TAG, "Ignoring message:ADD_PKG_START for null pkgName");
+                    break;
+                }
+                ps = data.getParcelable(ATTR_APP_PKG_STATS);
+                mAppInfoAdapter.addToList(pkgName, ps);
+                break;
+            case REFRESH_ICONS:
+                Map<String, AppInfo> iconMap = (Map<String, AppInfo>) msg.obj;
+                if(iconMap == null) {
+                    Log.w(TAG, "Error loading icons for applications");
+                } else {
+                    mAppInfoAdapter.updateAppsResourceInfo(iconMap);   
+                }
+                mLoadLabels = true;
+                mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
+                break;
+            case NEXT_LOAD_STEP:
+                if (mComputeSizes && mLoadLabels) {
+                    doneLoadingData();
+                } else if (!mComputeSizes && !mLoadLabels) {
+                     // Either load the package labels or initiate get size info
+                    if (mSizesFirst) {
+                        initComputeSizes();
+                    } else {
+                        initResourceThread();
+                    }
+                } else {
+                    // Create list view from the adapter here. Wait till the sort order
+                    // of list is defined. its either by label or by size. so atleast one of the
+                    // first steps should be complete before filling the list
+                    if (mJustCreated) {
+                        // Set the adapter here.
+                        mJustCreated = false;
+                        mListView.setAdapter(mAppInfoAdapter);
+                        dismissLoadingMsg();
+                    }
+                    if (!mComputeSizes) {
+                        initComputeSizes();
+                    } else if (!mLoadLabels) {
+                        initResourceThread();
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    };
+    
+    
+    
+    private void doneLoadingData() {
+        setProgressBarIndeterminateVisibility(false);
+    }
+    
+    List<ApplicationInfo> getInstalledApps(int filterOption) {
+        List<ApplicationInfo> installedAppList = mPm.getInstalledApplications(
+                PackageManager.GET_UNINSTALLED_PACKAGES);
+        if (installedAppList == null) {
+            return new ArrayList<ApplicationInfo> ();
+        }
+        if (filterOption == FILTER_APPS_THIRD_PARTY) {
+            List<ApplicationInfo> appList =new ArrayList<ApplicationInfo> ();
+            for (ApplicationInfo appInfo : installedAppList) {
+                boolean flag = false;
+                if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+                    // Updated system app
+                    flag = true;
+                } else if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                    // Non-system app
+                    flag = true;
+                }
+                if (flag) {
+                    appList.add(appInfo);
+                }
+            }
+            return appList;
+        } else if (filterOption == FILTER_APPS_RUNNING) {
+            List<ApplicationInfo> appList =new ArrayList<ApplicationInfo> ();
+            List<ActivityManager.RunningAppProcessInfo> procList = getRunningAppProcessesList();
+            if ((procList == null) || (procList.size() == 0)) {
+                return appList;
+            }
+            // Retrieve running processes from ActivityManager
+            for (ActivityManager.RunningAppProcessInfo appProcInfo : procList) {
+                if ((appProcInfo != null)  && (appProcInfo.pkgList != null)){
+                    int size = appProcInfo.pkgList.length;
+                    for (int i = 0; i < size; i++) {
+                        ApplicationInfo appInfo = null;
+                        try {
+                            appInfo = mPm.getApplicationInfo(appProcInfo.pkgList[i], 
+                                    PackageManager.GET_UNINSTALLED_PACKAGES);
+                        } catch (NameNotFoundException e) {
+                           Log.w(TAG, "Error retrieving ApplicationInfo for pkg:"+appProcInfo.pkgList[i]);
+                           continue;
+                        }
+                        if(appInfo != null) {
+                            appList.add(appInfo);
+                        }
+                    }
+                }
+            }
+            return appList;
+        } else {
+            return installedAppList;
+        }
+    }
+    
+    private List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesList() {
+        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
+        return am.getRunningAppProcesses();
+    }
+    
+    // some initialization code used when kicking off the size computation
+    private void initAppList(int filterOption) {
+        setProgressBarIndeterminateVisibility(true);
+        mComputeIndex = 0;
+        mComputeSizes = false;
+        mLoadLabels = false;
+        // Initialize lists
+        List<ApplicationInfo> appList = getInstalledApps(filterOption);
+        mAddRemoveMap = new TreeMap<String, Boolean>();
+        mAppInfoAdapter.resetAppList(filterOption, appList);
+    }
+    
+    // Utility method to start a thread to read application labels and icons
+    private void initResourceThread() {
+        //load resources now
+        if(mResourceThread.isAlive()) {
+            mResourceThread.interrupt();
+        }
+        mResourceThread.loadAllResources(mAppInfoAdapter.getAppList());
+    }
+    
+    private void initComputeSizes() {
+         // initiate compute pkg sizes
+        if (localLOGV) Log.i(TAG, "Initiating compute sizes for first time");
+        if (mAppInfoAdapter.getCount() > 0) {
+            mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(0),
+                    COMPUTE_PKG_SIZE_DONE);
+        } else {
+            mComputeSizes = true;
+        }
+    }
+    
+    private void showEmptyViewIfListEmpty() {
+        if (localLOGV) Log.i(TAG, "Checking for empty view");
+        if (mAppInfoAdapter.getCount() > 0) {
+            mListView.setVisibility(View.VISIBLE);
+            mEmptyView.setVisibility(View.GONE);
+        } else {
+            mListView.setVisibility(View.GONE);
+            mEmptyView.setVisibility(View.VISIBLE);
+        }
+    }
+    
+    // internal structure used to track added and deleted packages when
+    // the activity has focus
+    class AddRemoveInfo {
+        String pkgName;
+        boolean add;
+        public AddRemoveInfo(String pPkgName, boolean pAdd) {
+            pkgName = pPkgName;
+            add = pAdd;
+        }
+    }
+    
+    class ResourceLoaderThread extends Thread {
+        List<ApplicationInfo> mAppList;
+        
+        void loadAllResources(List<ApplicationInfo> appList) {
+            mAppList = appList;
+            start();
+        }
+
+        public void run() {
+            Map<String, AppInfo> iconMap = new HashMap<String, AppInfo>();
+            if(mAppList == null || mAppList.size() <= 0) {
+                Log.w(TAG, "Empty or null application list");
+            } else {
+                for (ApplicationInfo appInfo : mAppList) {
+                    CharSequence appName = appInfo.loadLabel(mPm);
+                    Drawable appIcon = appInfo.loadIcon(mPm);
+                    iconMap.put(appInfo.packageName, 
+                            new AppInfo(appInfo.packageName, appName, appIcon));
+                }
+            }
+            Message msg = mHandler.obtainMessage(REFRESH_ICONS);
+            msg.obj = iconMap;
+            mHandler.sendMessage(msg);
+        }
+    }
+    
+    /* Internal class representing an application or packages displayable attributes
+     * 
+     */
+    class AppInfo {
+        public String pkgName;
+        int index;
+        public  CharSequence appName;
+        public  Drawable appIcon;
+        public CharSequence appSize;
+        public PackageStats appStats;
+        
+        public void refreshIcon(AppInfo pInfo) {
+            appName = pInfo.appName;
+            appIcon = pInfo.appIcon;
+        }
+
+        public AppInfo(String pName, CharSequence aName, Drawable aIcon) {
+            index = -1;
+            pkgName = pName;
+            appName = aName;
+            appIcon = aIcon;
+            appStats = null;
+            appSize = mComputingSizeStr;
+        }
+        
+        public AppInfo(String pName, int pIndex, CharSequence aName, Drawable aIcon, 
+                PackageStats ps) {
+            index = pIndex;
+            pkgName = pName;
+            appName = aName;
+            appIcon = aIcon;
+            if(ps == null) {
+                appSize = mComputingSizeStr;
+            } else {
+                appStats = ps;
+                appSize = getSizeStr();
+            }
+        }
+        public void setSize(PackageStats ps) {
+            appStats = ps;
+            if (ps != null) {
+                appSize = getSizeStr();
+            }
+        }
+        public long getTotalSize() {
+            PackageStats ps = appStats;
+            if (ps != null) {
+                return ps.cacheSize+ps.codeSize+ps.dataSize;
+            }
+            return SIZE_INVALID;
+        }
+        
+        private String getSizeStr() {
+            PackageStats ps = appStats;
+            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 = getTotalSize();
+                if (size == SIZE_INVALID) {
+                    return mInvalidSizeStr.toString();
+                }
+                return Formatter.formatFileSize(ManageApplications.this, size);
+            }
+            return retStr;
+        }
+    }
+    
+    // View Holder used when displaying views
+    static class AppViewHolder {
+        TextView appName;
+        ImageView appIcon;
+        TextView appSize;
+    }
+    
+    /* Custom adapter implementation for the ListView
+     * This adapter maintains a map for each displayed application and its properties
+     * An index value on each AppInfo object indicates the correct position or index
+     * in the list. If the list gets updated dynamically when the user is viewing the list of
+     * applications, we need to return the correct index of position. This is done by mapping
+     * the getId methods via the package name into the internal maps and indices.
+     * The order of applications in the list is mirrored in mAppLocalList
+     */
+    class AppInfoAdapter extends BaseAdapter {
+        private Map<String, AppInfo> mAppPropMap;
+        private List<ApplicationInfo> mAppLocalList;
+        ApplicationInfo.DisplayNameComparator mAlphaComparator;
+        AppInfoComparator mSizeComparator;
+        
+        private AppInfo getFromCache(String packageName) {
+            if(mAppPropCache == null) {
+                return null;
+            }
+            return mAppPropCache.get(packageName);
+        }
+        
+        public AppInfoAdapter(Context c, List<ApplicationInfo> appList) {
+            mAppLocalList = appList;
+            boolean useCache = false;
+            int sortOrder = SORT_ORDER_ALPHA;
+            int imax = mAppLocalList.size();
+            if(mAppPropCache != null) {
+                useCache = true;
+                // Activity has been resumed. can use the cache to populate values initially
+                mAppPropMap = mAppPropCache;
+                sortOrder = mSortOrder;
+            }
+            sortAppList(sortOrder);
+            // Recreate property map
+            mAppPropMap = new TreeMap<String, AppInfo>();
+            for (int i = 0; i < imax; i++) {
+                ApplicationInfo info = mAppLocalList.get(i);
+                AppInfo aInfo = getFromCache(info.packageName);
+                if(aInfo == null){
+                    aInfo = new AppInfo(info.packageName, i, 
+                            info.packageName, mDefaultAppIcon, null);   
+                } else {
+                    aInfo.index = i;
+                }
+                mAppPropMap.put(info.packageName, aInfo);
+            }
+        }
+        
+        public int getCount() {
+            return mAppLocalList.size();
+        }
+        
+        public Object getItem(int position) {
+            return mAppLocalList.get(position);
+        }
+        
+        /*
+         * This method returns the index of the package position in the application list
+         */
+        public int getIndex(String pkgName) {
+            if(pkgName == null) {
+                Log.w(TAG, "Getting index of null package in List Adapter");
+            }
+            int imax = mAppLocalList.size();
+            ApplicationInfo appInfo;
+            for(int i = 0; i < imax; i++) {
+                appInfo = mAppLocalList.get(i);
+                if(appInfo.packageName.equalsIgnoreCase(pkgName)) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+        
+        public ApplicationInfo getApplicationInfo(int position) {
+            int imax = mAppLocalList.size();
+            if( (position < 0) || (position >= imax)) {
+                Log.w(TAG, "Position out of bounds in List Adapter");
+                return null;
+            }
+            return mAppLocalList.get(position);
+        }
+        
+        public void addApplicationInfo(ApplicationInfo info) {
+            if(info == null) {
+                Log.w(TAG, "Ignoring null add in List Adapter");
+                return;
+            }
+            mAppLocalList.add(info);
+        }
+
+        public long getItemId(int position) {
+            int imax = mAppLocalList.size();
+            if( (position < 0) || (position >= imax)) {
+                Log.w(TAG, "Position out of bounds in List Adapter");
+                return -1;
+            }
+            return mAppPropMap.get(mAppLocalList.get(position).packageName).index;
+        }
+        
+        public List<ApplicationInfo> getAppList() {
+            return mAppLocalList;
+        }
+        
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (position >= mAppLocalList.size()) {
+                Log.w(TAG, "Invalid view position:"+position+", actual size is:"+mAppLocalList.size());
+                return null;
+            }
+            // A ViewHolder keeps references to children views to avoid unneccessary calls
+            // to findViewById() on each row.
+            AppViewHolder holder;
+
+            // When convertView is not null, we can reuse it directly, there is no need
+            // to reinflate it. We only inflate a new View when the convertView supplied
+            // by ListView is null.
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.manage_applications_item, null);
+
+                // Creates a ViewHolder and store references to the two children views
+                // we want to bind data to.
+                holder = new AppViewHolder();
+                holder.appName = (TextView) convertView.findViewById(R.id.app_name);
+                holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
+                holder.appSize = (TextView) convertView.findViewById(R.id.app_size);
+                convertView.setTag(holder);
+            } else {
+                // Get the ViewHolder back to get fast access to the TextView
+                // and the ImageView.
+                holder = (AppViewHolder) convertView.getTag();
+            }
+
+            // Bind the data efficiently with the holder
+            ApplicationInfo appInfo = mAppLocalList.get(position);
+            AppInfo mInfo = mAppPropMap.get(appInfo.packageName);
+            if(mInfo != null) {
+                if(mInfo.appName != null) {
+                    holder.appName.setText(mInfo.appName);
+                }
+                if(mInfo.appIcon != null) {
+                    holder.appIcon.setImageDrawable(mInfo.appIcon);
+                }
+                if (mInfo.appSize != null) {
+                    holder.appSize.setText(mInfo.appSize);
+                }
+            } else {
+                Log.w(TAG, "No info for package:"+appInfo.packageName+" in property map");
+            }
+            return convertView;
+        }
+        
+        private void adjustIndex() {
+            int imax = mAppLocalList.size();
+            ApplicationInfo info;
+            for (int i = 0; i < imax; i++) {
+                info = mAppLocalList.get(i);
+                mAppPropMap.get(info.packageName).index = i;
+            }
+        }
+        
+        public void sortAppList(int sortOrder) {
+            Collections.sort(mAppLocalList, getAppComparator(sortOrder));
+        }
+        
+        public void sortList(int sortOrder) {
+            sortAppList(sortOrder);
+            adjustIndex();
+            notifyDataSetChanged();
+        }
+        
+        public boolean resetAppList(int filterOption, List<ApplicationInfo> appList) {
+           // Create application list based on the filter value
+           mAppLocalList = appList;
+           // Check for all properties in map before sorting. Populate values from cache
+           for(ApplicationInfo applicationInfo : mAppLocalList) {
+               AppInfo appInfo = mAppPropMap.get(applicationInfo.packageName);
+               if(appInfo == null) {
+                   AppInfo rInfo = getFromCache(applicationInfo.packageName);
+                   if(rInfo == null) {
+                       // Need to load resources again. Inconsistency somewhere
+                       return false;
+                   }
+                   mAppPropMap.put(applicationInfo.packageName, rInfo);
+               }
+           }
+           if (mAppLocalList.size() > 0) {
+               sortList(mSortOrder);
+           } else {
+               notifyDataSetChanged();
+           }
+           showEmptyViewIfListEmpty();
+           return true;
+        }
+        
+        private Comparator<ApplicationInfo> getAppComparator(int sortOrder) {
+            if (sortOrder == SORT_ORDER_ALPHA) {
+                // Lazy initialization
+                if (mAlphaComparator == null) {
+                    mAlphaComparator = new ApplicationInfo.DisplayNameComparator(mPm);
+                }
+                return mAlphaComparator;
+            }
+            // Lazy initialization
+            if(mSizeComparator == null) {
+                mSizeComparator = new AppInfoComparator(mAppPropMap);
+            }
+            return mSizeComparator;
+        }
+        
+        public void updateAppsResourceInfo(Map<String, AppInfo> iconMap) {
+            if(iconMap == null) {
+                Log.w(TAG, "Null iconMap when refreshing icon in List Adapter");
+                return;
+            }
+            boolean changed = false;
+            for (ApplicationInfo info : mAppLocalList) {
+                AppInfo pInfo = iconMap.get(info.packageName);
+                if(pInfo != null) {
+                    AppInfo aInfo = mAppPropMap.get(info.packageName);
+                    if (aInfo != null) {
+                        aInfo.refreshIcon(pInfo);
+                    } else {
+                        mAppPropMap.put(info.packageName, pInfo);
+                    }
+                    changed = true;
+                }
+            }
+            if(changed) {
+                notifyDataSetChanged();
+            }
+        }
+        
+        public void addToList(String pkgName, PackageStats ps) {
+            if(pkgName == null) {
+                Log.w(TAG, "Adding null pkg to List Adapter");
+                return;
+            }
+            ApplicationInfo info;
+            try {
+                info = mPm.getApplicationInfo(pkgName, 0);
+            } catch (NameNotFoundException e) {
+                Log.w(TAG, "Ignoring non-existent package:"+pkgName);
+                return;
+            }
+            if(info == null) {
+                // Nothing to do log error message and return
+                Log.i(TAG, "Null ApplicationInfo for package:"+pkgName);
+                return;
+            }
+            // Binary search returns a negative index (ie --index) of the position where
+            // this might be inserted. 
+            int newIdx = Collections.binarySearch(mAppLocalList, info, 
+                    getAppComparator(mSortOrder));
+            if(newIdx >= 0) {
+                Log.i(TAG, "Strange. Package:"+pkgName+" is not new");
+                return;
+            }
+            // New entry
+            newIdx = -newIdx-1;
+            mAppLocalList.add(newIdx, info);
+            mAppPropMap.put(info.packageName, new AppInfo(pkgName, newIdx,
+                    info.loadLabel(mPm), info.loadIcon(mPm), ps));
+            adjustIndex();
+            notifyDataSetChanged();
+        }
+        
+        public void removeFromList(List<String> pkgNames) {
+            if(pkgNames == null) {
+                Log.w(TAG, "Removing null pkg list from List Adapter");
+                return;
+            }
+            int imax = mAppLocalList.size();
+            boolean found = false;
+            ApplicationInfo info;
+            int i, k;
+            String pkgName;
+            int kmax = pkgNames.size();
+            if(kmax  <= 0) {
+                Log.w(TAG, "Removing empty pkg list from List Adapter");
+                return;
+            }
+            int idxArr[] = new int[kmax];
+            for (k = 0; k < kmax; k++) {
+                idxArr[k] = -1;
+            }
+            for (i = 0; i < imax; i++) {
+                info = mAppLocalList.get(i);
+                for (k = 0; k < kmax; k++) {
+                    pkgName = pkgNames.get(k);
+                    if (info.packageName.equalsIgnoreCase(pkgName)) {
+                        idxArr[k] = i;
+                        found = true;
+                        break;
+                    }
+                }
+            }
+            // Sort idxArr
+            Arrays.sort(idxArr);
+            // remove the packages based on decending indices
+            for (k = kmax-1; k >= 0; k--) {
+                // Check if package has been found in the list of existing apps first
+                if(idxArr[k] == -1) {
+                    break;
+                }
+                info = mAppLocalList.get(idxArr[k]);
+                mAppLocalList.remove(idxArr[k]);
+                mAppPropMap.remove(info.packageName);
+                if (localLOGV) Log.i(TAG, "Removed pkg:"+info.packageName+ " list");
+            }
+            if (found) {
+                adjustIndex();
+                notifyDataSetChanged();
+            }
+        }   
+        
+        public void updateAppSize(String pkgName, PackageStats ps) {
+            if(pkgName == null) {
+                return;
+            }
+            AppInfo entry = mAppPropMap.get(pkgName);
+            if (entry == null) {
+                Log.w(TAG, "Entry for package:"+pkgName+"doesnt exist in map");
+                return;
+            }
+            // Copy the index into the newly updated entry
+            entry.setSize(ps);
+            notifyDataSetChanged();
+        }
+
+        public PackageStats getAppStats(String pkgName) {
+            if(pkgName == null) {
+                return null;
+            }
+            AppInfo entry = mAppPropMap.get(pkgName);
+            if (entry == null) {
+                return null;
+            }
+            return entry.appStats;
+        }
+    }
+    
+    /*
+     * Utility method to clear messages to Handler
+     * We need'nt synchronize on the Handler since posting messages is guaranteed
+     * to be thread safe. Even if the other thread that retrieves package sizes
+     * posts a message, we do a cursory check of validity on mAppInfoAdapter's applist
+     */
+    private void clearMessagesInHandler() {
+        mHandler.removeMessages(INIT_PKG_INFO);
+        mHandler.removeMessages(COMPUTE_PKG_SIZE_DONE);
+        mHandler.removeMessages(REMOVE_PKG);
+        mHandler.removeMessages(REORDER_LIST);
+        mHandler.removeMessages(ADD_PKG_START);
+        mHandler.removeMessages(ADD_PKG_DONE);
+    }
+    
+    private void sendMessageToHandler(int msgId, int arg1) {
+        Message msg = mHandler.obtainMessage(msgId);
+        msg.arg1 = arg1;
+        mHandler.sendMessage(msg);
+    }
+    
+    private void sendMessageToHandler(int msgId, Bundle data) {
+        Message msg = mHandler.obtainMessage(msgId);
+        msg.setData(data);
+        mHandler.sendMessage(msg);
+    }
+    
+    private void sendMessageToHandler(int msgId) {
+        mHandler.sendEmptyMessage(msgId);
+    }
+    
+    /*
+     * Stats Observer class used to compute package sizes and retrieve size information
+     * PkgSizeOberver is the call back thats used when invoking getPackageSizeInfo on
+     * PackageManager. The values in call back onGetStatsCompleted are validated
+     * and the specified message is passed to mHandler. The package name
+     * and the AppInfo object corresponding to the package name are set on the message
+     */
+    class PkgSizeObserver extends IPackageStatsObserver.Stub {
+        private ApplicationInfo mAppInfo;
+        private int mMsgId; 
+        public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
+            if(DEBUG_PKG_DELAY) {
+                try {
+                    Thread.sleep(10*1000);
+                } catch (InterruptedException e) {
+                }
+            }
+            AppInfo appInfo = null;
+            Bundle data = new Bundle();
+            data.putString(ATTR_PKG_NAME, mAppInfo.packageName);
+            if(pSucceeded && pStats != null) {
+                if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pStats.packageName+", ("+
+                        pStats.cacheSize+","+
+                        pStats.codeSize+", "+pStats.dataSize);
+                data.putParcelable(ATTR_APP_PKG_STATS, pStats);
+            } else {
+                Log.w(TAG, "Invalid package stats from PackageManager");
+            }
+            //post message to Handler
+            Message msg = mHandler.obtainMessage(mMsgId, data);
+            msg.setData(data);
+            mHandler.sendMessage(msg);
+        }
+
+        public void invokeGetSizeInfo(ApplicationInfo pAppInfo, int msgId) {
+            if(pAppInfo == null || pAppInfo.packageName == null) {
+                return;
+            }
+            if(localLOGV) Log.i(TAG, "Invoking getPackageSizeInfo for package:"+
+                    pAppInfo.packageName);
+            mMsgId = msgId;
+            mAppInfo = pAppInfo;
+            mPm.getPackageSizeInfo(pAppInfo.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_START, data);
+        } else if (Intent.ACTION_PACKAGE_REMOVED.equalsIgnoreCase(actionStr)) {
+            Bundle data = new Bundle();
+            data.putString(ATTR_PKG_NAME, pkgName);
+            sendMessageToHandler(REMOVE_PKG, data);
+        }
+    }
+    
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent lIntent = getIntent();
+        String action = lIntent.getAction();
+        if (action.equals(Intent.ACTION_MANAGE_PACKAGE_STORAGE)) {
+            mSortOrder = SORT_ORDER_SIZE;
+            mSizesFirst = true;
+        }
+        mPm = getPackageManager();
+        // initialize some window features
+        requestWindowFeature(Window.FEATURE_RIGHT_ICON);
+        requestWindowFeature(Window.FEATURE_PROGRESS);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.compute_sizes);
+        mDefaultAppIcon =Resources.getSystem().getDrawable(
+                com.android.internal.R.drawable.sym_def_app_icon);
+        mInvalidSizeStr = getText(R.string.invalid_size_value);
+        mComputingSizeStr = getText(R.string.computing_size);
+        // initialize the inflater
+        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mReceiver = new PackageIntentReceiver();
+        mEmptyView = (TextView) findViewById(R.id.empty_view);
+        mObserver = new PkgSizeObserver();
+        // Create adapter and list view here
+        List<ApplicationInfo> appList = getInstalledApps(mSortOrder);
+        mAppInfoAdapter = new AppInfoAdapter(this, appList);
+        ListView lv= (ListView) findViewById(android.R.id.list);
+        //lv.setAdapter(mAppInfoAdapter);
+        lv.setOnItemClickListener(this);
+        lv.setSaveEnabled(true);
+        lv.setItemsCanFocus(true);
+        lv.setOnItemClickListener(this);
+        mListView = lv;
+        showLoadingMsg();
+    }
+    
+    @Override
+    public Dialog onCreateDialog(int id) {
+        if (id == DLG_LOADING) {
+            ProgressDialog dlg = new ProgressDialog(this);
+            dlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+            dlg.setMessage(getText(R.string.loading));
+            dlg.setIndeterminate(true);        
+            dlg.setOnCancelListener(this);
+            return dlg;
+        }
+        return null;
+    }
+    
+    
+    private void showLoadingMsg() {
+        showDialog(DLG_LOADING);
+        if(localLOGV) Log.i(TAG, "Displaying Loading message");
+    }
+    
+    private void dismissLoadingMsg() {
+        if(localLOGV) Log.i(TAG, "Dismissing Loading message");
+        dismissDialog(DLG_LOADING);
+    }
+    
+    @Override
+    public void onStart() {
+        super.onStart();
+        // Create a thread to load resources
+        mResourceThread = new ResourceLoaderThread();
+        sendMessageToHandler(INIT_PKG_INFO);
+        // register receiver
+        mReceiver.registerReceiver();
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        // clear all messages related to application list
+        clearMessagesInHandler();
+        // register receiver here
+        unregisterReceiver(mReceiver);        
+        mAppPropCache = mAppInfoAdapter.mAppPropMap;
+    }
+    
+    // Avoid the restart and pause when orientation changes
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+    }
+    
+    /*
+     * comparator class used to sort AppInfo objects based on size
+     */
+    public static class AppInfoComparator implements Comparator<ApplicationInfo> {
+        public AppInfoComparator(Map<String, AppInfo> pAppPropMap) {
+            mAppPropMap= pAppPropMap;
+        }
+
+        public final int compare(ApplicationInfo a, ApplicationInfo b) {
+            AppInfo ainfo = mAppPropMap.get(a.packageName);
+            AppInfo binfo = mAppPropMap.get(b.packageName);
+            long atotal = ainfo.getTotalSize();
+            long btotal = binfo.getTotalSize();
+            long ret = atotal - btotal;
+            // negate result to sort in descending order
+            if (ret < 0) {
+                return 1;
+            }
+            if (ret == 0) {
+                return 0;
+            }
+            return -1;
+        }
+        private Map<String, AppInfo> mAppPropMap;
+    }
+     
+    // utility method used to start sub activity
+    private void startApplicationDetailsActivity() {
+        // Create intent to start new activity
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setClass(this, InstalledAppDetails.class);
+        intent.putExtra(APP_PKG_NAME, mCurrentPkgName);
+        // start new activity to display extended information
+        startActivityForResult(intent, INSTALLED_APP_DETAILS);
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
+                .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
+        menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
+                .setIcon(android.R.drawable.ic_menu_sort_by_size); 
+        menu.add(0, FILTER_OPTIONS, 3, R.string.filter)
+                .setIcon(R.drawable.ic_menu_filter_settings);
+        return true;
+    }
+    
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        if (mFirst) {
+            menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
+            menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
+            menu.findItem(FILTER_OPTIONS).setVisible(true);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int menuId = item.getItemId();
+        if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
+            sendMessageToHandler(REORDER_LIST, menuId);
+        } else if (menuId == FILTER_OPTIONS) {
+            if (mAlertDlg == null) {
+                mAlertDlg = new AlertDialog.Builder(this).
+                        setTitle(R.string.filter_dlg_title).
+                        setNeutralButton(R.string.cancel, this).
+                        setSingleChoiceItems(new CharSequence[] {getText(R.string.filter_apps_all),
+                                getText(R.string.filter_apps_running),
+                                getText(R.string.filter_apps_third_party)},
+                                -1, this).
+                        create();
+            }
+            mAlertDlg.show();
+        }
+        return true;
+    }
+
+    public void onItemClick(AdapterView<?> parent, View view, int position,
+            long id) {
+        ApplicationInfo info = (ApplicationInfo)mAppInfoAdapter.getItem(position);
+        mCurrentPkgName = info.packageName;
+        startApplicationDetailsActivity();
+    }
+    
+    // Finish the activity if the user presses the back button to cancel the activity
+    public void onCancel(DialogInterface dialog) {
+        finish();
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        int newOption;
+        switch (which) {
+        // Make sure that values of 0, 1, 2 match options all, running, third_party when
+        // created via the AlertDialog.Builder
+        case 0:
+            newOption = FILTER_APPS_ALL;
+            break;
+        case 1:
+            newOption = FILTER_APPS_RUNNING;
+            break;
+        case 2:
+            newOption = FILTER_APPS_THIRD_PARTY;
+            break;
+        default:
+            return;
+        }
+        mAlertDlg.dismiss();
+        sendMessageToHandler(REORDER_LIST, newOption);
+    }
+}
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/MediaFormat.java b/src/com/android/settings/MediaFormat.java
new file mode 100644
index 0000000..3594572
--- /dev/null
+++ b/src/com/android/settings/MediaFormat.java
@@ -0,0 +1,193 @@
+/*
+ * 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.IMountService;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Confirm and execute a format of the sdcard.
+ * 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 SD CARD" 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 MediaFormat 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 Mount Service to format the SD card.
+     */
+    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 format
+                if (!TextUtils.isEmpty(SystemProperties.get("ro.monkey"))) {
+                    return;
+                }
+                IMountService service =
+                        IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+                if (service != null) {
+                    try {
+                        service.formatMedia(Environment.getExternalStorageDirectory().toString());
+                    } catch (android.os.RemoteException e) {
+                        // Intentionally blank - there's nothing we can do here
+                        Log.w("MediaFormat", "Unable to invoke IMountService.formatMedia()");
+                    }
+                } else {
+                    Log.w("MediaFormat", "Unable to locate IMountService");
+                }
+            finish();
+            }
+        };
+
+    /**
+     *  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.media_format_gesture_prompt));
+        intent.putExtra(ConfirmLockPattern.FOOTER_TEXT,
+                getText(R.string.media_format_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.media_format_final, null);
+            mFinalButton =
+                    (Button) mFinalView.findViewById(R.id.execute_media_format);
+            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.media_format_primary, null);
+            mInitiateButton =
+                    (Button) mInitialView.findViewById(R.id.initiate_media_format);
+            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..80fe3c9
--- /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.Secure.putString(res, Settings.Secure.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..dbad45d
--- /dev/null
+++ b/src/com/android/settings/RadioInfo.java
@@ -0,0 +1,1184 @@
+/*
+ * 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.preference.PreferenceManager;
+import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.NeighboringCellInfo;
+import android.telephony.gsm.GsmCellLocation;
+import android.text.format.DateUtils;
+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.ArrayList;
+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 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 TextView dnsCheckState;
+    private EditText smsc;
+    private Button radioPowerButton;
+    private Button qxdmLogButton;
+    private Button cipherToggleButton;
+    private Button dnsCheckToggleButton;
+    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((ArrayList<NeighboringCellInfo>)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);
+        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);
+        dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
+
+        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);
+        dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
+        dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
+        
+        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();
+        updateDnsCheckState();
+
+        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 void updateDnsCheckState() {
+        GSMPhone gsmPhone = (GSMPhone) phone;
+        dnsCheckState.setText(gsmPhone.isDnsCheckDisabled() ?
+                "0.0.0.0 allowed" :"0.0.0.0 not allowed");
+    }
+    
+    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(ArrayList<NeighboringCellInfo> cids) {
+        String neighborings = "";
+        if (cids != null) {
+            if ( cids.isEmpty() ) {
+                neighborings = "no neighboring cells";
+            } else {
+                for (NeighboringCellInfo cell : cids) {
+                    neighborings += "{" + Integer.toHexString(cell.getCid()) 
+                    + "@" + cell.getRssi() + "} ";
+                }
+            }
+        } else {
+            neighborings = "unknown";
+        }
+        mNeighboringCids.setText(neighborings);
+    }
+
+    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.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 {
+            long txPackets = netstat.getMobileTxPackets();
+            long rxPackets = netstat.getMobileRxPackets();
+            long txBytes   = netstat.getMobileTxBytes();
+            long rxBytes   = netstat.getMobileRxBytes();
+    
+            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.getActiveApnTypes()[0]))
+                  .append("\naddress: ")
+                  .append(phone.getIpAddress(phone.getActiveApnTypes()[0]))
+                  .append("\ngateway: ")
+                  .append(phone.getGateway(phone.getActiveApnTypes()[0]));
+                String[] dns = phone.getDnsServers(phone.getActiveApnTypes()[0]);
+                if (dns != null) {
+                    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 mDnsCheckButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            GSMPhone gsmPhone = (GSMPhone) phone;
+            gsmPhone.disableDnsCheck(!gsmPhone.isDnsCheckDisabled());
+            updateDnsCheckState();
+        }
+    };
+    
+    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/RingerVolumePreference.java b/src/com/android/settings/RingerVolumePreference.java
new file mode 100644
index 0000000..2d21ec6
--- /dev/null
+++ b/src/com/android/settings/RingerVolumePreference.java
@@ -0,0 +1,129 @@
+/*
+ * 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.media.AudioManager;
+import android.preference.VolumePreference;
+import android.preference.VolumePreference.SeekBarVolumizer;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * Special preference type that allows configuration of both the ring volume and
+ * notification volume.
+ */
+public class RingerVolumePreference extends VolumePreference implements
+        CheckBox.OnCheckedChangeListener {
+    private static final String TAG = "RingerVolumePreference";
+
+    private CheckBox mNotificationsUseRingVolumeCheckbox;
+    private SeekBarVolumizer mNotificationSeekBarVolumizer;
+    private TextView mNotificationVolumeTitle;
+    
+    public RingerVolumePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        // The always visible seekbar is for ring volume
+        setStreamType(AudioManager.STREAM_RING);
+        
+        setDialogLayoutResource(R.layout.preference_dialog_ringervolume);
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+     
+        mNotificationsUseRingVolumeCheckbox =
+                (CheckBox) view.findViewById(R.id.same_notification_volume);
+        mNotificationsUseRingVolumeCheckbox.setOnCheckedChangeListener(this);
+        mNotificationsUseRingVolumeCheckbox.setChecked(Settings.System.getInt(
+                getContext().getContentResolver(),
+                Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1);
+        
+        final SeekBar seekBar = (SeekBar) view.findViewById(R.id.notification_volume_seekbar);
+        mNotificationSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar,
+                AudioManager.STREAM_NOTIFICATION);
+        
+        mNotificationVolumeTitle = (TextView) view.findViewById(R.id.notification_volume_title);
+        
+        setNotificationVolumeVisibility(!mNotificationsUseRingVolumeCheckbox.isChecked());
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        
+        if (!positiveResult && mNotificationSeekBarVolumizer != null) {
+            mNotificationSeekBarVolumizer.revertVolume();
+        }
+        
+        cleanup();
+    }
+
+    @Override
+    public void onActivityStop() {
+        super.onActivityStop();
+        cleanup();
+    }
+    
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        setNotificationVolumeVisibility(!isChecked);
+        
+        Settings.System.putInt(getContext().getContentResolver(),
+                Settings.System.NOTIFICATIONS_USE_RING_VOLUME, isChecked ? 1 : 0);
+        
+        if (isChecked) {
+            // The user wants the notification to be same as ring, so do a
+            // one-time sync right now
+            AudioManager audioManager = (AudioManager) getContext()
+                    .getSystemService(Context.AUDIO_SERVICE);
+            audioManager.setStreamVolume(AudioManager.STREAM_NOTIFICATION,
+                    audioManager.getStreamVolume(AudioManager.STREAM_RING), 0);
+        }
+    }
+
+    @Override
+    protected void onSampleStarting(SeekBarVolumizer volumizer) {
+        super.onSampleStarting(volumizer);
+        
+        if (mNotificationSeekBarVolumizer != null && volumizer != mNotificationSeekBarVolumizer) {
+            mNotificationSeekBarVolumizer.stopSample();
+        }
+    }
+
+    private void setNotificationVolumeVisibility(boolean visible) {
+        if (mNotificationSeekBarVolumizer != null) {
+            mNotificationSeekBarVolumizer.getSeekBar().setVisibility(
+                    visible ? View.VISIBLE : View.GONE);
+            mNotificationVolumeTitle.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
+    }
+    
+    private void cleanup() {
+        if (mNotificationSeekBarVolumizer != null) {
+            mNotificationSeekBarVolumizer.stop();
+            mNotificationSeekBarVolumizer = null;
+        }
+    }
+    
+}
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..b6935a2
--- /dev/null
+++ b/src/com/android/settings/SdCardSettings.java
@@ -0,0 +1,232 @@
+/*
+ * 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);
+
+        Button formatButton = (Button)findViewById(R.id.sdcard_format);
+        formatButton.setOnClickListener(mFormatButtonHandler);
+
+        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_CHECKING);
+        intentFilter.addAction(Intent.ACTION_MEDIA_NOFS);
+        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) {
+            }
+        }
+    };
+
+    OnClickListener mFormatButtonHandler = new OnClickListener() {
+        public void onClick(View v) {
+            try {
+                mMountService.formatMedia(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..cd26492
--- /dev/null
+++ b/src/com/android/settings/SecuritySettings.java
@@ -0,0 +1,304 @@
+/*
+ * 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 String KEY_TACTILE_FEEDBACK_ENABLED = "tactilefeedback";
+    private static final int CONFIRM_PATTERN_THEN_DISABLE_REQUEST_CODE = 55;
+    private static final int CONFIRM_PATTERN_THEN_ENABLE_REQUEST_CODE = 56;
+
+    private LockPatternUtils mLockPatternUtils;
+    private CheckBoxPreference mLockEnabled;
+    private CheckBoxPreference mVisiblePattern;
+    private CheckBoxPreference mTactileFeedback;
+    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);
+
+        // tactile feedback
+        mTactileFeedback = new CheckBoxPreference(this);
+        mTactileFeedback.setKey(KEY_TACTILE_FEEDBACK_ENABLED);
+        mTactileFeedback.setTitle(R.string.lockpattern_settings_enable_tactile_feedback_title);
+        inlinePrefCat.addPreference(mTactileFeedback);
+
+        // 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);
+        mTactileFeedback.setEnabled(patternExists);
+
+        mLockEnabled.setChecked(mLockPatternUtils.isLockPatternEnabled());
+        mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled());
+        mTactileFeedback.setChecked(mLockPatternUtils.isTactileFeedbackEnabled());
+
+        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 (KEY_TACTILE_FEEDBACK_ENABLED.equals(key)) {
+            mLockPatternUtils.setTactileFeedbackEnabled(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 secure setting LOCATION_PROVIDERS_ALLOWED
+        Settings.Secure.putString(getContentResolver(),
+            Settings.Secure.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.Secure.getString(getContentResolver(),
+                Settings.Secure.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 (mLockPatternUtils.savedPatternExists()) {
+                if (isChecked()) {
+                    confirmPatternThenDisable();
+                } else {
+                    confirmPatternThenEnable();
+                }
+            } else {
+                super.onClick();
+            }
+        }
+    }
+
+    private void confirmPatternThenEnable() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
+        startActivityForResult(intent, CONFIRM_PATTERN_THEN_ENABLE_REQUEST_CODE);
+    }
+
+    /**
+     * 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_THEN_DISABLE_REQUEST_CODE);
+    }
+
+    /**
+     * @see #confirmPatternThenDisable
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        final boolean resultOk = resultCode == Activity.RESULT_OK;
+
+        if ((requestCode == CONFIRM_PATTERN_THEN_DISABLE_REQUEST_CODE) && resultOk) {
+            mLockPatternUtils.setLockPatternEnabled(false);
+        } else if ((requestCode == CONFIRM_PATTERN_THEN_ENABLE_REQUEST_CODE) && resultOk) {
+            mLockPatternUtils.setLockPatternEnabled(true);
+        }
+    }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
new file mode 100644
index 0000000..0c4545e
--- /dev/null
+++ b/src/com/android/settings/Settings.java
@@ -0,0 +1,46 @@
+/*
+ * 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() {
+        super.onResume();
+        findPreference(KEY_CALL_SETTINGS).setEnabled(!AirplaneModeEnabler.isAirplaneModeOn(this));
+    }
+
+}
diff --git a/src/com/android/settings/SettingsLicenseActivity.java b/src/com/android/settings/SettingsLicenseActivity.java
new file mode 100644
index 0000000..0b809e1
--- /dev/null
+++ b/src/com/android/settings/SettingsLicenseActivity.java
@@ -0,0 +1,123 @@
+/*
+ * 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.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.zip.GZIPInputStream;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+/**
+ * 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.gz";
+    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;
+        }
+
+        InputStreamReader inputReader = null;
+        StringBuilder data = null;
+        try {
+            data = new StringBuilder(2048);
+            char tmp[] = new char[2048];
+            int numRead;
+            if (fileName.endsWith(".gz")) {
+                inputReader = new InputStreamReader(
+                    new GZIPInputStream(new FileInputStream(fileName)));
+            } else {
+                inputReader = new FileReader(fileName);
+            }
+            while ((numRead = inputReader.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 (inputReader != null) {
+                    inputReader.close();
+                }
+            } catch (IOException e) {
+            }
+        }
+
+        if (TextUtils.isEmpty(data)) {
+            Log.e(TAG, "License HTML is empty (from " + fileName + ")");
+            showErrorAndFinish();
+            return;
+        }
+
+        WebView webView = new WebView(this);
+
+        // Begin the loading.  This will be done in a separate thread in WebView.
+        webView.loadDataWithBaseURL(null, data.toString(), "text/html", "utf-8", null);
+        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..53912e3
--- /dev/null
+++ b/src/com/android/settings/SoundAndDisplaySettings.java
@@ -0,0 +1,245 @@
+/*
+ * 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.os.IMountService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+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;
+import android.view.IWindowManager;
+
+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 static final String KEY_ANIMATIONS = "animations";
+    private static final String KEY_PLAY_MEDIA_NOTIFICATION_SOUNDS = "play_media_notification_sounds";
+    
+    private CheckBoxPreference mSilent;
+
+    private CheckBoxPreference mPlayMediaNotificationSounds;
+
+    private IMountService mMountService = null;
+
+    /*
+     * If we are currently in one of the silent modes (the ringer mode is set to either
+     * "silent mode" or "vibrate mode"), then toggling the "Phone vibrate"
+     * preference will switch between "silent mode" and "vibrate mode".
+     * Otherwise, it will adjust the normal ringer mode's ring or ring+vibrate
+     * setting.
+     */
+    private CheckBoxPreference mVibrate;
+    private CheckBoxPreference mDtmfTone;
+    private CheckBoxPreference mSoundEffects;
+    private CheckBoxPreference mAnimations;
+    private float[] mAnimationScales;
+    
+    private AudioManager mAudioManager;
+    
+    private IWindowManager mWindowManager;
+
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateState(false);
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ContentResolver resolver = getContentResolver();
+        
+        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+
+        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        
+        addPreferencesFromResource(R.xml.sound_and_display_settings);
+        
+        mSilent = (CheckBoxPreference) findPreference(KEY_SILENT);
+        mPlayMediaNotificationSounds = (CheckBoxPreference) findPreference(KEY_PLAY_MEDIA_NOTIFICATION_SOUNDS);
+
+        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);
+        mAnimations = (CheckBoxPreference) findPreference(KEY_ANIMATIONS);
+        mAnimations.setPersistent(false);
+        
+        ListPreference screenTimeoutPreference =
+            (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
+        screenTimeoutPreference.setValue(String.valueOf(Settings.System.getInt(
+                resolver, 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 int ringerMode = mAudioManager.getRingerMode();
+        final boolean silentOrVibrateMode =
+                ringerMode != AudioManager.RINGER_MODE_NORMAL;
+        
+        if (silentOrVibrateMode != mSilent.isChecked() || force) {
+            mSilent.setChecked(silentOrVibrateMode);
+        }
+
+        try {
+            mPlayMediaNotificationSounds.setChecked(mMountService.getPlayNotificationSounds());
+        } catch (RemoteException e) {
+        }
+       
+        boolean vibrateSetting;
+        if (silentOrVibrateMode) {
+            vibrateSetting = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+        } else {
+            vibrateSetting = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER)
+                    == AudioManager.VIBRATE_SETTING_ON;            
+        }
+        if (vibrateSetting != mVibrate.isChecked() || force) {
+            mVibrate.setChecked(vibrateSetting);
+        }
+        
+        boolean animations = true;
+        try {
+            mAnimationScales = mWindowManager.getAnimationScales();
+        } catch (RemoteException e) {
+        }
+        if (mAnimationScales != null) {
+            for (int i=0; i<mAnimationScales.length; i++) {
+                if (mAnimationScales[i] == 0) {
+                    animations = false;
+                    break;
+                }
+            }
+        }
+        if (animations != mAnimations.isChecked() || force) {
+            mAnimations.setChecked(animations);
+        }
+    }
+
+    @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);
+            updateState(false);
+            
+        } else if (preference == mPlayMediaNotificationSounds) {
+            try {
+                mMountService.setPlayNotificationSounds(mPlayMediaNotificationSounds.isChecked());
+            } catch (RemoteException e) {
+            }
+        } else if (preference == mVibrate) {
+            final boolean vibrate = mVibrate.isChecked();
+            final boolean silent = mSilent.isChecked();
+            
+            if (silent) {
+                mAudioManager.setRingerMode(vibrate ? AudioManager.RINGER_MODE_VIBRATE :
+                    AudioManager.RINGER_MODE_SILENT);                
+            } else {
+                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);
+            
+        } else if (preference == mAnimations) {
+            for (int i=0; i<mAnimationScales.length; i++) {
+                mAnimationScales[i] = mAnimations.isChecked() ? 1 : 0;
+            }
+            try {
+                mWindowManager.setAnimationScales(mAnimationScales);
+            } catch (RemoteException e) {
+            }
+        }
+        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/UsageStats.java b/src/com/android/settings/UsageStats.java
new file mode 100755
index 0000000..89caa54
--- /dev/null
+++ b/src/com/android/settings/UsageStats.java
@@ -0,0 +1,249 @@
+
+
+/**
+ * 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.app.IUsageStats;
+import com.android.settings.R;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import com.android.internal.os.PkgUsageStats;
+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 android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+/**
+ * Activity to display package usage statistics.
+ */
+public class UsageStats extends Activity implements OnItemSelectedListener {
+    private static final String TAG="UsageStatsActivity";
+    private static final boolean localLOGV = true;
+    private Spinner mTypeSpinner;
+    private ListView mListView;
+    private IUsageStats mUsageStatsService;
+    private LayoutInflater mInflater;
+    private UsageStatsAdapter mAdapter;
+    private PackageManager mPm;
+    
+    public static class AppNameComparator implements Comparator<PkgUsageStats> {
+        Map<String, CharSequence> mAppLabelList;
+        AppNameComparator(Map<String, CharSequence> appList) {
+            mAppLabelList = appList;
+        }
+        public final int compare(PkgUsageStats a, PkgUsageStats b) {
+            String alabel = mAppLabelList.get(a.packageName).toString();
+            String blabel = mAppLabelList.get(b.packageName).toString();
+            return alabel.compareTo(blabel);
+        }
+    }
+    
+    public static class LaunchCountComparator implements Comparator<PkgUsageStats> {
+        public final int compare(PkgUsageStats a, PkgUsageStats b) {
+            // return by descending order
+            return b.launchCount - a.launchCount;
+        }
+    }
+    
+    public static class UsageTimeComparator implements Comparator<PkgUsageStats> {
+        public final int compare(PkgUsageStats a, PkgUsageStats b) {
+            long ret = a.usageTime-b.usageTime;
+            if (ret == 0) {
+                return 0;
+            }
+            if (ret < 0) {
+                return 1;
+            }
+            return -1;
+        }
+    }
+    
+     // View Holder used when displaying views
+    static class AppViewHolder {
+        TextView pkgName;
+        TextView launchCount;
+        TextView usageTime;
+    }
+    
+    class UsageStatsAdapter extends BaseAdapter {
+         // Constants defining order for display order
+        private static final int _DISPLAY_ORDER_USAGE_TIME = 0;
+        private static final int _DISPLAY_ORDER_LAUNCH_COUNT = 1;
+        private static final int _DISPLAY_ORDER_APP_NAME = 2;
+        
+        private int mDisplayOrder = _DISPLAY_ORDER_USAGE_TIME;
+        private List<PkgUsageStats> mUsageStats;
+        private LaunchCountComparator mLaunchCountComparator;
+        private UsageTimeComparator mUsageTimeComparator;
+        private AppNameComparator mAppLabelComparator;
+        private HashMap<String, CharSequence> mAppLabelMap;
+        
+        UsageStatsAdapter() {
+            mUsageStats = new ArrayList<PkgUsageStats>();
+            mAppLabelMap = new HashMap<String, CharSequence>();
+            PkgUsageStats[] stats;
+            try {
+                stats = mUsageStatsService.getAllPkgUsageStats();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed initializing usage stats service");
+                return;
+            }
+           if (stats == null) {
+               return;
+           }
+           for (PkgUsageStats ps : stats) {
+               mUsageStats.add(ps);
+               // load application labels for each application
+               CharSequence label;
+               try {
+                   ApplicationInfo appInfo = mPm.getApplicationInfo(ps.packageName, 0);
+                   label = appInfo.loadLabel(mPm);
+                } catch (NameNotFoundException e) {
+                    label = ps.packageName;
+                }
+                mAppLabelMap.put(ps.packageName, label);
+           }
+           // Sort list
+           mLaunchCountComparator = new LaunchCountComparator();
+           mUsageTimeComparator = new UsageTimeComparator();
+           mAppLabelComparator = new AppNameComparator(mAppLabelMap);
+           sortList();
+        }
+        public int getCount() {
+            return mUsageStats.size();
+        }
+
+        public Object getItem(int position) {
+            return mUsageStats.get(position);
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            // A ViewHolder keeps references to children views to avoid unneccessary calls
+            // to findViewById() on each row.
+            AppViewHolder holder;
+
+            // When convertView is not null, we can reuse it directly, there is no need
+            // to reinflate it. We only inflate a new View when the convertView supplied
+            // by ListView is null.
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.usage_stats_item, null);
+
+                // Creates a ViewHolder and store references to the two children views
+                // we want to bind data to.
+                holder = new AppViewHolder();
+                holder.pkgName = (TextView) convertView.findViewById(R.id.package_name);
+                holder.launchCount = (TextView) convertView.findViewById(R.id.launch_count);
+                holder.usageTime = (TextView) convertView.findViewById(R.id.usage_time);
+                convertView.setTag(holder);
+            } else {
+                // Get the ViewHolder back to get fast access to the TextView
+                // and the ImageView.
+                holder = (AppViewHolder) convertView.getTag();
+            }
+
+            // Bind the data efficiently with the holder
+            PkgUsageStats pkgStats = mUsageStats.get(position);
+            if (pkgStats != null) {
+                CharSequence label = mAppLabelMap.get(pkgStats.packageName);
+                holder.pkgName.setText(label);
+                holder.launchCount.setText(String.valueOf(pkgStats.launchCount));
+                holder.usageTime.setText(String.valueOf(pkgStats.usageTime)+" ms");
+            } else {
+                Log.w(TAG, "No usage stats info for package:"+pkgStats.packageName);
+            }
+            return convertView;
+        }
+        
+        void sortList(int sortOrder) {
+            if (mDisplayOrder == sortOrder) {
+                // do nothing
+                return;
+            }
+            mDisplayOrder= sortOrder;
+            sortList();
+        }
+        private void sortList() {
+            if (mDisplayOrder == _DISPLAY_ORDER_USAGE_TIME) {
+                if (localLOGV) Log.i(TAG, "Sorting by usage time");
+                Collections.sort(mUsageStats, mUsageTimeComparator);
+            } else if (mDisplayOrder == _DISPLAY_ORDER_LAUNCH_COUNT) {
+                if (localLOGV) Log.i(TAG, "Sorting launch count");
+                Collections.sort(mUsageStats, mLaunchCountComparator);
+            } else if (mDisplayOrder == _DISPLAY_ORDER_APP_NAME) {
+                if (localLOGV) Log.i(TAG, "Sorting by application name");
+                Collections.sort(mUsageStats, mAppLabelComparator);
+            }
+            notifyDataSetChanged();
+        }
+    }
+
+    /** Called when the activity is first created. */
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mUsageStatsService = IUsageStats.Stub.asInterface(ServiceManager.getService("usagestats"));
+        if (mUsageStatsService == null) {
+            Log.e(TAG, "Failed to retrieve usagestats service");
+            return;
+        }
+        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mPm = getPackageManager();
+        
+        setContentView(R.layout.usage_stats);
+        mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
+        mTypeSpinner.setOnItemSelectedListener(this);
+        
+        mListView = (ListView) findViewById(R.id.pkg_list);
+        // Initialize the inflater
+        
+        mAdapter = new UsageStatsAdapter();
+        mListView.setAdapter(mAdapter);
+    }
+
+    public void onItemSelected(AdapterView<?> parent, View view, int position,
+            long id) {
+        mAdapter.sortList(position);
+    }
+
+    public void onNothingSelected(AdapterView<?> parent) {
+        // do nothing
+    }
+}
+
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
new file mode 100644
index 0000000..aeddcf7
--- /dev/null
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -0,0 +1,271 @@
+/**
+ * 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.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.UserDictionary;
+import android.text.InputType;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AlphabetIndexer;
+import android.widget.EditText;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.SectionIndexer;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+import java.util.Locale;
+
+public class UserDictionarySettings extends ListActivity {
+
+    private static final String INSTANCE_KEY_DIALOG_EDITING_WORD = "DIALOG_EDITING_WORD";
+    private static final String INSTANCE_KEY_ADDED_WORD = "DIALOG_ADDED_WORD";
+
+    private static final String[] QUERY_PROJECTION = {
+        UserDictionary.Words._ID, UserDictionary.Words.WORD
+    };
+    
+    // Either the locale is empty (means the word is applicable to all locales)
+    // or the word equals our current locale
+    private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=? OR "
+            + UserDictionary.Words.LOCALE + " is null";
+
+    private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?";
+
+    private static final String EXTRA_WORD = "word";
+    
+    private static final int CONTEXT_MENU_EDIT = Menu.FIRST;
+    private static final int CONTEXT_MENU_DELETE = Menu.FIRST + 1;
+    
+    private static final int OPTIONS_MENU_ADD = Menu.FIRST;
+
+    private static final int DIALOG_ADD_OR_EDIT = 0;
+    
+    /** The word being edited in the dialog (null means the user is adding a word). */
+    private String mDialogEditingWord;
+    
+    private Cursor mCursor;
+    
+    private boolean mAddedWordAlready;
+    private boolean mAutoReturn;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.list_content_with_empty_view);
+        
+        mCursor = createCursor();
+        setListAdapter(createAdapter());
+        
+        TextView emptyView = (TextView) findViewById(R.id.empty);
+        emptyView.setText(R.string.user_dict_settings_empty_text);
+        
+        ListView listView = getListView();
+        listView.setFastScrollEnabled(true);
+        listView.setEmptyView(emptyView);
+
+        registerForContextMenu(listView);
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (!mAddedWordAlready 
+                && getIntent().getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) {
+            String word = getIntent().getStringExtra(EXTRA_WORD);
+            mAutoReturn = true;
+            if (word != null) {
+                showAddOrEditDialog(word);
+            }
+        }
+    }
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        mDialogEditingWord = state.getString(INSTANCE_KEY_DIALOG_EDITING_WORD);
+        mAddedWordAlready = state.getBoolean(INSTANCE_KEY_ADDED_WORD, false);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putString(INSTANCE_KEY_DIALOG_EDITING_WORD, mDialogEditingWord);
+        outState.putBoolean(INSTANCE_KEY_ADDED_WORD, mAddedWordAlready);
+    }
+
+    private Cursor createCursor() {
+        String currentLocale = Locale.getDefault().toString();
+        // Case-insensitive sort
+        return managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
+                QUERY_SELECTION, new String[] { currentLocale },
+                "UPPER(" + UserDictionary.Words.WORD + ")");
+    }
+
+    private ListAdapter createAdapter() {
+        return new MyAdapter(this,
+                android.R.layout.simple_list_item_1, mCursor,
+                new String[] { UserDictionary.Words.WORD },
+                new int[] { android.R.id.text1 });
+    }
+    
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        showAddOrEditDialog(getWord(position));
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+        if (!(menuInfo instanceof AdapterContextMenuInfo)) return;
+        
+        AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
+        menu.setHeaderTitle(getWord(adapterMenuInfo.position));
+        menu.add(0, CONTEXT_MENU_EDIT, 0, R.string.user_dict_settings_context_menu_edit_title);
+        menu.add(0, CONTEXT_MENU_DELETE, 0, R.string.user_dict_settings_context_menu_delete_title);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        ContextMenuInfo menuInfo = item.getMenuInfo();
+        if (!(menuInfo instanceof AdapterContextMenuInfo)) return false;
+        
+        AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
+        String word = getWord(adapterMenuInfo.position);
+        
+        switch (item.getItemId()) {
+            case CONTEXT_MENU_DELETE:
+                deleteWord(word);
+                return true;
+                
+            case CONTEXT_MENU_EDIT:
+                showAddOrEditDialog(word);
+                return true;
+        }
+        
+        return false;
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title)
+                .setIcon(R.drawable.ic_menu_add);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        showAddOrEditDialog(null);
+        return true;
+    }
+
+    private void showAddOrEditDialog(String editingWord) {
+        mDialogEditingWord = editingWord;
+        showDialog(DIALOG_ADD_OR_EDIT);
+    }
+    
+    private String getWord(int position) {
+        mCursor.moveToPosition(position);
+        return mCursor.getString(
+                mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD));
+    }
+    
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        View content = getLayoutInflater().inflate(R.layout.dialog_edittext, null);
+        final EditText editText = (EditText) content.findViewById(R.id.edittext);
+        // No prediction in soft keyboard mode. TODO: Create a better way to disable prediction
+        editText.setInputType(InputType.TYPE_CLASS_TEXT 
+                | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+        
+        return new AlertDialog.Builder(this)
+                .setTitle(R.string.user_dict_settings_add_dialog_title)
+                .setView(content)
+                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        onAddOrEditFinished(editText.getText().toString());
+                        if (mAutoReturn) finish();
+                    }})
+                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        if (mAutoReturn) finish();                        
+                    }})
+                .create();
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog d) {
+        AlertDialog dialog = (AlertDialog) d;
+        EditText editText = (EditText) dialog.findViewById(R.id.edittext);
+        editText.setText(mDialogEditingWord);
+    }
+
+    private void onAddOrEditFinished(String word) {
+        if (mDialogEditingWord != null) {
+            // The user was editing a word, so do a delete/add
+            deleteWord(mDialogEditingWord);
+        }
+        
+        // Disallow duplicates
+        deleteWord(word);
+        
+        // TODO: present UI for picking whether to add word to all locales, or current.
+        UserDictionary.Words.addWord(this, word.toString(),
+                250, UserDictionary.Words.LOCALE_TYPE_ALL);
+        mCursor.requery();
+        mAddedWordAlready = true;
+    }
+
+    private void deleteWord(String word) {
+        getContentResolver().delete(UserDictionary.Words.CONTENT_URI, DELETE_SELECTION,
+                new String[] { word });
+    }
+    
+    private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer {
+        private AlphabetIndexer mIndexer;        
+        
+        public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
+            super(context, layout, c, from, to);
+
+            int wordColIndex = c.getColumnIndexOrThrow(UserDictionary.Words.WORD);
+            String alphabet = context.getString(com.android.internal.R.string.fast_scroll_alphabet);
+            mIndexer = new AlphabetIndexer(c, wordColIndex, alphabet); 
+        }
+
+        public int getPositionForSection(int section) {
+            return mIndexer.getPositionForSection(section);
+        }
+
+        public int getSectionForPosition(int position) {
+            return mIndexer.getSectionForPosition(position);
+        }
+
+        public Object[] getSections() {
+            return mIndexer.getSections();
+        }
+    }
+}
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..d112915
--- /dev/null
+++ b/src/com/android/settings/WirelessSettings.java
@@ -0,0 +1,80 @@
+/*
+ * 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.bluetooth.BluetoothEnabler;
+import com.android.settings.wifi.WifiEnabler;
+
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.CheckBoxPreference;
+
+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 BluetoothEnabler mBtEnabler;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        addPreferencesFromResource(R.xml.wireless_settings);
+
+        initToggles();
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        mWifiEnabler.resume();
+        mAirplaneModeEnabler.resume();
+        mBtEnabler.resume();
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        
+        mWifiEnabler.pause();
+        mAirplaneModeEnabler.pause();
+        mBtEnabler.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));
+        
+        mBtEnabler = new BluetoothEnabler(
+                this,
+                (CheckBoxPreference) findPreference(KEY_TOGGLE_BLUETOOTH));
+    }
+    
+}
diff --git a/src/com/android/settings/ZoneList.java b/src/com/android/settings/ZoneList.java
new file mode 100644
index 0000000..2877f00
--- /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(android.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/battery_history/BatteryHistory.java b/src/com/android/settings/battery_history/BatteryHistory.java
new file mode 100644
index 0000000..dcf6cbf
--- /dev/null
+++ b/src/com/android/settings/battery_history/BatteryHistory.java
@@ -0,0 +1,861 @@
+/*
+ * 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.battery_history;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.settings.R;
+
+import android.app.Activity;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.BatteryStats;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.BatteryStats.Timer;
+import android.os.BatteryStats.Uid;
+import android.util.Log;
+import android.util.LogPrinter;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class BatteryHistory extends Activity implements OnClickListener, OnItemSelectedListener {
+    private static final String TAG = "BatteryHistory";
+
+    private static final int SECONDS_PER_MINUTE = 60;
+    private static final int SECONDS_PER_HOUR = 60 * 60;
+    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
+    
+    // Must be in sync with the values in res/values/array.xml (id battery_history_type_spinner)
+    private static final int CPU_USAGE = 0;
+    private static final int NETWORK_USAGE = 1;
+    private static final int GPS_USAGE = 2;
+    private static final int SENSOR_USAGE = 3;
+    private static final int WAKELOCK_USAGE = 4;
+    private static final int MISC_USAGE = 5;
+
+    // Must be in sync with the values in res/values/array.xml (id battery_history_which_spinner)
+    private static final int UNPLUGGED = 0;
+    private static final int CURRENT = 1;
+    private static final int TOTAL = 2;
+    
+    private BatteryStats mStats;
+    private int mWhich = BatteryStats.STATS_UNPLUGGED;
+    private int mType = CPU_USAGE;
+    
+    private GraphableButton[] mButtons;
+    IBatteryStats mBatteryInfo;
+    
+    private List<CpuUsage> mCpuUsage = new ArrayList<CpuUsage>();
+    private List<NetworkUsage> mNetworkUsage = new ArrayList<NetworkUsage>();
+    private List<SensorUsage> mSensorUsage = new ArrayList<SensorUsage>();
+    private List<SensorUsage> mGpsUsage = new ArrayList<SensorUsage>();
+    private List<WakelockUsage> mWakelockUsage = new ArrayList<WakelockUsage>();
+    private List<MiscUsage> mMiscUsage = new ArrayList<MiscUsage>();
+    
+    private boolean mHaveCpuUsage, mHaveNetworkUsage, mHaveSensorUsage,
+            mHaveWakelockUsage, mHaveMiscUsage;
+    
+    private LinearLayout mGraphLayout;
+    private LinearLayout mTextLayout;
+    private TextView mMessageText;
+    private TextView mDetailsText;
+    private Button mDetailsBackButton;
+    private Spinner mTypeSpinner;
+    private Spinner mWhichSpinner;
+    
+    private boolean mDetailsShown = false;
+    
+    private static String getLabel(String packageName, PackageManager pm) {
+        try {
+            ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
+            CharSequence label = ai.loadLabel(pm);
+            if (label != null) {
+                return label.toString();
+            }
+        } catch (NameNotFoundException e) {
+            return packageName;
+        }
+        
+        return "";
+    }
+    
+    void formatTime(double millis, StringBuilder sb) {
+        int seconds = (int) Math.floor(millis / 1000);
+        
+        int days = 0, hours = 0, minutes = 0;
+        if (seconds > SECONDS_PER_DAY) {
+            days = seconds / SECONDS_PER_DAY;
+            seconds -= days * SECONDS_PER_DAY;
+        }
+        if (seconds > SECONDS_PER_HOUR) {
+            hours = seconds / SECONDS_PER_HOUR;
+            seconds -= hours * SECONDS_PER_HOUR;
+        }
+        if (seconds > SECONDS_PER_MINUTE) {
+            minutes = seconds / SECONDS_PER_MINUTE;
+            seconds -= minutes * SECONDS_PER_MINUTE;
+        }
+        if (days > 0) {
+            sb.append(getString(R.string.battery_history_days, days, hours, minutes, seconds));
+        } else if (hours > 0) {
+            sb.append(getString(R.string.battery_history_hours, hours, minutes, seconds));
+        } else if (minutes > 0) { 
+            sb.append(getString(R.string.battery_history_minutes, minutes, seconds));
+        } else {
+            sb.append(getString(R.string.battery_history_seconds, seconds));
+        }
+    }
+    
+    abstract class Graphable implements Comparable<Graphable> {        
+        protected String mName;
+        protected String mNamePackage;
+        protected boolean mUniqueName;
+        protected String[] mPackages;
+        protected String[] mPackageNames;
+        
+        public abstract String getLabel();
+        public abstract double getSortValue();
+        public abstract double[] getValues();
+        public abstract void getInfo(StringBuilder info);
+        
+        public double getMaxValue() {
+            return -Double.MAX_VALUE;            
+        }
+        
+        public int compareTo(Graphable o) {
+            double t = getSortValue();
+            double ot = o.getSortValue();
+            if (t < ot) {
+                // Largest first
+                return 1;
+            } else if (t > ot) {
+                return -1;
+            } else {
+                return 0;
+            }
+        }
+                
+        // Side effects: sets mName and mUniqueName
+        void getNameForUid(int uid) {
+            PackageManager pm = getPackageManager();
+            mPackages = pm.getPackagesForUid(uid);
+            if (mPackages == null) {
+                mName = Integer.toString(uid);
+                mNamePackage = null;
+                return;
+            }
+            
+            mPackageNames = new String[mPackages.length];
+            System.arraycopy(mPackages, 0, mPackageNames, 0, mPackages.length);
+            
+            // Convert package names to user-facing labels where possible
+            for (int i = 0; i < mPackageNames.length; i++) {
+                mPackageNames[i] = BatteryHistory.getLabel(mPackageNames[i], pm);
+            }
+
+            if (mPackageNames.length == 1) {
+                mNamePackage = mPackages[0];
+                mName = mPackageNames[0];
+                mUniqueName = true;
+            } else {
+                mName = getString(R.string.battery_history_uid, uid); // Default name
+                // Look for an official name for this UID.
+                for (String name : mPackages) {
+                    try {
+                        PackageInfo pi = pm.getPackageInfo(name, 0);
+                        if (pi.sharedUserLabel != 0) {
+                            CharSequence nm = pm.getText(name,
+                                    pi.sharedUserLabel, pi.applicationInfo);
+                            if (nm != null) {
+                                mName = nm.toString();
+                                break;
+                            }
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                    }
+                }
+            }
+        }
+    }
+
+    class CpuUsage extends Graphable {
+        String mProcess;
+        double[] mUsage;
+        double mTotalRuntime;
+        long mStarts;
+        
+        public CpuUsage(int uid, String process, long userTime, long systemTime,
+                long starts, long totalRuntime) {
+            getNameForUid(uid);
+            mProcess = process;
+            PackageManager pm = BatteryHistory.this.getPackageManager();
+            mName = BatteryHistory.getLabel(process, pm);
+            mUsage = new double[2];
+            
+            mUsage[0] = userTime;
+            mUsage[1] = userTime + systemTime;
+            mTotalRuntime = totalRuntime;
+            mStarts = starts;
+        }
+        
+        public String getLabel() {
+            return mName;
+        }
+        
+        public double getSortValue() {
+            return mUsage[1];
+        }
+        
+        public double[] getValues() {
+            return mUsage;
+        }
+        
+        public double getMaxValue() {
+            return mTotalRuntime;            
+        }
+        
+        public void getInfo(StringBuilder info) {
+            info.append(getString(R.string.battery_history_cpu_usage, mProcess));
+            info.append("\n\n");
+            info.append(getString(R.string.battery_history_user_time));
+            formatTime(mUsage[0] * 10, info);
+            info.append('\n');
+            info.append(getString(R.string.battery_history_system_time));
+            formatTime((mUsage[1] - mUsage[0]) * 10, info);
+            info.append('\n');
+            info.append(getString(R.string.battery_history_total_time));
+            formatTime((mUsage[1]) * 10, info);
+            info.append('\n');
+            info.append(getString(R.string.battery_history_starts, mStarts));
+        }
+    }
+    
+    class NetworkUsage extends Graphable {
+        double[] mUsage;
+        
+        public NetworkUsage(int uid, long received, long sent) {
+            getNameForUid(uid);
+            
+            mUsage = new double[2];
+            mUsage[0] = received;
+            mUsage[1] = received + sent;
+        }
+        
+        public String getLabel() {
+            return mName;
+        }
+        
+        public double getSortValue() {
+            return mUsage[1];
+        }
+        
+        public double[] getValues() {
+            return mUsage;
+        }
+        
+        public void getInfo(StringBuilder info) {
+            info.append(getString(R.string.battery_history_network_usage, mName));
+            info.append("\n\n");
+            info.append(getString(R.string.battery_history_bytes_received, (long) mUsage[0]));
+            info.append('\n');
+            info.append(getString(R.string.battery_history_bytes_sent,
+                    (long) mUsage[1] - (long) mUsage[0]));
+            info.append('\n');
+            info.append(getString(R.string.battery_history_bytes_total, (long) mUsage[1]));
+
+            if (!mUniqueName) {
+                info.append("\n\n");
+                info.append(getString(R.string.battery_history_packages_sharing_this_uid));
+                info.append('\n');
+
+                PackageManager pm = BatteryHistory.this.getPackageManager();
+                List<String> names = new ArrayList<String>();
+                for (String name : mPackageNames) {
+                    names.add(BatteryHistory.getLabel(name, pm));
+                }
+                Collections.sort(names);
+                for (String name : names) {
+                    info.append("    ");
+                    info.append(name);
+                    info.append('\n');
+                }
+            }
+        }
+    }
+    
+    class SensorUsage extends Graphable {
+        double[] mUsage;
+        double mTotalRealtime;
+        int mCount;
+        
+        public SensorUsage(int uid, long time, int count, long totalRealtime) {
+            getNameForUid(uid);
+            
+            mUsage = new double[1];
+            mUsage[0] = time;
+            mTotalRealtime = totalRealtime;
+            
+            mCount = count;
+        }
+        
+        public String getLabel() {
+            return mName;
+        }
+        
+        public double getSortValue() {
+            return mUsage[0];
+        }
+        
+        public double[] getValues() {
+            return mUsage;
+        }
+        
+        public double getMaxValue() {
+            return mTotalRealtime;            
+        }
+        
+        public void getInfo(StringBuilder info) {
+            info.append(getString(R.string.battery_history_sensor));
+            info.append(mName);
+            info.append("\n\n");
+            info.append(getString(R.string.battery_history_total_time));
+            formatTime(mUsage[0], info);
+            info.append("\n\n");
+        }
+    }
+    
+    
+    class WakelockUsage extends Graphable {
+        double[] mUsage;
+        double mTotalRealtime;
+        int mCount;
+        
+        public WakelockUsage(int uid, long time, int count, long totalRealtime) {
+            getNameForUid(uid);
+            
+            mUsage = new double[1];
+            mUsage[0] = time;
+            mTotalRealtime = totalRealtime;
+            
+            mCount = count;
+        }
+        
+        public String getLabel() {
+            return mName;
+        }
+        
+        public double getSortValue() {
+            return mUsage[0];
+        }
+        
+        public double[] getValues() {
+            return mUsage;
+        }
+        
+        public double getMaxValue() {
+            return mTotalRealtime;            
+        }
+        
+        public void getInfo(StringBuilder info) {
+            info.append(getString(R.string.battery_history_wakelock));
+            info.append(mName);
+            info.append("\n\n");
+            info.append(getString(R.string.battery_history_total_time));
+            formatTime(mUsage[0], info);
+            info.append("\n\n");
+        }
+    }
+    
+    class MiscUsage extends Graphable {
+        int mInfoLabelRes;
+        double[] mUsage;
+        double mTotalRealtime;
+        
+        public MiscUsage(String name, int infoLabelRes, long value,
+                long totalRealtime) {
+            mName = name;
+            
+            mInfoLabelRes = infoLabelRes;
+            
+            mUsage = new double[2];
+            mUsage[0] = value;
+            mTotalRealtime = totalRealtime;
+        }
+        
+        public String getLabel() {
+            return mName;
+        }
+        
+        public double getSortValue() {
+            return mUsage[1];
+        }
+        
+        public double[] getValues() {
+            return mUsage;
+        }
+        
+        public double getMaxValue() {
+            return mTotalRealtime;            
+        }
+        
+        public void getInfo(StringBuilder info) {
+            info.append(getString(mInfoLabelRes));
+            info.append(' ');
+            formatTime(mUsage[0], info);
+            info.append(" (");
+            info.append((mUsage[0]*100)/mTotalRealtime);
+            info.append("%)");
+        }
+    }
+    
+    private List<? extends Graphable> getGraphRecords() {
+        switch (mType) {
+            case CPU_USAGE: return mCpuUsage;
+            case NETWORK_USAGE : return mNetworkUsage;
+            case SENSOR_USAGE: return mSensorUsage;
+            case GPS_USAGE: return mGpsUsage;
+            case WAKELOCK_USAGE: return mWakelockUsage;
+            case MISC_USAGE: return mMiscUsage;
+            default:
+                return (List<? extends Graphable>) null; // TODO
+        }
+    }
+    
+    private void displayGraph() {
+        Log.i(TAG, "displayGraph");
+
+        collectStatistics();
+        
+        // Hide the UI and selectively enable it below
+        mMessageText.setVisibility(View.GONE);
+        for (int i = 0; i < mButtons.length; i++) {
+            mButtons[i].setVisibility(View.INVISIBLE);
+        }
+        
+        double maxValue = -Double.MAX_VALUE;
+        
+        List<? extends Graphable> records = getGraphRecords();
+        for (Graphable g : records) {
+            double[] values = g.getValues();
+            maxValue = Math.max(maxValue, values[values.length - 1]);
+            maxValue = Math.max(maxValue, g.getMaxValue());
+        }
+        
+        int[] colors = new int[2];
+        colors[0] = 0xff0000ff;
+        colors[1] = 0xffff0000;
+        
+        for (int i = 0; i < mButtons.length; i++) {
+            mButtons[i].setVisibility(View.INVISIBLE);
+        }
+        
+        int numRecords = Math.min(records.size(), mButtons.length);
+        if (numRecords == 0) {
+             mMessageText.setVisibility(View.VISIBLE);
+             mMessageText.setText(R.string.battery_history_no_data);
+        } else {
+            for (int i = 0; i < numRecords; i++) {
+                Graphable r = records.get(i);           
+
+                mButtons[i].setText(r.getLabel());
+                mButtons[i].setValues(r.getValues(), maxValue);
+                mButtons[i].setVisibility(View.VISIBLE);
+            }
+        }
+    }
+    
+    private void hideDetails() {
+        mTextLayout.setVisibility(View.GONE);
+        mGraphLayout.setVisibility(View.VISIBLE);
+        mDetailsShown = false;
+    }
+    
+    private void showDetails(int id) {
+        mGraphLayout.setVisibility(View.GONE);
+        mTextLayout.setVisibility(View.VISIBLE);
+            
+        StringBuilder info = new StringBuilder();
+        List<? extends Graphable> records = getGraphRecords();
+        if (id < records.size()) {
+            Graphable record = records.get(id);
+            record.getInfo(info);
+        } else {
+            info.append(getString(R.string.battery_history_details_for, id));
+        }
+        mDetailsText.setText(info.toString());
+        mDetailsShown = true;
+    }
+
+    private void processCpuUsage() {
+        mCpuUsage.clear();
+        
+        long uSecTime = SystemClock.uptimeMillis() * 1000;
+        final long uSecNow = mStats.computeBatteryUptime(uSecTime, mWhich) / 1000;
+        
+        SparseArray<? extends Uid> uidStats = mStats.getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            Uid u = uidStats.valueAt(iu);
+
+            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+            if (processStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+                        : processStats.entrySet()) {
+
+                    Uid.Proc ps = ent.getValue();
+                    long userTime = ps.getUserTime(mWhich);
+                    long systemTime = ps.getSystemTime(mWhich);
+                    long starts = ps.getStarts(mWhich);
+
+                    if (userTime != 0 || systemTime != 0) {
+                        mCpuUsage.add(new CpuUsage(u.getUid(), ent.getKey(),
+                                userTime, systemTime, starts, uSecNow));
+                    }
+                }
+            }
+        }
+        Collections.sort(mCpuUsage);
+    }
+    
+    private void processNetworkUsage() {
+        mNetworkUsage.clear();
+        
+        SparseArray<? extends Uid> uidStats = mStats.getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            Uid u = uidStats.valueAt(iu);
+            
+            long received = u.getTcpBytesReceived(mWhich);
+            long sent = u.getTcpBytesSent(mWhich);
+            if (received + sent > 0) {
+                mNetworkUsage.add(new NetworkUsage(u.getUid(), received, sent));
+            }
+        }
+        Collections.sort(mNetworkUsage);
+    }
+    
+    private void processSensorUsage() {
+        mGpsUsage.clear();
+        mSensorUsage.clear();
+        
+        long uSecTime = SystemClock.elapsedRealtime() * 1000;
+        final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
+        
+        SparseArray<? extends Uid> uidStats = mStats.getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            Uid u = uidStats.valueAt(iu);
+            int uid = u.getUid();
+            
+            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
+            long timeGps = 0;
+            int countGps = 0;
+            long timeOther = 0;
+            int countOther = 0;
+            if (sensorStats.size() > 0) {
+                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
+                        : sensorStats.entrySet()) {
+
+                    Uid.Sensor se = ent.getValue();
+                    int handle = se.getHandle();
+                    Timer timer = se.getSensorTime();
+                    if (timer != null) {
+                        // Convert from microseconds to milliseconds with rounding
+                        long totalTime = (timer.getTotalTime(uSecNow, mWhich) + 500) / 1000;
+                        int count = timer.getCount(mWhich);
+                        if (handle == BatteryStats.Uid.Sensor.GPS) {
+                            timeGps += totalTime;
+                            countGps += count;
+                        } else {
+                            timeOther += totalTime;
+                            countOther += count;
+                        }
+                    }
+                }
+            }
+            
+            if (timeGps > 0) {
+                mGpsUsage.add(new SensorUsage(uid, timeGps, countGps, uSecNow));
+            }
+            if (timeOther > 0) {
+                mSensorUsage.add(new SensorUsage(uid, timeOther, countOther, uSecNow));
+            }
+        }
+        
+        Collections.sort(mGpsUsage);
+        Collections.sort(mSensorUsage);
+    }
+    
+    private void processWakelockUsage() {
+        mWakelockUsage.clear();
+        
+        long uSecTime = SystemClock.elapsedRealtime() * 1000;
+        final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
+        
+        SparseArray<? extends Uid> uidStats = mStats.getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            Uid u = uidStats.valueAt(iu);
+            int uid = u.getUid();
+            
+            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats();
+            long time = 0;
+            int count = 0;
+            if (wakelockStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
+                        : wakelockStats.entrySet()) {
+
+                    Uid.Wakelock wl = ent.getValue();
+                    Timer timer = wl.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
+                    if (timer != null) {
+                        // Convert from microseconds to milliseconds with rounding
+                        time += (timer.getTotalTime(uSecNow, mWhich) + 500) / 1000;
+                        count += timer.getCount(mWhich);
+                    }
+                }
+            }
+            
+            if (time > 0) {
+                mWakelockUsage.add(new WakelockUsage(uid, time, count, uSecNow));
+            }
+        }
+        
+        Collections.sort(mWakelockUsage);
+    }
+    
+    private void processMiscUsage() {
+        mMiscUsage.clear();
+        
+        long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+        final long batteryRealtime = mStats.getBatteryRealtime(rawRealtime);
+        final long whichRealtime = mStats.computeBatteryRealtime(rawRealtime, mWhich) / 1000;
+        
+        long time = mStats.computeBatteryUptime(SystemClock.uptimeMillis() * 1000, mWhich) / 1000;
+        if (time > 0) {
+            mMiscUsage.add(new MiscUsage(getString(
+                    R.string.battery_history_awake_label),
+                    R.string.battery_history_awake,
+                    time, whichRealtime)); 
+        }
+        
+        time = mStats.getScreenOnTime(batteryRealtime, mWhich) / 1000;
+        if (time > 0) {
+            mMiscUsage.add(new MiscUsage(getString(
+                    R.string.battery_history_screen_on_label),
+                    R.string.battery_history_screen_on,
+                    time, whichRealtime)); 
+        }
+        
+        time = mStats.getPhoneOnTime(batteryRealtime, mWhich) / 1000;
+        if (time > 0) {
+            mMiscUsage.add(new MiscUsage(getString(
+                    R.string.battery_history_phone_on_label),
+                    R.string.battery_history_phone_on,
+                    time, whichRealtime)); 
+        }
+        
+        Collections.sort(mMiscUsage);
+    }
+    
+    private void collectStatistics() {
+        if (mType == CPU_USAGE) {
+            if (!mHaveCpuUsage) {
+                mHaveCpuUsage = true;
+                processCpuUsage();
+            }
+        }
+        if (mType == NETWORK_USAGE) {
+            if (!mHaveNetworkUsage) {
+                mHaveNetworkUsage = true;
+                processNetworkUsage();
+            }
+        }
+        if (mType == GPS_USAGE || mType == SENSOR_USAGE) {
+            if (!mHaveSensorUsage) {
+                mHaveSensorUsage = true;
+                processSensorUsage();
+            }
+        }
+        if (mType == WAKELOCK_USAGE) {
+            if (!mHaveWakelockUsage) {
+                mHaveWakelockUsage = true;
+                processWakelockUsage();
+            }
+        }
+        if (mType == MISC_USAGE) {
+            if (!mHaveMiscUsage) {
+                mHaveMiscUsage = true;
+                processMiscUsage();
+            }
+        }
+    }
+    
+    private void load() {
+        try {
+            byte[] data = mBatteryInfo.getStatistics();
+            Parcel parcel = Parcel.obtain();
+            //Log.i(TAG, "Got data: " + data.length + " bytes");
+            parcel.unmarshall(data, 0, data.length);
+            parcel.setDataPosition(0);
+            mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
+                    .createFromParcel(parcel);
+            //Log.i(TAG, "RECEIVED BATTERY INFO:");
+            //mStats.dumpLocked(new LogPrinter(Log.INFO, TAG));
+            
+            mHaveCpuUsage =  mHaveNetworkUsage =  mHaveSensorUsage
+                    = mHaveWakelockUsage = mHaveMiscUsage = false;
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException:", e);
+        }
+    }
+    
+    public void onClick(View v) {
+        if (v == mDetailsBackButton) {
+            hideDetails();
+            return;
+        }
+        
+        int id = ((Integer) v.getTag()).intValue();
+        showDetails(id);
+    }
+    
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && mDetailsShown) {
+            hideDetails();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+        int oldWhich = mWhich;
+        
+        if (parent.equals(mTypeSpinner)) {
+            mType = position;
+        } else if (parent.equals(mWhichSpinner)) {
+            switch (position) {
+                case UNPLUGGED:
+                    mWhich = BatteryStats.STATS_UNPLUGGED;
+                    break;
+                case CURRENT:
+                    mWhich = BatteryStats.STATS_CURRENT;
+                    break;
+                case TOTAL:
+                    mWhich = BatteryStats.STATS_TOTAL;
+                    break;
+            }
+        }
+        
+        if (oldWhich != mWhich) {
+            mHaveCpuUsage =  mHaveNetworkUsage =  mHaveSensorUsage
+                    = mHaveWakelockUsage = mHaveMiscUsage = false;
+        }
+        
+        displayGraph();
+    }
+
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Do nothing
+    }
+    
+    @Override
+    public Object onRetainNonConfigurationInstance() {
+        BatteryStats stats = mStats;
+        mStats = null;
+        return stats;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        if (mStats != null) {
+            outState.putParcelable("stats", mStats);
+        }
+        outState.putInt("type", mType);
+        outState.putInt("which", mWhich);
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, "onCreate");
+        
+        setContentView(R.layout.battery_history);
+        
+        mGraphLayout = (LinearLayout) findViewById(R.id.graphLayout);
+        mTextLayout = (LinearLayout) findViewById(R.id.textLayout);
+        mDetailsText = (TextView) findViewById(R.id.detailsText);
+        mMessageText = (TextView) findViewById(R.id.messageText);
+        
+        mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
+        mTypeSpinner.setOnItemSelectedListener(this);
+        
+        mWhichSpinner = (Spinner) findViewById(R.id.whichSpinner);
+        mWhichSpinner.setOnItemSelectedListener(this);
+        mWhichSpinner.setEnabled(true);
+        
+        mButtons = new GraphableButton[8];
+        mButtons[0] = (GraphableButton) findViewById(R.id.button0);
+        mButtons[1] = (GraphableButton) findViewById(R.id.button1);
+        mButtons[2] = (GraphableButton) findViewById(R.id.button2);
+        mButtons[3] = (GraphableButton) findViewById(R.id.button3);
+        mButtons[4] = (GraphableButton) findViewById(R.id.button4);
+        mButtons[5] = (GraphableButton) findViewById(R.id.button5);
+        mButtons[6] = (GraphableButton) findViewById(R.id.button6);
+        mButtons[7] = (GraphableButton) findViewById(R.id.button7);
+        
+        for (int i = 0; i < mButtons.length; i++) {
+            mButtons[i].setTag(i);
+            mButtons[i].setOnClickListener(this);
+        }
+        
+        mBatteryInfo = IBatteryStats.Stub.asInterface(
+                ServiceManager.getService("batteryinfo"));
+        
+        mStats = (BatteryStats)getLastNonConfigurationInstance();
+        if (icicle != null) {
+            if (mStats == null) {
+                mStats = (BatteryStats)icicle.getParcelable("stats");
+            }
+            mType = icicle.getInt("type");
+            mWhich = icicle.getInt("which");
+        }
+        if (mStats == null) {
+            load();
+        }
+        displayGraph();
+    }
+}
diff --git a/src/com/android/settings/battery_history/GraphableButton.java b/src/com/android/settings/battery_history/GraphableButton.java
new file mode 100644
index 0000000..39028d0
--- /dev/null
+++ b/src/com/android/settings/battery_history/GraphableButton.java
@@ -0,0 +1,55 @@
+package com.android.settings.battery_history;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.Button;
+
+public class GraphableButton extends Button {
+    private static final String TAG = "GraphableButton";
+
+    static Paint[] sPaint = new Paint[2];
+    static {
+        sPaint[0] = new Paint();
+        sPaint[0].setStyle(Paint.Style.FILL);
+        sPaint[0].setColor(Color.BLUE);
+        
+        sPaint[1] = new Paint();
+        sPaint[1].setStyle(Paint.Style.FILL);
+        sPaint[1].setColor(Color.RED);
+    }
+    
+    double[] mValues;
+    
+    public GraphableButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+    
+    public void setValues(double[] values, double maxValue) {
+        mValues = values.clone();
+        for (int i = 0; i < values.length; i++) {
+            mValues[i] /= maxValue;
+        }
+    }
+    
+    @Override
+    public void onDraw(Canvas canvas) {
+        Log.i(TAG, "onDraw: w = " + getWidth() + ", h = " + getHeight());
+        
+        int xmin = getPaddingLeft();
+        int xmax = getWidth() - getPaddingRight();
+        int ymin = getPaddingTop();
+        int ymax = getHeight() - getPaddingBottom();
+        
+        int startx = xmin;
+        for (int i = 0; i < mValues.length; i++) {
+            int endx = xmin + (int) (mValues[i] * (xmax - xmin));
+            canvas.drawRect(startx, ymin, endx, ymax, sPaint[i]);
+            startx = endx;
+        }
+        super.onDraw(canvas);
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
new file mode 100644
index 0000000..f0a8189
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -0,0 +1,122 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.ImageView;
+
+/**
+ * BluetoothDevicePreference is the preference type used to display each remote
+ * Bluetooth device in the Bluetooth Settings screen.
+ */
+public class BluetoothDevicePreference extends Preference implements LocalBluetoothDevice.Callback {
+    private static final String TAG = "BluetoothDevicePreference";
+
+    private static int sDimAlpha = Integer.MIN_VALUE;
+    
+    private LocalBluetoothDevice mLocalDevice;
+    
+    /**
+     * Cached local copy of whether the device is busy. This is only updated
+     * from {@link #onDeviceAttributesChanged(LocalBluetoothDevice)}.
+     */ 
+    private boolean mIsBusy;
+    
+    public BluetoothDevicePreference(Context context, LocalBluetoothDevice localDevice) {
+        super(context);
+
+        if (sDimAlpha == Integer.MIN_VALUE) {
+            TypedValue outValue = new TypedValue();
+            context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
+            sDimAlpha = (int) (outValue.getFloat() * 255);
+        }
+            
+        mLocalDevice = localDevice;
+        
+        setLayoutResource(R.layout.preference_bluetooth);
+        
+        localDevice.registerCallback(this);
+        
+        onDeviceAttributesChanged(localDevice);
+    }
+    
+    public LocalBluetoothDevice getDevice() {
+        return mLocalDevice;
+    }
+
+    @Override
+    protected void onPrepareForRemoval() {
+        super.onPrepareForRemoval();
+        mLocalDevice.unregisterCallback(this);
+    }
+
+    public void onDeviceAttributesChanged(LocalBluetoothDevice device) {
+
+        /*
+         * The preference framework takes care of making sure the value has
+         * changed before proceeding.
+         */
+        
+        setTitle(mLocalDevice.getName());
+        
+        /*
+         * TODO: Showed "Paired" even though it was "Connected". This may be
+         * related to BluetoothHeadset not bound to the actual
+         * BluetoothHeadsetService when we got here.
+         */
+        setSummary(mLocalDevice.getSummary());
+
+        // Used to gray out the item
+        mIsBusy = mLocalDevice.isBusy();
+        
+        // Data has changed
+        notifyChanged();
+        
+        // This could affect ordering, so notify that also
+        notifyHierarchyChanged();
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return super.isEnabled() && !mIsBusy;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
+        btClass.setImageResource(mLocalDevice.getBtClassDrawable());
+        btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);        
+    }
+
+    @Override
+    public int compareTo(Preference another) {
+        if (!(another instanceof BluetoothDevicePreference)) {
+            // Put other preference types above us
+            return 1;
+        }
+        
+        return mLocalDevice.compareTo(((BluetoothDevicePreference) another).mLocalDevice);
+    }
+ 
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
new file mode 100644
index 0000000..a51f9b5e
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -0,0 +1,198 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.CheckBoxPreference;
+import android.util.Log;
+
+/**
+ * BluetoothDiscoverableEnabler is a helper to manage the "Discoverable"
+ * checkbox. It sets/unsets discoverability and keeps track of how much time
+ * until the the discoverability is automatically turned off.
+ */
+public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
+    private static final String TAG = "BluetoothDiscoverableEnabler";
+    private static final boolean V = LocalBluetoothManager.V;
+    
+    private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
+            "debug.bt.discoverable_time";
+    private static final int DISCOVERABLE_TIMEOUT = 120; 
+
+    private static final String SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP =
+            "discoverable_end_timestamp";
+    
+    private final Context mContext;
+    private final Handler mUiHandler;
+    private final CheckBoxPreference mCheckBoxPreference;
+    
+    private final LocalBluetoothManager mLocalManager;
+    
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (BluetoothIntent.SCAN_MODE_CHANGED_ACTION.equals(intent.getAction())) {
+                int mode = intent.getIntExtra(BluetoothIntent.SCAN_MODE, BluetoothError.ERROR);
+                if (mode != BluetoothError.ERROR) {
+                    handleModeChanged(mode);
+                }
+            }
+        }
+    };
+
+    private final Runnable mUpdateCountdownSummaryRunnable = new Runnable() {
+        public void run() {
+            updateCountdownSummary();        
+        } 
+    };
+
+    public BluetoothDiscoverableEnabler(Context context, CheckBoxPreference checkBoxPreference) {
+        mContext = context;
+        mUiHandler = new Handler();
+        mCheckBoxPreference = checkBoxPreference;
+        
+        checkBoxPreference.setPersistent(false);
+        
+        mLocalManager = LocalBluetoothManager.getInstance(context);
+        if (mLocalManager == null) {
+            // Bluetooth not supported
+            checkBoxPreference.setEnabled(false);
+        }
+    }
+
+    public void resume() {
+        if (mLocalManager == null) {
+            return;
+        }
+
+        IntentFilter filter = new IntentFilter(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
+        filter.addAction(BluetoothIntent.DISABLED_ACTION);
+        mContext.registerReceiver(mReceiver, filter);
+        mCheckBoxPreference.setOnPreferenceChangeListener(this);
+        
+        handleModeChanged(mLocalManager.getBluetoothManager().getScanMode());
+    }
+    
+    public void pause() {
+        if (mLocalManager == null) {
+            return;
+        }
+        
+        mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
+        mCheckBoxPreference.setOnPreferenceChangeListener(null);
+        mContext.unregisterReceiver(mReceiver);
+    }
+    
+    public boolean onPreferenceChange(Preference preference, Object value) {
+        if (V) {
+            Log.v(TAG, "Preference changed to " + value);
+        }
+        
+        // Turn on/off BT discoverability
+        setEnabled((Boolean) value);
+        
+        return true;
+    }
+    
+    private void setEnabled(final boolean enable) {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+        
+        if (enable) {
+
+            int timeout = getDiscoverableTimeout();
+            manager.setDiscoverableTimeout(timeout);
+            
+            long endTimestamp = System.currentTimeMillis() + timeout * 1000;
+            persistDiscoverableEndTimestamp(endTimestamp);
+            
+            manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+        } else {
+            manager.setScanMode(BluetoothDevice.SCAN_MODE_CONNECTABLE);
+        }
+    }
+
+    private int getDiscoverableTimeout() {
+        int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
+        if (timeout <= 0) {
+            timeout = DISCOVERABLE_TIMEOUT;
+        }
+        
+        return timeout;
+    }
+
+    private void persistDiscoverableEndTimestamp(long endTimestamp) {
+        SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit();
+        editor.putLong(SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
+        editor.commit();
+    }
+    
+    private void handleModeChanged(int mode) {
+        if (V) {
+            Log.v(TAG, "Got mode changed: " + mode);
+        }
+        
+        if (mode == BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+            mCheckBoxPreference.setChecked(true);
+            updateCountdownSummary();
+            
+        } else {
+            mCheckBoxPreference.setChecked(false);
+        }
+    }
+    
+    private void updateCountdownSummary() {
+        int mode = mLocalManager.getBluetoothManager().getScanMode();
+        if (mode != BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+            return;
+        }
+            
+        long currentTimestamp = System.currentTimeMillis();
+        long endTimestamp = mLocalManager.getSharedPreferences().getLong(
+                SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
+            
+        if (currentTimestamp > endTimestamp) {
+            // We're still in discoverable mode, but maybe there isn't a timeout.
+            mCheckBoxPreference.setSummaryOn(null);
+            return;
+        }
+        
+        String formattedTimeLeft = String.valueOf((endTimestamp - currentTimestamp) / 1000);
+        
+        mCheckBoxPreference.setSummaryOn(
+                mContext.getResources().getString(R.string.bluetooth_is_discoverable,
+                        formattedTimeLeft));
+        
+        synchronized (this) {
+            mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
+            mUiHandler.postDelayed(mUpdateCountdownSummaryRunnable, 1000);
+        }
+    }
+    
+        
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
new file mode 100644
index 0000000..661700f
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -0,0 +1,149 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.preference.Preference;
+import android.preference.CheckBoxPreference;
+import android.text.TextUtils;
+import android.util.Config;
+
+/**
+ * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox
+ * preference. It is turns on/off Bluetooth and ensures the summary of the
+ * preference reflects the current state.
+ */
+public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
+    
+    private static final boolean LOCAL_LOGD = Config.LOGD || false;
+    private static final String TAG = "BluetoothEnabler";
+    
+    private final Context mContext; 
+    private final CheckBoxPreference mCheckBoxPreference;
+    private final CharSequence mOriginalSummary;
+    
+    private final LocalBluetoothManager mLocalManager;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            handleStateChanged(mLocalManager.getBluetoothState());
+        }
+    };
+
+    public BluetoothEnabler(Context context, CheckBoxPreference checkBoxPreference) {
+        mContext = context;
+        mCheckBoxPreference = checkBoxPreference;
+        
+        mOriginalSummary = checkBoxPreference.getSummary();
+        checkBoxPreference.setPersistent(false);
+        
+        mLocalManager = LocalBluetoothManager.getInstance(context);
+        if (mLocalManager == null) {
+            // Bluetooth not supported
+            checkBoxPreference.setEnabled(false);
+        }
+    }
+
+    public void resume() {
+        if (mLocalManager == null) {
+            return;
+        }
+        
+        ExtendedBluetoothState state = mLocalManager.getBluetoothState();
+        // This is the widget enabled state, not the preference toggled state
+        mCheckBoxPreference.setEnabled(state == ExtendedBluetoothState.ENABLED ||
+                state == ExtendedBluetoothState.DISABLED);
+        // BT state is not a sticky broadcast, so set it manually
+        handleStateChanged(state);
+        
+        mContext.registerReceiver(mReceiver, 
+                new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+        mCheckBoxPreference.setOnPreferenceChangeListener(this);
+    }
+    
+    public void pause() {
+        if (mLocalManager == null) {
+            return;
+        }
+        
+        mContext.unregisterReceiver(mReceiver);
+        mCheckBoxPreference.setOnPreferenceChangeListener(null);
+    }
+    
+    public boolean onPreferenceChange(Preference preference, Object value) {
+        // Turn on/off BT
+        setEnabled((Boolean) value);
+        
+        // Don't update UI to opposite state until we're sure
+        return false;
+    }
+    
+    private void setEnabled(final boolean enable) {
+        // Disable preference
+        mCheckBoxPreference.setEnabled(false);
+        
+        mLocalManager.setBluetoothEnabled(enable);
+    }
+    
+    private void handleStateChanged(ExtendedBluetoothState state) {
+
+        if (state == ExtendedBluetoothState.DISABLED || state == ExtendedBluetoothState.ENABLED) {
+            mCheckBoxPreference.setChecked(state == ExtendedBluetoothState.ENABLED);
+            mCheckBoxPreference
+                    .setSummary(state == ExtendedBluetoothState.DISABLED ? mOriginalSummary : null);
+            
+            mCheckBoxPreference.setEnabled(isEnabledByDependency());
+            
+        } else if (state == ExtendedBluetoothState.ENABLING ||
+                state == ExtendedBluetoothState.DISABLING) {
+            mCheckBoxPreference.setSummary(state == ExtendedBluetoothState.ENABLING
+                    ? R.string.wifi_starting
+                    : R.string.wifi_stopping);
+            
+        } else if (state == ExtendedBluetoothState.UNKNOWN) {
+            mCheckBoxPreference.setChecked(false);
+            mCheckBoxPreference.setSummary(R.string.wifi_error);
+            mCheckBoxPreference.setEnabled(true);
+        }
+    }
+
+    private boolean isEnabledByDependency() {
+        Preference dep = getDependencyPreference();
+        if (dep == null) {
+            return true;
+        }
+        
+        return !dep.shouldDisableDependents();
+    }
+    
+    private Preference getDependencyPreference() {
+        String depKey = mCheckBoxPreference.getDependency();
+        if (TextUtils.isEmpty(depKey)) {
+            return null;
+        }
+        
+        return mCheckBoxPreference.getPreferenceManager().findPreference(depKey);
+    }
+    
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
new file mode 100644
index 0000000..2ad5726
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
@@ -0,0 +1,147 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+/**
+ * BluetoothEventRedirector receives broadcasts and callbacks from the Bluetooth
+ * API and dispatches the event on the UI thread to the right class in the
+ * Settings.
+ */
+public class BluetoothEventRedirector {
+    private static final String TAG = "BluetoothEventRedirector";
+    private static final boolean V = LocalBluetoothManager.V;
+    
+    private LocalBluetoothManager mManager;
+    
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (V) {
+                Log.v(TAG, "Received " + intent.getAction());
+            }
+            
+            String action = intent.getAction();
+            String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+                
+            if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
+                mManager.setBluetoothStateInt(ExtendedBluetoothState.ENABLED);
+                
+            } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
+                mManager.setBluetoothStateInt(ExtendedBluetoothState.DISABLED);
+                    
+            } else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) {
+                mManager.onScanningStateChanged(true);
+                
+            } else if (action.equals(BluetoothIntent.DISCOVERY_COMPLETED_ACTION)) {
+                mManager.onScanningStateChanged(false);
+                    
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)) {
+                short rssi = intent.getShortExtra(BluetoothIntent.RSSI, Short.MIN_VALUE);
+                mManager.getLocalDeviceManager().onDeviceAppeared(address, rssi);
+                
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION)) {
+                mManager.getLocalDeviceManager().onDeviceDisappeared(address);
+                
+            } else if (action.equals(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION)) {
+                mManager.getLocalDeviceManager().onDeviceNameUpdated(address);
+                
+            } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
+                int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
+                                                   BluetoothError.ERROR);
+                mManager.getLocalDeviceManager().onBondingStateChanged(address, bondState);
+                if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
+                    int reason = intent.getIntExtra(BluetoothIntent.REASON, BluetoothError.ERROR);
+                    if (reason == BluetoothDevice.UNBOND_REASON_AUTH_FAILED ||
+                            reason == BluetoothDevice.UNBOND_REASON_AUTH_REJECTED ||
+                            reason == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN) {
+                        mManager.getLocalDeviceManager().onBondingError(address, reason);
+                    }
+                }
+                
+            } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
+                mManager.getLocalDeviceManager().onProfileStateChanged(address);
+
+                int newState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 0);
+                int oldState = intent.getIntExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, 0);
+                if (newState == BluetoothHeadset.STATE_DISCONNECTED &&
+                        oldState == BluetoothHeadset.STATE_CONNECTING) {
+                    Log.i(TAG, "Failed to connect BT headset");
+                }
+                
+            } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
+                mManager.getLocalDeviceManager().onProfileStateChanged(address);
+
+                int newState = intent.getIntExtra(BluetoothA2dp.SINK_STATE, 0);
+                int oldState = intent.getIntExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, 0);
+                if (newState == BluetoothA2dp.STATE_DISCONNECTED &&
+                        oldState == BluetoothA2dp.STATE_CONNECTING) {
+                    Log.i(TAG, "Failed to connect BT A2DP");
+                }
+                
+            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) {
+                mManager.getLocalDeviceManager().onBtClassChanged(address);
+                
+            }
+        }
+    };
+
+    public BluetoothEventRedirector(LocalBluetoothManager localBluetoothManager) {
+        mManager = localBluetoothManager;
+    }
+
+    public void start() {
+        IntentFilter filter = new IntentFilter();
+        
+        // Bluetooth on/off broadcasts
+        filter.addAction(BluetoothIntent.ENABLED_ACTION);
+        filter.addAction(BluetoothIntent.DISABLED_ACTION);
+        
+        // Discovery broadcasts
+        filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION);
+        filter.addAction(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
+        filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
+        filter.addAction(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
+        filter.addAction(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
+        
+        // Pairing broadcasts
+        filter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+        
+        // Fine-grained state broadcasts
+        filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
+        filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
+        filter.addAction(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
+        
+        mManager.getContext().registerReceiver(mBroadcastReceiver, filter);
+    }
+    
+    public void stop() {
+        mManager.getContext().unregisterReceiver(mBroadcastReceiver);   
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
new file mode 100644
index 0000000..3065b26
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
@@ -0,0 +1,79 @@
+/*
+ * 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.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.preference.EditTextPreference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+
+/**
+ * BluetoothNamePreference is the preference type for editing the device's
+ * Bluetooth name. It asks the user for a name, and persists it via the
+ * Bluetooth API.
+ */
+public class BluetoothNamePreference extends EditTextPreference {
+    private static final String TAG = "BluetoothNamePreference";
+
+    private LocalBluetoothManager mLocalManager;
+    
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            setSummaryToName();
+        }
+    };
+    
+    public BluetoothNamePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        
+        mLocalManager = LocalBluetoothManager.getInstance(context);
+        
+        setSummaryToName();        
+    }
+
+    public void resume() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothIntent.ENABLED_ACTION);
+        filter.addAction(BluetoothIntent.NAME_CHANGED_ACTION);
+        getContext().registerReceiver(mReceiver, filter);
+    }
+    
+    public void pause() {
+        getContext().unregisterReceiver(mReceiver);
+    }
+    
+    private void setSummaryToName() {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+        if (manager.isEnabled()) {
+            setSummary(manager.getName());
+        }
+    }
+
+    @Override
+    protected boolean persistString(String value) {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+        manager.setName(value);
+        return true;        
+    }
+    
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothPinDialog.java b/src/com/android/settings/bluetooth/BluetoothPinDialog.java
new file mode 100644
index 0000000..5e289f7
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothPinDialog.java
@@ -0,0 +1,202 @@
+/*
+ * 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.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.text.InputFilter.LengthFilter;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+import com.android.settings.R;
+
+/**
+ * BluetoothPinDialog asks the user to enter a PIN for pairing with a remote
+ * Bluetooth device. It is an activity that appears as a dialog.
+ */
+public class BluetoothPinDialog extends AlertActivity implements DialogInterface.OnClickListener,
+        TextWatcher {
+    private static final String TAG = "BluetoothPinDialog";
+
+    private LocalBluetoothManager mLocalManager;
+    private String mAddress;
+    private EditText mPinView;
+    private Button mOkButton;
+
+    private static final String INSTANCE_KEY_PAIRING_CANCELED = "received_pairing_canceled";
+    private boolean mReceivedPairingCanceled;
+    
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!BluetoothIntent.PAIRING_CANCEL_ACTION.equals(intent.getAction())) {
+                return;
+            }
+            
+            String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+            if (address == null || address.equals(mAddress)) {
+                onReceivedPairingCanceled();
+            }
+        }
+    };
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        if (!intent.getAction().equals(BluetoothIntent.PAIRING_REQUEST_ACTION))
+        {
+            Log.e(TAG,
+                  "Error: this activity may be started only with intent " +
+                  BluetoothIntent.PAIRING_REQUEST_ACTION);
+            finish();
+        }
+        
+        mLocalManager = LocalBluetoothManager.getInstance(this);
+        mAddress = intent.getStringExtra(BluetoothIntent.ADDRESS);
+        
+        // Set up the "dialog"
+        final AlertController.AlertParams p = mAlertParams;
+        p.mIconId = android.R.drawable.ic_dialog_info;
+        p.mTitle = getString(R.string.bluetooth_pin_entry);
+        p.mView = createView();
+        p.mPositiveButtonText = getString(android.R.string.ok);
+        p.mPositiveButtonListener = this;
+        p.mNegativeButtonText = getString(android.R.string.cancel);
+        p.mNegativeButtonListener = this;
+        setupAlert();
+        
+        mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
+        mOkButton.setEnabled(false);
+
+        /*
+         * Leave this registered through pause/resume since we still want to
+         * finish the activity in the background if pairing is canceled.
+         */
+        registerReceiver(mReceiver, new IntentFilter(BluetoothIntent.PAIRING_CANCEL_ACTION));
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        
+        mReceivedPairingCanceled = savedInstanceState.getBoolean(INSTANCE_KEY_PAIRING_CANCELED);
+        if (mReceivedPairingCanceled) {
+            onReceivedPairingCanceled();
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        
+        outState.putBoolean(INSTANCE_KEY_PAIRING_CANCELED, mReceivedPairingCanceled);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        
+        unregisterReceiver(mReceiver);
+    }
+
+    private View createView() {
+        View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
+        
+        String name = mLocalManager.getLocalDeviceManager().getName(mAddress);
+        TextView messageView = (TextView) view.findViewById(R.id.message);
+        messageView.setText(getString(R.string.bluetooth_enter_pin_msg, name));
+        
+        mPinView = (EditText) view.findViewById(R.id.text);
+        mPinView.addTextChangedListener(this);
+        // Maximum of 10 characters in a PIN
+        mPinView.setFilters(new InputFilter[] { new LengthFilter(10) });
+        
+        return view;
+    }
+
+    public void afterTextChanged(Editable s) {
+        if (s.length() > 0) {
+            mOkButton.setEnabled(true);
+        }
+    }
+
+    private void onReceivedPairingCanceled() {
+        mReceivedPairingCanceled = true;
+        
+        TextView messageView = (TextView) findViewById(R.id.message);
+        messageView.setText(getString(R.string.bluetooth_pairing_error_message,
+                mLocalManager.getLocalDeviceManager().getName(mAddress)));
+        
+        mPinView.setVisibility(View.GONE);
+        mPinView.clearFocus();
+        mPinView.removeTextChangedListener(this);
+
+        mOkButton.setEnabled(true);
+        mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
+    }
+    
+    private void onPair(String pin) {
+        byte[] pinBytes = BluetoothDevice.convertPinToBytes(pin);
+        
+        if (pinBytes == null) {
+            return;
+        }
+        
+        mLocalManager.getBluetoothManager().setPin(mAddress, pinBytes);
+    }
+
+    private void onCancel() {
+        mLocalManager.getBluetoothManager().cancelBondProcess(mAddress);
+    }
+    
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                onPair(mPinView.getText().toString());
+                break;
+                
+            case DialogInterface.BUTTON_NEGATIVE:
+                onCancel();
+                break;
+        }
+    }
+
+    /* Not used */
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+    }
+
+    /* Not used */
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothPinRequest.java b/src/com/android/settings/bluetooth/BluetoothPinRequest.java
new file mode 100644
index 0000000..619052d
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothPinRequest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+
+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;
+import android.text.TextUtils;
+
+/**
+ * BluetoothPinRequest is a receiver for any Bluetooth pairing PIN request. It
+ * checks if the Bluetooth Settings is currently visible and brings up the PIN
+ * entry dialog. 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 {
+
+    public static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
+    
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (action.equals(BluetoothIntent.PAIRING_REQUEST_ACTION)) {
+
+            LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context);        
+        
+            String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+            Intent pinIntent = new Intent();
+            pinIntent.setClass(context, BluetoothPinDialog.class);
+            pinIntent.putExtra(BluetoothIntent.ADDRESS, address); 
+            pinIntent.setAction(BluetoothIntent.PAIRING_REQUEST_ACTION);
+            pinIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            
+            if (localManager.getForegroundActivity() != null) {
+                // Since the BT-related activity is in the foreground, just open the dialog
+                context.startActivity(pinIntent);
+                
+            } else {
+                
+                // Put up a notification that leads to the dialog
+                Resources res = context.getResources();
+                Notification notification = new Notification(
+                        android.R.drawable.stat_sys_data_bluetooth,
+                        res.getString(R.string.bluetooth_notif_ticker),
+                        System.currentTimeMillis());
+
+                PendingIntent pending = PendingIntent.getActivity(context, 0, 
+                        pinIntent, PendingIntent.FLAG_ONE_SHOT);
+                
+                String name = intent.getStringExtra(BluetoothIntent.NAME);
+                if (TextUtils.isEmpty(name)) {
+                    name = localManager.getLocalDeviceManager().getName(address);
+                }
+                
+                notification.setLatestEventInfo(context, 
+                        res.getString(R.string.bluetooth_notif_title), 
+                        res.getString(R.string.bluetooth_notif_message) + name, 
+                        pending);
+                notification.flags |= Notification.FLAG_AUTO_CANCEL;
+                
+                NotificationManager manager = (NotificationManager) 
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                manager.notify(NOTIFICATION_ID, notification);
+            }
+            
+        } else if (action.equals(BluetoothIntent.PAIRING_CANCEL_ACTION)) {
+            
+            // Remove the notification
+            NotificationManager manager = (NotificationManager) context
+                    .getSystemService(Context.NOTIFICATION_SERVICE);
+            manager.cancel(NOTIFICATION_ID);
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
new file mode 100644
index 0000000..5adada3
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.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.bluetooth;
+
+import com.android.settings.ProgressCategory;
+import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
+
+import java.util.List;
+import java.util.WeakHashMap;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+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.AdapterContextMenuInfo;
+
+/**
+ * BluetoothSettings is the Settings screen for Bluetooth configuration and
+ * connection management.
+ */
+public class BluetoothSettings extends PreferenceActivity
+        implements LocalBluetoothManager.Callback {
+
+    private static final String TAG = "BluetoothSettings";
+
+    private static final int MENU_SCAN = Menu.FIRST;
+    
+    private static final String KEY_BT_CHECKBOX = "bt_checkbox";
+    private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
+    private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
+    private static final String KEY_BT_NAME = "bt_name";
+    private static final String KEY_BT_SCAN = "bt_scan";
+    
+    private LocalBluetoothManager mLocalManager;
+    
+    private BluetoothEnabler mEnabler;
+    private BluetoothDiscoverableEnabler mDiscoverableEnabler;
+    
+    private BluetoothNamePreference mNamePreference;
+    
+    private ProgressCategory mDeviceList;
+    
+    private WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
+            new WeakHashMap<LocalBluetoothDevice, BluetoothDevicePreference>();
+    
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // TODO: put this in callback instead of receiving
+            onBluetoothStateChanged(mLocalManager.getBluetoothState());
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mLocalManager = LocalBluetoothManager.getInstance(this);
+        if (mLocalManager == null) finish();        
+        
+        addPreferencesFromResource(R.xml.bluetooth_settings);
+        
+        mEnabler = new BluetoothEnabler(
+                this,
+                (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
+        
+        mDiscoverableEnabler = new BluetoothDiscoverableEnabler(
+                this,
+                (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE));
+    
+        mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
+        
+        mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
+        
+        registerForContextMenu(getListView());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        // Repopulate (which isn't too bad since it's cached in the settings
+        // bluetooth manager
+        mDevicePreferenceMap.clear();
+        mDeviceList.removeAll();
+        addDevices();
+
+        mEnabler.resume();
+        mDiscoverableEnabler.resume();
+        mNamePreference.resume();
+        mLocalManager.registerCallback(this);
+        
+        mLocalManager.startScanning(false);
+
+        registerReceiver(mReceiver, 
+                new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+        
+        mLocalManager.setForegroundActivity(this);
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        mLocalManager.setForegroundActivity(null);
+        
+        unregisterReceiver(mReceiver);
+        
+        mLocalManager.unregisterCallback(this);
+        mNamePreference.pause();
+        mDiscoverableEnabler.pause();
+        mEnabler.pause();
+    }
+
+    private void addDevices() {
+        List<LocalBluetoothDevice> devices = mLocalManager.getLocalDeviceManager().getDevicesCopy();
+        for (LocalBluetoothDevice device : devices) {
+            onDeviceAdded(device);
+        }
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        menu.add(0, MENU_SCAN, 0, R.string.bluetooth_scan_for_devices)
+                .setIcon(com.android.internal.R.drawable.ic_menu_refresh)
+                .setAlphabeticShortcut('r');
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(MENU_SCAN).setEnabled(mLocalManager.getBluetoothManager().isEnabled());
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        
+            case MENU_SCAN:
+                mLocalManager.startScanning(true);
+                return true;
+                
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+            Preference preference) {
+
+        if (KEY_BT_SCAN.equals(preference.getKey())) {
+            mLocalManager.startScanning(true);
+            return true;
+        }
+        
+        if (preference instanceof BluetoothDevicePreference) {
+            BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
+            btPreference.getDevice().onClicked();
+            return true;
+        }
+        
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+    
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        LocalBluetoothDevice device = getDeviceFromMenuInfo(menuInfo);
+        if (device == null) return;
+        
+        device.onCreateContextMenu(menu);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        LocalBluetoothDevice device = getDeviceFromMenuInfo(item.getMenuInfo());
+        if (device == null) return false;
+        
+        device.onContextItemSelected(item);
+        return true;
+    }
+
+    private LocalBluetoothDevice getDeviceFromMenuInfo(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 BluetoothDevicePreference)) {
+            return null;
+        }
+
+        return ((BluetoothDevicePreference) pref).getDevice();
+    }
+    
+    public void onDeviceAdded(LocalBluetoothDevice device) {
+
+        if (mDevicePreferenceMap.get(device) != null) {
+            throw new IllegalStateException("Got onDeviceAdded, but device already exists");
+        }
+        
+        createDevicePreference(device);            
+    }
+
+    private void createDevicePreference(LocalBluetoothDevice device) {
+        BluetoothDevicePreference preference = new BluetoothDevicePreference(this, device);
+        mDeviceList.addPreference(preference);
+        mDevicePreferenceMap.put(device, preference);
+    }
+    
+    public void onDeviceDeleted(LocalBluetoothDevice device) {
+        BluetoothDevicePreference preference = mDevicePreferenceMap.remove(device);
+        if (preference != null) {
+            mDeviceList.removePreference(preference);
+        }
+    }
+
+    public void onScanningStateChanged(boolean started) {
+        mDeviceList.setProgress(started);
+    }
+    
+    private void onBluetoothStateChanged(ExtendedBluetoothState bluetoothState) {
+        // When bluetooth is enabled (and we are in the activity, which we are),
+        // we should start a scan
+        if (bluetoothState == ExtendedBluetoothState.ENABLED) {
+            mLocalManager.startScanning(false);
+        } else if (bluetoothState == ExtendedBluetoothState.DISABLED) {
+            mDeviceList.setProgress(false);
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
new file mode 100644
index 0000000..7dd1b70
--- /dev/null
+++ b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
@@ -0,0 +1,298 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * ConnectSpecificProfilesActivity presents the user with all of the profiles
+ * for a particular device, and allows him to choose which should be connected
+ * (or disconnected).
+ */
+public class ConnectSpecificProfilesActivity extends PreferenceActivity
+        implements LocalBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
+    private static final String TAG = "ConnectSpecificProfilesActivity";
+
+    private static final String KEY_ONLINE_MODE = "online_mode";
+    private static final String KEY_TITLE = "title";
+    private static final String KEY_PROFILE_CONTAINER = "profile_container";
+
+    public static final String EXTRA_ADDRESS = "address";
+    
+    private LocalBluetoothManager mManager;
+    private LocalBluetoothDevice mDevice;
+    
+    private PreferenceGroup mProfileContainer;
+    private CheckBoxPreference mOnlineModePreference;
+
+    /**
+     * The current mode of this activity and its checkboxes (either online mode
+     * or offline mode). In online mode, user interactions with the profile
+     * checkboxes will also toggle the profile's connectivity. In offline mode,
+     * they will not, and only the preferred state will be saved for the
+     * profile.
+     */
+    private boolean mOnlineMode;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        String address;
+        if (savedInstanceState != null) {
+            address = savedInstanceState.getString(EXTRA_ADDRESS);
+        } else {
+            Intent intent = getIntent();
+            address = intent.getStringExtra(EXTRA_ADDRESS);
+        }
+
+        if (TextUtils.isEmpty(address)) {
+            Log.w(TAG, "Activity started without address");
+            finish();
+        }
+        
+        mManager = LocalBluetoothManager.getInstance(this);
+        mDevice = mManager.getLocalDeviceManager().findDevice(address);
+        if (mDevice == null) {
+            Log.w(TAG, "Device not found, cannot connect to it");
+            finish();
+        }
+
+        addPreferencesFromResource(R.xml.bluetooth_device_advanced);
+        mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
+        
+        // Set the title of the screen
+        findPreference(KEY_TITLE).setTitle(
+                getString(R.string.bluetooth_device_advanced_title, mDevice.getName()));
+
+        // Listen for check/uncheck of the online mode checkbox
+        mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
+        mOnlineModePreference.setOnPreferenceChangeListener(this);
+        
+        // Add a preference for each profile
+        addPreferencesForProfiles();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        
+        outState.putString(EXTRA_ADDRESS, mDevice.getAddress());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        
+        mManager.setForegroundActivity(this);
+        mDevice.registerCallback(this);
+
+        refresh();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        
+        mDevice.unregisterCallback(this);
+        mManager.setForegroundActivity(null);
+    }
+
+    private void addPreferencesForProfiles() {
+        for (Profile profile : mDevice.getProfiles()) {
+            Preference pref = createProfilePreference(profile);
+            mProfileContainer.addPreference(pref);
+        }
+    }
+
+    /**
+     * Creates a checkbox preference for the particular profile. The key will be
+     * the profile's name.
+     * 
+     * @param profile The profile for which the preference controls.
+     * @return A preference that allows the user to choose whether this profile
+     *         will be connected to.
+     */
+    private CheckBoxPreference createProfilePreference(Profile profile) {
+        CheckBoxPreference pref = new CheckBoxPreference(this);
+        pref.setKey(profile.toString());
+        pref.setTitle(profile.localizedString);
+        pref.setPersistent(false);
+        pref.setOnPreferenceChangeListener(this);
+
+        refreshProfilePreference(pref, profile);
+        
+        return pref;
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        String key = preference.getKey();
+        if (TextUtils.isEmpty(key) || newValue == null) return true;
+        
+        if (key.equals(KEY_ONLINE_MODE)) {
+            onOnlineModeCheckedStateChanged((Boolean) newValue);
+            
+        } else {
+            Profile profile = getProfileOf(preference);
+            if (profile == null) return false;
+            onProfileCheckedStateChanged(profile, (Boolean) newValue);
+        }
+
+        return true;
+    }
+
+    private void onOnlineModeCheckedStateChanged(boolean checked) {
+        setOnlineMode(checked, true);
+    }
+    
+    private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
+        if (mOnlineMode) {
+            if (checked) {
+                mDevice.connect(profile);
+            } else {
+                mDevice.disconnect(profile);
+            }
+        }
+        
+        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                .getProfileManager(mManager, profile);
+        profileManager.setPreferred(mDevice.getAddress(), checked);
+    }
+    
+    public void onDeviceAttributesChanged(LocalBluetoothDevice device) {
+        refresh();
+    }
+
+    private void refresh() {
+        // We are in 'online mode' if we are connected, connecting, or disconnecting
+        setOnlineMode(mDevice.isConnected() || mDevice.isBusy(), false);
+        refreshProfiles();
+    }
+
+    /**
+     * Switches between online/offline mode.
+     * 
+     * @param onlineMode Whether to be in online mode, or offline mode.
+     * @param takeAction Whether to take action (i.e., connect or disconnect)
+     *            based on the new online mode.
+     */
+    private void setOnlineMode(boolean onlineMode, boolean takeAction) {
+        mOnlineMode = onlineMode;
+            
+        if (takeAction) {
+            if (onlineMode) {
+                mDevice.connect();
+            } else {
+                mDevice.disconnect();
+            }
+        }
+            
+        refreshOnlineModePreference();
+    }
+    
+    private void refreshOnlineModePreference() {
+        mOnlineModePreference.setChecked(mOnlineMode);
+
+        /* Gray out checkbox while connecting and disconnecting */
+        mOnlineModePreference.setEnabled(!mDevice.isBusy());
+
+        /**
+         * If the device is online, show status. Otherwise, show a summary that
+         * describes what the checkbox does.
+         */
+        mOnlineModePreference.setSummary(mOnlineMode ? mDevice.getSummary()
+                : R.string.bluetooth_device_advanced_online_mode_summary);
+    }
+    
+    private void refreshProfiles() {
+        for (Profile profile : mDevice.getProfiles()) {
+            CheckBoxPreference profilePref =
+                    (CheckBoxPreference) findPreference(profile.toString());
+            if (profilePref == null) {
+                profilePref = createProfilePreference(profile);
+                mProfileContainer.addPreference(profilePref);
+            } else {
+                refreshProfilePreference(profilePref, profile);
+            }
+        }
+    }
+    
+    private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
+        String address = mDevice.getAddress();
+        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                .getProfileManager(mManager, profile);
+        
+        int connectionStatus = profileManager.getConnectionStatus(address);
+
+        /* Gray out checkbox while connecting and disconnecting */
+        profilePref.setEnabled(!mDevice.isBusy());
+
+        profilePref.setSummary(getProfileSummary(profileManager, profile, address,
+                connectionStatus, mOnlineMode));
+        
+        profilePref.setChecked(profileManager.isPreferred(address));
+    }
+
+    private Profile getProfileOf(Preference pref) {
+        if (!(pref instanceof CheckBoxPreference)) return null;
+        String key = pref.getKey();
+        if (TextUtils.isEmpty(key)) return null;
+        
+        try {
+            return Profile.valueOf(pref.getKey());
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
+
+    private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
+            Profile profile, String address, int connectionStatus, boolean onlineMode) {
+        if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
+            return getProfileSummaryForSettingPreference(profile);
+        } else {
+            return profileManager.getSummary(address);
+        }
+    }
+    
+    /**
+     * Gets the summary that describes when checked, it will become a preferred profile.
+     * 
+     * @param profile The profile to get the summary for.
+     * @return The summary.
+     */
+    private static final int getProfileSummaryForSettingPreference(Profile profile) {
+        switch (profile) {
+            case A2DP:
+                return R.string.bluetooth_a2dp_profile_summary_use_for;
+            case HEADSET:
+                return R.string.bluetooth_headset_profile_summary_use_for;
+            default:
+                return 0;
+        }
+    }
+    
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
new file mode 100644
index 0000000..a488540
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
@@ -0,0 +1,576 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.IBluetoothDeviceCallback;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * LocalBluetoothDevice represents a remote Bluetooth device. It contains
+ * attributes of the device (such as the address, name, RSSI, etc.) and
+ * functionality that can be performed on the device (connect, pair, disconnect,
+ * etc.).
+ */
+public class LocalBluetoothDevice implements Comparable<LocalBluetoothDevice> {
+    private static final String TAG = "LocalBluetoothDevice";
+
+    private static final int CONTEXT_ITEM_CONNECT = Menu.FIRST + 1;
+    private static final int CONTEXT_ITEM_DISCONNECT = Menu.FIRST + 2;
+    private static final int CONTEXT_ITEM_UNPAIR = Menu.FIRST + 3;
+    private static final int CONTEXT_ITEM_CONNECT_ADVANCED = Menu.FIRST + 4;
+
+    private final String mAddress;
+    private String mName;
+    private short mRssi;
+    private int mBtClass = BluetoothClass.ERROR;
+
+    private List<Profile> mProfiles = new ArrayList<Profile>();
+
+    private boolean mVisible;
+
+    private final LocalBluetoothManager mLocalManager;
+
+    private List<Callback> mCallbacks = new ArrayList<Callback>();
+
+    /**
+     * When we connect to multiple profiles, we only want to display a single
+     * error even if they all fail. This tracks that state.
+     */
+    private boolean mIsConnectingErrorPossible;
+
+    LocalBluetoothDevice(Context context, String address) {
+        mLocalManager = LocalBluetoothManager.getInstance(context);
+        if (mLocalManager == null) {
+            throw new IllegalStateException(
+                    "Cannot use LocalBluetoothDevice without Bluetooth hardware");
+        }
+
+        mAddress = address;
+
+        fillData();
+    }
+
+    public void onClicked() {
+        int bondState = getBondState();
+
+        if (isConnected()) {
+            askDisconnect();
+        } else if (bondState == BluetoothDevice.BOND_BONDED) {
+            connect();
+        } else if (bondState == BluetoothDevice.BOND_NOT_BONDED) {
+            pair();
+        }
+    }
+
+    public void disconnect() {
+        for (Profile profile : mProfiles) {
+            disconnect(profile);
+        }
+    }
+
+    public void disconnect(Profile profile) {
+        LocalBluetoothProfileManager profileManager =
+                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+        int status = profileManager.getConnectionStatus(mAddress);
+        if (SettingsBtStatus.isConnectionStatusConnected(status)) {
+            profileManager.disconnect(mAddress);
+        }
+    }
+
+    public void askDisconnect() {
+        Context context = mLocalManager.getForegroundActivity();
+        if (context == null) {
+            // Cannot ask, since we need an activity context
+            disconnect();
+            return;
+        }
+
+        Resources res = context.getResources();
+
+        String name = getName();
+        if (TextUtils.isEmpty(name)) {
+            name = res.getString(R.string.bluetooth_device);
+        }
+        String message = res.getString(R.string.bluetooth_disconnect_blank, name);
+
+        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                disconnect();
+            }
+        };
+
+        AlertDialog ad = new AlertDialog.Builder(context)
+                .setTitle(getName())
+                .setMessage(message)
+                .setPositiveButton(android.R.string.ok, disconnectListener)
+                .setNegativeButton(android.R.string.cancel, null)
+                .show();
+    }
+
+    public void connect() {
+        if (!ensurePaired()) return;
+
+        // Reset the only-show-one-error-dialog tracking variable
+        mIsConnectingErrorPossible = true;
+
+        Context context = mLocalManager.getContext();
+        boolean hasAtLeastOnePreferredProfile = false;
+        for (Profile profile : mProfiles) {
+            LocalBluetoothProfileManager profileManager =
+                    LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+            if (profileManager.isPreferred(mAddress)) {
+                hasAtLeastOnePreferredProfile = true;
+                connectInt(profile);
+            }
+        }
+
+        if (!hasAtLeastOnePreferredProfile) {
+            connectAndPreferAllProfiles();
+        }
+    }
+
+    private void connectAndPreferAllProfiles() {
+        if (!ensurePaired()) return;
+
+        // Reset the only-show-one-error-dialog tracking variable
+        mIsConnectingErrorPossible = true;
+
+        Context context = mLocalManager.getContext();
+        for (Profile profile : mProfiles) {
+            LocalBluetoothProfileManager profileManager =
+                    LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+            profileManager.setPreferred(mAddress, true);
+            connectInt(profile);
+        }
+    }
+
+    public void connect(Profile profile) {
+        // Reset the only-show-one-error-dialog tracking variable
+        mIsConnectingErrorPossible = true;
+        connectInt(profile);
+    }
+
+    public void connectInt(Profile profile) {
+        if (!ensurePaired()) return;
+
+        LocalBluetoothProfileManager profileManager =
+                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+        int status = profileManager.getConnectionStatus(mAddress);
+        if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
+            if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
+                Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
+            }
+        }
+    }
+
+    public void showConnectingError() {
+        if (!mIsConnectingErrorPossible) return;
+        mIsConnectingErrorPossible = false;
+
+        mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
+                R.string.bluetooth_connecting_error_message);
+    }
+
+    private boolean ensurePaired() {
+        if (getBondState() == BluetoothDevice.BOND_NOT_BONDED) {
+            pair();
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public void pair() {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+
+        // Pairing is unreliable while scanning, so cancel discovery
+        if (manager.isDiscovering()) {
+            manager.cancelDiscovery();
+        }
+
+        if (!mLocalManager.getBluetoothManager().createBond(mAddress)) {
+            mLocalManager.showError(mAddress, R.string.bluetooth_error_title,
+                    R.string.bluetooth_pairing_error_message);
+        }
+    }
+
+    public void unpair() {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+
+        switch (getBondState()) {
+        case BluetoothDevice.BOND_BONDED:
+            manager.removeBond(mAddress);
+            break;
+
+        case BluetoothDevice.BOND_BONDING:
+            manager.cancelBondProcess(mAddress);
+            break;
+        }
+    }
+
+    private void fillData() {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+
+        fetchName();
+        fetchBtClass();
+
+        mVisible = false;
+
+        dispatchAttributesChanged();
+    }
+
+    public String getAddress() {
+        return mAddress;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public void refreshName() {
+        fetchName();
+        dispatchAttributesChanged();
+    }
+
+    private void fetchName() {
+        mName = mLocalManager.getBluetoothManager().getRemoteName(mAddress);
+
+        if (TextUtils.isEmpty(mName)) {
+            mName = mAddress;
+        }
+    }
+
+    public void refresh() {
+        dispatchAttributesChanged();
+    }
+
+    public boolean isVisible() {
+        return mVisible;
+    }
+
+    void setVisible(boolean visible) {
+        if (mVisible != visible) {
+            mVisible = visible;
+            dispatchAttributesChanged();
+        }
+    }
+
+    public int getBondState() {
+        return mLocalManager.getBluetoothManager().getBondState(mAddress);
+    }
+
+    void setRssi(short rssi) {
+        if (mRssi != rssi) {
+            mRssi = rssi;
+            dispatchAttributesChanged();
+        }
+    }
+
+    /**
+     * Checks whether we are connected to this device (any profile counts).
+     *
+     * @return Whether it is connected.
+     */
+    public boolean isConnected() {
+        for (Profile profile : mProfiles) {
+            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
+                    .getConnectionStatus(mAddress);
+            if (SettingsBtStatus.isConnectionStatusConnected(status)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean isBusy() {
+        for (Profile profile : mProfiles) {
+            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
+                    .getConnectionStatus(mAddress);
+            if (SettingsBtStatus.isConnectionStatusBusy(status)) {
+                return true;
+            }
+        }
+
+        if (getBondState() == BluetoothDevice.BOND_BONDING) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public int getBtClassDrawable() {
+
+        // First try looking at profiles
+        if (mProfiles.contains(Profile.A2DP)) {
+            return R.drawable.ic_bt_headphones_a2dp;
+        } else if (mProfiles.contains(Profile.HEADSET)) {
+            return R.drawable.ic_bt_headset_hfp;
+        }
+
+        // Fallback on class
+        switch (BluetoothClass.Device.Major.getDeviceMajor(mBtClass)) {
+        case BluetoothClass.Device.Major.COMPUTER:
+            return R.drawable.ic_bt_laptop;
+
+        case BluetoothClass.Device.Major.PHONE:
+            return R.drawable.ic_bt_cellphone;
+
+        default:
+            return 0;
+        }
+    }
+
+    /**
+     * Fetches a new value for the cached BT class.
+     */
+    private void fetchBtClass() {
+        mBtClass = mLocalManager.getBluetoothManager().getRemoteClass(mAddress);
+        mProfiles.clear();
+        LocalBluetoothProfileManager.fill(mBtClass, mProfiles);
+    }
+
+    /**
+     * Refreshes the UI for the BT class, including fetching the latest value
+     * for the class.
+     */
+    public void refreshBtClass() {
+        fetchBtClass();
+        dispatchAttributesChanged();
+    }
+
+    public int getSummary() {
+        // TODO: clean up
+        int oneOffSummary = getOneOffSummary();
+        if (oneOffSummary != 0) {
+            return oneOffSummary;
+        }
+
+        for (Profile profile : mProfiles) {
+            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                    .getProfileManager(mLocalManager, profile);
+            int connectionStatus = profileManager.getConnectionStatus(mAddress);
+
+            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
+                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
+                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
+                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
+            }
+        }
+
+        return SettingsBtStatus.getPairingStatusSummary(getBondState());
+    }
+
+    /**
+     * We have special summaries when particular profiles are connected. This
+     * checks for those states and returns an applicable summary.
+     *
+     * @return A one-off summary that is applicable for the current state, or 0.
+     */
+    private int getOneOffSummary() {
+        boolean isA2dpConnected = false, isHeadsetConnected = false, isConnecting = false;
+
+        if (mProfiles.contains(Profile.A2DP)) {
+            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                    .getProfileManager(mLocalManager, Profile.A2DP);
+            isConnecting = profileManager.getConnectionStatus(mAddress) ==
+                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+            isA2dpConnected = profileManager.isConnected(mAddress);
+        }
+
+        if (mProfiles.contains(Profile.HEADSET)) {
+            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                    .getProfileManager(mLocalManager, Profile.HEADSET);
+            isConnecting |= profileManager.getConnectionStatus(mAddress) ==
+                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+            isHeadsetConnected = profileManager.isConnected(mAddress);
+        }
+
+        if (isConnecting) {
+            // If any of these important profiles is connecting, prefer that
+            return SettingsBtStatus.getConnectionStatusSummary(
+                    SettingsBtStatus.CONNECTION_STATUS_CONNECTING);
+        } else if (isA2dpConnected && isHeadsetConnected) {
+            return R.string.bluetooth_summary_connected_to_a2dp_headset;
+        } else if (isA2dpConnected) {
+            return R.string.bluetooth_summary_connected_to_a2dp;
+        } else if (isHeadsetConnected) {
+            return R.string.bluetooth_summary_connected_to_headset;
+        } else {
+            return 0;
+        }
+    }
+
+    public List<Profile> getProfiles() {
+        return new ArrayList<Profile>(mProfiles);
+    }
+
+    public void onCreateContextMenu(ContextMenu menu) {
+        // No context menu if it is busy (none of these items are applicable if busy)
+        if (isBusy()) return;
+
+        int bondState = getBondState();
+        boolean isConnected = isConnected();
+        boolean hasProfiles = mProfiles.size() > 0;
+
+        menu.setHeaderTitle(getName());
+
+        if (isConnected) {
+            menu.add(0, CONTEXT_ITEM_DISCONNECT, 0, R.string.bluetooth_device_context_disconnect);
+        } else if (hasProfiles) {
+            // For connection action, show either "Connect" or "Pair & connect"
+            int connectString = (bondState == BluetoothDevice.BOND_NOT_BONDED)
+                    ? R.string.bluetooth_device_context_pair_connect
+                    : R.string.bluetooth_device_context_connect;
+            menu.add(0, CONTEXT_ITEM_CONNECT, 0, connectString);
+        }
+
+        if (bondState == BluetoothDevice.BOND_BONDED) {
+            // For unpair action, show either "Unpair" or "Disconnect & unpair"
+            int unpairString = isConnected
+                    ? R.string.bluetooth_device_context_disconnect_unpair
+                    : R.string.bluetooth_device_context_unpair;
+            menu.add(0, CONTEXT_ITEM_UNPAIR, 0, unpairString);
+
+            // Show the connection options item
+            menu.add(0, CONTEXT_ITEM_CONNECT_ADVANCED, 0,
+                    R.string.bluetooth_device_context_connect_advanced);
+        }
+    }
+
+    /**
+     * Called when a context menu item is clicked.
+     *
+     * @param item The item that was clicked.
+     */
+    public void onContextItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case CONTEXT_ITEM_DISCONNECT:
+                disconnect();
+                break;
+
+            case CONTEXT_ITEM_CONNECT:
+                connect();
+                break;
+
+            case CONTEXT_ITEM_UNPAIR:
+                mLocalManager.getBluetoothManager().disconnectRemoteDeviceAcl(mAddress);
+                unpair();
+                break;
+
+            case CONTEXT_ITEM_CONNECT_ADVANCED:
+                Intent intent = new Intent();
+                // Need an activity context to open this in our task
+                Context context = mLocalManager.getForegroundActivity();
+                if (context == null) {
+                    // Fallback on application context, and open in a new task
+                    context = mLocalManager.getContext();
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                }
+                intent.setClass(context, ConnectSpecificProfilesActivity.class);
+                intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_ADDRESS, mAddress);
+                context.startActivity(intent);
+                break;
+        }
+    }
+
+    public void registerCallback(Callback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.add(callback);
+        }
+    }
+
+    public void unregisterCallback(Callback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.remove(callback);
+        }
+    }
+
+    private void dispatchAttributesChanged() {
+        synchronized (mCallbacks) {
+            for (Callback callback : mCallbacks) {
+                callback.onDeviceAttributesChanged(this);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return mAddress;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof LocalBluetoothDevice)) {
+            throw new ClassCastException();
+        }
+
+        return mAddress.equals(((LocalBluetoothDevice) o).mAddress);
+    }
+
+    @Override
+    public int hashCode() {
+        return mAddress.hashCode();
+    }
+
+    public int compareTo(LocalBluetoothDevice another) {
+        int comparison;
+
+        // Connected above not connected
+        comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
+        if (comparison != 0) return comparison;
+
+        // Paired above not paired
+        comparison = (another.getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0) -
+            (getBondState() == BluetoothDevice.BOND_BONDED ? 1 : 0);
+        if (comparison != 0) return comparison;
+
+        // Visible above not visible
+        comparison = (another.mVisible ? 1 : 0) - (mVisible ? 1 : 0);
+        if (comparison != 0) return comparison;
+
+        // Stronger signal above weaker signal
+        comparison = another.mRssi - mRssi;
+        if (comparison != 0) return comparison;
+
+        // Fallback on name
+        return getName().compareTo(another.getName());
+    }
+
+    public interface Callback {
+        void onDeviceAttributesChanged(LocalBluetoothDevice device);
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
new file mode 100644
index 0000000..6bb2b4a
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
@@ -0,0 +1,229 @@
+/*
+ * 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.bluetooth;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothDevice;
+import android.util.Log;
+import android.widget.Toast;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * LocalBluetoothDeviceManager manages the set of remote Bluetooth devices.
+ */
+public class LocalBluetoothDeviceManager {
+    private static final String TAG = "LocalBluetoothDeviceManager";
+
+    final LocalBluetoothManager mLocalManager;
+    final List<Callback> mCallbacks;
+    
+    final List<LocalBluetoothDevice> mDevices = new ArrayList<LocalBluetoothDevice>();
+
+    public LocalBluetoothDeviceManager(LocalBluetoothManager localManager) {
+        mLocalManager = localManager;
+        mCallbacks = localManager.getCallbacks();
+        readPairedDevices();
+    }
+
+    private synchronized boolean readPairedDevices() {
+        BluetoothDevice manager = mLocalManager.getBluetoothManager();
+        String[] bondedAddresses = manager.listBonds();
+        if (bondedAddresses == null) return false;
+        
+        boolean deviceAdded = false;
+        for (String address : bondedAddresses) {
+            LocalBluetoothDevice device = findDevice(address);
+            if (device == null) {
+                device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
+                mDevices.add(device);
+                dispatchDeviceAdded(device);
+                deviceAdded = true;
+            }
+        }
+        
+        return deviceAdded;
+    }
+    
+    public synchronized List<LocalBluetoothDevice> getDevicesCopy() {
+        return new ArrayList<LocalBluetoothDevice>(mDevices);
+    }
+    
+    void onBluetoothStateChanged(boolean enabled) {
+        if (enabled) {
+            readPairedDevices();
+        }
+    }
+
+    public synchronized void onDeviceAppeared(String address, short rssi) {
+        boolean deviceAdded = false;
+        
+        LocalBluetoothDevice device = findDevice(address);
+        if (device == null) {
+            device = new LocalBluetoothDevice(mLocalManager.getContext(), address);
+            mDevices.add(device);
+            deviceAdded = true;
+        }
+        
+        device.setRssi(rssi);
+        device.setVisible(true);
+        
+        if (deviceAdded) {
+            dispatchDeviceAdded(device);
+        }
+    }
+    
+    public synchronized void onDeviceDisappeared(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device == null) return;
+        
+        device.setVisible(false);
+        checkForDeviceRemoval(device);
+    }
+    
+    private void checkForDeviceRemoval(LocalBluetoothDevice device) {
+        if (device.getBondState() == BluetoothDevice.BOND_NOT_BONDED &&
+                !device.isVisible()) {
+            // If device isn't paired, remove it altogether
+            mDevices.remove(device);
+            dispatchDeviceDeleted(device);
+        }            
+    }
+    
+    public synchronized void onDeviceNameUpdated(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device != null) {
+            device.refreshName();
+        }
+    }
+
+    public synchronized LocalBluetoothDevice findDevice(String address) {
+        
+        for (int i = mDevices.size() - 1; i >= 0; i--) {
+            LocalBluetoothDevice device = mDevices.get(i);
+            
+            if (device.getAddress().equals(address)) {
+                return device;
+            }
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Attempts to get the name of a remote device, otherwise returns the address.
+     * 
+     * @param address The address.
+     * @return The name, or if unavailable, the address.
+     */
+    public String getName(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        return device != null ? device.getName() : address;
+    }
+    
+    private void dispatchDeviceAdded(LocalBluetoothDevice device) {
+        synchronized (mCallbacks) {
+            for (Callback callback : mCallbacks) {
+                callback.onDeviceAdded(device);
+            }
+        }
+        
+        // TODO: divider between prev paired/connected and scanned
+    }
+    
+    private void dispatchDeviceDeleted(LocalBluetoothDevice device) {
+        synchronized (mCallbacks) {
+            for (Callback callback : mCallbacks) {
+                callback.onDeviceDeleted(device);
+            }
+        }
+    }
+
+    public synchronized void onBondingStateChanged(String address, int bondState) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device == null) {
+            if (!readPairedDevices()) {
+                Log.e(TAG, "Got bonding state changed for " + address +
+                        ", but we have no record of that device.");
+            }
+            return;
+        }
+
+        device.refresh();
+
+        if (bondState == BluetoothDevice.BOND_BONDED) {
+            // Auto-connect after pairing
+            device.connect();
+        }
+    }
+
+    /**
+     * Called when there is a bonding error.
+     * 
+     * @param address The address of the remote device.
+     * @param reason The reason, one of the error reasons from
+     *            BluetoothDevice.UNBOND_REASON_*
+     */
+    public synchronized void onBondingError(String address, int reason) {
+        mLocalManager.showError(address, R.string.bluetooth_error_title,
+                (reason == BluetoothDevice.UNBOND_REASON_AUTH_FAILED) ?
+                        R.string.bluetooth_pairing_pin_error_message :
+                        R.string.bluetooth_pairing_error_message);
+    }
+    
+    public synchronized void onProfileStateChanged(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device == null) return;
+        
+        device.refresh();
+    }
+    
+    public synchronized void onConnectingError(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device == null) return;
+        
+        /*
+         * Go through the device's delegate so we don't spam the user with
+         * errors connecting to different profiles, and instead make sure the
+         * user sees a single error for his single 'connect' action.
+         */
+        device.showConnectingError();
+    }
+    
+    public synchronized void onScanningStateChanged(boolean started) {
+        if (!started) return;
+        
+        // If starting a new scan, clear old visibility
+        for (int i = mDevices.size() - 1; i >= 0; i--) {
+            LocalBluetoothDevice device = mDevices.get(i);
+            device.setVisible(false);
+            checkForDeviceRemoval(device);
+        }
+    }
+    
+    public synchronized void onBtClassChanged(String address) {
+        LocalBluetoothDevice device = findDevice(address);
+        if (device != null) {
+            device.refreshBtClass();
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
new file mode 100644
index 0000000..4671fac
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -0,0 +1,279 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.util.Log;
+import android.widget.Toast;
+
+// TODO: have some notion of shutting down.  Maybe a minute after they leave BT settings?
+/**
+ * LocalBluetoothManager provides a simplified interface on top of a subset of
+ * the Bluetooth API.
+ */
+public class LocalBluetoothManager {
+    private static final String TAG = "LocalBluetoothManager";
+    static final boolean V = true;
+    
+    public static final String EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION =
+        "com.android.settings.bluetooth.intent.action.EXTENDED_BLUETOOTH_STATE_CHANGED";
+    private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
+    
+    private static LocalBluetoothManager INSTANCE;
+    /** Used when obtaining a reference to the singleton instance. */
+    private static Object INSTANCE_LOCK = new Object();
+    private boolean mInitialized;
+    
+    private Context mContext;
+    /** If a BT-related activity is in the foreground, this will be it. */
+    private Activity mForegroundActivity;
+    private AlertDialog mErrorDialog = null;
+
+    private BluetoothDevice mManager;
+
+    private LocalBluetoothDeviceManager mLocalDeviceManager;
+    private BluetoothEventRedirector mEventRedirector;
+    private BluetoothA2dp mBluetoothA2dp;
+    
+    public static enum ExtendedBluetoothState { ENABLED, ENABLING, DISABLED, DISABLING, UNKNOWN }
+    private ExtendedBluetoothState mState = ExtendedBluetoothState.UNKNOWN;
+
+    private List<Callback> mCallbacks = new ArrayList<Callback>();
+    
+    private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
+    private long mLastScan;
+    
+    public static LocalBluetoothManager getInstance(Context context) {
+        synchronized (INSTANCE_LOCK) {
+            if (INSTANCE == null) {
+                INSTANCE = new LocalBluetoothManager();
+            }
+            
+            if (!INSTANCE.init(context)) {
+                return null;
+            }
+            
+            return INSTANCE;
+        }
+    }
+
+    private boolean init(Context context) {
+        if (mInitialized) return true;
+        mInitialized = true;
+        
+        // This will be around as long as this process is
+        mContext = context.getApplicationContext();
+        
+        mManager = (BluetoothDevice) context.getSystemService(Context.BLUETOOTH_SERVICE);
+        if (mManager == null) {
+            return false;
+        }
+        
+        mLocalDeviceManager = new LocalBluetoothDeviceManager(this);
+
+        mEventRedirector = new BluetoothEventRedirector(this);
+        mEventRedirector.start();
+
+        mBluetoothA2dp = new BluetoothA2dp(context);
+
+        return true;
+    }
+    
+    public BluetoothDevice getBluetoothManager() {
+        return mManager;
+    }
+    
+    public Context getContext() {
+        return mContext;
+    }
+
+    public Activity getForegroundActivity() {
+        return mForegroundActivity;
+    }
+    
+    public void setForegroundActivity(Activity activity) {
+        if (mErrorDialog != null) {
+            mErrorDialog.dismiss();
+            mErrorDialog = null;
+        }
+        mForegroundActivity = activity;
+    }
+    
+    public SharedPreferences getSharedPreferences() {
+        return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+    }
+    
+    public LocalBluetoothDeviceManager getLocalDeviceManager() {
+        return mLocalDeviceManager;
+    }
+    
+    List<Callback> getCallbacks() {
+        return mCallbacks;
+    }
+    
+    public void registerCallback(Callback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.add(callback);
+        }
+    }
+    
+    public void unregisterCallback(Callback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.remove(callback);
+        }
+    }
+    
+    public void startScanning(boolean force) {
+        if (mManager.isDiscovering()) {
+            /*
+             * Already discovering, but give the callback that information.
+             * Note: we only call the callbacks, not the same path as if the
+             * scanning state had really changed (in that case the device
+             * manager would clear its list of unpaired scanned devices).
+             */ 
+            dispatchScanningStateChanged(true);
+        } else {
+            if (!force) {
+                // Don't scan more than frequently than SCAN_EXPIRATION_MS,
+                // unless forced
+                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
+                    return;
+                }
+
+                // If we are playing music, don't scan unless forced.
+                List<String> sinks = mBluetoothA2dp.listConnectedSinks();
+                if (sinks != null) {
+                    for (String address : sinks) {
+                        if (mBluetoothA2dp.getSinkState(address) == BluetoothA2dp.STATE_PLAYING) {
+                            return;
+                        }
+                    }
+                }
+            }
+            
+            if (mManager.startDiscovery(true)) {
+                mLastScan = System.currentTimeMillis();
+            }
+        }
+    }
+    
+    public ExtendedBluetoothState getBluetoothState() {
+        
+        if (mState == ExtendedBluetoothState.UNKNOWN) {
+            syncBluetoothState();
+        }
+            
+        return mState;
+    }
+    
+    void setBluetoothStateInt(ExtendedBluetoothState state) {
+        mState = state;
+        
+        /*
+         * TODO: change to callback method. originally it was broadcast to
+         * parallel the framework's method, but it just complicates things here.
+         */
+        // If this were a real API, I'd add as an extra
+        mContext.sendBroadcast(new Intent(EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+        
+        if (state == ExtendedBluetoothState.ENABLED || state == ExtendedBluetoothState.DISABLED) {
+            mLocalDeviceManager.onBluetoothStateChanged(state == ExtendedBluetoothState.ENABLED);
+        }
+    }
+    
+    private void syncBluetoothState() {
+        setBluetoothStateInt(mManager.isEnabled()
+                ? ExtendedBluetoothState.ENABLED
+                : ExtendedBluetoothState.DISABLED);
+    }
+
+    public void setBluetoothEnabled(boolean enabled) {
+        boolean wasSetStateSuccessful = enabled
+                ? mManager.enable()
+                : mManager.disable();
+                
+        if (wasSetStateSuccessful) {
+            setBluetoothStateInt(enabled
+                    ? ExtendedBluetoothState.ENABLING
+                    : ExtendedBluetoothState.DISABLING);
+        } else {
+            if (V) {
+                Log.v(TAG,
+                        "setBluetoothEnabled call, manager didn't return success for enabled: "
+                                + enabled);
+            }
+            
+            syncBluetoothState();
+        }
+    }
+    
+    /**
+     * @param started True if scanning started, false if scanning finished.
+     */
+    void onScanningStateChanged(boolean started) {
+        // TODO: have it be a callback (once we switch bluetooth state changed to callback)
+        mLocalDeviceManager.onScanningStateChanged(started);
+        dispatchScanningStateChanged(started);
+    }
+    
+    private void dispatchScanningStateChanged(boolean started) {
+        synchronized (mCallbacks) {
+            for (Callback callback : mCallbacks) {
+                callback.onScanningStateChanged(started);
+            }
+        }
+    }
+
+    public void showError(String address, int titleResId, int messageResId) {
+        LocalBluetoothDevice device = mLocalDeviceManager.findDevice(address);
+        if (device == null) return;
+
+        String name = device.getName();
+        String message = mContext.getString(messageResId, name);
+
+        if (mForegroundActivity != null) {
+            // Need an activity context to show a dialog
+            mErrorDialog = new AlertDialog.Builder(mForegroundActivity)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setTitle(titleResId)
+                .setMessage(message)
+                .setPositiveButton(android.R.string.ok, null)
+                .show();
+        } else {
+            // Fallback on a toast 
+            Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    public interface Callback {
+        void onScanningStateChanged(boolean started);
+        void onDeviceAdded(LocalBluetoothDevice device);
+        void onDeviceDeleted(LocalBluetoothDevice device);
+    }
+    
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
new file mode 100644
index 0000000..a1a2af6
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -0,0 +1,280 @@
+/*
+ * 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.bluetooth;
+
+import com.android.settings.R;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothClass;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.text.TextUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * LocalBluetoothProfileManager is an abstract class defining the basic
+ * functionality related to a profile.
+ */
+public abstract class LocalBluetoothProfileManager {
+
+    // TODO: close profiles when we're shutting down
+    private static Map<Profile, LocalBluetoothProfileManager> sProfileMap =
+            new HashMap<Profile, LocalBluetoothProfileManager>(); 
+    
+    protected LocalBluetoothManager mLocalManager;
+    
+    public static LocalBluetoothProfileManager getProfileManager(LocalBluetoothManager localManager,
+            Profile profile) {
+        
+        LocalBluetoothProfileManager profileManager;
+        
+        synchronized (sProfileMap) {
+            profileManager = sProfileMap.get(profile);
+            
+            if (profileManager == null) {
+                switch (profile) {
+                case A2DP:
+                    profileManager = new A2dpProfileManager(localManager);
+                    break;
+                    
+                case HEADSET:
+                    profileManager = new HeadsetProfileManager(localManager);
+                    break;
+                }
+                
+                sProfileMap.put(profile, profileManager);    
+            }
+        }
+        
+        return profileManager;
+    }
+
+    /**
+     * Temporary method to fill profiles based on a device's class.
+     * 
+     * @param btClass The class
+     * @param profiles The list of profiles to fill
+     */
+    public static void fill(int btClass, List<Profile> profiles) {
+        profiles.clear();
+
+        if (BluetoothA2dp.doesClassMatchSink(btClass)) {
+            profiles.add(Profile.A2DP);
+        }
+        
+        if (BluetoothHeadset.doesClassMatch(btClass)) {
+            profiles.add(Profile.HEADSET);
+        }
+    }
+
+    protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
+        mLocalManager = localManager;
+    }
+    
+    public abstract int connect(String address);
+    
+    public abstract int disconnect(String address);
+    
+    public abstract int getConnectionStatus(String address);
+
+    public abstract int getSummary(String address);
+
+    public abstract boolean isPreferred(String address);
+
+    public abstract void setPreferred(String address, boolean preferred);
+
+    public boolean isConnected(String address) {
+        return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(address));
+    }
+    
+    // TODO: int instead of enum
+    public enum Profile {
+        HEADSET(R.string.bluetooth_profile_headset),
+        A2DP(R.string.bluetooth_profile_a2dp);
+        
+        public final int localizedString;
+        
+        private Profile(int localizedString) {
+            this.localizedString = localizedString;
+        }
+    }
+
+    /**
+     * A2dpProfileManager is an abstraction for the {@link BluetoothA2dp} service. 
+     */
+    private static class A2dpProfileManager extends LocalBluetoothProfileManager {
+        private BluetoothA2dp mService;
+        
+        public A2dpProfileManager(LocalBluetoothManager localManager) {
+            super(localManager);
+            mService = new BluetoothA2dp(localManager.getContext());
+        }
+
+        @Override
+        public int connect(String address) {
+            return mService.connectSink(address);
+        }
+
+        @Override
+        public int disconnect(String address) {
+            return mService.disconnectSink(address);
+        }
+        
+        @Override
+        public int getConnectionStatus(String address) {
+            return convertState(mService.getSinkState(address));
+        }
+        
+        @Override
+        public int getSummary(String address) {
+            int connectionStatus = getConnectionStatus(address);
+
+            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
+                return R.string.bluetooth_a2dp_profile_summary_connected;
+            } else {
+                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
+            }
+        }
+
+        @Override
+        public boolean isPreferred(String address) {
+            return mService.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
+        }
+
+        @Override
+        public void setPreferred(String address, boolean preferred) {
+            mService.setSinkPriority(address,
+                    preferred ? BluetoothA2dp.PRIORITY_AUTO : BluetoothA2dp.PRIORITY_OFF);
+        }
+
+        private static int convertState(int a2dpState) {
+            switch (a2dpState) {
+            case BluetoothA2dp.STATE_CONNECTED:
+                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
+            case BluetoothA2dp.STATE_CONNECTING:
+                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+            case BluetoothA2dp.STATE_DISCONNECTED:
+                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
+            case BluetoothA2dp.STATE_DISCONNECTING:
+                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
+            case BluetoothA2dp.STATE_PLAYING:
+                return SettingsBtStatus.CONNECTION_STATUS_ACTIVE;
+            default:
+                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
+            }
+        }
+    }
+    
+    /**
+     * HeadsetProfileManager is an abstraction for the {@link BluetoothHeadset} service. 
+     */
+    private static class HeadsetProfileManager extends LocalBluetoothProfileManager
+            implements BluetoothHeadset.ServiceListener {
+        private BluetoothHeadset mService;
+        private Handler mUiHandler = new Handler();
+        
+        public HeadsetProfileManager(LocalBluetoothManager localManager) {
+            super(localManager);
+            mService = new BluetoothHeadset(localManager.getContext(), this);
+        }
+
+        public void onServiceConnected() {
+            // This could be called on a non-UI thread, funnel to UI thread.
+            mUiHandler.post(new Runnable() {
+                public void run() {
+                    /*
+                     * We just bound to the service, so refresh the UI of the
+                     * headset device.
+                     */
+                    String address = mService.getHeadsetAddress();
+                    if (TextUtils.isEmpty(address)) return;
+                    mLocalManager.getLocalDeviceManager().onProfileStateChanged(address);
+                }
+            });
+        }
+
+        public void onServiceDisconnected() {
+        }
+
+        @Override
+        public int connect(String address) {
+            // Since connectHeadset fails if already connected to a headset, we
+            // disconnect from any headset first
+            mService.disconnectHeadset();
+            return mService.connectHeadset(address)
+                    ? BluetoothError.SUCCESS : BluetoothError.ERROR;
+        }
+
+        @Override
+        public int disconnect(String address) {
+            if (mService.getHeadsetAddress().equals(address)) {
+                return mService.disconnectHeadset() ? BluetoothError.SUCCESS : BluetoothError.ERROR;
+            } else {
+                return BluetoothError.SUCCESS;
+            }
+        }
+        
+        @Override
+        public int getConnectionStatus(String address) {
+            String headsetAddress = mService.getHeadsetAddress();
+            return headsetAddress != null && headsetAddress.equals(address)
+                    ? convertState(mService.getState())
+                    : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
+        }
+        
+        @Override
+        public int getSummary(String address) {
+            int connectionStatus = getConnectionStatus(address);
+            
+            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
+                return R.string.bluetooth_headset_profile_summary_connected;
+            } else {
+                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
+            }
+        }
+
+        @Override
+        public boolean isPreferred(String address) {
+            return mService.getPriority(address) > BluetoothHeadset.PRIORITY_OFF;
+        }
+
+        @Override
+        public void setPreferred(String address, boolean preferred) {
+            mService.setPriority(address,
+                    preferred ? BluetoothHeadset.PRIORITY_AUTO : BluetoothHeadset.PRIORITY_OFF);
+        }
+
+        private static int convertState(int headsetState) {
+            switch (headsetState) {
+            case BluetoothHeadset.STATE_CONNECTED:
+                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
+            case BluetoothHeadset.STATE_CONNECTING:
+                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
+            case BluetoothHeadset.STATE_DISCONNECTED:
+                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
+            default:
+                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/SettingsBtStatus.java b/src/com/android/settings/bluetooth/SettingsBtStatus.java
new file mode 100644
index 0000000..d2cbef5
--- /dev/null
+++ b/src/com/android/settings/bluetooth/SettingsBtStatus.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.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+import com.android.settings.R;
+
+/**
+ * SettingsBtStatus is a helper class that contains constants for various status
+ * codes.
+ */
+public class SettingsBtStatus {
+    private static final String TAG = "SettingsBtStatus";
+   
+    // Connection status
+    
+    public static final int CONNECTION_STATUS_UNKNOWN = 0;
+    public static final int CONNECTION_STATUS_ACTIVE = 1;
+    /** Use {@link #isConnected} to check for the connected state */
+    public static final int CONNECTION_STATUS_CONNECTED = 2;
+    public static final int CONNECTION_STATUS_CONNECTING = 3;
+    public static final int CONNECTION_STATUS_DISCONNECTED = 4;
+    public static final int CONNECTION_STATUS_DISCONNECTING = 5;
+
+    public static final int getConnectionStatusSummary(int connectionStatus) {
+        switch (connectionStatus) {
+        case CONNECTION_STATUS_ACTIVE:
+            return R.string.bluetooth_connected;
+        case CONNECTION_STATUS_CONNECTED:
+            return R.string.bluetooth_connected;
+        case CONNECTION_STATUS_CONNECTING:
+            return R.string.bluetooth_connecting;
+        case CONNECTION_STATUS_DISCONNECTED:
+            return R.string.bluetooth_disconnected;
+        case CONNECTION_STATUS_DISCONNECTING:
+            return R.string.bluetooth_disconnecting;
+        case CONNECTION_STATUS_UNKNOWN:
+            return R.string.bluetooth_unknown;
+        default:
+            return 0;
+        }
+    }
+    
+    public static final boolean isConnectionStatusConnected(int connectionStatus) {
+        return connectionStatus == CONNECTION_STATUS_ACTIVE
+                || connectionStatus == CONNECTION_STATUS_CONNECTED;
+    }
+    
+    public static final boolean isConnectionStatusBusy(int connectionStatus) {
+        return connectionStatus == CONNECTION_STATUS_CONNECTING
+                || connectionStatus == CONNECTION_STATUS_DISCONNECTING;
+    }
+    
+    public static final int getPairingStatusSummary(int bondState) {
+        switch (bondState) {
+        case BluetoothDevice.BOND_BONDED:
+            return R.string.bluetooth_paired;
+        case BluetoothDevice.BOND_BONDING:
+            return R.string.bluetooth_pairing;
+        case BluetoothDevice.BOND_NOT_BONDED:
+            return R.string.bluetooth_not_connected;
+        default:
+            return 0;
+        }
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
new file mode 100644
index 0000000..75a84b7
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -0,0 +1,218 @@
+/*
+ * 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.IBinder;
+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 android.util.Log;
+
+import com.android.settings.R;
+
+import java.io.File;
+import java.text.DecimalFormat;
+
+public class Memory extends PreferenceActivity {
+    
+    private static final String TAG = "Memory";
+
+    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 static final String MEMORY_SD_FORMAT = "memory_sd_format";
+    private Resources mRes;
+
+    private Preference mSdSize;
+    private Preference mSdAvail;
+    private Preference mSdUnmount;
+    private Preference mSdFormat;
+    
+    // Access using getMountService()
+    private IMountService mMountService = null;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        
+        addPreferencesFromResource(R.xml.device_info_memory);
+        
+        mRes = getResources();
+        mSdSize = findPreference(MEMORY_SD_SIZE);
+        mSdAvail = findPreference(MEMORY_SD_AVAIL);
+        mSdUnmount = findPreference(MEMORY_SD_UNMOUNT);
+        mSdFormat = findPreference(MEMORY_SD_FORMAT);
+    }
+    
+    @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_UNMOUNTABLE);
+        intentFilter.addAction(Intent.ACTION_MEDIA_NOFS);
+        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);
+    }
+    
+    private synchronized IMountService getMountService() {
+       if (mMountService == null) {
+           IBinder service = ServiceManager.getService("mount");
+           if (service != null) {
+               mMountService = IMountService.Stub.asInterface(service);
+           } else {
+               Log.e(TAG, "Can't get mount service");
+           }
+       }
+       return mMountService;
+    }
+    
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mSdUnmount) {
+            unmount();
+            return true;
+        } else if (preference == mSdFormat) {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setClass(this, com.android.settings.MediaFormat.class);
+            startActivity(intent);
+            return true;
+        }
+        
+        return false;
+    }
+     
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            updateMemoryStatus();
+        }
+    };
+
+    private void unmount() {
+        IMountService mountService = getMountService();
+        try {
+            if (mountService != null) {
+                mountService.unmountMedia(Environment.getExternalStorageDirectory().toString());
+            } else {
+                Log.e(TAG, "Mount service is null, can't unmount");
+            }
+        } 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);
+        }
+ 
+        mSdFormat.setEnabled(false);
+
+        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);
+
+            if (status.equals(Environment.MEDIA_UNMOUNTED) ||
+                status.equals(Environment.MEDIA_NOFS) ||
+                status.equals(Environment.MEDIA_UNMOUNTABLE) ) {
+                mSdFormat.setEnabled(true);
+            }
+
+            
+        }
+
+        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..4132ed5
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -0,0 +1,392 @@
+/*
+ * 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.os.NetStat;
+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
+ * # 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 String KEY_NETWORK_TRAFFIC_STATS = "network_traffic_stats";
+    private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
+    private static final int EVENT_SERVICE_STATE_CHANGED = 300;
+
+    private static final int EVENT_UPDATE_STATS = 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_UPDATE_STATS:
+                    status.updateTimes();
+                    status.setNetworkTrafficStats();
+                    sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 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("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.sendEmptyMessage(EVENT_UPDATE_STATS);
+    }
+    
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        mPhoneStateReceiver.unregisterIntent();
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+        unregisterReceiver(mBatteryInfoReceiver);
+        mHandler.removeMessages(EVENT_UPDATE_STATS);
+    }
+
+    /**
+     * @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 (TextUtils.isEmpty(text)) {
+            text = sUnknown;
+        }
+        
+        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));
+        }
+    }
+
+    private void setNetworkTrafficStats() {
+        long txPkts = NetStat.getTotalTxPkts();
+        long txBytes = NetStat.getTotalTxBytes();
+        long rxPkts = NetStat.getTotalRxPkts();
+        long rxBytes = NetStat.getTotalRxBytes();
+
+        Preference netStatsPref = findPreference(KEY_NETWORK_TRAFFIC_STATS);
+        netStatsPref.setSummary(getString(R.string.status_network_traffic_summary,
+                txPkts, txBytes, rxPkts, rxBytes));
+    }
+
+    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..7152abb
--- /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(com.android.internal.R.drawable.ic_menu_archive);
+        menu.add(0, DISPLAY_MODE_SHORTCUT, 0, R.string.quick_launch_display_mode_shortcuts)
+                .setIcon(com.android.internal.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..4d44524
--- /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 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.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.provider.Settings.Bookmarks;
+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;
+
+import com.android.settings.R;
+
+/**
+ * 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 int COLUMN_INTENT = 2;
+    private static final String[] sProjection = new String[] {
+            Bookmarks.SHORTCUT, Bookmarks.TITLE, Bookmarks.INTENT
+    };
+    private static final String sShortcutSelection = Bookmarks.SHORTCUT + "=?";
+    
+    private Handler mUiHandler = new Handler();
+    
+    private static final String DEFAULT_BOOKMARK_FOLDER = "@quicklaunch";
+    /** 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 PreferenceGroup mShortcutGroup;
+    /** 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);
+        
+        mShortcutGroup = (PreferenceGroup) 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(android.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, data);
+            
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
+        }
+    }
+
+    private void updateShortcut(char shortcut, Intent intent) {
+        // Update the bookmark for a shortcut
+        // Pass an empty title so it gets resolved each time this bookmark is
+        // displayed (since the locale could change after we insert into the provider).
+        Bookmarks.add(getContentResolver(), intent, "", 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);
+        mShortcutGroup.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.getMaxKeyCode() - 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(Bookmarks.getTitle(this, c));
+            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..917ed96
--- /dev/null
+++ b/src/com/android/settings/wifi/AccessPointDialog.java
@@ -0,0 +1,600 @@
+/*
+ * 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.format.Formatter;
+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, Formatter.formatIpAddress(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;
+    }
+    
+
+    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..c224954
--- /dev/null
+++ b/src/com/android/settings/wifi/AccessPointState.java
@@ -0,0 +1,879 @@
+/*
+ * 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)) {
+                if (mPassword.length() == 64 && isHex(mPassword)) {
+                    // Goes unquoted as hex
+                    config.preSharedKey = mPassword;
+                } else {
+                    // Goes quoted as ASCII
+                    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;
+        }
+        
+        return isHex(wepKey);
+    }
+    
+    private static boolean isHex(String key) {
+        for (int i = key.length() - 1; i >= 0; i--) {
+            final char c = key.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/AdvancedSettings.java b/src/com/android/settings/wifi/AdvancedSettings.java
new file mode 100644
index 0000000..323d5c7
--- /dev/null
+++ b/src/com/android/settings/wifi/AdvancedSettings.java
@@ -0,0 +1,274 @@
+/*
+ * 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.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.provider.Settings;
+import android.provider.Settings.System;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+public class AdvancedSettings extends PreferenceActivity
+        implements Preference.OnPreferenceChangeListener {
+
+    private static final String KEY_MAC_ADDRESS = "mac_address";
+    private static final String KEY_USE_STATIC_IP = "use_static_ip";
+    private static final String KEY_NUM_CHANNELS = "num_channels";
+    private static final String KEY_SLEEP_POLICY = "sleep_policy";
+    
+    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.wifi_advanced_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();
+        initNumChannelsPreference();
+        initSleepPolicyPreference();
+        refreshMacAddress();
+    }
+
+    private void initNumChannelsPreference() {
+        ListPreference pref = (ListPreference) findPreference(KEY_NUM_CHANNELS);
+        pref.setOnPreferenceChangeListener(this);
+
+        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        /*
+         * Generate the list of valid channel counts to show in the ListPreference.
+         * The values are numerical, so the only text to be localized is the
+         * "channel_word" resource.
+         */
+        int[] validChannelCounts = wifiManager.getValidChannelCounts();
+        if (validChannelCounts == null) {
+            Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+                           Toast.LENGTH_SHORT).show();
+            pref.setEnabled(false);
+            return;
+        }
+        String[] entries = new String[validChannelCounts.length];
+        String[] entryValues = new String[validChannelCounts.length];
+
+        for (int i = 0; i < validChannelCounts.length; i++) {
+            entryValues[i] = String.valueOf(validChannelCounts[i]);
+            entries[i] = getString(R.string.wifi_setting_num_channels_channel_phrase,
+                                   validChannelCounts[i]);
+        }
+        pref.setEntries(entries);
+        pref.setEntryValues(entryValues);
+        pref.setEnabled(true);
+        int numChannels = wifiManager.getNumAllowedChannels();
+        if (numChannels >= 0) {
+            pref.setValue(String.valueOf(numChannels));
+        }
+    }
+    
+    private void initSleepPolicyPreference() {
+        ListPreference pref = (ListPreference) findPreference(KEY_SLEEP_POLICY);
+        pref.setOnPreferenceChangeListener(this);
+        int value = Settings.System.getInt(getContentResolver(),
+                Settings.System.WIFI_SLEEP_POLICY,Settings. System.WIFI_SLEEP_POLICY_DEFAULT);
+        pref.setValue(String.valueOf(value));
+    }
+
+    @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 key = preference.getKey();
+        if (key == null) return true;
+
+        if (key.equals(KEY_NUM_CHANNELS)) {
+            try {
+                int numChannels = Integer.parseInt((String) newValue);
+                WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+                if (!wifiManager.setNumAllowedChannels(numChannels)) {
+                    Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+                            Toast.LENGTH_SHORT).show();
+                }
+            } catch (NumberFormatException e) {
+                Toast.makeText(this, R.string.wifi_setting_num_channels_error,
+                        Toast.LENGTH_SHORT).show();
+                return false;
+            }
+            
+        } else if (key.equals(KEY_SLEEP_POLICY)) {
+            try {
+                Settings.System.putInt(getContentResolver(),
+                        Settings.System.WIFI_SLEEP_POLICY, Integer.parseInt(((String) newValue)));
+            } catch (NumberFormatException e) {
+                Toast.makeText(this, R.string.wifi_setting_sleep_policy_error,
+                        Toast.LENGTH_SHORT).show();
+                return false;
+            }
+                
+        } else {
+            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());
+        }
+    }
+    
+    private void refreshMacAddress() {
+        WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
+        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+
+        Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS);
+        String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
+        wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 
+                : getString(R.string.status_unavailable));
+    }
+    
+}
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..b0857d2
--- /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 android.provider.Settings.Secure#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.Secure.getInt(mContext.getContentResolver(),
+            Settings.Secure.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..d2683c0
--- /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.Secure.getInt(getContentResolver(),
+            Settings.Secure.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(android.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, AdvancedSettings.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.Secure.putInt(getContentResolver(),
+                Settings.Secure.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);
+    }
+    
+}
