Merge "Fork a new developer options page."
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6241850..fcc0b6d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9066,4 +9066,11 @@
 
     <!-- Note displayed when certain features are not available on low ram devices. [CHAR LIMIT=NONE] -->
     <string name="disabled_low_ram_device">This feature is not available on this device</string>
+
+    <!--Label of IMS registration header -->
+    <string name="ims_reg_title">"IMS registration state"</string>
+    <!--Used when IMS registration state is registered -->
+    <string name="ims_reg_status_registered">"Registered"</string>
+    <!--Used when IMS registration state is not registered -->
+    <string name="ims_reg_status_not_registered">"Not registered"</string>
 </resources>
diff --git a/res/xml/device_info_status.xml b/res/xml/device_info_status.xml
index 9a57af9..6fe43ec 100644
--- a/res/xml/device_info_status.xml
+++ b/res/xml/device_info_status.xml
@@ -89,4 +89,10 @@
         android:title="@string/status_wimax_mac_address"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
+    <Preference
+        android:key="ims_reg_state"
+        android:enabled="false"
+        android:shouldDisableView="false"
+        android:title="@string/ims_reg_title"
+        android:persistent="false" />
 </PreferenceScreen>
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index 4696dd3..587e814 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -61,6 +61,7 @@
 import android.widget.TabHost;
 import android.widget.TextView;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
@@ -152,6 +153,7 @@
     private int mConfirmingCredentialUser;
     private IntConsumer mConfirmingCredentialListener;
     private Set<AdapterData.AliasLoader> mAliasLoaders = new ArraySet<AdapterData.AliasLoader>(2);
+    @GuardedBy("mKeyChainConnectionByProfileId")
     private final SparseArray<KeyChainConnection>
             mKeyChainConnectionByProfileId = new SparseArray<KeyChainConnection>();
 
