auto import from //depot/cupcake/@137055
diff --git a/src/com/android/settings/ApnSettings.java b/src/com/android/settings/ApnSettings.java
index aab529c..87e3412 100644
--- a/src/com/android/settings/ApnSettings.java
+++ b/src/com/android/settings/ApnSettings.java
@@ -16,60 +16,86 @@
 
 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.PreferenceCategory;
 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);    
+
+        addPreferencesFromResource(R.xml.apn_settings);
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        
-        fillList();
+
+        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);
@@ -79,17 +105,20 @@
                 pref.setPersistent(false);
                 apnList.addPreference(pref);
             }
-            
+
             mCursor.moveToNext();
         }
     }
-    
+
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-        menu.add(0, MENU_NEW, 0, 
+        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;
     }
 
@@ -99,14 +128,18 @@
         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());
@@ -114,4 +147,83 @@
         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/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index 3097e96..47fc07f 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -292,6 +292,7 @@
 
         mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
         mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());        
 
         mFooterText = (TextView) findViewById(R.id.footerText);
 
diff --git a/src/com/android/settings/InstalledAppDetails.java b/src/com/android/settings/InstalledAppDetails.java
index eee8b75..327874b 100644
--- a/src/com/android/settings/InstalledAppDetails.java
+++ b/src/com/android/settings/InstalledAppDetails.java
@@ -444,7 +444,7 @@
                 Uri packageURI = Uri.parse("package:"+packageName);
                 Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
                 startActivity(uninstallIntent);
-                setIntentAndFinish(true, false);
+                setIntentAndFinish(true, true);
             }
         } else if(v == mActivitiesButton) {
             mPm.clearPackagePreferredActivities(packageName);
diff --git a/src/com/android/settings/LanguageSettings.java b/src/com/android/settings/LanguageSettings.java
index b406df6..8463d26 100644
--- a/src/com/android/settings/LanguageSettings.java
+++ b/src/com/android/settings/LanguageSettings.java
@@ -17,14 +17,24 @@
 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.preference.CheckBoxPreference;
+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 {
     
@@ -48,6 +58,18 @@
             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);
@@ -71,10 +93,117 @@
                                               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], 
@@ -82,6 +211,36 @@
                 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/ManageApplications.java b/src/com/android/settings/ManageApplications.java
index 512e547..74957ed 100644
--- a/src/com/android/settings/ManageApplications.java
+++ b/src/com/android/settings/ManageApplications.java
@@ -19,6 +19,7 @@
 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;
@@ -31,6 +32,7 @@
 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;
@@ -86,8 +88,6 @@
  *  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.
- *  This activity passes the package name and size information to the 
- *  InstalledAppDetailsActivity to avoid recomputation of the package size information.
  */
 public class ManageApplications extends ListActivity implements
         OnItemClickListener, DialogInterface.OnCancelListener,
@@ -95,13 +95,12 @@
     // TAG for this activity
     private static final String TAG = "ManageApplications";
     
-    // log information boolean
+    // 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_PKG_SIZE = APP_PKG_PREFIX+"size";
     public static final String APP_CHG = APP_PKG_PREFIX+"changed";
     
     // attribute name used in receiver for tagging names of added/deleted packages
@@ -122,7 +121,7 @@
     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.Builder mAlertDlgBuilder;
+    AlertDialog mAlertDlg;
     // sort order
     private int mSortOrder = SORT_ORDER_ALPHA;
     // Filter value
@@ -157,7 +156,8 @@
     private Drawable mDefaultAppIcon;
     
     // temporary dialog displayed while the application info loads
-    private ProgressDialog mLoadingDlg = null;
+    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;
@@ -196,6 +196,12 @@
     // 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
@@ -242,8 +248,6 @@
             switch (msg.what) {
             case INIT_PKG_INFO:
                 if(localLOGV) Log.i(TAG, "Message INIT_PKG_INFO");
-                setProgressBarIndeterminateVisibility(true);
-                mComputeIndex = 0;
                 // Retrieve the package list and init some structures
                 initAppList(mFilterApps);
                 mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
@@ -308,6 +312,7 @@
                     } else {
                         // end computation here
                         mComputeSizes = true;
+                        mFirst = true;
                         mAppInfoAdapter.sortList(mSortOrder);
                         mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
                     }
@@ -408,8 +413,13 @@
                 } 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 creating the list
-                    createListView();
+                    // 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) {
@@ -423,6 +433,8 @@
         }
     };
     
