Merge "Fix assist gesture settings summary" into oc-dr1-dev
diff --git a/res/drawable/ic_translate_24dp.xml b/res/drawable/ic_translate_24dp.xml
new file mode 100644
index 0000000..4df035c
--- /dev/null
+++ b/res/drawable/ic_translate_24dp.xml
@@ -0,0 +1,26 @@
+<!--
+  Copyright (C) 2017 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
+</vector>
diff --git a/res/layout-land/fingerprint_enroll_enrolling.xml b/res/layout-land/fingerprint_enroll_enrolling.xml
index b321519..135250b 100644
--- a/res/layout-land/fingerprint_enroll_enrolling.xml
+++ b/res/layout-land/fingerprint_enroll_enrolling.xml
@@ -49,6 +49,7 @@
                 style="@style/SuwGlifIcon"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_gravity="?attr/suwGlifHeaderGravity"
                 android:layout_marginStart="0dp"
                 android:layout_marginEnd="0dp"
                 android:src="@drawable/ic_fingerprint_header" />
@@ -82,6 +83,18 @@
 
             </FrameLayout>
 
+            <Space
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+
+            <Button
+                android:id="@+id/skip_button"
+                style="@style/SuwGlifButton.Secondary"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/security_settings_fingerprint_enroll_enrolling_skip" />
+
         </LinearLayout>
 
         <FrameLayout
diff --git a/res/layout-land/fingerprint_enroll_find_sensor.xml b/res/layout-land/fingerprint_enroll_find_sensor.xml
index a43534f..7877d98 100644
--- a/res/layout-land/fingerprint_enroll_find_sensor.xml
+++ b/res/layout-land/fingerprint_enroll_find_sensor.xml
@@ -42,7 +42,7 @@
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
+                android:layout_height="match_parent"
                 android:orientation="vertical"
                 android:clipChildren="false"
                 android:clipToPadding="false">
@@ -52,6 +52,7 @@
                     style="@style/SuwGlifIcon"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_gravity="?attr/suwGlifHeaderGravity"
                     android:layout_marginStart="0dp"
                     android:layout_marginEnd="0dp"
                     android:src="@drawable/ic_fingerprint_header" />
@@ -70,13 +71,18 @@
                     android:layout_height="wrap_content"
                     android:text="@string/security_settings_fingerprint_enroll_find_sensor_message"/>
 
+                <Space
+                    android:layout_width="0dp"
+                    android:layout_height="0dp"
+                    android:layout_weight="1" />
+
                 <Button
-                    style="@style/SetupWizardButton.Positive"
-                    android:id="@+id/next_button"
+                    style="@style/SetupWizardButton.Negative"
+                    android:id="@+id/skip_button"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_marginTop="8dp"
-                    android:text="@string/fingerprint_enroll_button_next" />
+                    android:text="@string/skip_label" />
 
             </LinearLayout>
 
diff --git a/res/layout/choose_lock_password_footer.xml b/res/layout/choose_lock_password_footer.xml
index 57be320..323a884 100644
--- a/res/layout/choose_lock_password_footer.xml
+++ b/res/layout/choose_lock_password_footer.xml
@@ -38,6 +38,6 @@
         style="@style/SuwGlifButton.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/lockpassword_continue_label" />
+        android:text="@string/next_label" />
 
 </LinearLayout>
diff --git a/res/layout/dashboard_header_spacer.xml b/res/layout/dashboard_header_spacer.xml
deleted file mode 100644
index 442ae48..0000000
--- a/res/layout/dashboard_header_spacer.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:padding="@dimen/search_bar_margin">
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="?android:attr/actionBarSize"/>
-</LinearLayout>
diff --git a/res/layout/fingerprint_enroll_enrolling_base.xml b/res/layout/fingerprint_enroll_enrolling_base.xml
index e312c50..c1d1a7f 100644
--- a/res/layout/fingerprint_enroll_enrolling_base.xml
+++ b/res/layout/fingerprint_enroll_enrolling_base.xml
@@ -17,10 +17,12 @@
 
 <com.android.setupwizardlib.GlifLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/setup_wizard_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    style="?attr/fingerprint_layout_theme">
+    style="?attr/fingerprint_layout_theme"
+    app:suwFooter="@layout/fingerprint_enroll_enrolling_base_footer">
 
     <LinearLayout
         style="@style/SuwContentFrame"
@@ -58,8 +60,7 @@
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="0dp"
-            android:layout_weight="1"
-            android:paddingBottom="80dp">
+            android:layout_weight="1">
 
             <include layout="@layout/fingerprint_enroll_enrolling_content"
                 android:layout_width="@dimen/fingerprint_progress_bar_max_size"
diff --git a/res/layout/fingerprint_enroll_enrolling_base_footer.xml b/res/layout/fingerprint_enroll_enrolling_base_footer.xml
new file mode 100644
index 0000000..b4ed37e
--- /dev/null
+++ b/res/layout/fingerprint_enroll_enrolling_base_footer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/SuwGlifButtonBar"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <Button
+        style="@style/SuwGlifButton.Secondary"
+        android:id="@+id/skip_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/security_settings_fingerprint_enroll_enrolling_skip" />
+
+</LinearLayout>
diff --git a/res/layout/fingerprint_enroll_find_sensor_base.xml b/res/layout/fingerprint_enroll_find_sensor_base.xml
index fa344ab..44455c5 100644
--- a/res/layout/fingerprint_enroll_find_sensor_base.xml
+++ b/res/layout/fingerprint_enroll_find_sensor_base.xml
@@ -17,10 +17,12 @@
 
 <com.android.setupwizardlib.GlifLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/setup_wizard_layout"
     style="?attr/fingerprint_layout_theme"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    app:suwFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
 
     <FrameLayout
         android:layout_width="match_parent"
@@ -56,7 +58,7 @@
                 android:layout_weight="1"/>
 
             <Button
-                style="@style/SuwGlifButton.Primary"
+                style="@style/SuwGlifButton.Secondary"
                 android:id="@+id/next_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/res/layout/fingerprint_enroll_find_sensor_base_footer.xml b/res/layout/fingerprint_enroll_find_sensor_base_footer.xml
new file mode 100644
index 0000000..e93fae9
--- /dev/null
+++ b/res/layout/fingerprint_enroll_find_sensor_base_footer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2017 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.
+-->
+
+<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/SuwGlifButtonBar"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <Button
+        style="@style/SuwGlifButton.Secondary"
+        android:id="@+id/skip_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/skip_label" />
+
+</LinearLayout>
diff --git a/res/layout/settings_main_dashboard.xml b/res/layout/settings_main_dashboard.xml
index 1a3b133..189c732 100644
--- a/res/layout/settings_main_dashboard.xml
+++ b/res/layout/settings_main_dashboard.xml
@@ -17,32 +17,36 @@
 */
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_width="match_parent">
+    android:orientation="vertical">
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/material_grey_300">
+        <android.support.v7.widget.CardView
+            android:id="@+id/search_bar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/search_bar_margin"
+            app:cardCornerRadius="2dp"
+            app:cardBackgroundColor="?android:attr/colorBackground"
+            app:cardElevation="2dp">
+            <Toolbar
+                android:id="@+id/search_action_bar"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="?android:attr/selectableItemBackground"
+                android:contentInsetStartWithNavigation="64dp"
+                android:navigationIcon="@drawable/ic_search_24dp"
+                android:titleTextColor="@*android:color/text_color_primary"
+                android:theme="?android:attr/actionBarTheme"/>
+        </android.support.v7.widget.CardView>
+    </FrameLayout>
     <FrameLayout
         android:id="@+id/main_content"
         android:layout_height="match_parent"
         android:layout_width="match_parent"/>
