Merge "Don't show TrustAgent entries when no security is enabled." into lmp-dev
diff --git a/res/layout/bluetooth_device_picker.xml b/res/layout/bluetooth_device_picker.xml
index 0a63e25..9d8ae86 100755
--- a/res/layout/bluetooth_device_picker.xml
+++ b/res/layout/bluetooth_device_picker.xml
@@ -15,14 +15,38 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
+        android:gravity="center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
-    <fragment
-        android:id="@+id/bluetooth_device_picker_fragment"
-        android:name="com.android.settings.bluetooth.DevicePickerFragment"
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1" />
+    <LinearLayout android:id="@+id/dialog_layout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingBottom="@dimen/bluetooth_dialog_padding"
+            style="@style/wifi_item" >
+
+            <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/bluetooth_preference_paired_dialog_name_label"
+                    android:textDirection="locale"
+                    style="@style/wifi_item_label" />
+
+            <EditText android:id="@+id/name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:inputType="textNoSuggestions"
+                    android:maxLength="@integer/bluetooth_name_length"
+                    android:singleLine="true"
+                    style="@style/wifi_item_edit_content" />
+
+            <fragment android:id="@+id/bluetooth_fragment_settings"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    class="com.android.settings.bluetooth.DeviceProfilesSettings" />
+
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/res/layout/preference_home_app.xml b/res/layout/preference_home_app.xml
index 0ee154e..9415752 100644
--- a/res/layout/preference_home_app.xml
+++ b/res/layout/preference_home_app.xml
@@ -30,6 +30,7 @@
         android:clickable="true"
         android:gravity="center_vertical"
         android:background="?android:attr/selectableItemBackground" >
+
             <RadioButton
                 android:id="@+id/home_radio"
                 android:layout_width="wrap_content"
@@ -40,6 +41,7 @@
                 android:orientation="vertical"
                 android:clickable="false"
                 android:focusable="false" />
+
             <ImageView
                 android:id="@+android:id/icon"
                 android:layout_width="48dp"
@@ -47,17 +49,35 @@
                 android:layout_gravity="center"
                 android:minWidth="48dp"
                 android:scaleType="centerInside"
-                android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"
-                />
-            <TextView
-                android:id="@+android:id/title"
+                android:layout_marginEnd="@*android:dimen/preference_item_padding_inner" />
+
+            <LinearLayout
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:singleLine="true"
+                android:layout_height="match_parent"
                 android:layout_weight="1"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:ellipsize="end" />
+                android:focusable="true"
+                android:clickable="true"
+                android:gravity="center_vertical"
+                android:orientation="vertical">
+
+                    <TextView
+                        android:id="@+android:id/title"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:singleLine="true"
+                        android:textAppearance="?android:attr/textAppearanceMedium"
+                        android:ellipsize="end" />
+
+                    <TextView
+                        android:id="@+android:id/summary"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            </LinearLayout>
+
     </LinearLayout>
+
     <View
         android:id="@+id/home_divider"
         android:layout_width="2dip"
@@ -65,6 +85,7 @@
         android:layout_marginTop="5dip"
         android:layout_marginBottom="5dip"
         android:background="@android:drawable/divider_horizontal_dark" />
+
     <ImageView
         android:id="@+id/home_app_uninstall"
         android:layout_width="wrap_content"
@@ -77,4 +98,5 @@
         android:clickable="true"
         android:focusable="true"
         android:background="?android:attr/selectableItemBackground" />
+
 </LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 62162d3..cb87bf0 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -204,4 +204,8 @@
     <dimen name="checkbox_widget_min_width">58dip</dimen>
     <dimen name="checkbox_layout_padding">16dip</dimen>
 
+    <!-- Bluetooth Preferences -->
+    <dimen name="bluetooth_dialog_padding">8dip</dimen>
+    <integer name="bluetooth_name_length">32</integer>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 413d6fd..5b0950a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1928,6 +1928,10 @@
     <!-- Sound settings screen, the caption of the checkbox for having the notification volume be
          the same as the incoming call volume. -->
     <string name="checkbox_notification_same_as_incoming_call">Use incoming call volume for notifications</string>
+
+    <!-- Home settings screen, text indicating that a launcer does not support work profiles [CHAR LIMIT=100] -->
+    <string name="home_work_profile_not_supported">Doesn\'t support work profiles</string>
+
     <!-- Sound settings screen, setting option title-->
     <string name="notification_sound_dialog_title">Default notification sound</string>
     <!-- Sound settings screen, setting option name -->