+    
+    
     private void doneLoadingData() {
         setProgressBarIndeterminateVisibility(false);
     }
@@ -487,13 +499,14 @@
     
     // 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 = new AppInfoAdapter(this, appList);       
-        // register receiver
-        mReceiver.registerReceiver();
+        mAppInfoAdapter.resetAppList(filterOption, appList);
     }
     
     // Utility method to start a thread to read application labels and icons
@@ -519,23 +532,13 @@
     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);
         }
     }
-
-    private void createListView() {
-        dismissLoadingMsg();
-        // get list and set listeners and adapter
-        ListView lv= (ListView) findViewById(android.R.id.list);
-        lv.setAdapter(mAppInfoAdapter);
-        lv.setOnItemClickListener(this);
-        lv.setSaveEnabled(true);
-        lv.setItemsCanFocus(true);
-        lv.setOnItemClickListener(this);
-        showEmptyViewIfListEmpty();
-    }
     
     // internal structure used to track added and deleted packages when
     // the activity has focus
@@ -868,7 +871,11 @@
                 AppInfo pInfo = iconMap.get(info.packageName);
                 if(pInfo != null) {
                     AppInfo aInfo = mAppPropMap.get(info.packageName);
-                    aInfo.refreshIcon(pInfo);
+                    if (aInfo != null) {
+                        aInfo.refreshIcon(pInfo);
+                    } else {
+                        mAppPropMap.put(info.packageName, pInfo);
+                    }
                     changed = true;
                 }
             }
@@ -1114,12 +1121,6 @@
         requestWindowFeature(Window.FEATURE_PROGRESS);
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         setContentView(R.layout.compute_sizes);
-        // init mLoadingDlg
-        mLoadingDlg = new ProgressDialog(this);
-        mLoadingDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
-        mLoadingDlg.setMessage(getText(R.string.loading));
-        mLoadingDlg.setIndeterminate(true);        
-        mLoadingDlg.setOnCancelListener(this);
         mDefaultAppIcon =Resources.getSystem().getDrawable(
                 com.android.internal.R.drawable.sym_def_app_icon);
         mInvalidSizeStr = getText(R.string.invalid_size_value);
@@ -1129,29 +1130,51 @@
         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();
     }
     
-    private void showLoadingMsg() {
-        if (mLoadingDlg != null) {
-            if(localLOGV) Log.i(TAG, "Displaying Loading message");
-            mLoadingDlg.show();
+    @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 ((mLoadingDlg != null) && (mLoadingDlg.isShowing())) {
-            if(localLOGV) Log.i(TAG, "Dismissing Loading message");
-            mLoadingDlg.dismiss();
-        }
+        if(localLOGV) Log.i(TAG, "Dismissing Loading message");
+        dismissDialog(DLG_LOADING);
     }
     
     @Override
     public void onStart() {
         super.onStart();
-        showLoadingMsg();
         // Create a thread to load resources
         mResourceThread = new ResourceLoaderThread();
         sendMessageToHandler(INIT_PKG_INFO);
+        // register receiver
+        mReceiver.registerReceiver();
     }
 
     @Override
@@ -1164,6 +1187,12 @@
         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
      */
@@ -1191,13 +1220,11 @@
     }
      
     // utility method used to start sub activity
-    private void startApplicationDetailsActivity(ApplicationInfo info, PackageStats ps) {
+    private void startApplicationDetailsActivity() {
         // Create intent to start new activity
         Intent intent = new Intent(Intent.ACTION_VIEW);
         intent.setClass(this, InstalledAppDetails.class);
-        mCurrentPkgName = info.packageName;
         intent.putExtra(APP_PKG_NAME, mCurrentPkgName);
-        intent.putExtra(APP_PKG_SIZE, ps);
         // start new activity to display extended information
         startActivityForResult(intent, INSTALLED_APP_DETAILS);
     }
@@ -1215,12 +1242,12 @@
     
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        if (mComputeSizes) {
+        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;
     }
 
@@ -1230,16 +1257,17 @@
         if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
             sendMessageToHandler(REORDER_LIST, menuId);
         } else if (menuId == FILTER_OPTIONS) {
-            if (mAlertDlgBuilder == null) {
-                mAlertDlgBuilder = 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);
+            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();
             }
-            mAlertDlgBuilder.show();
+            mAlertDlg.show();
         }
         return true;
     }