-    <android.support.v7.widget.CardView
-        android:id="@+id/search_bar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="@dimen/search_bar_margin"
-        app:cardCornerRadius="2dp"
-        app:cardBackgroundColor="?android:attr/colorBackground"
-        app:cardElevation="2dp">
-        <Toolbar
-            android:id="@+id/search_action_bar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/search_bar_negative_margin"
-            android:background="?android:attr/selectableItemBackground"
-            android:navigationIcon="@drawable/ic_search_24dp"
-            android:title="@string/search_menu"
-            android:titleTextAppearance="?android:attr/subtitleTextAppearance"
-            android:titleTextColor="?android:attr/textColorHint"
-            android:theme="?android:attr/actionBarTheme"/>
-    </android.support.v7.widget.CardView>
-</FrameLayout>
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9580206..28968d4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -872,6 +872,8 @@
     <string name="security_settings_fingerprint_enroll_finish_title">Fingerprint added</string>
     <!-- Message shown in fingerprint enrollment dialog once enrollment is completed -->
     <string name="security_settings_fingerprint_enroll_finish_message">When you see this icon, use your fingerprint for identification or to approve purchases.</string>
+    <!-- Button text to skip enrollment of fingerprint [CHAR LIMIT=40] -->
+    <string name="security_settings_fingerprint_enroll_enrolling_skip">Do it later</string>
     <!-- Title of the dialog shown when the user tries to skip fingerprint setup, asking them to confirm the action [CHAR LIMIT=40] -->
     <string name="setup_fingerprint_enroll_enrolling_skip_title">Skip fingerprint setup?</string>
     <!-- Content of the dialog shown when the user tries to skip fingerprint setup, asking them to confirm the action [CHAR LIMIT=NONE] -->
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index 5ea8836..1cbeecd 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -23,6 +23,7 @@
     <Preference
         android:key="phone_language"
         android:title="@string/phone_language"
+        android:icon="@drawable/ic_translate_24dp"
         android:fragment="com.android.settings.localepicker.LocaleListEditor"/>
 
     <PreferenceCategory
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index f61dfd3..556dbfb 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -87,8 +87,6 @@
     private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
     @VisibleForTesting
     static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
-    @VisibleForTesting
-    static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
 
     /**
      * When starting this activity, the invoking Intent can contain this extra
@@ -192,22 +190,18 @@
 
     private DynamicIndexableContentMonitor mDynamicIndexableContentMonitor;
 
-    private ActionBar mActionBar;
     private SwitchBar mSwitchBar;
 
     private Button mNextButton;
 
     @VisibleForTesting
     boolean mDisplayHomeAsUpEnabled;
-    @VisibleForTesting
-    boolean mDisplaySearch;
 
     private boolean mIsShowingDashboard;
     private boolean mIsShortcut;
 
     private ViewGroup mContent;
 
-    private SearchFeatureProvider mSearchFeatureProvider;
     private MetricsFeatureProvider mMetricsFeatureProvider;
 
     // Categories
@@ -233,15 +227,6 @@
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        if (!mDisplaySearch) {
-            return false;
-        }
-        mSearchFeatureProvider.setUpSearchMenu(menu, this);
-        return true;
-    }
-
-    @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         if (name.equals(getPackageName() + "_preferences")) {
             return new SharedPreferencesLogger(this, getMetricsTag());
@@ -284,7 +269,6 @@
         final FeatureFactory factory = FeatureFactory.getFactory(this);
 
         mDashboardFeatureProvider = factory.getDashboardFeatureProvider(this);
-        mSearchFeatureProvider = factory.getSearchFeatureProvider();
         mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
 
         // Should happen before any call to getIntent()
@@ -324,7 +308,7 @@
         setContentView(mIsShowingDashboard ?
                 R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
 
-        mContent = (ViewGroup) findViewById(R.id.main_content);
+        mContent = findViewById(R.id.main_content);
 
         getFragmentManager().addOnBackStackChangedListener(this);
 
@@ -353,14 +337,22 @@
             Toolbar toolbar = findViewById(R.id.search_action_bar);
             toolbar.setOnClickListener(this);
             setActionBar(toolbar);
+
+            // Please forgive me for what I am about to do.
+            //
+            // Need to make the navigation icon non-clickable so that the entire card is clickable
+            // and goes to the search UI. Also set the background to null so there's no ripple.
+            View navView = toolbar.getNavigationView();
+            navView.setClickable(false);
+            navView.setBackground(null);
         }
 
-        mActionBar = getActionBar();
-        if (mActionBar != null) {
-            mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
-            mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
+            actionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
         }
-        mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
+        mSwitchBar = findViewById(R.id.switch_bar);
         if (mSwitchBar != null) {
             mSwitchBar.setMetricsTag(getMetricsTag());
         }
@@ -427,7 +419,6 @@
     @VisibleForTesting
     void launchSettingFragment(String initialFragmentName, boolean isSubSettings, Intent intent) {
         if (!mIsShowingDashboard && initialFragmentName != null) {
-            mDisplaySearch = false;
             // UP will be shown only if it is a sub settings
             if (mIsShortcut) {
                 mDisplayHomeAsUpEnabled = isSubSettings;
@@ -444,8 +435,6 @@
         } else {
             // Show search icon as up affordance if we are displaying the main Dashboard
             mDisplayHomeAsUpEnabled = true;
-            // toolbar is search affordance so don't show search
-            mDisplaySearch = false;
             mInitialTitleResId = R.string.dashboard_title;
 
             switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
@@ -453,13 +442,6 @@
         }
     }
 
-    public void setDisplaySearchMenu(boolean displaySearch) {
-        if (displaySearch != mDisplaySearch) {
-            mDisplaySearch = displaySearch;
-            invalidateOptionsMenu();
-        }
-    }
-
     private void setTitleFromIntent(Intent intent) {
         final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
         if (initialTitleResId > 0) {
@@ -540,7 +522,6 @@
         }
 
         outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
-        outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
     }
 
     @Override
@@ -548,19 +529,13 @@
         super.onRestoreInstanceState(savedInstanceState);
 
         mDisplayHomeAsUpEnabled = savedInstanceState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
-        mDisplaySearch = savedInstanceState.getBoolean(SAVE_KEY_SHOW_SEARCH);
     }
 
     @Override
     protected void onResume() {
         super.onResume();
 
-        mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
-            @Override
-            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-                updateTilesList();
-            }
-        };
+        mDevelopmentPreferencesListener = (sharedPreferences, key) -> updateTilesList();
         mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
                 mDevelopmentPreferencesListener);
 
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
index c81e1ee..2445619 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
@@ -20,6 +20,11 @@
 
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
@@ -36,15 +41,42 @@
     public static final String KEY_DEVICE_ADDRESS = "device_address";
     private static final String TAG = "BTDeviceDetailsFrg";
 
+    @VisibleForTesting
+    static int EDIT_DEVICE_NAME_ITEM_ID = Menu.FIRST;
+
     private String mDeviceAddress;
+    private LocalBluetoothManager mManager;
+    private CachedBluetoothDevice mCachedDevice;
 
     public BluetoothDeviceDetailsFragment() {
         super(DISALLOW_CONFIG_BLUETOOTH);
     }
 
+    @VisibleForTesting
+    LocalBluetoothManager getLocalBluetoothManager(Context context) {
+        return Utils.getLocalBtManager(context);
+    }
+
+    @VisibleForTesting
+    CachedBluetoothDevice getCachedDevice(String deviceAddress) {
+        BluetoothDevice remoteDevice =
+                mManager.getBluetoothAdapter().getRemoteDevice(deviceAddress);
+        return mManager.getCachedDeviceManager().findDevice(remoteDevice);
+    }
+
+    public static BluetoothDeviceDetailsFragment newInstance(String deviceAddress) {
+        Bundle args = new Bundle(1);
+        args.putString(KEY_DEVICE_ADDRESS, deviceAddress);
+        BluetoothDeviceDetailsFragment fragment = new BluetoothDeviceDetailsFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
     @Override
     public void onAttach(Context context) {
         mDeviceAddress = getArguments().getString(KEY_DEVICE_ADDRESS);
+        mManager = getLocalBluetoothManager(context);
+        mCachedDevice = getCachedDevice(mDeviceAddress);
         super.onAttach(context);
     }
 
@@ -64,20 +96,36 @@
     }
 
     @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        MenuItem item = menu.add(0, EDIT_DEVICE_NAME_ITEM_ID, 0, R.string.bluetooth_rename_button);
+        item.setIcon(R.drawable.ic_mode_edit);
+        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem menuItem) {
+        if (menuItem.getItemId() == EDIT_DEVICE_NAME_ITEM_ID) {
+            RemoteDeviceNameDialogFragment.newInstance(mCachedDevice).show(
+                    getFragmentManager(), RemoteDeviceNameDialogFragment.TAG);
+            return true;
+        }
+        return super.onOptionsItemSelected(menuItem);
+    }
+
+    @Override
     protected List<PreferenceController> getPreferenceControllers(Context context) {
         ArrayList<PreferenceController> controllers = new ArrayList<>();
-        LocalBluetoothManager manager = Utils.getLocalBtManager(context);
-        BluetoothDevice remoteDevice = manager.getBluetoothAdapter().getRemoteDevice(
-                mDeviceAddress);
-        CachedBluetoothDevice device = manager.getCachedDeviceManager().findDevice(remoteDevice);
-        if (device != null) {
+
+        if (mCachedDevice != null) {
             Lifecycle lifecycle = getLifecycle();
-            controllers.add(new BluetoothDetailsHeaderController(context, this, device, lifecycle));
-            controllers.add(new BluetoothDetailsButtonsController(context, this, device,
+            controllers.add(new BluetoothDetailsHeaderController(context, this, mCachedDevice,
                     lifecycle));
-            controllers.add(new BluetoothDetailsProfilesController(context, this, manager, device,
+            controllers.add(new BluetoothDetailsButtonsController(context, this, mCachedDevice,
                     lifecycle));
-            controllers.add(new BluetoothDetailsMacAddressController(context, this, device,
+            controllers.add(new BluetoothDetailsProfilesController(context, this, mManager,
+                    mCachedDevice, lifecycle));
+            controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
                     lifecycle));
         }
         return controllers;
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index baab3fc..7e826c8 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -37,7 +37,6 @@
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnResume;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
@@ -111,7 +110,8 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (KEY_DEVICE_NAME.equals(preference.getKey())) {
-            new BluetoothNameDialogFragment().show(mFragment.getFragmentManager(), "rename device");
+            LocalDeviceNameDialogFragment.newInstance()
+                    .show(mFragment.getFragmentManager(), LocalDeviceNameDialogFragment.TAG);
             return true;
         }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
index 484d4b3..e415b47 100644
--- a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
@@ -18,19 +18,13 @@
 
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.TextWatcher;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -40,25 +34,19 @@
 import android.widget.EditText;
 import android.widget.TextView;
 
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
-import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
 /**
- * Dialog fragment for renaming the local Bluetooth device.
+ * Dialog fragment for renaming a Bluetooth device.
  */