diff --git a/res/xml/bluetooth_device_advanced.xml b/res/xml/bluetooth_device_advanced.xml
index 8d2261c..75c89ca 100644
--- a/res/xml/bluetooth_device_advanced.xml
+++ b/res/xml/bluetooth_device_advanced.xml
@@ -18,19 +18,6 @@
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:title="@string/bluetooth_device_advanced_title">
 
-    <EditTextPreference
-            android:key="rename_device"
-            android:title="@string/bluetooth_device_advanced_rename_device"
-            android:order="20"
-            android:persistent="false" />
-
-    <Preference
-            android:key="unpair"
-            android:title="@string/bluetooth_device_context_unpair"
-            android:order="40"
-            android:persistent="false"
-            />
-
     <PreferenceCategory
             android:key="profile_container"
             android:order="100"
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index c8691e1..ec52128 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -819,14 +819,21 @@
 
         View title = null;
         if (detail.detailLabels != null) {
-            for (CharSequence label : detail.detailLabels) {
+            final int n = detail.detailLabels.length;
+            for (int i = 0; i < n; ++i) {
+                CharSequence label = detail.detailLabels[i];
+                CharSequence contentDescription = detail.detailContentDescriptions[i];
                 title = inflater.inflate(R.layout.data_usage_app_title, mAppTitles, false);
-                ((TextView) title.findViewById(R.id.app_title)).setText(label);
+                TextView appTitle = (TextView) title.findViewById(R.id.app_title);
+                appTitle.setText(label);
+                appTitle.setContentDescription(contentDescription);
                 mAppTitles.addView(title);
             }
         } else {
             title = inflater.inflate(R.layout.data_usage_app_title, mAppTitles, false);
-            ((TextView) title.findViewById(R.id.app_title)).setText(detail.label);
+            TextView appTitle = (TextView) title.findViewById(R.id.app_title);
+            appTitle.setText(detail.label);
+            appTitle.setContentDescription(detail.contentDescription);
             mAppTitles.addView(title);
         }
 
@@ -2222,6 +2229,7 @@
             if (detail != null) {
                 icon.setImageDrawable(detail.icon);
                 title.setText(detail.label);
+                title.setContentDescription(detail.contentDescription);
             } else {
                 icon.setImageDrawable(null);
                 title.setText(null);
diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java
index 845fe1e..817c61a 100644
--- a/src/com/android/settings/HomeSettings.java
+++ b/src/com/android/settings/HomeSettings.java
@@ -32,18 +32,22 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.content.pm.UserInfo;
 import android.graphics.ColorFilter;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.UserManager;
 import android.preference.Preference;
 import android.preference.PreferenceGroup;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.ImageView;
 import android.widget.RadioButton;
@@ -171,6 +175,7 @@
         mPrefs = new ArrayList<HomeAppPreference>();
         mHomeComponentSet = new ComponentName[homeActivities.size()];
         int prefIndex = 0;
+        boolean hasManagedProfile = hasManagedProfile();
         for (int i = 0; i < homeActivities.size(); i++) {
             final ResolveInfo candidate = homeActivities.get(i);
             final ActivityInfo info = candidate.activityInfo;
@@ -179,11 +184,19 @@
             try {
                 Drawable icon = info.loadIcon(mPm);
                 CharSequence name = info.loadLabel(mPm);
-                HomeAppPreference pref = new HomeAppPreference(context, activityName, prefIndex,
-                        icon, name, this, info);
+                HomeAppPreference pref;
+
+                if (hasManagedProfile && !launcherHasManagedProfilesFeature(candidate)) {
+                    pref = new HomeAppPreference(context, activityName, prefIndex,
+                            icon, name, this, info, false /* not enabled */,
+                            getResources().getString(R.string.home_work_profile_not_supported));
+                } else  {
+                    pref = new HomeAppPreference(context, activityName, prefIndex,
+                            icon, name, this, info, true /* enabled */, null);
+                }
+
                 mPrefs.add(pref);
                 mPrefGroup.addPreference(pref);
-                pref.setEnabled(true);
                 if (activityName.equals(currentDefaultHome)) {
                     mCurrentHome = pref;
                 }
@@ -202,6 +215,31 @@
         }
     }
 
+    private boolean hasManagedProfile() {
+        Context context = getActivity();
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        List<UserInfo> profiles = userManager.getProfiles(context.getUserId());
+        for (UserInfo userInfo : profiles) {
+            if (userInfo.isManagedProfile()) return true;
+        }
+        return false;
+    }
+
+    private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo) {
+        try {
+            ApplicationInfo appInfo = getPackageManager().getApplicationInfo(
+                    resolveInfo.activityInfo.packageName, 0 /* default flags */);
+            return versionNumberAtLeastL(appInfo.targetSdkVersion);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    private boolean versionNumberAtLeastL(int versionNumber) {
+        // TODO: remove "|| true" once the build code for L is fixed.
+        return versionNumber >= Build.VERSION_CODES.L || true;
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -245,12 +283,14 @@
         String uninstallTarget;
 
         public HomeAppPreference(Context context, ComponentName activity,
-                int i, Drawable icon, CharSequence title,
-                HomeSettings parent, ActivityInfo info) {
+                int i, Drawable icon, CharSequence title, HomeSettings parent, ActivityInfo info,
+                boolean enabled, CharSequence summary) {
             super(context);
             setLayoutResource(R.layout.preference_home_app);
             setIcon(icon);
             setTitle(title);
+            setEnabled(enabled);
+            setSummary(summary);
             activityName = activity;
             fragment = parent;
             index = i;
@@ -305,13 +345,15 @@
                 icon.setEnabled(false);
                 icon.setColorFilter(grayscaleFilter);
             } else {
+                icon.setEnabled(true);
                 icon.setOnClickListener(mDeleteClickListener);
                 icon.setTag(indexObj);
             }
 
             View v = view.findViewById(R.id.home_app_pref);
-            v.setOnClickListener(mHomeClickListener);
             v.setTag(indexObj);
+
+            v.setOnClickListener(mHomeClickListener);
         }
 
         void setChecked(boolean state) {
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 2ba1e7f..d14ad39 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -65,7 +65,10 @@
                     getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
 
             if (pdbManager != null) {
-                pdbManager.wipe();
+                // if OEM unlock is enabled, this will be wiped during FR process.
+                if (!pdbManager.getOemUnlockEnabled()) {
+                    pdbManager.wipe();
+                }
             }
 
             if (mEraseSdCard) {
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index f1125bc..7441c8c 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,28 +18,39 @@
 
 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
 
+import android.app.Activity;
+import android.app.AlertDialog;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
 import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.EditText;
 import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Index;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settings.widget.SwitchBar;
@@ -64,6 +75,8 @@
     private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
             "android.btopp.intent.action.OPEN_RECEIVED_FILES";
 
+    private static View mSettingsDialogView = null;
+
     private BluetoothEnabler mBluetoothEnabler;
 
     private PreferenceGroup mPairedDevicesCategory;
@@ -371,20 +384,60 @@
     private final View.OnClickListener mDeviceProfilesListener = new View.OnClickListener() {
         public void onClick(View v) {
             // User clicked on advanced options icon for a device in the list
-            if (v.getTag() instanceof CachedBluetoothDevice) {
-                if (isUiRestricted()) return;
-
-                CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
-
-                Bundle args = new Bundle(1);
-                args.putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, device.getDevice());
-
-                ((SettingsActivity) getActivity()).startPreferencePanel(
-                        DeviceProfilesSettings.class.getName(), args,
-                        R.string.bluetooth_device_advanced_title, null, null, 0);
-            } else {
-                Log.w(TAG, "onClick() called for other View: " + v); // TODO remove
+            if (!(v.getTag() instanceof CachedBluetoothDevice)) {
+                Log.w(TAG, "onClick() called for other View: " + v);
+                return;
             }
+
+            final CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+            final Activity activity = getActivity();
+            DeviceProfilesSettings profileFrag = (DeviceProfilesSettings)activity.
+                getFragmentManager().findFragmentById(R.id.bluetooth_fragment_settings);
+
+            if (mSettingsDialogView != null){
+                ViewGroup parent = (ViewGroup) mSettingsDialogView.getParent();
+                if (parent != null) {
+                    parent.removeView(mSettingsDialogView);
+                }
+            }
+            if (profileFrag == null) {
+                LayoutInflater inflater = getActivity().getLayoutInflater();
+                mSettingsDialogView = inflater.inflate(R.layout.bluetooth_device_picker, null);
+                profileFrag = (DeviceProfilesSettings)activity.getFragmentManager()
+                .findFragmentById(R.id.bluetooth_fragment_settings);
+            }
+
+            final View dialogLayout = mSettingsDialogView;
+            AlertDialog.Builder settingsDialog = new AlertDialog.Builder(activity);
+            profileFrag.setDevice(device);
+            final EditText deviceName = (EditText)dialogLayout.findViewById(R.id.name);
+            deviceName.setText(device.getName(), TextView.BufferType.EDITABLE);
+            settingsDialog.setView(dialogLayout);
+            settingsDialog.setTitle(R.string.bluetooth_preference_paired_devices);
+            settingsDialog.setPositiveButton(R.string.okay,
+                    new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    EditText deviceName = (EditText)dialogLayout.findViewById(R.id.name);
+                    device.setName(deviceName.getText().toString());
+                }
+            });
+            final Context context = v.getContext();
+            settingsDialog.setNegativeButton(R.string.forget,
+                    new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    device.unpair();
+                    com.android.settings.bluetooth.Utils.updateSearchIndex(activity,
+                            BluetoothSettings.class.getName(), device.getName(),
+                            context.getResources().getString(R.string.bluetooth_settings),
+                            R.drawable.ic_settings_bluetooth2, false);
+                }
+            });
+
+            AlertDialog dialog = settingsDialog.create();
+            dialog.create();
+            dialog.show();
         }
     };
 
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index fb7668f..ea43bad 100755
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -17,6 +17,7 @@
 package com.android.settings.bluetooth;
 
 import android.app.AlertDialog;
+import android.app.Fragment;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
@@ -36,6 +37,7 @@
 import android.app.Dialog;
 import android.widget.Button;
 import android.text.Editable;
+
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.search.Index;
@@ -52,15 +54,14 @@
         implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
     private static final String TAG = "DeviceProfilesSettings";
 
-    private static final String KEY_RENAME_DEVICE = "rename_device";
     private static final String KEY_PROFILE_CONTAINER = "profile_container";
     private static final String KEY_UNPAIR = "unpair";
     private static final String KEY_PBAP_SERVER = "PBAP Server";
 
     public static final String EXTRA_DEVICE = "device";
-    private RenameEditTextPreference mRenameDeviceNamePref;
-    private LocalBluetoothManager mManager;
+
     private CachedBluetoothDevice mCachedDevice;
+    private LocalBluetoothManager mManager;
     private LocalBluetoothProfileManager mProfileManager;
 
     private PreferenceGroup mProfileContainer;
@@ -72,66 +73,18 @@
     private AlertDialog mDisconnectDialog;
     private boolean mProfileGroupIsRemoved;
 
-    private class RenameEditTextPreference implements TextWatcher{
-        public void afterTextChanged(Editable s) {
-            Dialog d = mDeviceNamePref.getDialog();
-            if (d instanceof AlertDialog) {
-                ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(s.length() > 0);
-            }
-        }
-
-        // TextWatcher interface
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-            // not used
-        }
-
-        // TextWatcher interface
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-            // not used
-        }
-    }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        BluetoothDevice device;
-        if (savedInstanceState != null) {
-            device = savedInstanceState.getParcelable(EXTRA_DEVICE);
-        } else {
-            Bundle args = getArguments();
-            device = args.getParcelable(EXTRA_DEVICE);
-        }
-
         addPreferencesFromResource(R.xml.bluetooth_device_advanced);
         getPreferenceScreen().setOrderingAsAdded(false);
         mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