@@ -1247,12 +1275,12 @@
     public void onItemClick(AdapterView<?> parent, View view, int position,
             long id) {
         ApplicationInfo info = (ApplicationInfo)mAppInfoAdapter.getItem(position);
-        startApplicationDetailsActivity(info, mAppInfoAdapter.getAppStats(info.packageName));
+        mCurrentPkgName = info.packageName;
+        startApplicationDetailsActivity();
     }
     
-    // onCancel call back for dialog thats displayed when data is being loaded
+    // Finish the activity if the user presses the back button to cancel the activity
     public void onCancel(DialogInterface dialog) {
-        mLoadingDlg = null;
         finish();
     }
 
@@ -1273,6 +1301,7 @@
         default:
             return;
         }
+        mAlertDlg.dismiss();
         sendMessageToHandler(REORDER_LIST, newOption);
     }
 }
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index 89d5279..aeddcf7 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -21,10 +21,10 @@
 import android.app.ListActivity;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 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;
@@ -198,6 +198,9 @@
     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)
diff --git a/src/com/android/settings/battery_history/BatteryHistory.java b/src/com/android/settings/battery_history/BatteryHistory.java
index 4265ac6..dcf6cbf 100644
--- a/src/com/android/settings/battery_history/BatteryHistory.java
+++ b/src/com/android/settings/battery_history/BatteryHistory.java
@@ -63,8 +63,8 @@
     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 WAKE_LOCKS = 4;
-    private static final int SCREEN_ON = 5;
+    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;
@@ -83,9 +83,10 @@
     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, mHaveScreenOnTime;
+            mHaveWakelockUsage, mHaveMiscUsage;
     
     private LinearLayout mGraphLayout;
     private LinearLayout mTextLayout;
@@ -150,6 +151,10 @@
         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();
@@ -209,9 +214,11 @@
     class CpuUsage extends Graphable {
         String mProcess;
         double[] mUsage;
+        double mTotalRuntime;
         long mStarts;
         
-        public CpuUsage(int uid, String process, long userTime, long systemTime, long starts) {
+        public CpuUsage(int uid, String process, long userTime, long systemTime,
+                long starts, long totalRuntime) {
             getNameForUid(uid);
             mProcess = process;
             PackageManager pm = BatteryHistory.this.getPackageManager();
@@ -220,6 +227,7 @@
             
             mUsage[0] = userTime;
             mUsage[1] = userTime + systemTime;
+            mTotalRuntime = totalRuntime;
             mStarts = starts;
         }
         
@@ -235,6 +243,10 @@
             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");
@@ -306,13 +318,15 @@
     
     class SensorUsage extends Graphable {
         double[] mUsage;
+        double mTotalRealtime;
         int mCount;
         
-        public SensorUsage(int uid, long time, int count) {
+        public SensorUsage(int uid, long time, int count, long totalRealtime) {
             getNameForUid(uid);
             
             mUsage = new double[1];
             mUsage[0] = time;
+            mTotalRealtime = totalRealtime;
             
             mCount = count;
         }
@@ -329,6 +343,10 @@
             return mUsage;
         }
         
+        public double getMaxValue() {
+            return mTotalRealtime;            
+        }
+        
         public void getInfo(StringBuilder info) {
             info.append(getString(R.string.battery_history_sensor));
             info.append(mName);
@@ -342,13 +360,15 @@
     
     class WakelockUsage extends Graphable {
         double[] mUsage;
+        double mTotalRealtime;
         int mCount;
         
-        public WakelockUsage(int uid, long time, int count) {
+        public WakelockUsage(int uid, long time, int count, long totalRealtime) {
             getNameForUid(uid);
             
             mUsage = new double[1];
             mUsage[0] = time;
+            mTotalRealtime = totalRealtime;
             
             mCount = count;
         }
@@ -365,6 +385,10 @@
             return mUsage;
         }
         
+        public double getMaxValue() {
+            return mTotalRealtime;            
+        }
+        
         public void getInfo(StringBuilder info) {
             info.append(getString(R.string.battery_history_wakelock));
             info.append(mName);
@@ -375,35 +399,61 @@
         }
     }
     
+    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 WAKE_LOCKS: return mWakelockUsage;
-            case SCREEN_ON: return null;
+            case WAKELOCK_USAGE: return mWakelockUsage;
+            case MISC_USAGE: return mMiscUsage;
             default:
                 return (List<? extends Graphable>) null; // TODO
         }
     }
     
-    private void displayScreenUsage() {
-        mMessageText.setVisibility(View.VISIBLE);
-        StringBuilder sb = new StringBuilder();
-        sb.append(getString(R.string.battery_history_screen_on));
-        sb.append("\n\n");
-        sb.append(getString(R.string.battery_history_screen_on_battery));
-        sb.append(' ');
-        formatTime((double) mStats.getBatteryScreenOnTime(), sb);
-        sb.append('\n');
-        sb.append(getString(R.string.battery_history_screen_on_plugged));
-        sb.append(' ');
-        formatTime((double) mStats.getPluggedScreenOnTime(), sb);
-        sb.append('\n');
-        mMessageText.setText(sb.toString());
-    }
-    
     private void displayGraph() {
         Log.i(TAG, "displayGraph");
 
@@ -415,17 +465,13 @@
             mButtons[i].setVisibility(View.INVISIBLE);
         }
         
-        if (mType == SCREEN_ON) {
-            displayScreenUsage();
-            return;
-        }
-        
         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];
@@ -476,6 +522,9 @@
     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++) {
@@ -493,7 +542,7 @@
 
                     if (userTime != 0 || systemTime != 0) {
                         mCpuUsage.add(new CpuUsage(u.getUid(), ent.getKey(),
-                                userTime, systemTime, starts));
+                                userTime, systemTime, starts, uSecNow));
                     }
                 }
             }