@@ -256,11 +258,13 @@
     }
 
     private void closeKeyChainConnections() {
-        final int n = mKeyChainConnectionByProfileId.size();
-        for (int i = 0; i < n; ++i) {
-            mKeyChainConnectionByProfileId.valueAt(i).close();
+        synchronized (mKeyChainConnectionByProfileId) {
+            final int n = mKeyChainConnectionByProfileId.size();
+            for (int i = 0; i < n; ++i) {
+                mKeyChainConnectionByProfileId.valueAt(i).close();
+            }
+            mKeyChainConnectionByProfileId.clear();
         }
-        mKeyChainConnectionByProfileId.clear();
     }
 
     private void addTab(Tab tab) {
@@ -684,62 +688,64 @@
                 SparseArray<List<CertHolder>> certHoldersByProfile =
                         new SparseArray<List<CertHolder>>();
                 try {
-                    List<UserHandle> profiles = mUserManager.getUserProfiles();
-                    final int n = profiles.size();
-                    // First we get all aliases for all profiles in order to show progress
-                    // correctly. Otherwise this could all be in a single loop.
-                    SparseArray<List<String>> aliasesByProfileId = new SparseArray<
-                            List<String>>(n);
-                    int max = 0;
-                    int progress = 0;
-                    for (int i = 0; i < n; ++i) {
-                        UserHandle profile = profiles.get(i);
-                        int profileId = profile.getIdentifier();
-                        if (shouldSkipProfile(profile)) {
-                            continue;
+                    synchronized(mKeyChainConnectionByProfileId) {
+                        List<UserHandle> profiles = mUserManager.getUserProfiles();
+                        final int n = profiles.size();
+                        // First we get all aliases for all profiles in order to show progress
+                        // correctly. Otherwise this could all be in a single loop.
+                        SparseArray<List<String>> aliasesByProfileId = new SparseArray<
+                                List<String>>(n);
+                        int max = 0;
+                        int progress = 0;
+                        for (int i = 0; i < n; ++i) {
+                            UserHandle profile = profiles.get(i);
+                            int profileId = profile.getIdentifier();
+                            if (shouldSkipProfile(profile)) {
+                                continue;
+                            }
+                            KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext,
+                                    profile);
+                            // Saving the connection for later use on the certificate dialog.
+                            mKeyChainConnectionByProfileId.put(profileId, keyChainConnection);
+                            IKeyChainService service = keyChainConnection.getService();
+                            List<String> aliases = mTab.getAliases(service);
+                            if (isCancelled()) {
+                                return new SparseArray<List<CertHolder>>();
+                            }
+                            max += aliases.size();
+                            aliasesByProfileId.put(profileId, aliases);
                         }
-                        KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext,
-                                profile);
-                        // Saving the connection for later use on the certificate dialog.
-                        mKeyChainConnectionByProfileId.put(profileId, keyChainConnection);
-                        IKeyChainService service = keyChainConnection.getService();
-                        List<String> aliases = mTab.getAliases(service);
-                        if (isCancelled()) {
-                            return new SparseArray<List<CertHolder>>();
+                        for (int i = 0; i < n; ++i) {
+                            UserHandle profile = profiles.get(i);
+                            int profileId = profile.getIdentifier();
+                            List<String> aliases = aliasesByProfileId.get(profileId);
+                            if (isCancelled()) {
+                                return new SparseArray<List<CertHolder>>();
+                            }
+                            KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
+                                    profileId);
+                            if (shouldSkipProfile(profile) || aliases == null
+                                    || keyChainConnection == null) {
+                                certHoldersByProfile.put(profileId, new ArrayList<CertHolder>(0));
+                                continue;
+                            }
+                            IKeyChainService service = keyChainConnection.getService();
+                            List<CertHolder> certHolders = new ArrayList<CertHolder>(max);
+                            final int aliasMax = aliases.size();
+                            for (int j = 0; j < aliasMax; ++j) {
+                                String alias = aliases.get(j);
+                                byte[] encodedCertificate = service.getEncodedCaCertificate(alias,
+                                        true);
+                                X509Certificate cert = KeyChain.toCertificate(encodedCertificate);
+                                certHolders.add(new CertHolder(service, mAdapter,
+                                        mTab, alias, cert, profileId));
+                                publishProgress(++progress, max);
+                            }
+                            Collections.sort(certHolders);
+                            certHoldersByProfile.put(profileId, certHolders);
                         }
-                        max += aliases.size();
-                        aliasesByProfileId.put(profileId, aliases);
+                        return certHoldersByProfile;
                     }
-                    for (int i = 0; i < n; ++i) {
-                        UserHandle profile = profiles.get(i);
-                        int profileId = profile.getIdentifier();
-                        List<String> aliases = aliasesByProfileId.get(profileId);
-                        if (isCancelled()) {
-                            return new SparseArray<List<CertHolder>>();
-                        }
-                        KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                                profileId);
-                        if (shouldSkipProfile(profile) || aliases == null
-                                || keyChainConnection == null) {
-                            certHoldersByProfile.put(profileId, new ArrayList<CertHolder>(0));
-                            continue;
-                        }
-                        IKeyChainService service = keyChainConnection.getService();
-                        List<CertHolder> certHolders = new ArrayList<CertHolder>(max);
-                        final int aliasMax = aliases.size();
-                        for (int j = 0; j < aliasMax; ++j) {
-                            String alias = aliases.get(j);
-                            byte[] encodedCertificate = service.getEncodedCaCertificate(alias,
-                                    true);
-                            X509Certificate cert = KeyChain.toCertificate(encodedCertificate);
-                            certHolders.add(new CertHolder(service, mAdapter,
-                                    mTab, alias, cert, profileId));
-                            publishProgress(++progress, max);
-                        }
-                        Collections.sort(certHolders);
-                        certHoldersByProfile.put(profileId, certHolders);
-                    }
-                    return certHoldersByProfile;
                 } catch (RemoteException e) {
                     Log.e(TAG, "Remote exception while loading aliases.", e);
                     return new SparseArray<List<CertHolder>>();
@@ -936,16 +942,18 @@
     public List<X509Certificate> getX509CertsFromCertHolder(CertHolder certHolder) {
         List<X509Certificate> certificates = null;
         try {
-            KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                    certHolder.mProfileId);
-            IKeyChainService service = keyChainConnection.getService();
-            List<String> chain = service.getCaCertificateChainAliases(certHolder.mAlias, true);
-            final int n = chain.size();
-            certificates = new ArrayList<X509Certificate>(n);
-            for (int i = 0; i < n; ++i) {
-                byte[] encodedCertificate = service.getEncodedCaCertificate(chain.get(i), true);
-                X509Certificate certificate = KeyChain.toCertificate(encodedCertificate);
-                certificates.add(certificate);
+            synchronized (mKeyChainConnectionByProfileId) {
+                KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
+                        certHolder.mProfileId);
+                IKeyChainService service = keyChainConnection.getService();
+                List<String> chain = service.getCaCertificateChainAliases(certHolder.mAlias, true);
+                final int n = chain.size();
+                certificates = new ArrayList<X509Certificate>(n);
+                for (int i = 0; i < n; ++i) {
+                    byte[] encodedCertificate = service.getEncodedCaCertificate(chain.get(i), true);
+                    X509Certificate certificate = KeyChain.toCertificate(encodedCertificate);
+                    certificates.add(certificate);
+                }
             }
         } catch (RemoteException ex) {
             Log.e(TAG, "RemoteException while retrieving certificate chain for root "
@@ -985,15 +993,17 @@
         @Override
         protected Boolean doInBackground(Void... params) {
             try {
-                KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
-                        mCertHolder.mProfileId);
-                IKeyChainService service = keyChainConnection.getService();
-                if (mCertHolder.mDeleted) {
-                    byte[] bytes = mCertHolder.mX509Cert.getEncoded();
-                    service.installCaCertificate(bytes);
-                    return true;
-                } else {
-                    return service.deleteCaCertificate(mCertHolder.mAlias);
+                synchronized (mKeyChainConnectionByProfileId) {
+                    KeyChainConnection keyChainConnection = mKeyChainConnectionByProfileId.get(
+                            mCertHolder.mProfileId);
+                    IKeyChainService service = keyChainConnection.getService();
+                    if (mCertHolder.mDeleted) {
+                        byte[] bytes = mCertHolder.mX509Cert.getEncoded();
+                        service.installCaCertificate(bytes);
+                        return true;
+                    } else {
+                        return service.deleteCaCertificate(mCertHolder.mAlias);
+                    }
                 }
             } catch (CertificateEncodingException | SecurityException | IllegalStateException
                     | RemoteException e) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 084b50e..94ba478 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -188,22 +188,27 @@
     }
 
     void onClicked() {
+        Context context = getContext();
         int bondState = mCachedDevice.getBondState();
 
         final MetricsFeatureProvider metricsFeatureProvider =
-                FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider();
+                FeatureFactory.getFactory(context).getMetricsFeatureProvider();
 
         if (mCachedDevice.isConnected()) {
-            metricsFeatureProvider.action(getContext(),
+            metricsFeatureProvider.action(context,
                     MetricsEvent.ACTION_SETTINGS_BLUETOOTH_DISCONNECT);
             askDisconnect();
         } else if (bondState == BluetoothDevice.BOND_BONDED) {
-            metricsFeatureProvider.action(getContext(),
+            metricsFeatureProvider.action(context,
                     MetricsEvent.ACTION_SETTINGS_BLUETOOTH_CONNECT);
             mCachedDevice.connect(true);
         } else if (bondState == BluetoothDevice.BOND_NONE) {
-            metricsFeatureProvider.action(getContext(),
+            metricsFeatureProvider.action(context,
                     MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
+            if (!mCachedDevice.hasHumanReadableName()) {
+                metricsFeatureProvider.action(context,
+                        MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES);
+            }
             pair();
         }
     }
diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java
index b346ae5..920386a 100644
--- a/src/com/android/settings/dashboard/DashboardData.java
+++ b/src/com/android/settings/dashboard/DashboardData.java
@@ -436,6 +436,17 @@
                     // Only check title and summary for dashboard tile
                     return TextUtils.equals(localTile.title, targetTile.title)
                             && TextUtils.equals(localTile.summary, targetTile.summary);
+                case TYPE_SUGGESTION_CONDITION_CONTAINER:
+                    // If entity is suggestion and contains remote view, force refresh
+                    final List entities = (List) entity;
+                    if (!entities.isEmpty()) {
+                        Object firstEntity = entities.get(0);
+                        if (firstEntity instanceof Tile
+                                && ((Tile) firstEntity).remoteViews != null) {
+                            return false;
+                        }
+                    }
+                    // Otherwise Fall through to default
                 default:
                     return entity == null ? targetItem.entity == null
                             : entity.equals(targetItem.entity);
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index b920850..53a51cd 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -230,6 +230,9 @@
 
     @VisibleForTesting
     boolean tintTileIcon(Tile tile) {
+        if (tile.icon == null) {
+            return false;
+        }
         // First check if the tile has set the icon tintable metadata.
         final Bundle metadata = tile.metaData;
         if (metadata != null
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index 4539680..2c9da41 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -29,6 +29,8 @@
 import com.android.settings.dashboard.DashboardAdapter.IconCache;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtils;
+
 import java.util.List;
 import java.util.Objects;
 
@@ -73,6 +75,7 @@
             mSuggestionsShownLogged.add(suggestionId);
         }
         if (suggestion.remoteViews != null) {
+            TileUtils.updateTileUsingSummaryUri(mContext, suggestion);
             final ViewGroup itemView = (ViewGroup) holder.itemView;
             itemView.removeAllViews();
             itemView.addView(suggestion.remoteViews.apply(itemView.getContext(), itemView));
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceController.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceController.java
new file mode 100644
index 0000000..261f66c
--- /dev/null
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceController.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.deletionhelper;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.format.DateUtils;
+import android.text.format.Formatter;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * Handles the wall of text which appears below the options in the Storage Management settings drill
+ * down.
+ */
+public class AutomaticStorageManagerDescriptionPreferenceController
+        extends AbstractPreferenceController implements PreferenceControllerMixin {
+    private static final String KEY_FREED = "freed_bytes";
+
+    public AutomaticStorageManagerDescriptionPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_FREED;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        Preference preference = screen.findPreference(getPreferenceKey());
+        final Context context = preference.getContext();
+        ContentResolver cr = context.getContentResolver();
+        long freedBytes =
+                Settings.Secure.getLong(
+                        cr, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED, 0);
+        long lastRunMillis =
+                Settings.Secure.getLong(cr, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN, 0);
+        if (freedBytes == 0 || lastRunMillis == 0 || !isStorageManagerEnabled(cr)) {
+            preference.setSummary(R.string.automatic_storage_manager_text);
+        } else {
+            preference.setSummary(
+                    context.getString(
+                            R.string.automatic_storage_manager_freed_bytes,
+                            Formatter.formatFileSize(context, freedBytes),
+                            DateUtils.formatDateTime(
+                                    context, lastRunMillis, DateUtils.FORMAT_SHOW_DATE)));
+        }
+    }
+
+    private boolean isStorageManagerEnabled(ContentResolver cr) {
+        return Settings.Secure.getInt(cr, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0)
+                != 0;
+    }
+}
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
index f7b62b1..e38317a 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
@@ -16,15 +16,13 @@
 
 package com.android.settings.deletionhelper;
 
-import android.app.Activity;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.support.v7.preference.DropDownPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -32,39 +30,34 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * AutomaticStorageManagerSettings is the Settings screen for configuration and management of the
  * automatic storage manager.
  */
-public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment
+public class AutomaticStorageManagerSettings extends DashboardFragment
         implements OnPreferenceChangeListener {
     private static final String KEY_DAYS = "days";
-    private static final String KEY_FREED = "freed_bytes";
-    private static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY =
-            "ro.storage_manager.enabled";
 
     private AutomaticStorageManagerSwitchBarController mSwitchController;
     private DropDownPreference mDaysToRetain;
-    private Preference mFreedBytes;
     private SwitchBar mSwitchBar;
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.automatic_storage_management_settings);
-    }
-
-    @Override
     public View onCreateView(
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         View view = super.onCreateView(inflater, container, savedInstanceState);
 
         initializeDaysToRetainPreference();
-        initializeFreedBytesPreference();
         initializeSwitchBar();
 
         return view;
@@ -98,35 +91,25 @@
                         getFragmentManager());
     }
 
-    private void initializeFreedBytesPreference() {
-        ContentResolver cr = getContentResolver();
-        mFreedBytes = findPreference(KEY_FREED);
-        long freedBytes = Settings.Secure.getLong(cr,
-                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
-                0);
-        long lastRunMillis = Settings.Secure.getLong(cr,
-                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
-                0);
-        if (freedBytes == 0 || lastRunMillis == 0) {
-            mFreedBytes.setVisible(false);
-        } else {
-            final Activity activity = getActivity();
-            mFreedBytes.setSummary(
-                    activity.getString(
-                            R.string.automatic_storage_manager_freed_bytes,
-                            Formatter.formatFileSize(activity, freedBytes),
-                            DateUtils.formatDateTime(
-                                    activity, lastRunMillis, DateUtils.FORMAT_SHOW_DATE)));
-        }
-    }
-
     @Override
     public void onResume() {
         super.onResume();
-        boolean isStorageManagerChecked =
-                Settings.Secure.getInt(getContentResolver(),
-                        Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0;
-        mDaysToRetain.setEnabled(isStorageManagerChecked);
+        mDaysToRetain.setEnabled(isStorageManagerEnabled());
+    }
+
+    @Override
+    protected String getLogTag() {
+        return null;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.automatic_storage_management_settings;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context);
     }
 
     @Override
@@ -168,4 +151,30 @@
         return indices.length - 1;
     }
 
+    private boolean isStorageManagerEnabled() {
+        return Settings.Secure.getInt(
+                        getContentResolver(), Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0)
+                != 0;
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new AutomaticStorageManagerDescriptionPreferenceController(context));
+        return controllers;
+    }
+
+    /** For Search. */
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return false;
+                }
+
+                @Override
+                public List<AbstractPreferenceController> getPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context);
+                }
+            };
 }
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index 18fe084..3115dc4 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -53,6 +53,7 @@
 import android.os.ServiceManager;
 import android.os.StrictMode;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.provider.SearchIndexableResource;