-        mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
 
-        if (device == null) {
-            Log.w(TAG, "Activity started without a remote Bluetooth device");
-            finish();
-            return;  // TODO: test this failure path
-        }
-        mRenameDeviceNamePref = new RenameEditTextPreference();
         mManager = LocalBluetoothManager.getInstance(getActivity());
         CachedBluetoothDeviceManager deviceManager =
                 mManager.getCachedDeviceManager();
         mProfileManager = mManager.getProfileManager();
-        mCachedDevice = deviceManager.findDevice(device);
-        if (mCachedDevice == null) {
-            Log.w(TAG, "Device not found, cannot connect to it");
-            finish();
-            return;  // TODO: test this failure path
-        }
-
-        String deviceName = mCachedDevice.getName();
-        mDeviceNamePref.setSummary(deviceName);
-        mDeviceNamePref.setText(deviceName);
-        mDeviceNamePref.setOnPreferenceChangeListener(this);
-
-        // Add a preference for each profile
-        addPreferencesForProfiles();
     }
 
     @Override
@@ -141,6 +94,9 @@
             mDisconnectDialog.dismiss();
             mDisconnectDialog = null;
         }
+        if (mCachedDevice != null) {
+            mCachedDevice.unregisterCallback(this);
+        }
     }
 
     @Override