-public final class BluetoothNameDialogFragment extends InstrumentedDialogFragment
+abstract class BluetoothNameDialogFragment extends InstrumentedDialogFragment
         implements TextWatcher {
     private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
 
     private AlertDialog mAlertDialog;
     private Button mOkButton;
 
-    // accessed from inner class (not private to avoid thunks)
-    static final String TAG = "BluetoothNameDialogFragment";
-    LocalBluetoothAdapter mLocalAdapter;
     EditText mDeviceNameView;
 
     // This flag is set when the name is updated by code, to distinguish from user changes
@@ -71,63 +59,43 @@
     private static final String KEY_NAME = "device_name";
     private static final String KEY_NAME_EDITED = "device_name_edited";
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
-                updateDeviceName();
-            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
-                    (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
-                            BluetoothAdapter.STATE_ON)) {
-                updateDeviceName();
-            }
-        }
-    };
+    /**
+     * @return the title to use for the dialog.
+     */
+    abstract protected int getDialogTitle();
 
-    @Override
-    public int getMetricsCategory() {
-        return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_RENAME;
-    }
+    /**
+     * @return the current name used for this device.
+     */
+    abstract protected String getDeviceName();
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        LocalBluetoothManager localManager = Utils.getLocalBtManager(getActivity());
-        mLocalAdapter = localManager.getBluetoothAdapter();
-    }
+    /**
+     * Set the device to the given name.
+     * @param deviceName the name to use
+     */
+    abstract protected void setDeviceName(String deviceName);
 
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        String deviceName = mLocalAdapter.getName();
+        String deviceName = getDeviceName();
         if (savedInstanceState != null) {
             deviceName = savedInstanceState.getString(KEY_NAME, deviceName);
             mDeviceNameEdited = savedInstanceState.getBoolean(KEY_NAME_EDITED, false);
         }
-        mAlertDialog = new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.bluetooth_rename_device)
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+                .setTitle(getDialogTitle())
                 .setView(createDialogView(deviceName))
-                .setPositiveButton(R.string.bluetooth_rename_button,
-                        new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int which) {
-                                String deviceName = mDeviceNameView.getText().toString();
-                                setDeviceName(deviceName);
-                            }
-                        })
-                .setNegativeButton(android.R.string.cancel, null)
-                .create();
+                .setPositiveButton(R.string.bluetooth_rename_button, (dialog, which) -> {
+                    setDeviceName(mDeviceNameView.getText().toString());
+                })
+                .setNegativeButton(android.R.string.cancel, null);
+        mAlertDialog = builder.create();
         mAlertDialog.getWindow().setSoftInputMode(
                 WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
 
         return mAlertDialog;
     }
 