@@ -523,7 +572,7 @@
         mSensorUsage.clear();
         
         long uSecTime = SystemClock.elapsedRealtime() * 1000;
-        final long uSecNow = mStats.getBatteryUptime(uSecTime);
+        final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
         
         SparseArray<? extends Uid> uidStats = mStats.getUidStats();
         final int NU = uidStats.size();
@@ -559,10 +608,10 @@
             }
             
             if (timeGps > 0) {
-                mGpsUsage.add(new SensorUsage(uid, timeGps, countGps));
+                mGpsUsage.add(new SensorUsage(uid, timeGps, countGps, uSecNow));
             }
             if (timeOther > 0) {
-                mSensorUsage.add(new SensorUsage(uid, timeOther, countOther));
+                mSensorUsage.add(new SensorUsage(uid, timeOther, countOther, uSecNow));
             }
         }
         
@@ -574,7 +623,7 @@
         mWakelockUsage.clear();
         
         long uSecTime = SystemClock.elapsedRealtime() * 1000;
-        final long uSecNow = mStats.getBatteryUptime(uSecTime);
+        final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
         
         SparseArray<? extends Uid> uidStats = mStats.getUidStats();
         final int NU = uidStats.size();
@@ -600,15 +649,45 @@
             }
             
             if (time > 0) {
-                mWakelockUsage.add(new WakelockUsage(uid, time, count));
+                mWakelockUsage.add(new WakelockUsage(uid, time, count, uSecNow));
             }
         }
         
         Collections.sort(mWakelockUsage);
     }
     
-    private void processScreenOn() {
-        // Do nothing
+    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() {
@@ -630,16 +709,16 @@
                 processSensorUsage();
             }
         }