@@ -154,18 +110,13 @@
         super.onResume();
 
         mManager.setForegroundActivity(getActivity());
-        mCachedDevice.registerCallback(this);
-        if(mCachedDevice.getBondState() == BluetoothDevice.BOND_NONE)
-            finish();
-        refresh();
-        EditText et = mDeviceNamePref.getEditText();
-        if (et != null) {
-            et.addTextChangedListener(mRenameDeviceNamePref);
-            Dialog d = mDeviceNamePref.getDialog();
-            if (d instanceof AlertDialog) {
-                Button b = ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE);
-                b.setEnabled(et.getText().length() > 0);
+        if (mCachedDevice != null) {
+            mCachedDevice.registerCallback(this);
+            if (mCachedDevice.getBondState() == BluetoothDevice.BOND_NONE) {
+                finish();
+                return;
             }
+            refresh();
         }
     }
 
@@ -173,11 +124,23 @@
     public void onPause() {
         super.onPause();
 
-        mCachedDevice.unregisterCallback(this);
+        if (mCachedDevice != null) {
+            mCachedDevice.unregisterCallback(this);
+        }
+
         mManager.setForegroundActivity(null);
     }
 
+    public void setDevice(CachedBluetoothDevice cachedDevice) {
+        mCachedDevice = cachedDevice;
+
+        mCachedDevice.registerCallback(this);
+        addPreferencesForProfiles();
+        refresh();
+    }
+
     private void addPreferencesForProfiles() {
+        mProfileContainer.removeAll();
         for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
             Preference pref = createProfilePreference(profile);
             mProfileContainer.addPreference(pref);
@@ -238,28 +201,6 @@
         return pref;
     }
 
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
-        String key = preference.getKey();
-        if (key.equals(KEY_UNPAIR)) {
-            unpairDevice();
-            finish();
-            final Context context = preference.getContext();
-
-            SearchIndexableRaw data = new SearchIndexableRaw(context);
-            data.className = BluetoothSettings.class.getName();
-            data.title = mCachedDevice.getName();
-            data.screenTitle = context.getResources().getString(R.string.bluetooth_settings);
-            data.iconResId = R.drawable.ic_settings_bluetooth2;
-            data.enabled = false;
-
-            Index.getInstance(context).updateFromSearchIndexableData(data);
-            return true;
-        }
-
-        return super.onPreferenceTreeClick(screen, preference);
-    }
-
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         if (preference == mDeviceNamePref) {
             mCachedDevice.setName((String) newValue);
@@ -331,14 +272,16 @@
                 mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
     }
 