-    private void setDeviceName(String deviceName) {
-        Log.d(TAG, "Setting device name to " + deviceName);
-        mLocalAdapter.setName(deviceName);
-    }
-
     @Override
     public void onSaveInstanceState(Bundle outState) {
         outState.putString(KEY_NAME, mDeviceNameView.getText().toString());
@@ -174,23 +142,14 @@
             mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
             mOkButton.setEnabled(mDeviceNameEdited);    // Ok button enabled after user edits
         }
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
-        getActivity().registerReceiver(mReceiver, filter);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        getActivity().unregisterReceiver(mReceiver);
     }
 
     void updateDeviceName() {
-        if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+        String name = getDeviceName();
+        if (name != null) {
             mDeviceNameUpdated = true;
             mDeviceNameEdited = false;
-            mDeviceNameView.setText(mLocalAdapter.getName());
+            mDeviceNameView.setText(name);
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 4703031..85eb23e 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -316,7 +316,6 @@
             // New version - uses a separate screen.
             args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS,
                     device.getDevice().getAddress());
-            BluetoothDeviceDetailsFragment fragment = new BluetoothDeviceDetailsFragment();
             final SettingsActivity activity =
                     (SettingsActivity) BluetoothSettings.this.getActivity();
             activity.startPreferencePanel(this,
diff --git a/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java
new file mode 100644
index 0000000..029b974
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalDeviceNameDialogFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+/** Provides a dialog for changing the advertised name of the local bluetooth adapter. */
+public class LocalDeviceNameDialogFragment extends BluetoothNameDialogFragment {
+    public static final String TAG = "LocalAdapterName";
+    private LocalBluetoothAdapter mLocalAdapter;
+
+    public static LocalDeviceNameDialogFragment newInstance() {
+        return new LocalDeviceNameDialogFragment();
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action) ||
+                    (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action) &&
+                            intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
+                                    == BluetoothAdapter.STATE_ON)) {
+                updateDeviceName();
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        LocalBluetoothManager localManager = Utils.getLocalBtManager(getActivity());
+        mLocalAdapter = localManager.getBluetoothAdapter();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        getActivity().registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        getActivity().unregisterReceiver(mReceiver);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_RENAME;
+    }
+
+    @Override
+    protected int getDialogTitle() {
+        return R.string.bluetooth_rename_device;
+    }
+
+    @Override
+    protected String getDeviceName() {
+        if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+            return mLocalAdapter.getName();
+        }
+        return null;
+    }
+
+    @Override
+    protected void setDeviceName(String deviceName) {
+        mLocalAdapter.setName(deviceName);
+    }
+}
diff --git a/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragment.java b/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragment.java
new file mode 100644
index 0000000..4e5acefe
--- /dev/null
+++ b/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragment.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+/** Provides a dialog for changing the display name of a remote bluetooth device. */
+public class RemoteDeviceNameDialogFragment extends BluetoothNameDialogFragment {
+    public static final String TAG = "RemoteDeviceName";
+    private static final String KEY_CACHED_DEVICE_ADDRESS = "cached_device";
+
+    private CachedBluetoothDevice mDevice;
+
+    public static RemoteDeviceNameDialogFragment newInstance(CachedBluetoothDevice device) {
+        Bundle args = new Bundle(1);
+        args.putString(KEY_CACHED_DEVICE_ADDRESS, device.getDevice().getAddress());
+        RemoteDeviceNameDialogFragment fragment = new RemoteDeviceNameDialogFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @VisibleForTesting
+    CachedBluetoothDevice getDevice(Context context) {
+        String deviceAddress = getArguments().getString(KEY_CACHED_DEVICE_ADDRESS);
+        LocalBluetoothManager manager = Utils.getLocalBtManager(context);
+        BluetoothDevice device = manager.getBluetoothAdapter().getRemoteDevice(deviceAddress);
+        return manager.getCachedDeviceManager().findDevice(device);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        mDevice = getDevice(context);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME;
+    }
+
+    @Override
+    protected int getDialogTitle() {
+        return R.string.bluetooth_device_name;
+    }
+
+    @Override
+    protected String getDeviceName() {
+        if (mDevice != null) {
+            return mDevice.getName();
+        }
+        return null;
+    }
+
+    @Override
+    protected void setDeviceName(String deviceName) {
+        if (mDevice != null) {
+            mDevice.setName(deviceName);
+        }
+    }
+}
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 8e795cb..38c6a28 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -65,7 +65,6 @@
     private static final String STATE_CATEGORY_LIST = "category_list";
     private static final String STATE_SUGGESTION_MODE = "suggestion_mode";
     private static final String STATE_SUGGESTIONS_SHOWN_LOGGED = "suggestions_shown_logged";
-    private static final int DONT_SET_BACKGROUND_ATTR = -1;
     private static final String STATE_SUGGESTION_CONDITION_MODE = "suggestion_condition_mode";
 
     private final IconCache mCache;
@@ -305,9 +304,6 @@
     public void onBindViewHolder(DashboardItemHolder holder, int position) {
         final int type = mDashboardData.getItemTypeByPosition(position);
         switch (type) {
-            case R.layout.dashboard_header_spacer:
-                onBindHeaderSpacer(holder, position);
-                break;
             case R.layout.dashboard_category:
                 onBindCategory(holder,
                         (DashboardCategory) mDashboardData.getItemEntityByPosition(position));
@@ -484,33 +480,6 @@
         notifyDashboardDataChanged(prevData);
     }
 
-    private void onBindHeaderSpacer(DashboardItemHolder holder, int position) {
-        if (mDashboardData.size() > (position + 1)) {
-            // The spacer that goes underneath the search bar needs to match the
-            // background of the first real view. That view is either a condition,
-            // a suggestion, or the dashboard item.
-            //
-            // If it's a dashboard item, set null background so it uses the parent's
-            // background like the other views. Otherwise, match the colors.
-            int nextType = mDashboardData.getItemTypeByPosition(position + 1);
-            int colorAttr = nextType == R.layout.suggestion_header
-                    ? android.R.attr.colorSecondary
-                    : nextType == R.layout.condition_card
-                            ? android.R.attr.colorAccent
-                            : DONT_SET_BACKGROUND_ATTR;
-
-            if (colorAttr != DONT_SET_BACKGROUND_ATTR) {
-                TypedArray array = holder.itemView.getContext()
-                        .obtainStyledAttributes(new int[]{colorAttr});
-                @ColorInt int color = array.getColor(0, 0);
-                array.recycle();
-                holder.itemView.setBackgroundColor(color);
-            } else {
-                holder.itemView.setBackground(null);
-            }
-        }
-    }
-
     @VisibleForTesting
     void onBindSuggestionHeader(final DashboardItemHolder holder, DashboardData
             .SuggestionHeaderData data) {
diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java
index 64e8af2..6f776b2 100644
--- a/src/com/android/settings/dashboard/DashboardData.java
+++ b/src/com/android/settings/dashboard/DashboardData.java
@@ -60,8 +60,7 @@
     public static final int DEFAULT_SUGGESTION_COUNT = 2;
 
     // id namespace for different type of items.
-    private static final int NS_HEADER_SPACER = 0;
-    private static final int NS_SPACER = 1000;
+    private static final int NS_SPACER = 0;
     private static final int NS_ITEMS = 2000;
     private static final int NS_CONDITION = 3000;
     private static final int NS_SUGGESTION_CONDITION = 4000;
@@ -283,9 +282,6 @@
      * and mIsShowingAll, mSuggestionMode flag.
      */
     private void buildItemsData() {
-        // add the view that goes under the search bar
-        countItem(null, R.layout.dashboard_header_spacer, true, NS_HEADER_SPACER);
-        resetCount();
         final boolean hasSuggestions = sizeOf(mSuggestions) > 0;
         if (!mCombineSuggestionAndCondition) {
             boolean hasConditions = false;
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
index 14c5ae2..11a84bc 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollEnrolling.java
@@ -36,6 +36,7 @@
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
+import android.widget.Button;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
@@ -98,6 +99,10 @@
         mRepeatMessage = (TextView) findViewById(R.id.repeat_message);
         mErrorText = (TextView) findViewById(R.id.error_text);
         mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar);
+
+        Button skipButton = findViewById(R.id.skip_button);
+        skipButton.setOnClickListener(this);
+
         final LayerDrawable fingerprintDrawable = (LayerDrawable) mProgressBar.getBackground();
         mIconAnimationDrawable = (AnimatedVectorDrawable)
                 fingerprintDrawable.findDrawableByLayerId(R.id.fingerprint_animation);
@@ -211,6 +216,18 @@
         super.onBackPressed();
     }
 
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.skip_button:
+                setResult(RESULT_SKIP);
+                finish();
+                break;
+            default:
+                super.onClick(v);
+        }
+    }
+
     private void animateProgress(int progress) {
         if (mProgressAnim != null) {
             mProgressAnim.cancel();
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
index e34a90b..1902a52 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
@@ -22,6 +22,7 @@
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
 import android.view.View;
+import android.widget.Button;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -48,6 +49,9 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(getContentView());
+        Button skipButton = findViewById(R.id.skip_button);
+        skipButton.setOnClickListener(this);
+
         setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
         if (savedInstanceState != null) {
             mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM);
@@ -132,9 +136,15 @@
     }
 
     @Override
-    protected void onNextButtonClick() {
-        mNextClicked = true;
-        proceedToEnrolling(true /* cancelEnrollment */);
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case R.id.skip_button:
+                setResult(RESULT_SKIP);
+                finish();
+                break;
+            default:
+                super.onClick(v);
+        }
     }
 
     private void proceedToEnrolling(boolean cancelEnrollment) {
diff --git a/src/com/android/settings/fingerprint/SetupFingerprintEnrollFinish.java b/src/com/android/settings/fingerprint/SetupFingerprintEnrollFinish.java
index 43ff097..02f6cb8 100644
--- a/src/com/android/settings/fingerprint/SetupFingerprintEnrollFinish.java
+++ b/src/com/android/settings/fingerprint/SetupFingerprintEnrollFinish.java
@@ -19,8 +19,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.UserHandle;
-import android.view.View;
-import android.widget.TextView;
+import android.widget.Button;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -49,6 +48,8 @@
     @Override
     protected void initViews() {
         super.initViews();
+        Button nextButton = findViewById(R.id.next_button);
+        nextButton.setText(R.string.next_label);
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index e9863b3..5eada88 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -227,8 +227,9 @@
                 final String chargeStatusLabel = resources.getString(
                         R.string.battery_info_status_charging_lower);
                 info.remainingLabel = null;
-                info.chargeLabel = resources.getString(
-                        R.string.power_charging, info.batteryPercentString, chargeStatusLabel);
+                info.chargeLabel = info.batteryLevel == 100 ? info.batteryPercentString :
+                        resources.getString(R.string.power_charging, info.batteryPercentString,
+                                chargeStatusLabel);
             }
         }
         return info;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index e4ae053..730f061 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -46,6 +46,7 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
 import android.widget.TextView;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatterySipper.DrainType;
@@ -69,6 +70,7 @@
 import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -574,31 +576,8 @@
                 if (((int) (percentOfTotal + .5)) < 1) {
                     continue;
                 }
-                if (sipper.drainType == BatterySipper.DrainType.OVERCOUNTED) {
-                    // Don't show over-counted unless it is at least 2/3 the size of
-                    // the largest real entry, and its percent of total is more significant
-                    if (sipper.totalPowerMah < ((mStatsHelper.getMaxRealPower() * 2) / 3)) {
-                        continue;
-                    }
-                    if (percentOfTotal < 10) {
-                        continue;
-                    }
-                    if ("user".equals(Build.TYPE)) {
-                        continue;
-                    }
-                }
-                if (sipper.drainType == BatterySipper.DrainType.UNACCOUNTED) {
-                    // Don't show over-counted unless it is at least 1/2 the size of
-                    // the largest real entry, and its percent of total is more significant
-                    if (sipper.totalPowerMah < (mStatsHelper.getMaxRealPower() / 2)) {
-                        continue;
-                    }
-                    if (percentOfTotal < 5) {
-                        continue;
-                    }
-                    if ("user".equals(Build.TYPE)) {
-                        continue;
-                    }
+                if (shouldHideSipper(sipper)) {
+                    continue;
                 }
                 final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid()));
                 final BatteryEntry entry = new BatteryEntry(getActivity(), mHandler, mUm, sipper);