@@ -1031,8 +1032,19 @@
         return context.getSystemService(Context.OEM_LOCK_SERVICE) != null;
     }
 
+    /**
+     * Returns whether OEM unlock is allowed by the user and carrier.
+     *
+     * This does not take into account any restrictions imposed by the device policy.
+     */
+    private boolean isOemUnlockAllowedByUserAndCarrier() {
+        final UserHandle userHandle = UserHandle.of(UserHandle.myUserId());
+        return mOemLockManager.isOemUnlockAllowedByCarrier()
+                && !mUm.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET, userHandle);
+    }
+
     private boolean enableOemUnlockPreference() {
-        return !isBootloaderUnlocked() && mOemLockManager.canUserAllowOemUnlock();
+        return !isBootloaderUnlocked() && isOemUnlockAllowedByUserAndCarrier();
     }
 
     private void updateOemUnlockOptions() {
@@ -1046,10 +1058,6 @@
                 // Check restriction, disable mEnableOemUnlock and apply policy transparency.
                 mEnableOemUnlock.checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
             }
-            if (mEnableOemUnlock.isEnabled()) {
-                // Check restriction, disable mEnableOemUnlock and apply policy transparency.
-                mEnableOemUnlock.checkRestrictionAndSetDisabled(UserManager.DISALLOW_OEM_UNLOCK);
-            }
         }
     }
 