+    @Override
     public void onDeviceAttributesChanged() {
         refresh();
     }
 
     private void refresh() {
-        String deviceName = mCachedDevice.getName();
-        mDeviceNamePref.setSummary(deviceName);
-        mDeviceNamePref.setText(deviceName);
+        final EditText deviceNameField = (EditText) getView().findViewById(R.id.name);
+        if (deviceNameField != null) {
+            deviceNameField.setText(mCachedDevice.getName());
+        }
 
         refreshProfiles();
     }
@@ -391,8 +334,4 @@
     private int getProfilePreferenceIndex(int profIndex) {
         return mProfileContainer.getOrder() + profIndex * 10;
     }
-
-    private void unpairDevice() {
-        mCachedDevice.unpair();
-    }
 }
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
index 1970400..e9230de 100755
--- a/src/com/android/settings/bluetooth/Utils.java
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -24,6 +24,8 @@
 import android.widget.Toast;
 
 import com.android.settings.R;
+import com.android.settings.search.Index;
+import com.android.settings.search.SearchIndexableRaw;
 
 /**
  * Utils is a helper class that contains constants for various
@@ -101,4 +103,19 @@
             Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
         }
     }
+
+    /**
+     * Update the search Index for a specific class name and resources.
+     */
+    public static void updateSearchIndex(Context context, String className, String title,
+            String screenTitle, int iconResId, boolean enabled) {
+        SearchIndexableRaw data = new SearchIndexableRaw(context);
+        data.className = className;
+        data.title = title;
+        data.screenTitle = screenTitle;
+        data.iconResId = iconResId;
+        data.enabled = enabled;
+
+        Index.getInstance(context).updateFromSearchIndexableData(data);
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java b/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java
index 248d471..63e4e13 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java
@@ -18,31 +18,27 @@
 
 import android.app.Fragment;
 import android.content.Intent;
+import android.os.BatteryStats;
 import android.os.Bundle;
-import android.os.Parcel;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 
 public class BatteryHistoryDetail extends Fragment {
     public static final String EXTRA_STATS = "stats";
     public static final String EXTRA_BROADCAST = "broadcast";
 
-    private BatteryStatsImpl mStats;
+    private BatteryStats mStats;
     private Intent mBatteryBroadcast;
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        byte[] data = getArguments().getByteArray(EXTRA_STATS);
-        Parcel parcel = Parcel.obtain();
-        parcel.unmarshall(data, 0, data.length);
-        parcel.setDataPosition(0);
-        mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
-                .createFromParcel(parcel);
+        String histFile = getArguments().getString(EXTRA_STATS);
+        mStats = BatteryStatsHelper.statsFromFile(getActivity(), histFile);
         mBatteryBroadcast = getArguments().getParcelable(EXTRA_BROADCAST);
     }
     
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
index 300b98f..e7326b1 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java
@@ -47,8 +47,6 @@
         setLayoutResource(R.layout.preference_batteryhistory);
         mStats = stats;
         mBatteryBroadcast = batteryBroadcast;
-        // Make it non selectable
-        setSelectable(false);
     }
 
     BatteryStats getStats() {
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index 990b654..a558533 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -34,12 +34,15 @@
     private BatteryEntry mInfo;
     private int mProgress;
     private CharSequence mProgressText;
+    private final CharSequence mContentDescription;
 
-    public PowerGaugePreference(Context context, Drawable icon, BatteryEntry info) {
+    public PowerGaugePreference(Context context, Drawable icon, CharSequence contentDescription,
+            BatteryEntry info) {
         super(context);
         setLayoutResource(R.layout.preference_app_percentage);
         setIcon(icon != null ? icon : new ColorDrawable(0));
         mInfo = info;
+        mContentDescription = contentDescription;
     }
 
     public void setPercent(double percentOfMax, double percentOfTotal) {
@@ -62,5 +65,10 @@
 
         final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
         text1.setText(mProgressText);
+
+        if (mContentDescription != null) {
+            final TextView titleView = (TextView) view.findViewById(android.R.id.title);
+            titleView.setContentDescription(mContentDescription);
+        }
     }
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 3ce2ac0..ad8afa5 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -21,11 +21,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.os.BatteryStats;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.Preference;
@@ -45,8 +45,6 @@
 import com.android.settings.SettingsActivity;
 
 import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
 
 /**
  * Displays a list of apps and subsystems that consume power, ordered by how much power was
@@ -60,6 +58,8 @@
 
     private static final String KEY_APP_LIST = "app_list";
 
+    private static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin";
+
     private static final int MENU_STATS_TYPE = Menu.FIRST;
     private static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
     private static final int MENU_BATTERY_SAVER = Menu.FIRST + 2;
@@ -115,6 +115,7 @@
     @Override
     public void onResume() {
         super.onResume();
+        BatteryStatsHelper.dropFile(getActivity(), BATTERY_HISTORY_FILE);
         updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver,
                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED)));
         if (mHandler.hasMessages(MSG_REFRESH_STATS)) {
@@ -150,11 +151,9 @@
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         if (preference instanceof BatteryHistoryPreference) {
-            Parcel hist = Parcel.obtain();
-            mStatsHelper.getStats().writeToParcelWithoutUids(hist, 0);
-            byte[] histData = hist.marshall();
+            mStatsHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE);
             Bundle args = new Bundle();
-            args.putByteArray(BatteryHistoryDetail.EXTRA_STATS, histData);
+            args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE);
             args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST,
                     mStatsHelper.getBatteryBroadcast());
             SettingsActivity sa = (SettingsActivity) getActivity();
@@ -294,8 +293,12 @@
                 }
                 final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid()));
                 final BatteryEntry entry = new BatteryEntry(getActivity(), mHandler, mUm, sipper);
+                final Drawable badgedIcon = mUm.getBadgedDrawableForUser(entry.getIcon(),
+                        userHandle);
+                final CharSequence contentDescription = mUm.getBadgedLabelForUser(entry.getLabel(),
+                        userHandle);
                 final PowerGaugePreference pref = new PowerGaugePreference(getActivity(),
-                        mUm.getBadgedDrawableForUser(entry.getIcon(), userHandle), entry);
+                        badgedIcon, contentDescription, entry);
 
                 final double percentOfMax = (sipper.value * 100) / mStatsHelper.getMaxPower();
                 sipper.percent = percentOfTotal;
diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java
index 8e1ec05..13d282d 100644
--- a/src/com/android/settings/location/RecentLocationApps.java
+++ b/src/com/android/settings/location/RecentLocationApps.java
@@ -22,6 +22,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.IPackageManager;
+import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Process;
@@ -30,6 +31,8 @@
 import android.os.UserManager;
 import android.preference.Preference;
 import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
@@ -74,12 +77,35 @@
         }
     }
 
-    private Preference createRecentLocationEntry(
+    /**
+     * Subclass of {@link Preference} to intercept views and allow content description to be set on
+     * them for accessibility purposes.
+     */
+    private static class AccessiblePreference extends Preference {
+        public CharSequence mContentDescription;
+
+        public AccessiblePreference(Context context, CharSequence contentDescription) {
+            super(context);
+            mContentDescription = contentDescription;
+        }
+
+        @Override
+        protected void onBindView(View view) {
+            super.onBindView(view);
+            if (mContentDescription != null) {
+                final TextView titleView = (TextView) view.findViewById(android.R.id.title);
+                titleView.setContentDescription(mContentDescription);
+            }
+        }
+    }
+
+    private AccessiblePreference createRecentLocationEntry(
             Drawable icon,
             CharSequence label,
             boolean isHighBattery,
+            CharSequence contentDescription,
             Preference.OnPreferenceClickListener listener) {
-        Preference pref = new Preference(mActivity);
+        AccessiblePreference pref = new AccessiblePreference(mActivity, contentDescription);
         pref.setIcon(icon);
         pref.setTitle(label);
         if (isHighBattery) {
@@ -172,16 +198,20 @@
         int uid = ops.getUid();
         int userId = UserHandle.getUserId(uid);
 
-        Preference preference = null;
+        AccessiblePreference preference = null;
         try {
             IPackageManager ipm = AppGlobals.getPackageManager();
             ApplicationInfo appInfo =
                     ipm.getApplicationInfo(packageName, PackageManager.GET_META_DATA, userId);
+            Resources res = mActivity.getResources();
 
-            Drawable icon = um.getBadgedDrawableForUser(
-                    mPackageManager.getApplicationIcon(appInfo), new UserHandle(userId));
+            final UserHandle userHandle = new UserHandle(userId);
+            Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
+            Drawable icon = um.getBadgedDrawableForUser(appIcon, userHandle);
+            CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
+            CharSequence badgedAppLabel = um.getBadgedLabelForUser(appLabel.toString(), userHandle);
             preference = createRecentLocationEntry(icon,
-                    mPackageManager.getApplicationLabel(appInfo), highBattery,
+                    appLabel, highBattery, badgedAppLabel,
                     new PackageEntryClickedListener(packageName));
         } catch (RemoteException e) {
             Log.w(TAG, "Error while retrieving application info", e);
diff --git a/src/com/android/settings/net/UidDetail.java b/src/com/android/settings/net/UidDetail.java
index fd44d47..0b14254 100644
--- a/src/com/android/settings/net/UidDetail.java
+++ b/src/com/android/settings/net/UidDetail.java
@@ -20,6 +20,8 @@
 
 public class UidDetail {
     public CharSequence label;
+    public CharSequence contentDescription;
     public CharSequence[] detailLabels;
+    public CharSequence[] detailContentDescriptions;
     public Drawable icon;
 }
diff --git a/src/com/android/settings/net/UidDetailProvider.java b/src/com/android/settings/net/UidDetailProvider.java
index cd101c9..b933025 100644
--- a/src/com/android/settings/net/UidDetailProvider.java
+++ b/src/com/android/settings/net/UidDetailProvider.java
@@ -148,27 +148,30 @@
         final String[] packageNames = pm.getPackagesForUid(uid);
         final int length = packageNames != null ? packageNames.length : 0;
         try {
+            final UserHandle userHandle = new UserHandle(UserHandle.getUserId(uid));
             if (length == 1) {
                 final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0);
                 detail.label = info.loadLabel(pm).toString();
-                detail.icon = um.getBadgedDrawableForUser(info.loadIcon(pm),
-                        new UserHandle(UserHandle.getUserId(uid)));
+                detail.icon = um.getBadgedDrawableForUser(info.loadIcon(pm), userHandle);
             } else if (length > 1) {
                 detail.detailLabels = new CharSequence[length];
+                detail.detailContentDescriptions = new CharSequence[length];
                 for (int i = 0; i < length; i++) {
                     final String packageName = packageNames[i];
                     final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
                     final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
 
                     detail.detailLabels[i] = appInfo.loadLabel(pm).toString();
+                    detail.detailContentDescriptions[i] = um.getBadgedLabelForUser(
+                            detail.detailLabels[i], userHandle);
                     if (packageInfo.sharedUserLabel != 0) {
                         detail.label = pm.getText(packageName, packageInfo.sharedUserLabel,
                                 packageInfo.applicationInfo).toString();
-                        detail.icon = um.getBadgedDrawableForUser(appInfo.loadIcon(pm),
-                                new UserHandle(UserHandle.getUserId(uid)));
+                        detail.icon = um.getBadgedDrawableForUser(appInfo.loadIcon(pm), userHandle);
                     }
                 }
             }
+            detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle);
         } catch (NameNotFoundException e) {
         }
 
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 6bc29e1..33ac947 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -34,6 +34,7 @@
         DialogInterface.OnClickListener {
 
     public static final String TAG = "PaymentDefaultDialog";
+    private static final int PAYMENT_APP_MAX_CAPTION_LENGTH = 40;
 
     private PaymentBackend mBackend;
     private ComponentName mNewDefault;
@@ -109,12 +110,14 @@
         p.mTitle = getString(R.string.nfc_payment_set_default_label);
         if (defaultPaymentApp == null) {
             String formatString = getString(R.string.nfc_payment_set_default);
-            String msg = String.format(formatString, requestedPaymentApp.caption);
+            String msg = String.format(formatString,
+                    sanitizePaymentAppCaption(requestedPaymentApp.caption.toString()));
             p.mMessage = msg;
         } else {
             String formatString = getString(R.string.nfc_payment_set_default_instead_of);
-            String msg = String.format(formatString, requestedPaymentApp.caption,
-                    defaultPaymentApp.caption);
+            String msg = String.format(formatString,
+                    sanitizePaymentAppCaption(requestedPaymentApp.caption.toString()),
+                    sanitizePaymentAppCaption(defaultPaymentApp.caption.toString()));
             p.mMessage = msg;
         }
         p.mPositiveButtonText = getString(R.string.yes);
@@ -126,4 +129,15 @@
         return true;
     }
 
+    private String sanitizePaymentAppCaption(String input) {
+        String sanitizedString = input.replace('\n', ' ').replace('\r', ' ').trim();
+
+
+        if (sanitizedString.length() > PAYMENT_APP_MAX_CAPTION_LENGTH) {
+            return sanitizedString.substring(0, PAYMENT_APP_MAX_CAPTION_LENGTH);
+        }
+
+        return sanitizedString;
+    }
+
 }
diff --git a/src/com/android/settings/sim/SimSettings.java b/src/com/android/settings/sim/SimSettings.java
index 2e1c0f5..15c5548 100644
--- a/src/com/android/settings/sim/SimSettings.java
+++ b/src/com/android/settings/sim/SimSettings.java
@@ -273,8 +273,6 @@
                     // SubscriptionManager.setDefaultSMSSubId(subId);
                 }
 
-                updateAllOptions();
-
                 return true;
             }
         });
@@ -357,6 +355,7 @@
                         mSubInfoRecord.mSubId);
 
                     updateAllOptions();
+                    update();
                 }
             });