@@ -649,6 +628,13 @@
     }
 
     @VisibleForTesting
+    boolean shouldHideSipper(BatterySipper sipper) {
+        // Don't show over-counted and unaccounted in any condition
+        return sipper.drainType == BatterySipper.DrainType.OVERCOUNTED
+                || sipper.drainType == BatterySipper.DrainType.UNACCOUNTED;
+    }
+
+    @VisibleForTesting
     void refreshAnomalyIcon() {
         for (int i = 0, size = mAnomalySparseArray.size(); i < size; i++) {
             final String key = extractKeyFromUid(mAnomalySparseArray.keyAt(i));
diff --git a/src/com/android/settings/gestures/AssistGestureFeatureProvider.java b/src/com/android/settings/gestures/AssistGestureFeatureProvider.java
index 8902393..447562d 100644
--- a/src/com/android/settings/gestures/AssistGestureFeatureProvider.java
+++ b/src/com/android/settings/gestures/AssistGestureFeatureProvider.java
@@ -32,9 +32,6 @@
     /** Returns true if the sensor is available. */
     boolean isSensorAvailable(Context context);
 
-    /** Returns the resource */
-    int getPreferenceResourceId();
-
     /** Returns a list of additional preference controllers */
     List<PreferenceController> getControllers(Context context, Lifecycle lifecycle);
 
diff --git a/src/com/android/settings/gestures/AssistGestureFeatureProviderImpl.java b/src/com/android/settings/gestures/AssistGestureFeatureProviderImpl.java
index a2579ac..4509862 100644
--- a/src/com/android/settings/gestures/AssistGestureFeatureProviderImpl.java
+++ b/src/com/android/settings/gestures/AssistGestureFeatureProviderImpl.java
@@ -38,11 +38,6 @@
     }
 
     @Override
-    public int getPreferenceResourceId() {
-        return R.xml.assist_gesture_settings;
-    }
-
-    @Override
     public List<PreferenceController> getControllers(Context context, Lifecycle lifecycle) {
         return new ArrayList<>();
     }
diff --git a/src/com/android/settings/gestures/AssistGestureSettings.java b/src/com/android/settings/gestures/AssistGestureSettings.java
index 7e8d8db..dd0a991 100644
--- a/src/com/android/settings/gestures/AssistGestureSettings.java
+++ b/src/com/android/settings/gestures/AssistGestureSettings.java
@@ -49,8 +49,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return FeatureFactory.getFactory(getContext())
-                .getAssistGestureFeatureProvider().getPreferenceResourceId();
+        return R.xml.assist_gesture_settings;
     }
 
     @Override
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index b6f2387..2f359d1 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -241,7 +241,7 @@
                     R.string.lockpassword_choose_your_password_header_for_fingerprint,
                     R.string.lockpassword_choose_your_pin_header,
                     R.string.lockpassword_choose_your_pin_header_for_fingerprint,