-        if (mType == WAKE_LOCKS) {
+        if (mType == WAKELOCK_USAGE) {
             if (!mHaveWakelockUsage) {
                 mHaveWakelockUsage = true;
                 processWakelockUsage();
             }
         }
-        if (mType == SCREEN_ON) {
-            if (!mHaveScreenOnTime) {
-                mHaveScreenOnTime = true;
-                processScreenOn();
+        if (mType == MISC_USAGE) {
+            if (!mHaveMiscUsage) {
+                mHaveMiscUsage = true;
+                processMiscUsage();
             }
         }
     }
@@ -657,7 +736,7 @@
             //mStats.dumpLocked(new LogPrinter(Log.INFO, TAG));
             
             mHaveCpuUsage =  mHaveNetworkUsage =  mHaveSensorUsage
-                    = mHaveWakelockUsage = mHaveScreenOnTime = false;
+                    = mHaveWakelockUsage = mHaveMiscUsage = false;
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException:", e);
         }
@@ -686,26 +765,6 @@
         
         if (parent.equals(mTypeSpinner)) {
             mType = position;
-            switch (position) {
-                case CPU_USAGE:
-                    mWhichSpinner.setEnabled(true);
-                    break;
-                case NETWORK_USAGE:
-                    mWhichSpinner.setEnabled(true);
-                    break;
-                case GPS_USAGE:
-                    mWhichSpinner.setEnabled(true);
-                    break;
-                case SENSOR_USAGE:
-                    mWhichSpinner.setEnabled(true);
-                    break;
-                case WAKE_LOCKS:
-                    mWhichSpinner.setEnabled(true);
-                    break;
-                case SCREEN_ON:
-                    mWhichSpinner.setEnabled(false);
-                    break;
-            }
         } else if (parent.equals(mWhichSpinner)) {
             switch (position) {
                 case UNPLUGGED:
@@ -722,7 +781,7 @@
         
         if (oldWhich != mWhich) {
             mHaveCpuUsage =  mHaveNetworkUsage =  mHaveSensorUsage
-                    = mHaveWakelockUsage = mHaveScreenOnTime = false;
+                    = mHaveWakelockUsage = mHaveMiscUsage = false;
         }
         
         displayGraph();
@@ -766,6 +825,7 @@
         
         mWhichSpinner = (Spinner) findViewById(R.id.whichSpinner);
         mWhichSpinner.setOnItemSelectedListener(this);
+        mWhichSpinner.setEnabled(true);
         
         mButtons = new GraphableButton[8];
         mButtons[0] = (GraphableButton) findViewById(R.id.button0);
diff --git a/src/com/android/settings/bluetooth/BluetoothPinDialog.java b/src/com/android/settings/bluetooth/BluetoothPinDialog.java
index a8e7737..5e289f7 100644
--- a/src/com/android/settings/bluetooth/BluetoothPinDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPinDialog.java
@@ -157,11 +157,12 @@
         messageView.setText(getString(R.string.bluetooth_pairing_error_message,
                 mLocalManager.getLocalDeviceManager().getName(mAddress)));
         
-        mPinView.setEnabled(false);
+        mPinView.setVisibility(View.GONE);
         mPinView.clearFocus();
         mPinView.removeTextChangedListener(this);
-        
-        mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
+
+        mOkButton.setEnabled(true);
+        mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
     }
     
     private void onPair(String pin) {
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index f75e5f5..5adada3 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -253,6 +253,8 @@
         // 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
index b4a8ae0..7dd1b70 100644
--- a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
+++ b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
@@ -217,6 +217,9 @@
     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.
@@ -244,7 +247,10 @@
                 .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));
         
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 4fd708e..4671fac 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -23,6 +23,7 @@
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.content.Intent;
@@ -51,11 +52,13 @@
     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;
@@ -95,7 +98,9 @@
 
         mEventRedirector = new BluetoothEventRedirector(this);
         mEventRedirector.start();
-       
+
+        mBluetoothA2dp = new BluetoothA2dp(context);
+
         return true;
     }
     
@@ -112,6 +117,10 @@
     }
     
     public void setForegroundActivity(Activity activity) {
+        if (mErrorDialog != null) {
+            mErrorDialog.dismiss();
+            mErrorDialog = null;
+        }
         mForegroundActivity = activity;
     }
     
@@ -149,9 +158,23 @@
              */ 
             dispatchScanningStateChanged(true);
         } else {
-            
-            // Don't scan more than frequently than SCAN_EXPIRATION_MS, unless forced
-            if (!force && mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) return;
+            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();
@@ -235,7 +258,7 @@
 
         if (mForegroundActivity != null) {
             // Need an activity context to show a dialog
-            AlertDialog ad = new AlertDialog.Builder(mForegroundActivity)
+            mErrorDialog = new AlertDialog.Builder(mForegroundActivity)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setTitle(titleResId)
                 .setMessage(message)
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
index adfe88c..75a84b7 100644
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -81,6 +81,8 @@
         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");
diff --git a/src/com/android/settings/wifi/AdvancedSettings.java b/src/com/android/settings/wifi/AdvancedSettings.java
index 54aab4b..323d5c7 100644
--- a/src/com/android/settings/wifi/AdvancedSettings.java
+++ b/src/com/android/settings/wifi/AdvancedSettings.java
@@ -95,6 +95,7 @@
         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];
@@ -107,6 +108,7 @@
         }
         pref.setEntries(entries);
         pref.setEntryValues(entryValues);
+        pref.setEnabled(true);
         int numChannels = wifiManager.getNumAllowedChannels();
         if (numChannels >= 0) {
             pref.setValue(String.valueOf(numChannels));