@@ -2574,7 +2582,7 @@
                 oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_bootloader_unlocked;
             } else if (isSimLockedDevice()) {
                 oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_sim_locked_device;
-            } else if (!mOemLockManager.canUserAllowOemUnlock()) {
+            } else if (!isOemUnlockAllowedByUserAndCarrier()) {
                 // If the device isn't SIM-locked but OEM unlock is disallowed by some party, this
                 // means either some other carrier restriction is in place or the device hasn't been
                 // able to confirm which restrictions (SIM-lock or otherwise) apply.
diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java
index baddc6c..faa4134 100644
--- a/src/com/android/settings/deviceinfo/Status.java
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -28,11 +28,15 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PersistableBundle;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserManager;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -56,6 +60,7 @@
     private static final String KEY_WIMAX_MAC_ADDRESS = "wimax_mac_address";
     private static final String KEY_SIM_STATUS = "sim_status";
     private static final String KEY_IMEI_INFO = "imei_info";
+    private static final String KEY_IMS_REGISTRATION_STATE = "ims_reg_state";
 
     // Broadcasts to listen to for connectivity changes.
     private static final String[] CONNECTIVITY_INTENTS = {
@@ -85,6 +90,8 @@
     private Preference mIpAddress;
     private Preference mWifiMacAddress;
     private Preference mWimaxMacAddress;
+    private Preference mImsStatus;
+
     private Handler mHandler;
 
     private static class MyHandler extends Handler {
@@ -162,6 +169,7 @@
         mWifiMacAddress = findPreference(KEY_WIFI_MAC_ADDRESS);
         mWimaxMacAddress = findPreference(KEY_WIMAX_MAC_ADDRESS);
         mIpAddress = findPreference(KEY_IP_ADDRESS);
+        mImsStatus = findPreference(KEY_IMS_REGISTRATION_STATE);
 
         mRes = getResources();
         mUnavailable = mRes.getString(R.string.status_unavailable);
@@ -269,11 +277,31 @@
         }
     }
 
+    private void setImsRegistrationStatus() {
+        CarrierConfigManager configManager = (CarrierConfigManager)
+                getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+        PersistableBundle config = null;
+        if (configManager != null) {
+            config = configManager.getConfigForSubId(subId);
+        }
+        if (config != null && config.getBoolean(
+                CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL)) {
+            TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+            mImsStatus.setSummary((tm != null && tm.isImsRegistered(subId)) ?
+                    R.string.ims_reg_status_registered : R.string.ims_reg_status_not_registered);
+        } else {
+            removePreferenceFromScreen(KEY_IMS_REGISTRATION_STATE);
+            mImsStatus = null;
+        }
+    }
+
     void updateConnectivity() {
         setWimaxStatus();
         setWifiStatus();
         setBtStatus();
         setIpAddressStatus();
+        setImsRegistrationStatus();
     }
 
     void updateTimes() {
diff --git a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
index 59907cf..5656a27 100644
--- a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
@@ -32,6 +32,7 @@
 import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
 import com.android.settings.password.SetupChooseLockGeneric;
 import com.android.settings.password.SetupSkipDialog;
+import com.android.settings.password.StorageManagerWrapper;
 
 public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
     private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent";
@@ -56,11 +57,14 @@
 
     @Override
     protected Intent getChooseLockIntent() {
-        Intent intent = new Intent(this, SetupChooseLockGeneric.class)
-                .putExtra(
-                        LockPatternUtils.PASSWORD_TYPE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
-        intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
+        Intent intent = new Intent(this, SetupChooseLockGeneric.class);
+
+        if (StorageManagerWrapper.isFileEncryptedNativeOrEmulated()) {
+            intent.putExtra(
+                    LockPatternUtils.PASSWORD_TYPE_KEY,
+                    DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+            intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
+        }
         SetupWizardUtils.copySetupExtras(getIntent(), intent);
         return intent;
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index aa71252..7a18cd0 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -26,6 +26,7 @@
 import android.content.pm.UserInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -47,6 +48,7 @@
     public static final int MSG_REPORT_FULLY_DRAWN = 2;
 
     private static final String TAG = "BatteryEntry";
+    private static final String PACKAGE_SYSTEM = "android";
 
     static final HashMap<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>();
 
@@ -268,9 +270,11 @@
         if (sipper.mPackages == null) {
             sipper.mPackages = pm.getPackagesForUid(uid);
         }
-        if (sipper.mPackages != null) {
-            String[] packageLabels = new String[sipper.mPackages.length];
-            System.arraycopy(sipper.mPackages, 0, packageLabels, 0, sipper.mPackages.length);
+
+        final String[] packages = extractPackagesFromSipper(sipper);
+        if (packages != null) {
+            String[] packageLabels = new String[packages.length];
+            System.arraycopy(packages, 0, packageLabels, 0, packages.length);
 
             // Convert package names to user-facing labels where possible
             IPackageManager ipm = AppGlobals.getPackageManager();
@@ -289,7 +293,7 @@
                         packageLabels[i] = label.toString();
                     }
                     if (ai.icon != 0) {
-                        defaultPackageName = sipper.mPackages[i];
+                        defaultPackageName = packages[i];
                         icon = ai.loadIcon(pm);
                         break;
                     }
@@ -303,7 +307,7 @@
                 name = packageLabels[0];
             } else {
                 // Look for an official name for this UID.
-                for (String pkgName : sipper.mPackages) {
+                for (String pkgName : packages) {
                     try {
                         final PackageInfo pi = ipm.getPackageInfo(pkgName, 0 /* no flags */, userId);
                         if (pi == null) {
@@ -349,4 +353,11 @@
             sHandler.sendMessage(sHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this));
         }
     }
+
+    String[] extractPackagesFromSipper(BatterySipper sipper) {
+        // Only use system package if uid is system uid, so it could find a consistent name and icon
+        return sipper.getUid() == Process.SYSTEM_UID
+                ? new String[]{PACKAGE_SYSTEM}
+                : sipper.mPackages;
+    }
 }
diff --git a/src/com/android/settings/password/StorageManagerWrapper.java b/src/com/android/settings/password/StorageManagerWrapper.java
new file mode 100644
index 0000000..5adfaf2
--- /dev/null
+++ b/src/com/android/settings/password/StorageManagerWrapper.java
@@ -0,0 +1,29 @@
+/*
+ * 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.password;
+
+import android.os.storage.StorageManager;
+
+/**
+ * Wrapper class to allow Robolectric to shadow methods introduced in newer API
+ */
+public class StorageManagerWrapper {
+
+    public static boolean isFileEncryptedNativeOrEmulated() {
+        return StorageManager.isFileEncryptedNativeOrEmulated();
+    }
+}
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index d67e8eb..044a00c 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -44,6 +44,7 @@
 import com.android.settings.datausage.DataPlanUsageSummary;
 import com.android.settings.datausage.DataUsageMeteredSettings;
 import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
 import com.android.settings.development.DevelopmentSettings;
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.StorageSettings;
@@ -213,6 +214,10 @@
                 R.drawable.ic_settings_notifications);
         addIndex(DreamSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_display);
         addIndex(SupportDashboardActivity.class, NO_DATA_RES_ID, R.drawable.ic_help);
+        addIndex(
+                AutomaticStorageManagerSettings.class,
+                NO_DATA_RES_ID,
+                R.drawable.ic_settings_storage);
     }
 
     private SearchIndexableResources() {
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index aeee6ff..43f25f1 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -78,7 +78,7 @@
         final NetworkScoreManagerWrapper networkScoreManagerWrapper =
                 new NetworkScoreManagerWrapper(context.getSystemService(NetworkScoreManager.class));
         mWifiWakeupPreferenceController = new WifiWakeupPreferenceController(
-                context, getLifecycle(), networkScoreManagerWrapper);
+                context, getLifecycle());
         mUseOpenWifiPreferenceController = new UseOpenWifiPreferenceController(context, this,
                 networkScoreManagerWrapper, getLifecycle());
         final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index b319703..ef6a650 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -38,6 +38,7 @@
 import android.nfc.NfcAdapter;
 import android.os.Bundle;
 import android.os.HandlerThread;
+import android.os.PowerManager;
 import android.os.Process;
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
@@ -918,9 +919,8 @@
                 getContentResolver(), Settings.Global.WIFI_WAKEUP_AVAILABLE, defaultWakeupAvailable)
                 == 1;
         if (wifiWakeupAvailable) {
-            boolean wifiWakeupEnabled = Settings.Global.getInt(
-                    getContentResolver(), Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
-            mConfigureWifiSettingsPreference.setSummary(getString(wifiWakeupEnabled
+            mConfigureWifiSettingsPreference.setSummary(getString(
+                    isWifiWakeupEnabled()
                     ? R.string.wifi_configure_settings_preference_summary_wakeup_on
                     : R.string.wifi_configure_settings_preference_summary_wakeup_off));
         }
@@ -935,6 +935,20 @@
         }
     }
 
+    private boolean isWifiWakeupEnabled() {
+        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        ContentResolver contentResolver = getContentResolver();
+        return Settings.Global.getInt(contentResolver,
+                        Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1
+                && Settings.Global.getInt(contentResolver,
+                        Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1
+                && Settings.Global.getInt(contentResolver,
+                        Settings.Global.AIRPLANE_MODE_ON, 0) == 0
+                && Settings.Global.getInt(contentResolver,
+                        Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1
+                && !powerManager.isPowerSaveMode();
+    }
+
     private void setOffMessage() {
         final CharSequence title = getText(R.string.wifi_empty_list_wifi_off);
         // Don't use WifiManager.isScanAlwaysAvailable() to check the Wi-Fi scanning mode. Instead,
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index 0017a5d..efb8aa6 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -44,13 +44,10 @@
         implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause {
 
     private static final String KEY_ENABLE_WIFI_WAKEUP = "enable_wifi_wakeup";
-    private final NetworkScoreManagerWrapper mNetworkScoreManager;
     private SettingObserver mSettingObserver;
 
-    public WifiWakeupPreferenceController(
-            Context context, Lifecycle lifecycle, NetworkScoreManagerWrapper networkScoreManager) {
+    public WifiWakeupPreferenceController(Context context, Lifecycle lifecycle) {
         super(context);
-        mNetworkScoreManager = networkScoreManager;
         lifecycle.addObserver(this);
     }
 
@@ -116,11 +113,9 @@
         boolean networkRecommendationsEnabled = Settings.Global.getInt(
                 mContext.getContentResolver(),
                 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0) == 1;
-        boolean activeScorerSet = mNetworkScoreManager.getActiveScorerPackage() != null;
-        enableWifiWakeup.setEnabled(
-                networkRecommendationsEnabled && wifiScanningEnabled && activeScorerSet);
+        enableWifiWakeup.setEnabled(networkRecommendationsEnabled && wifiScanningEnabled);
 
-        if (!activeScorerSet) {
+        if (!networkRecommendationsEnabled) {
             enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scoring_disabled);
         } else if (!wifiScanningEnabled) {
             enableWifiWakeup.setSummary(R.string.wifi_wakeup_summary_scanning_disabled);
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index aa23419..0996416 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -446,9 +446,8 @@
             }
         }
 
-        // Find IPv4 DNS addresses.
+        // Find all (IPv4 and IPv6) DNS addresses.
         String dnsServers = mLinkProperties.getDnsServers().stream()
-                .filter(Inet4Address.class::isInstance)
                 .map(InetAddress::getHostAddress)
                 .collect(Collectors.joining("\n"));
 
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index a08536a..e38064a 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -64,7 +64,6 @@
 com.android.settings.deviceinfo.PrivateVolumeSettings
 com.android.settings.users.AppRestrictionsFragment
 com.android.settings.deviceinfo.PrivateVolumeUnmount
-com.android.settings.deletionhelper.AutomaticStorageManagerSettings
 com.android.settings.notification.ZenAccessSettings
 com.android.settings.accessibility.ToggleFontSizePreferenceFragment
 com.android.settings.applications.PremiumSmsAccess
diff --git a/tests/robotests/src/android/service/oemlock/OemLockManager.java b/tests/robotests/src/android/service/oemlock/OemLockManager.java
index 7c015cf..c168089 100644
--- a/tests/robotests/src/android/service/oemlock/OemLockManager.java
+++ b/tests/robotests/src/android/service/oemlock/OemLockManager.java
@@ -32,9 +32,6 @@
         return false;
     }
 
-    public boolean canUserAllowOemUnlock() {
-        return true;
-    }
     public boolean isOemUnlockAllowed() {
         return false;
     }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
index a1db5de..ac0720a 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -42,6 +42,7 @@
 
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -98,11 +99,29 @@
         when(mCachedBluetoothDevice.isConnected()).thenReturn(false);
         when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
         when(mCachedBluetoothDevice.startPairing()).thenReturn(true);
+        when(mCachedBluetoothDevice.hasHumanReadableName()).thenReturn(true);
 
         mPreference.onClicked();
 
         verify(mMetricsFeatureProvider).action(
                 mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
+        verify(mMetricsFeatureProvider, never()).action(mContext,
+                MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES);
+    }
+
+    @Test
+    public void onClicked_deviceNotBonded_shouldLogBluetoothPairEventAndPairWithoutNameEvent() {
+        when(mCachedBluetoothDevice.isConnected()).thenReturn(false);
+        when(mCachedBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        when(mCachedBluetoothDevice.startPairing()).thenReturn(true);
+        when(mCachedBluetoothDevice.hasHumanReadableName()).thenReturn(false);
+
+        mPreference.onClicked();
+
+        verify(mMetricsFeatureProvider).action(
+                mContext, MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR);
+        verify(mMetricsFeatureProvider).action(mContext,
+                MetricsEvent.ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
index 77213f5..68d3354 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
@@ -19,6 +19,7 @@
 import android.support.annotation.NonNull;
 import android.support.v7.util.DiffUtil;
 import android.support.v7.util.ListUpdateCallback;
+import android.widget.RemoteViews;
 
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.conditional.AirplaneModeCondition;
@@ -35,6 +36,7 @@
 import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -224,6 +226,28 @@
         testDiffUtil(mDashboardDataWithOneConditions, mDashboardDataWithNoItems, testResultData);
     }
 
+    @Test
+    public void testDiffUtil_typeSuggestedContainer_ResultDataNothingChanged() {
+        //Build testResultData
+        final List<ListUpdateResult.ResultData> testResultData = new ArrayList<>();
+        testResultData.add(new ListUpdateResult.ResultData(
+                ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 0, 1));
+        Tile tile = new Tile();
+        tile.remoteViews = mock(RemoteViews.class);
+
+        DashboardData prevData = new DashboardData.Builder()
+                .setConditions(null)
+                .setCategory(null)
+                .setSuggestions(Arrays.asList(tile))
+                .build();
+        DashboardData currentData = new DashboardData.Builder()
+                .setConditions(null)
+                .setCategory(null)
+                .setSuggestions(Arrays.asList(tile))
+                .build();
+        testDiffUtil(prevData, currentData, testResultData);
+    }
+
     /**
      * Test when using the
      * {@link com.android.settings.dashboard.DashboardData.ItemsDataDiffCallback}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 2687714..ea160dd 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -27,6 +27,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceManager;
@@ -158,6 +159,7 @@
     @Test
     public void tintTileIcon_hasMetadata_shouldReturnIconTintableMetadata() {
         final Tile tile = new Tile();
+        tile.icon = mock(Icon.class);
         final Bundle metaData = new Bundle();
         tile.metaData = metaData;
 
@@ -168,10 +170,19 @@
         assertThat(mTestFragment.tintTileIcon(tile)).isTrue();
     }
 
+    @Test
+    public void tintTileIcon_noIcon_shouldReturnFalse() {
+        final Tile tile = new Tile();
+        final Bundle metaData = new Bundle();
+        tile.metaData = metaData;
+
+        assertThat(mTestFragment.tintTileIcon(tile)).isFalse();
+    }
 
     @Test
     public void tintTileIcon_noMetadata_shouldReturnPackageNameCheck() {
         final Tile tile = new Tile();
+        tile.icon = mock(Icon.class);
         final Intent intent = new Intent();
         tile.intent = intent;
 
diff --git a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceControllerTest.java
new file mode 100644
index 0000000..dd438ff
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerDescriptionPreferenceControllerTest.java
@@ -0,0 +1,83 @@
+package com.android.settings.deletionhelper;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AutomaticStorageManagerDescriptionPreferenceControllerTest {
+    @Mock private PreferenceScreen mScreen;
+    @Mock private Preference mPreference;
+    private AutomaticStorageManagerDescriptionPreferenceController mController;
+    private Context mContext = RuntimeEnvironment.application;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new AutomaticStorageManagerDescriptionPreferenceController(mContext);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+        when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+        when(mPreference.getContext()).thenReturn(mContext);
+    }
+
+    @Test
+    public void displayPreference_asmDisabled_shouldHaveDescription() {
+        mController.displayPreference(mScreen);
+
+        verify(mPreference).setSummary(eq(R.string.automatic_storage_manager_text));
+    }
+
+    @Test
+    public void displayPreference_asmEnabledButUnused_shouldHaveDescription() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
+                1);
+
+        mController.displayPreference(mScreen);
+
+        verify(mPreference).setSummary(eq(R.string.automatic_storage_manager_text));
+    }
+
+    @Ignore("Robolectric doesn't do locale switching for date localization -- yet.")
+    @Test
+    @Config(qualifiers = "en")
+    public void displayPreference_asmEnabledAndUsed_shouldHaveDescriptionFilledOut() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
+                1);
+        Settings.Secure.putLong(
+                mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
+                10);
+        Settings.Secure.putLong(
+                mContext.getContentResolver(),
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
+                43200000); // January 1, 1970 12:00:00 PM to avoid timezone issues.
+
+        mController.displayPreference(mScreen);
+
+        verify(mPreference)
+                .setSummary(eq("10.00B total made available\n\nLast ran on January 1, 1970"));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
index 801ee5d..f5859ac 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
@@ -23,28 +23,38 @@
 
 import android.app.KeyguardManager;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.view.View;
 import android.widget.Button;
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
+import com.android.settings.fingerprint.SetupFingerprintEnrollIntroductionTest
+        .ShadowStorageManagerWrapper;
 import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
 import com.android.settings.password.SetupSkipDialog;
+import com.android.settings.password.StorageManagerWrapper;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
+import com.android.settings.testutils.shadow.ShadowFingerprintManager;
 import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.shadows.ShadowActivity.IntentForResult;
 import org.robolectric.shadows.ShadowKeyguardManager;
 import org.robolectric.util.ActivityController;
 
@@ -54,7 +64,9 @@
         sdk = TestConfig.SDK_VERSION,
         shadows = {
                 ShadowEventLogWriter.class,
+                ShadowFingerprintManager.class,
                 ShadowLockPatternUtils.class,
+                ShadowStorageManagerWrapper.class,
                 ShadowUserManager.class
         })
 public class SetupFingerprintEnrollIntroductionTest {
@@ -68,12 +80,22 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        RuntimeEnvironment.getRobolectricPackageManager()
+                .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
+        ShadowFingerprintManager.addToServiceMap();
+
         final Intent intent = new Intent();
         mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
 
         ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
     }
 
+    @After
+    public void tearDown() {
+        ShadowStorageManagerWrapper.reset();
+        ShadowFingerprintManager.reset();
+    }
+
     @Test
     public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() {
         getShadowKeyguardManager().setIsKeyguardSecure(false);
@@ -188,8 +210,41 @@
         assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
     }
 
+    @Test
+    public void testLockPattern() {
+        ShadowStorageManagerWrapper.sIsFileEncrypted = false;
+
+        mController.create().postCreate(null).resume();
+
+        SetupFingerprintEnrollIntroduction activity = mController.get();
+
+        final Button nextButton = activity.findViewById(R.id.fingerprint_next_button);
+        nextButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
+        IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult();
+        assertThat(startedActivity).isNotNull();
+        assertThat(startedActivity.intent.hasExtra(
+                SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse();
+    }
+
 
     private ShadowKeyguardManager getShadowKeyguardManager() {
         return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
     }
+
+    @Implements(StorageManagerWrapper.class)
+    public static class ShadowStorageManagerWrapper {
+
+        private static boolean sIsFileEncrypted = true;
+
+        public static void reset() {
+            sIsFileEncrypted = true;
+        }
+
+        @Implementation
+        public static boolean isFileEncryptedNativeOrEmulated() {
+            return sIsFileEncrypted;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index 632d549..a461f46 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Handler;
+import android.os.Process;
 import android.os.UserManager;
 
 import com.android.internal.os.BatterySipper;
@@ -46,9 +47,12 @@
 public class BatteryEntryTest {
 
     private static final int APP_UID = 123;
+    private static final int SYSTEM_UID = Process.SYSTEM_UID;
     private static final String APP_DEFAULT_PACKAGE_NAME = "com.android.test";
     private static final String APP_LABEL = "Test App Name";
     private static final String HIGH_DRAIN_PACKAGE = "com.android.test.screen";
+    private static final String ANDROID_PACKAGE = "android";
+    private static final String[] SYSTEM_PACKAGES = {HIGH_DRAIN_PACKAGE, ANDROID_PACKAGE};
 
     @Rule public MockitoRule mocks = MockitoJUnit.rule();
 
@@ -84,6 +88,18 @@
         return sipper;
     }
 
+    private BatteryEntry createBatteryEntryForSystem() {
+        return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem());
+    }
+
+    private BatterySipper createSipperForSystem() {
+        BatterySipper sipper =
+                new BatterySipper(DrainType.APP, new FakeUid(SYSTEM_UID), 0 /* power use */);
+        sipper.packageWithHighestDrain = HIGH_DRAIN_PACKAGE;
+        sipper.mPackages = SYSTEM_PACKAGES;
+        return sipper;
+    }
+
     @Test
     public void batteryEntryForApp_shouldSetDefaultPackageNameAndLabel() throws Exception {
         BatteryEntry entry = createBatteryEntryForApp();
@@ -118,7 +134,22 @@
             new String[]{APP_DEFAULT_PACKAGE_NAME, "package2", "package3"});
 
         BatteryEntry entry = createBatteryEntryForApp();
-        
+
         assertThat(entry.getLabel()).isEqualTo(HIGH_DRAIN_PACKAGE);
     }
+
+    @Test
+    public void extractPackageFromSipper_systemSipper_returnSystemPackage() {
+        BatteryEntry entry = createBatteryEntryForSystem();
+
+        assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(
+                new String[]{ANDROID_PACKAGE});
+    }
+
+    @Test
+    public void extractPackageFromSipper_normalSipper_returnDefaultPakcage() {
+        BatteryEntry entry = createBatteryEntryForApp();
+
+        assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(entry.sipper.mPackages);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
index 1f5c9be..7ea42b8 100644
--- a/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/AssistGestureSettingsTest.java
@@ -32,6 +32,7 @@
 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;
@@ -43,7 +44,7 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class AssistGestureSettingsTest {
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
     private FakeFeatureFactory mFakeFeatureFactory;
     private AssistGestureSettings mSettings;
@@ -51,6 +52,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
         mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
         mSettings = new AssistGestureSettings();
     }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowFingerprintManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowFingerprintManager.java
new file mode 100644
index 0000000..b84cf42
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowFingerprintManager.java
@@ -0,0 +1,102 @@
+/*
+ * 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.testutils.shadow;
+
+import android.content.Context;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
+import android.support.annotation.NonNull;
+
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+import org.robolectric.internal.ShadowExtractor;
+import org.robolectric.shadows.ShadowContextImpl;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.IntStream;
+
+@Implements(FingerprintManager.class)
+public class ShadowFingerprintManager {
+
+    private static Map<String, String> getSystemServiceMap() {
+        return ReflectionHelpers.getStaticField(ShadowContextImpl.class, "SYSTEM_SERVICE_MAP");
+    }
+
+    /**
+     * Call this in @Before of a test to add FingerprintManager to Robolectric's system service
+     * map. Otherwise getSystemService(FINGERPRINT_SERVICE) will return null.
+     */
+    public static void addToServiceMap() {
+        getSystemServiceMap().put(Context.FINGERPRINT_SERVICE, FingerprintManager.class.getName());
+    }
+
+    @Resetter
+    public static void reset() {
+        getSystemServiceMap().remove(Context.FINGERPRINT_SERVICE);
+    }
+
+    public boolean hardwareDetected = true;
+
+    @NonNull
+    private List<Fingerprint> mFingerprints = Collections.emptyList();
+
+    @Implementation
+    public boolean isHardwareDetected() {
+        return hardwareDetected;
+    }
+
+    @Implementation
+    public boolean hasEnrolledFingerprints() {
+        return !mFingerprints.isEmpty();
+    }
+
+    @Implementation
+    public List<Fingerprint> getEnrolledFingerprints() {
+        return mFingerprints;
+    }
+
+    @Implementation
+    public List<Fingerprint> getEnrolledFingerprints(int userId) {
+        return mFingerprints;
+    }
+
+    public void setEnrolledFingerprints(Fingerprint... fingerprints) {
+        mFingerprints = Arrays.asList(fingerprints);
+    }
+
+    public void setDefaultFingerprints(int num) {
+        setEnrolledFingerprints(
+                IntStream.range(0, num)
+                        .mapToObj(i -> new Fingerprint(
+                                "Fingerprint " + i,
+                                0, /* groupId */
+                                i, /* fingerId */
+                                0 /* deviceId */))
+                        .toArray(Fingerprint[]::new));
+    }
+
+    public static ShadowFingerprintManager get() {
+        return (ShadowFingerprintManager) ShadowExtractor.extract(
+                RuntimeEnvironment.application.getSystemService(FingerprintManager.class));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
index 8be686e..306b297 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java
@@ -56,8 +56,6 @@
     private static final String TEST_SCORER_PACKAGE_NAME = "Test Scorer";
 
     private Context mContext;
-    @Mock
-    private NetworkScoreManagerWrapper mNetworkScorer;
     private WifiWakeupPreferenceController mController;
 
     @Before
@@ -65,11 +63,11 @@
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mController = new WifiWakeupPreferenceController(
-                mContext, mock(Lifecycle.class), mNetworkScorer);
+                mContext, mock(Lifecycle.class));
         Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 1);
+        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
         SettingsShadowResources.overrideResource(
                 com.android.internal.R.integer.config_wifi_wakeup_available, 0);
-        when(mNetworkScorer.getActiveScorerPackage()).thenReturn(TEST_SCORER_PACKAGE_NAME);
     }
 
     @After
@@ -116,9 +114,8 @@
     }
 
     @Test
-    public void updateState_preferenceSetCheckedAndSetEnabledWhenSettingsAreEnabled() {
+    public void updateState_preferenceSetCheckedAndSetEnabledWhenWakeupSettingEnabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
-        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
 
         mController.updateState(preference);
@@ -129,22 +126,20 @@
     }
 
     @Test
-    public void updateState_preferenceSetCheckedAndSetEnabledWhenSettingsAreDisabled() {
+    public void updateState_preferenceSetUncheckedAndSetEnabledWhenWakeupSettingDisabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
-        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 0);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 0);
 
         mController.updateState(preference);
 
         verify(preference).setChecked(false);
-        verify(preference).setEnabled(false);
+        verify(preference).setEnabled(true);
         verify(preference).setSummary(R.string.wifi_wakeup_summary);
     }
 
     @Test
     public void updateState_preferenceSetUncheckedAndSetDisabledWhenWifiScanningDisabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
-        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_SCAN_ALWAYS_AVAILABLE, 0);
 
@@ -158,9 +153,8 @@
     @Test
     public void updateState_preferenceSetUncheckedAndSetDisabledWhenScoringDisabled() {
         final SwitchPreference preference = mock(SwitchPreference.class);
-        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 1);
         Settings.System.putInt(mContext.getContentResolver(), WIFI_WAKEUP_ENABLED, 1);
-        when(mNetworkScorer.getActiveScorerPackage()).thenReturn(null);
+        Settings.System.putInt(mContext.getContentResolver(), NETWORK_RECOMMENDATIONS_ENABLED, 0);
 
         mController.updateState(preference);
 
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 275f9a2..1c2ddb4 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -436,10 +436,14 @@
     public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException {
         mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4}));
         mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8}));