-                    R.string.lockpassword_continue_label),
+                    R.string.next_label),
 
             NeedToConfirm(
                     R.string.lockpassword_confirm_your_password_header,
@@ -255,7 +255,7 @@
                     R.string.lockpassword_confirm_passwords_dont_match,
                     R.string.lockpassword_confirm_pins_dont_match,
                     R.string.lockpassword_confirm_pins_dont_match,
-                    R.string.lockpassword_continue_label);
+                    R.string.next_label);
 
             Stage(int hintInAlpha, int hintInAlphaForFingerprint,
                     int hintInNumeric, int hintInNumericForFingerprint, int nextButtonText) {
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 1ae2af2..51c1569 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -305,8 +305,8 @@
          * The states of the right button.
          */
         enum RightButtonMode {
-            Continue(R.string.lockpattern_continue_button_text, true),
-            ContinueDisabled(R.string.lockpattern_continue_button_text, false),
+            Continue(R.string.next_label, true),
+            ContinueDisabled(R.string.next_label, false),
             Confirm(R.string.lockpattern_confirm_button_text, true),
             ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
             Ok(android.R.string.ok, true);
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 50edae7..8b589cd 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -37,14 +37,6 @@
     boolean isEnabled(Context context);
 
     /**
-     * Inserts the Menu items into Settings activity.
-     *
-     * @param menu Items will be inserted into this menu.
-     * @param activity The activity that precedes SearchActivity.
-     */
-    void setUpSearchMenu(Menu menu, Activity activity);
-
-    /**
      * Returns a new loader to search in index database.
      */
     DatabaseResultLoader getDatabaseSearchLoader(Context context, String query);
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index 8bb57c6..99771db 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -44,23 +44,6 @@
     }
 
     @Override
-    public void setUpSearchMenu(Menu menu, final Activity activity) {
-        if (menu == null || activity == null) {
-            return;
-        }
-        String menuTitle = activity.getString(R.string.search_menu);
-        MenuItem menuItem = menu.add(Menu.NONE, Menu.NONE, Menu.NONE, menuTitle)
-                .setIcon(R.drawable.ic_search_24dp)
-                .setOnMenuItemClickListener(item -> {
-                    Intent intent = new Intent(activity, SearchActivity.class);
-                    activity.startActivity(intent);
-                    return true;
-                });
-
-        menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-    }
-
-    @Override
     public DatabaseResultLoader getDatabaseSearchLoader(Context context, String query) {
         return new DatabaseResultLoader(context, query, getSiteMapManager());
     }
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index 84c299e..a50a1d9 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -61,7 +61,6 @@
         super.onAttach(context);
         mProgressiveDisclosureMixin.setTileLimit(
             mUseOpenWifiPreferenceController.isAvailable() ? 3 : 2);
-        ((SettingsActivity) getActivity()).setDisplaySearchMenu(true);
     }
 
     @Override
diff --git a/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml b/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
index 04489de..cedf5b9 100644
--- a/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
+++ b/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
@@ -17,10 +17,12 @@
 
 <com.android.setupwizardlib.GlifLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/setup_wizard_layout"
     style="?attr/fingerprint_layout_theme"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    app:suwFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
 
     <FrameLayout
         android:layout_width="match_parent"
@@ -65,7 +67,7 @@
                 android:layout_weight="1"/>
 
             <Button
-                style="@style/SuwGlifButton.Primary"
+                style="@style/SuwGlifButton.Secondary"
                 android:id="@+id/next_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 28babc2..3fc46e8 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -67,15 +67,10 @@
     private Bitmap mBitmap;
     private SettingsActivity mActivity;
 
-    private FakeFeatureFactory mFeatureFactory;
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        FakeFeatureFactory.setupForTest(mContext);
-        mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
-
         mActivity = spy(new SettingsActivity());
         doReturn(mBitmap).when(mActivity).getBitmapFromXmlResource(anyInt());
     }
@@ -99,26 +94,6 @@
     }
 
     @Test
-    public void testCreateOptionsMenu_setsUpSearch() {
-        ReflectionHelpers.setField(mActivity, "mSearchFeatureProvider",
-                mFeatureFactory.getSearchFeatureProvider());
-        mActivity.mDisplaySearch = true;
-        mActivity.onCreateOptionsMenu(null);
-
-        verify(mFeatureFactory.getSearchFeatureProvider()).setUpSearchMenu(nullable(Menu.class),
-                nullable(Activity.class));
-    }
-
-    @Test
-    public void testSaveState_DisplaySearchSaved() {
-        mActivity.mDisplaySearch = true;
-        Bundle bundle = new Bundle();
-        mActivity.saveState(bundle);
-
-        assertThat((boolean) bundle.get(SettingsActivity.SAVE_KEY_SHOW_SEARCH)).isTrue();
-    }
-
-    @Test
     public void testSaveState_EnabledHomeSaved() {
         mActivity.mDisplayHomeAsUpEnabled = true;
         Bundle bundle = new Bundle();
@@ -128,24 +103,6 @@
     }
 
     @Test
-    public void testRestoreState_DisplaySearchRestored() {
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(SettingsActivity.SAVE_KEY_SHOW_SEARCH, true);
-        mActivity.onRestoreInstanceState(bundle);
-
-        assertThat(mActivity.mDisplaySearch).isTrue();
-    }
-
-    @Test
-    public void testRestoreState_EnabledHomeRestored() {
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(SettingsActivity.SAVE_KEY_SHOW_SEARCH, true);
-        mActivity.onRestoreInstanceState(bundle);
-
-        assertThat(mActivity.mDisplaySearch).isTrue();
-    }
-
-    @Test
     public void testOnClick() {
         doReturn("com.android.settings").when(mActivity).getPackageName();
 
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
new file mode 100644
index 0000000..7bd1203
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.fakes.RoboMenu;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BluetoothDeviceDetailsFragmentTest {
+    private BluetoothDeviceDetailsFragment mFragment;
+    private Context mContext;
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private CachedBluetoothDevice mCachedDevice;
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private LocalBluetoothManager mLocalManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        FakeFeatureFactory.setupForTest(mContext);
+
+        String deviceAddress = "55:66:77:88:99:AA";
+        mFragment = spy(BluetoothDeviceDetailsFragment.newInstance(deviceAddress));
+        doReturn(mLocalManager).when(mFragment).getLocalBluetoothManager(any());
+        doReturn(mCachedDevice).when(mFragment).getCachedDevice(any());
+
+        when(mCachedDevice.getDevice().getAddress()).thenReturn(deviceAddress);
+        Bundle args = new Bundle();
+        args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, deviceAddress);
+        mFragment.setArguments(args);
+        mFragment.onAttach(mContext);
+    }
+
+    @Test
+    public void renameControlGetsAdded() {
+        RoboMenu menu = new RoboMenu(mContext);
+        MenuInflater inflater = new MenuInflater(mContext);
+        mFragment.onCreateOptionsMenu(menu, inflater);
+        MenuItem item = menu.getItem(0);
+        assertThat(item.getTitle()).isEqualTo(mContext.getString(R.string.bluetooth_rename_button));
+        assertThat(item.getIcon()).isEqualTo(mContext.getDrawable(R.drawable.ic_mode_edit));
+    }
+
+    @Test
+    public void renameControlClicked() {
+        RoboMenu menu = new RoboMenu(mContext);
+        MenuInflater inflater = new MenuInflater(mContext);
+        mFragment.onCreateOptionsMenu(menu, inflater);
+        MenuItem item = menu.getItem(0);
+        assertThat(item.getItemId()).isEqualTo(
+                BluetoothDeviceDetailsFragment.EDIT_DEVICE_NAME_ITEM_ID);
+
+        FragmentManager fragmentManager = mock(FragmentManager.class);
+        when(mFragment.getFragmentManager()).thenReturn(fragmentManager);
+        FragmentTransaction ft = mock(FragmentTransaction.class);
+        when(fragmentManager.beginTransaction()).thenReturn(ft);
+
+        ArgumentCaptor<Fragment> captor = ArgumentCaptor.forClass(Fragment.class);
+        mFragment.onOptionsItemSelected(item);
+        verify(ft).add(captor.capture(), eq(RemoteDeviceNameDialogFragment.TAG));
+        RemoteDeviceNameDialogFragment dialog = (RemoteDeviceNameDialogFragment) captor.getValue();
+        assertThat(dialog).isNotNull();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
new file mode 100644
index 0000000..2d7f215
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowDialog;
+import org.robolectric.util.FragmentTestUtil;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class RemoteDeviceNameDialogFragmentTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private CachedBluetoothDevice mCachedDevice;
+
+    private RemoteDeviceNameDialogFragment mFragment;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        FakeFeatureFactory.setupForTest(mContext);
+
+        String deviceAddress = "55:66:77:88:99:AA";
+        when(mCachedDevice.getDevice().getAddress()).thenReturn(deviceAddress);
+        mFragment = spy(RemoteDeviceNameDialogFragment.newInstance(mCachedDevice));
+        doReturn(mCachedDevice).when(mFragment).getDevice(any());
+    }
+
+    /**
+     * Helper method to set the mock device's name and show the dialog.
+     *
+     * @param deviceName what name to set
+     * @return the dialog created
+     */
+    AlertDialog startDialog(String deviceName) {
+        when(mCachedDevice.getName()).thenReturn(deviceName);
+        FragmentTestUtil.startFragment(mFragment);
+        return (AlertDialog) ShadowDialog.getLatestDialog();
+    }
+
+    @Test
+    public void deviceNameDisplayIsCorrect() {
+        String deviceName = "ABC Corp Headphones";
+        AlertDialog dialog = startDialog(deviceName);
+        EditText editText = (EditText) dialog.findViewById(R.id.edittext);
+        assertThat(editText.getText().toString()).isEqualTo(deviceName);
+
+        // Make sure that the "rename" button isn't enabled since the text hasn't changed yet, but
+        // the "cancel" button should be enabled.
+        Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+        assertThat(positiveButton.isEnabled()).isFalse();
+        Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+        assertThat(negativeButton.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void deviceNameEditSucceeds() {
+        String deviceNameInitial = "ABC Corp Headphones";
+        String deviceNameModified = "My Headphones";
+        AlertDialog dialog = startDialog(deviceNameInitial);
+
+        // Before modifying the text the "rename" button should be disabled but the cancel button
+        // should be enabled.
+        Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+        Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+        assertThat(negativeButton.isEnabled()).isTrue();
+        assertThat(positiveButton.isEnabled()).isFalse();
+
+        // Once we modify the text, the positive button should be clickable, and clicking it should
+        // cause a call to change the name.
+        EditText editText = (EditText) dialog.findViewById(R.id.edittext);
+        editText.setText(deviceNameModified);
+        assertThat(positiveButton.isEnabled()).isTrue();
+        positiveButton.performClick();
+        verify(mCachedDevice).setName(deviceNameModified);
+    }
+
+    @Test
+    public void deviceNameEditThenCancelDoesntRename() {
+        String deviceNameInitial = "ABC Corp Headphones";
+        String deviceNameModified = "My Headphones";
+        AlertDialog dialog = startDialog(deviceNameInitial);
+
+        // Modifying the text but then hitting cancel should not cause the name to change.
+        Button negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+        assertThat(negativeButton.isEnabled()).isTrue();
+        EditText editText = (EditText) dialog.findViewById(R.id.edittext);
+        editText.setText(deviceNameModified);
+        negativeButton.performClick();
+        verify(mCachedDevice, never()).setName(anyString());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index e9b29dd..af35520 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -124,53 +124,6 @@
     }
 
     @Test
-    public void testOnBindViewHolder_spacer_noSuggestions_noConditions() {
-        makeCategory();
-        DashboardAdapter.DashboardItemHolder holder = setupSpacer();
-
-        mDashboardAdapter.onBindViewHolder(holder, 0);
-
-        assertThat(holder.itemView.getBackground()).isNull();
-    }
-
-    @Test
-    public void testOnBindViewHolder_spacer_suggestion_noConditions() {
-        setupSuggestions(makeSuggestions("pkg1"));
-        makeCategory();
-        DashboardAdapter.DashboardItemHolder holder = setupSpacer();
-
-        mDashboardAdapter.onBindViewHolder(holder, 0);
-
-        assertThat(holder.itemView.getBackground()).isNotNull();
-        assertThat(holder.itemView.getBackground()).isInstanceOf(ColorDrawable.class);
-    }
-
-    @Test
-    public void testOnBindViewHolder_spacer_noSuggestion_condition() {
-        makeCondition();
-        makeCategory();
-        DashboardAdapter.DashboardItemHolder holder = setupSpacer();
-
-        mDashboardAdapter.onBindViewHolder(holder, 0);
-
-        assertThat(holder.itemView.getBackground()).isNotNull();
-        assertThat(holder.itemView.getBackground()).isInstanceOf(ColorDrawable.class);
-    }
-
-    @Test
-    public void testOnBindViewHolder_spacer_suggestion_condition() {
-        setupSuggestions(makeSuggestions("pkg1"));
-        makeCondition();
-        makeCategory();
-        DashboardAdapter.DashboardItemHolder holder = setupSpacer();
-
-        mDashboardAdapter.onBindViewHolder(holder, 0);
-
-        assertThat(holder.itemView.getBackground()).isNotNull();
-        assertThat(holder.itemView.getBackground()).isInstanceOf(ColorDrawable.class);
-    }
-
-    @Test
     public void testSuggestionsLogs_NotExpanded() {
         setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3"));
         verify(mFactory.metricsFeatureProvider, times(2)).action(
@@ -388,7 +341,7 @@
                 new FrameLayout(RuntimeEnvironment.application),
                 R.layout.suggestion_tile_card);
 
-        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 2);
+        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
         assertThat(textView.getParent()).isSameAs(mSuggestionHolder.itemView);
         mSuggestionHolder.itemView.performClick();
 
@@ -413,7 +366,7 @@
                 new FrameLayout(context),
                 R.layout.suggestion_tile_card);
 
-        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 2);
+        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
 
         mSuggestionHolder.itemView.performClick();
         assertThat(ShadowApplication.getInstance().getNextStartedActivity()).isNull();
@@ -442,8 +395,8 @@
                 new FrameLayout(context),
                 R.layout.suggestion_tile_card);
 
-        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 2);
-        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 2);
+        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
+        mDashboardAdapter.onBindViewHolder(mSuggestionHolder, 1);
 
         ViewGroup itemView = (ViewGroup) mSuggestionHolder.itemView;
         assertThat(itemView.getChildCount()).isEqualTo(1);