+        mLinkProperties.addDnsServer(Constants.IPV6_DNS);
 
         displayAndResume();
 
-        verify(mockDnsPref).setDetailText("8.8.4.4\n8.8.8.8");
+        verify(mockDnsPref).setDetailText(
+                "8.8.4.4\n" +
+                "8.8.8.8\n" +
+                Constants.IPV6_DNS.getHostAddress());
     }
 
     @Test
@@ -545,12 +549,14 @@
 
         lp.addDnsServer(Constants.IPV6_DNS);
         updateLinkProperties(lp);
-        inOrder.verify(mockDnsPref, never()).setVisible(true);
+        inOrder.verify(mockDnsPref).setDetailText(Constants.IPV6_DNS.getHostAddress());
+        inOrder.verify(mockDnsPref).setVisible(true);
 
         lp.addDnsServer(Constants.IPV4_DNS1);
         lp.addDnsServer(Constants.IPV4_DNS2);
         updateLinkProperties(lp);
         inOrder.verify(mockDnsPref).setDetailText(
+                Constants.IPV6_DNS.getHostAddress() + "\n" +
                 Constants.IPV4_DNS1.getHostAddress() + "\n" +
                 Constants.IPV4_DNS2.getHostAddress());
         inOrder.verify(mockDnsPref).setVisible(true);