@@ -509,25 +462,4 @@
                 new FrameLayout(RuntimeEnvironment.application),
                 mDashboardAdapter.getItemViewType(1));
     }
-
-    private void makeCondition() {
-        final List<Condition> conditions = new ArrayList<>();
-        Condition condition = mock(Condition.class);
-        when(condition.shouldShow()).thenReturn(true);
-        conditions.add(condition);
-        mDashboardAdapter.setConditions(conditions);
-    }
-
-    private void makeCategory() {
-        List<DashboardCategory> categories = new ArrayList<>();
-        categories.add(new DashboardCategory());
-        mDashboardAdapter.setCategory(categories);
-    }
-
-    private DashboardAdapter.DashboardItemHolder setupSpacer() {
-        Context context = RuntimeEnvironment.application;
-        final View view = LayoutInflater.from(context)
-                .inflate(R.layout.dashboard_header_spacer, new LinearLayout(context), false);
-        return new DashboardAdapter.DashboardItemHolder(view);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
index 23681bc..8c6a828 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
@@ -117,7 +117,7 @@
         final DashboardData.SuggestionConditionHeaderData data =
                 new DashboardData.SuggestionConditionHeaderData(
                     mDashboardDataWithOneConditions.getConditions(), 0);
-        final Object[] expectedObjects = {null, data,
+        final Object[] expectedObjects = {data,
             mDashboardDataWithOneConditions.getSuggestions(),
             mDashboardDataWithOneConditions.getConditions(),
             null, mDashboardCategory, mTestCategoryTile};
@@ -196,11 +196,11 @@
         // Item in position 1 is the header, which contains the number of conditions, changed from
         // 1 to 2
         testResultData.add(new ListUpdateResult.ResultData(
-                ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
+                ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 0, 1));
         // Item in position 3 is the condition container containing the list of conditions, which
         // gets 1 more item
         testResultData.add(new ListUpdateResult.ResultData(
-            ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 3, 1));
+            ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
 
         testDiffUtil(mDashboardDataWithOneConditions,
                 mDashboardDataWithTwoConditions, testResultData);
@@ -211,7 +211,7 @@
         //Build testResultData
         final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
         testResultData.add(new ListUpdateResult.ResultData(
-                ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 1, 6));
+                ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 6));
 
         testDiffUtil(mDashboardDataWithOneConditions, mDashboardDataWithNoItems, testResultData);
     }
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
index 84dfbfd..344914a 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -25,15 +25,16 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
 import android.os.CancellationSignal;
 import android.widget.Button;
 
 import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settings.password.IFingerprintManager;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
@@ -92,13 +93,26 @@
     }
 
     @Test
-    public void clickNextAndFingerprint_shouldNotCrash() {
+    public void enrollFingerprint_shouldProceed() {
         EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
 
-        Button nextButton = mActivity.findViewById(R.id.next_button);
-        nextButton.performClick();
         enrollmentCallback.onEnrollmentProgress(123);
-        nextButton.performClick();
+        enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        IntentForResult startedActivity =
+                shadowActivity.getNextStartedActivityForResult();
+        assertThat(startedActivity).named("Next activity 1").isNotNull();
+        assertThat(startedActivity.intent.getComponent())
+                .isEqualTo(new ComponentName(application, FingerprintEnrollEnrolling.class));
+    }
+
+    @Test
+    public void enrollFingerprintTwice_shouldStartOneEnrolling() {
+        EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
+
+        enrollmentCallback.onEnrollmentProgress(123);
+        enrollmentCallback.onEnrollmentProgress(123);  // A second enroll should be a no-op
 
         ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
         IntentForResult startedActivity =
@@ -120,9 +134,7 @@
     public void layoutWithoutAnimation_shouldNotCrash() {
         EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
         enrollmentCallback.onEnrollmentProgress(123);
-
-        Button nextButton = mActivity.findViewById(R.id.next_button);
-        nextButton.performClick();
+        enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
 
         ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
         IntentForResult startedActivity =
@@ -132,6 +144,16 @@
                 .isEqualTo(new ComponentName(application, FingerprintEnrollEnrolling.class));
     }
 
+    @Test
+    public void clickSkip_shouldReturnResultSkip() {
+        Button skipButton = mActivity.findViewById(R.id.skip_button);
+        skipButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        assertThat(shadowActivity.getResultCode()).named("result code")
+                .isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
+    }
+
     private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
         ArgumentCaptor<EnrollmentCallback> callbackCaptor =
                 ArgumentCaptor.forClass(EnrollmentCallback.class);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
index cf1146e..715e4f0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java
@@ -164,4 +164,15 @@
         assertThat(info.remainingLabel.toString())
                 .isEqualTo(TEST_CHARGE_TIME_REMAINING_STRINGIFIED);
     }
+
+    @Test
+    public void testGetBatteryInfo_pluggedInWithFullBattery_onlyShowBatteryLevel() {
+        mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 100);
+
+        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
+                mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
+                1000, false /* basedOnUsage */);
+
+        assertThat(info.chargeLabel).isEqualTo("100%");
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 5225a74..eb22d22 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -16,6 +16,7 @@
 package com.android.settings.fuelgauge;
 
 import java.util.List;
+
 import android.app.LoaderManager;
 import android.content.Context;
 import android.content.Intent;
@@ -514,6 +515,27 @@
         assertThat(preference.showAnomalyIcon()).isTrue();
     }
 
+    @Test
+    public void testShouldHideSipper_typeOvercounted_returnTrue() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
+
+        assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
+    }
+
+    @Test
+    public void testShouldHideSipper_typeUnaccounted_returnTrue() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
+
+        assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
+    }
+
+    @Test
+    public void testShouldHideSipper_typeNormal_returnFalse() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
+
+        assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isFalse();
+    }
+
     public static class TestFragment extends PowerUsageSummary {
 
         private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
index 17fa17b..49fd214 100644
--- a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
@@ -57,7 +57,6 @@
 
     @Test
     public void testGetPreferenceScreenResId() {
-        when(mFeatureProvider.getPreferenceResourceId()).thenReturn(R.xml.assist_gesture_settings);
         assertThat(mSettings.getPreferenceScreenResId())
                 .isEqualTo(R.xml.assist_gesture_settings);
     }
@@ -76,7 +75,6 @@
                         ShadowApplication.getInstance().getApplicationContext(),
                         true /* enabled */);
 
-        when(mFeatureProvider.getPreferenceResourceId()).thenReturn(R.xml.assist_gesture_settings);
         assertThat(indexRes).isNotNull();
         assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId());
     }
diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
index 6cf1cf4..26d9510 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
@@ -56,18 +56,6 @@
     }
 
     @Test
-    public void testPassNull_NoError() {
-        mProvider.setUpSearchMenu(null, null);
-    }
-
-    @Test
-    public void testSetUpMenu_HasItemAdded() {
-        mProvider.setUpSearchMenu(menu, mActivity);
-
-        verify(menu).add(anyInt(), anyInt(), anyInt(), anyString());
-    }
-
-    @Test
     public void getSiteMapManager_shouldCacheInstance() {
         final SiteMapManager manager1 = mProvider.getSiteMapManager();
         final SiteMapManager manager2 = mProvider.getSiteMapManager();