Merge "Revert accidential merge afe6320d70f46e8af724ef2cde86a5963d198868"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fcb57ad..852e81d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1579,6 +1579,8 @@
     <string name="wifi_starting">Turning Wi\u2011Fi on\u2026</string>
     <!-- Summary text when turning Wi-Fi or bluetooth off -->
     <string name="wifi_stopping">Turning off Wi\u2011Fi\u2026</string>
+    <!-- Title of Button to show all Wi-Fi networks in the picker. [CHAR LIMIT=30] -->
+    <string name="wifi_see_all_networks_button_title">See all networks</string>
     <!-- Summary text when Wi-Fi or bluetooth has error -->
     <string name="wifi_error">Error</string>
     <!-- Summary text when wifi SoftAP started failed due to no legal usable channel allowed in this region by regulatory -->
diff --git a/res/xml/account_type_settings.xml b/res/xml/account_type_settings.xml
index 6663d7b..ab997a5 100644
--- a/res/xml/account_type_settings.xml
+++ b/res/xml/account_type_settings.xml
@@ -23,22 +23,22 @@
       android:key="account_header"
       android:layout="@layout/account_header"
       android:selectable="false"
-      android:order="0"/>
+      android:order="-10000"/>
 
     <Preference
         android:key="account_sync"
         android:title="@string/account_sync_title"
         android:icon="@drawable/ic_sync"
-        android:order="1"/>
+        android:order="-9999"/>
 
     <PreferenceCategory
       android:key="dashboard_tile_placeholder"
-      android:order="10"/>
+      android:order="-9998"/>
 
     <com.android.settings.applications.LayoutPreference
       android:key="remove_account"
       android:layout="@layout/remove_account_button"
-      android:order="100"
+      android:order="1000"
       android:selectable="false"/>
 
 </PreferenceScreen>
diff --git a/res/xml/ia_sound_settings.xml b/res/xml/ia_sound_settings.xml
index e63db0d..27fcdda 100644
--- a/res/xml/ia_sound_settings.xml
+++ b/res/xml/ia_sound_settings.xml
@@ -60,32 +60,34 @@
 
         <PreferenceCategory
           android:key="ringtones_preferecence_category"
-          android:title="@string/ringtones_category_preference_title" />
+          android:title="@string/ringtones_category_preference_title" >
 
-        <!-- Phone ringtone -->
-        <com.android.settings.DefaultRingtonePreference
-                android:key="ringtone"
-                android:title="@string/ringtone_title"
-                android:dialogTitle="@string/ringtone_title"
-                android:summary="@string/ringtone_summary"
-                android:ringtoneType="ringtone" />
+                <!-- Phone ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="ringtone"
+                    android:title="@string/ringtone_title"
+                    android:dialogTitle="@string/ringtone_title"
+                    android:summary="@string/ringtone_summary"
+                    android:ringtoneType="ringtone" />
 
-        <!-- Default notification ringtone -->
-        <com.android.settings.DefaultRingtonePreference
-                android:key="notification_ringtone"
-                android:title="@string/notification_ringtone_title"
-                android:dialogTitle="@string/notification_ringtone_title"
-                android:summary="@string/ringtone_summary"
-                android:ringtoneType="notification" />
+                <!-- Default notification ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="notification_ringtone"
+                    android:title="@string/notification_ringtone_title"
+                    android:dialogTitle="@string/notification_ringtone_title"
+                    android:summary="@string/ringtone_summary"
+                    android:ringtoneType="notification" />
 
-        <!-- Default alarm ringtone -->
-        <com.android.settings.DefaultRingtonePreference
-                android:key="alarm_ringtone"
-                android:title="@string/alarm_ringtone_title"
-                android:dialogTitle="@string/alarm_ringtone_title"
-                android:summary="@string/ringtone_summary"
-                android:persistent="false"
-                android:ringtoneType="alarm" />
+                <!-- Default alarm ringtone -->
+                <com.android.settings.DefaultRingtonePreference
+                    android:key="alarm_ringtone"
+                    android:title="@string/alarm_ringtone_title"
+                    android:dialogTitle="@string/alarm_ringtone_title"
+                    android:summary="@string/ringtone_summary"
+                    android:persistent="false"
+                    android:ringtoneType="alarm" />
+
+        </PreferenceCategory>
 
         <!-- Other sounds -->
         <PreferenceCategory
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index f6d6310..e08ca96 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -43,4 +43,10 @@
         android:key="pref_system"
         android:title="@string/storage_detail_system">
     </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <Preference
+        android:key="manage_storage"
+        android:title="@string/storage_menu_manage"
+        android:icon="@drawable/ic_settings_storage"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </Preference>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index f274114..b66f2f5 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -1300,8 +1300,13 @@
                         dashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY);
                 mSummaryLoader.setSummary(this, getPackageVerifierSummary(dashboardCategory));
             } else {
-                mSummaryLoader.setSummary(this,
-                        mContext.getString(R.string.security_dashboard_summary));
+                final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(mContext);
+                if (fpm != null && fpm.isHardwareDetected()) {
+                    mSummaryLoader.setSummary(this,
+                            mContext.getString(R.string.security_dashboard_summary));
+                } else {
+                    mSummaryLoader.setSummary(this, null);
+                }
             }
         }
 
@@ -1319,8 +1324,7 @@
                 String summaryUri = tile.metaData.getString(
                         TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
                 return TileUtils.getTextFromUri(mContext, summaryUri,
-                            new ArrayMap<String, IContentProvider>(),
-                            TileUtils.META_DATA_PREFERENCE_SUMMARY);
+                        new ArrayMap<>(), TileUtils.META_DATA_PREFERENCE_SUMMARY);
             }
             return null;
         }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 51613c7..9168ead 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -527,8 +527,9 @@
             }
         }
 
-        if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
-                + " ms");
+        if (DEBUG_TIMING) {
+            Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms");
+        }
     }
 
     public void setDisplaySearchMenu(boolean displaySearch) {
diff --git a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
index 8143e96..801a20b 100644
--- a/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDetailDashboardFragment.java
@@ -24,6 +24,7 @@
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
 
+import android.support.v7.preference.PreferenceScreen;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -84,7 +85,7 @@
         if (mAccountLabel != null) {
             getActivity().setTitle(mAccountLabel);
         }
-        updateAccountHeader();
+        updateUi();
     }
 
     @Override
@@ -125,7 +126,7 @@
     }
 
     @VisibleForTesting
-    void updateAccountHeader() {
+    void updateUi() {
         final Preference headerPreference = findPreference(KEY_ACCOUNT_HEADER);
         headerPreference.setTitle(mAccount.name);
         final Context context = getContext();
@@ -136,6 +137,13 @@
         }
         final AuthenticatorHelper helper = new AuthenticatorHelper(context, userHandle, null);
         headerPreference.setIcon(helper.getDrawableForType(context, mAccountType));
+        final AccountTypePreferenceLoader accountTypePreferenceLoader =
+            new AccountTypePreferenceLoader(this, helper, userHandle);
+        PreferenceScreen prefs =
+            accountTypePreferenceLoader.addPreferencesForType(mAccountType, getPreferenceScreen());
+        if (prefs != null) {
+            accountTypePreferenceLoader.updatePreferenceIntents(prefs, mAccountType, mAccount);
+        }
     }
 
 }
\ No newline at end of file
diff --git a/src/com/android/settings/accounts/AccountPreferenceBase.java b/src/com/android/settings/accounts/AccountPreferenceBase.java
index aa5c518..605688e 100644
--- a/src/com/android/settings/accounts/AccountPreferenceBase.java
+++ b/src/com/android/settings/accounts/AccountPreferenceBase.java
@@ -58,6 +58,7 @@
     private Object mStatusChangeListenerHandle;
     protected AuthenticatorHelper mAuthenticatorHelper;
     protected UserHandle mUserHandle;
+    protected AccountTypePreferenceLoader mAccountTypePreferenceLoader;
 
     private java.text.DateFormat mDateFormat;
     private java.text.DateFormat mTimeFormat;
@@ -70,6 +71,8 @@
         mUserHandle = Utils.getSecureTargetUser(activity.getActivityToken(), mUm, getArguments(),
                 activity.getIntent().getExtras());
         mAuthenticatorHelper = new AuthenticatorHelper(activity, mUserHandle, this);
+        mAccountTypePreferenceLoader =
+            new AccountTypePreferenceLoader(this, mAuthenticatorHelper, mUserHandle);
     }
 
     /**
@@ -142,35 +145,7 @@
      */
     public PreferenceScreen addPreferencesForType(final String accountType,
             PreferenceScreen parent) {
-        PreferenceScreen prefs = null;
-        if (mAuthenticatorHelper.containsAccountType(accountType)) {
-            AuthenticatorDescription desc = null;
-            try {
-                desc = mAuthenticatorHelper.getAccountTypeDescription(accountType);
-                if (desc != null && desc.accountPreferencesId != 0) {
-                    // Load the context of the target package, then apply the
-                    // base Settings theme (no references to local resources)
-                    // and create a context theme wrapper so that we get the
-                    // correct text colors. Control colors will still be wrong,
-                    // but there's not much we can do about it since we can't
-                    // reference local color resources.
-                    final Context targetCtx = getActivity().createPackageContextAsUser(
-                            desc.packageName, 0, mUserHandle);
-                    final Theme baseTheme = getResources().newTheme();
-                    baseTheme.applyStyle(com.android.settings.R.style.Theme_SettingsBase, true);
-                    final Context themedCtx =
-                            new LocalClassLoaderContextThemeWrapper(getClass(), targetCtx, 0);
-                    themedCtx.getTheme().setTo(baseTheme);
-                    prefs = getPreferenceManager().inflateFromResource(themedCtx,
-                            desc.accountPreferencesId, parent);
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
-            } catch (Resources.NotFoundException e) {
-                Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
-            }
-        }
-        return prefs;
+        return mAccountTypePreferenceLoader.addPreferencesForType(accountType, parent);
     }
 
     public void updateAuthDescriptions() {
diff --git a/src/com/android/settings/accounts/AccountTypePreferenceLoader.java b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java
new file mode 100644
index 0000000..87f9c77
--- /dev/null
+++ b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java
@@ -0,0 +1,245 @@
+/*
+
+ * 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.accounts;
+
+import android.accounts.Account;
+import android.accounts.AuthenticatorDescription;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.os.UserHandle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.Log;
+
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.location.LocationSettings;
+import com.android.settings.utils.LocalClassLoaderContextThemeWrapper;
+import com.android.settingslib.accounts.AuthenticatorHelper;
+
+/**
+ * Class to load the preference screen to be added to the settings page for the specific account
+ * type as specified in the account-authenticator.
+ */
+public class AccountTypePreferenceLoader {
+
+    private static final String TAG = "AccountTypePrefLoader";
+    private static final String ACCOUNT_KEY = "account"; // to pass to auth settings
+    // Action name for the broadcast intent when the Google account preferences page is launching
+    // the location settings.
+    private static final String LAUNCHING_LOCATION_SETTINGS =
+        "com.android.settings.accounts.LAUNCHING_LOCATION_SETTINGS";
+
+
+    private AuthenticatorHelper mAuthenticatorHelper;
+    private UserHandle mUserHandle;
+    private PreferenceFragment mFragment;
+
+    public AccountTypePreferenceLoader(PreferenceFragment fragment,
+            AuthenticatorHelper authenticatorHelper, UserHandle userHandle) {
+        mFragment = fragment;
+        mAuthenticatorHelper = authenticatorHelper;
+        mUserHandle = userHandle;
+    }
+
+    /**
+     * Gets the preferences.xml file associated with a particular account type.
+     * @param accountType the type of account
+     * @return a PreferenceScreen inflated from accountPreferenceId.
+     */
+    public PreferenceScreen addPreferencesForType(final String accountType,
+            PreferenceScreen parent) {
+        PreferenceScreen prefs = null;
+        if (mAuthenticatorHelper.containsAccountType(accountType)) {
+            AuthenticatorDescription desc = null;
+            try {
+                desc = mAuthenticatorHelper.getAccountTypeDescription(accountType);
+                if (desc != null && desc.accountPreferencesId != 0) {
+                    // Load the context of the target package, then apply the
+                    // base Settings theme (no references to local resources)
+                    // and create a context theme wrapper so that we get the
+                    // correct text colors. Control colors will still be wrong,
+                    // but there's not much we can do about it since we can't
+                    // reference local color resources.
+                    final Context targetCtx = mFragment.getActivity().createPackageContextAsUser(
+                            desc.packageName, 0, mUserHandle);
+                    final Theme baseTheme = mFragment.getResources().newTheme();
+                    baseTheme.applyStyle(R.style.Theme_SettingsBase, true);
+                    final Context themedCtx =
+                            new LocalClassLoaderContextThemeWrapper(getClass(), targetCtx, 0);
+                    themedCtx.getTheme().setTo(baseTheme);
+                    prefs = mFragment.getPreferenceManager().inflateFromResource(themedCtx,
+                            desc.accountPreferencesId, parent);
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
+            } catch (Resources.NotFoundException e) {
+                Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
+            }
+        }
+        return prefs;
+    }
+
+    /**
+     * Recursively filters through the preference list provided by GoogleLoginService.
+     *
+     * This method removes all the invalid intent from the list, adds account name as extra into the
+     * intent, and hack the location settings to start it as a fragment.
+     */
+    public void updatePreferenceIntents(PreferenceGroup prefs, final String acccountType,
+            Account account) {
+        final PackageManager pm = mFragment.getActivity().getPackageManager();
+        for (int i = 0; i < prefs.getPreferenceCount(); ) {
+            Preference pref = prefs.getPreference(i);
+            if (pref instanceof PreferenceGroup) {
+                updatePreferenceIntents((PreferenceGroup) pref, acccountType, account);
+            }
+            Intent intent = pref.getIntent();
+            if (intent != null) {
+                // Hack. Launch "Location" as fragment instead of as activity.
+                //
+                // When "Location" is launched as activity via Intent, there's no "Up" button at the
+                // top left, and if there's another running instance of "Location" activity, the
+                // back stack would usually point to some other place so the user won't be able to
+                // go back to the previous page by "back" key. Using fragment is a much easier
+                // solution to those problems.
+                //
+                // If we set Intent to null and assign a fragment to the PreferenceScreen item here,
+                // in order to make it work as expected, we still need to modify the container
+                // PreferenceActivity, override onPreferenceStartFragment() and call
+                // startPreferencePanel() there. In order to inject the title string there, more
+                // dirty further hack is still needed. It's much easier and cleaner to listen to
+                // preference click event here directly.
+                if (intent.getAction().equals(
+                    android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)) {
+                    // The OnPreferenceClickListener overrides the click event completely. No intent
+                    // will get fired.
+                    pref.setOnPreferenceClickListener(new FragmentStarter(
+                        LocationSettings.class.getName(), R.string.location_settings_title));
+                } else {
+                    ResolveInfo ri = pm.resolveActivityAsUser(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY, mUserHandle.getIdentifier());
+                    if (ri == null) {
+                        prefs.removePreference(pref);
+                        continue;
+                    }
+                    intent.putExtra(ACCOUNT_KEY, account);
+                    intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
+                    pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference preference) {
+                            Intent prefIntent = preference.getIntent();
+                                /*
+                                 * Check the intent to see if it resolves to a exported=false
+                                 * activity that doesn't share a uid with the authenticator.
+                                 *
+                                 * Otherwise the intent is considered unsafe in that it will be
+                                 * exploiting the fact that settings has system privileges.
+                                 */
+                            if (isSafeIntent(pm, prefIntent, acccountType)) {
+                                mFragment.getActivity().startActivityAsUser(
+                                    prefIntent, mUserHandle);
+                            } else {
+                                Log.e(TAG,
+                                    "Refusing to launch authenticator intent because"
+                                        + "it exploits Settings permissions: "
+                                        + prefIntent);
+                            }
+                            return true;
+                        }
+                    });
+                }
+            }
+            i++;
+        }
+    }
+
+    /**
+     * Determines if the supplied Intent is safe. A safe intent is one that is
+     * will launch a exported=true activity or owned by the same uid as the
+     * authenticator supplying the intent.
+     */
+    private boolean isSafeIntent(PackageManager pm, Intent intent, String acccountType) {
+        AuthenticatorDescription authDesc =
+            mAuthenticatorHelper.getAccountTypeDescription(acccountType);
+        ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mUserHandle.getIdentifier());
+        if (resolveInfo == null) {
+            return false;
+        }
+        ActivityInfo resolvedActivityInfo = resolveInfo.activityInfo;
+        ApplicationInfo resolvedAppInfo = resolvedActivityInfo.applicationInfo;
+        try {
+            if (resolvedActivityInfo.exported) {
+                if (resolvedActivityInfo.permission == null) {
+                    return true; // exported activity without permission.
+                } else if (pm.checkPermission(resolvedActivityInfo.permission,
+                    authDesc.packageName) == PackageManager.PERMISSION_GRANTED) {
+                    return true;
+                }
+            }
+            ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0);
+            return resolvedAppInfo.uid == authenticatorAppInf.uid;
+        } catch (NameNotFoundException e) {
+            Log.e(TAG,
+                "Intent considered unsafe due to exception.",
+                e);
+            return false;
+        }
+    }
+
+    /** Listens to a preference click event and starts a fragment */
+    private class FragmentStarter
+        implements Preference.OnPreferenceClickListener {
+        private final String mClass;
+        private final int mTitleRes;
+
+        /**
+         * @param className the class name of the fragment to be started.
+         * @param title the title resource id of the started preference panel.
+         */
+        public FragmentStarter(String className, int title) {
+            mClass = className;
+            mTitleRes = title;
+        }
+
+        @Override
+        public boolean onPreferenceClick(Preference preference) {
+            ((SettingsActivity) mFragment.getActivity()).startPreferencePanel(
+                mClass, null, mTitleRes, null, null, 0);
+            // Hack: announce that the Google account preferences page is launching the location
+            // settings
+            if (mClass.equals(LocationSettings.class.getName())) {
+                Intent intent = new Intent(LAUNCHING_LOCATION_SETTINGS);
+                mFragment.getActivity().sendBroadcast(
+                    intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
+            }
+            return true;
+        }
+    }
+
+}
diff --git a/src/com/android/settings/accounts/ManageAccountsSettings.java b/src/com/android/settings/accounts/ManageAccountsSettings.java
index e6569e9..7c5ee00 100644
--- a/src/com/android/settings/accounts/ManageAccountsSettings.java
+++ b/src/com/android/settings/accounts/ManageAccountsSettings.java
@@ -18,26 +18,17 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.accounts.AuthenticatorDescription;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.ContentResolver;
-import android.content.Intent;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
 import android.content.SyncStatusInfo;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceScreen;
 import android.util.ArraySet;
 import android.util.Log;
@@ -53,7 +44,6 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
-import com.android.settings.location.LocationSettings;
 import com.android.settingslib.accounts.AuthenticatorHelper;
 
 import java.util.ArrayList;
@@ -66,15 +56,9 @@
 /** Manages settings for Google Account. */
 public class ManageAccountsSettings extends AccountPreferenceBase
         implements AuthenticatorHelper.OnAccountsUpdateListener {
-    private static final String ACCOUNT_KEY = "account"; // to pass to auth settings
     public static final String KEY_ACCOUNT_TYPE = "account_type";
     public static final String KEY_ACCOUNT_LABEL = "account_label";
 
-    // Action name for the broadcast intent when the Google account preferences page is launching
-    // the location settings.
-    private static final String LAUNCHING_LOCATION_SETTINGS =
-            "com.android.settings.accounts.LAUNCHING_LOCATION_SETTINGS";
-
     private static final int MENU_SYNC_NOW_ID = Menu.FIRST;
     private static final int MENU_SYNC_CANCEL_ID = Menu.FIRST + 1;
 
@@ -414,145 +398,7 @@
     private void addAuthenticatorSettings() {
         PreferenceScreen prefs = addPreferencesForType(mAccountType, getPreferenceScreen());
         if (prefs != null) {
-            updatePreferenceIntents(prefs);
-        }
-    }
-
-    /** Listens to a preference click event and starts a fragment */
-    private class FragmentStarter
-            implements Preference.OnPreferenceClickListener {
-        private final String mClass;
-        private final int mTitleRes;
-
-        /**
-         * @param className the class name of the fragment to be started.
-         * @param title the title resource id of the started preference panel.
-         */
-        public FragmentStarter(String className, int title) {
-            mClass = className;
-            mTitleRes = title;
-        }
-
-        @Override
-        public boolean onPreferenceClick(Preference preference) {
-            ((SettingsActivity) getActivity()).startPreferencePanel(
-                    mClass, null, mTitleRes, null, null, 0);
-            // Hack: announce that the Google account preferences page is launching the location
-            // settings
-            if (mClass.equals(LocationSettings.class.getName())) {
-                Intent intent = new Intent(LAUNCHING_LOCATION_SETTINGS);
-                getActivity().sendBroadcast(
-                        intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Recursively filters through the preference list provided by GoogleLoginService.
-     *
-     * This method removes all the invalid intent from the list, adds account name as extra into the
-     * intent, and hack the location settings to start it as a fragment.
-     */
-    private void updatePreferenceIntents(PreferenceGroup prefs) {
-        final PackageManager pm = getActivity().getPackageManager();
-        for (int i = 0; i < prefs.getPreferenceCount(); ) {
-            Preference pref = prefs.getPreference(i);
-            if (pref instanceof PreferenceGroup) {
-                updatePreferenceIntents((PreferenceGroup) pref);
-            }
-            Intent intent = pref.getIntent();
-            if (intent != null) {
-                // Hack. Launch "Location" as fragment instead of as activity.
-                //
-                // When "Location" is launched as activity via Intent, there's no "Up" button at the
-                // top left, and if there's another running instance of "Location" activity, the
-                // back stack would usually point to some other place so the user won't be able to
-                // go back to the previous page by "back" key. Using fragment is a much easier
-                // solution to those problems.
-                //
-                // If we set Intent to null and assign a fragment to the PreferenceScreen item here,
-                // in order to make it work as expected, we still need to modify the container
-                // PreferenceActivity, override onPreferenceStartFragment() and call
-                // startPreferencePanel() there. In order to inject the title string there, more
-                // dirty further hack is still needed. It's much easier and cleaner to listen to
-                // preference click event here directly.
-                if (intent.getAction().equals(
-                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)) {
-                    // The OnPreferenceClickListener overrides the click event completely. No intent
-                    // will get fired.
-                    pref.setOnPreferenceClickListener(new FragmentStarter(
-                            LocationSettings.class.getName(),
-                            R.string.location_settings_title));
-                } else {
-                    ResolveInfo ri = pm.resolveActivityAsUser(intent,
-                            PackageManager.MATCH_DEFAULT_ONLY, mUserHandle.getIdentifier());
-                    if (ri == null) {
-                        prefs.removePreference(pref);
-                        continue;
-                    } else {
-                        intent.putExtra(ACCOUNT_KEY, mFirstAccount);
-                        intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
-                        pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-                            @Override
-                            public boolean onPreferenceClick(Preference preference) {
-                                Intent prefIntent = preference.getIntent();
-                                /*
-                                 * Check the intent to see if it resolves to a exported=false
-                                 * activity that doesn't share a uid with the authenticator.
-                                 *
-                                 * Otherwise the intent is considered unsafe in that it will be
-                                 * exploiting the fact that settings has system privileges.
-                                 */
-                                if (isSafeIntent(pm, prefIntent)) {
-                                    getActivity().startActivityAsUser(prefIntent, mUserHandle);
-                                } else {
-                                    Log.e(TAG,
-                                            "Refusing to launch authenticator intent because"
-                                                    + "it exploits Settings permissions: "
-                                                    + prefIntent);
-                                }
-                                return true;
-                            }
-                        });
-                    }
-                }
-            }
-            i++;
-        }
-    }
-
-    /**
-     * Determines if the supplied Intent is safe. A safe intent is one that is
-     * will launch a exported=true activity or owned by the same uid as the
-     * authenticator supplying the intent.
-     */
-    private boolean isSafeIntent(PackageManager pm, Intent intent) {
-        AuthenticatorDescription authDesc =
-                mAuthenticatorHelper.getAccountTypeDescription(mAccountType);
-        ResolveInfo resolveInfo =
-            pm.resolveActivityAsUser(intent, 0, mUserHandle.getIdentifier());
-        if (resolveInfo == null) {
-            return false;
-        }
-        ActivityInfo resolvedActivityInfo = resolveInfo.activityInfo;
-        ApplicationInfo resolvedAppInfo = resolvedActivityInfo.applicationInfo;
-        try {
-            if (resolvedActivityInfo.exported) {
-                if (resolvedActivityInfo.permission == null) {
-                    return true; // exported activity without permission.
-                } else if (pm.checkPermission(resolvedActivityInfo.permission,
-                        authDesc.packageName) == PackageManager.PERMISSION_GRANTED) {
-                    return true;
-                }
-            }
-            ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0);
-            return  resolvedAppInfo.uid == authenticatorAppInf.uid;
-        } catch (NameNotFoundException e) {
-            Log.e(TAG,
-                    "Intent considered unsafe due to exception.",
-                    e);
-            return false;
+            mAccountTypePreferenceLoader.updatePreferenceIntents(prefs, mAccountType, mFirstAccount);
         }
     }
 
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index b6285ad..514eaf2 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -63,6 +63,7 @@
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final DashboardFeatureProvider mDashboardFeatureProvider;
     private SuggestionParser mSuggestionParser;
+    private boolean mFirstFrameDrawn;
 
     @VisibleForTesting
     DashboardData mDashboardData;
@@ -162,6 +163,15 @@
         notifyDashboardDataChanged(prevData);
     }
 
+    public void setCategory(List<DashboardCategory> category) {
+        final DashboardData prevData = mDashboardData;
+        Log.d(TAG, "adapter setCategory called");
+        mDashboardData = new DashboardData.Builder(prevData)
+                .setCategories(category)
+                .build();
+        notifyDashboardDataChanged(prevData);
+    }
+
     public void setConditions(List<Condition> conditions) {
         final DashboardData prevData = mDashboardData;
         Log.d(TAG, "adapter setConditions called");
@@ -304,11 +314,12 @@
     }
 
     private void notifyDashboardDataChanged(DashboardData prevData) {
-        if (prevData != null) {
+        if (mFirstFrameDrawn && prevData != null) {
             final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DashboardData
                     .ItemsDataDiffCallback(prevData.getItemList(), mDashboardData.getItemList()));
             diffResult.dispatchUpdatesTo(this);
         } else {
+            mFirstFrameDrawn = true;
             notifyDataSetChanged();
         }
     }
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 74c8bfa..a5a4f43 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -27,6 +27,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
@@ -231,26 +232,25 @@
             Log.d(TAG, "onViewCreated took "
                     + (System.currentTimeMillis() - startTime) + " ms");
         }
-        rebuildUI();
+        rebuildUI(true /* rebuildSuggestions */);
     }
 
-    private void rebuildUI() {
-        if (!isAdded()) {
-            Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added");
-            return;
-        }
-
-        // recheck to see if any suggestions have been changed.
-        new SuggestionLoader().execute();
-        // Set categories on their own if loading suggestions takes too long.
-        mHandler.postDelayed(() -> {
+    private void rebuildUI(boolean rebuildSuggestions) {
+        if (rebuildSuggestions) {
+            // recheck to see if any suggestions have been changed.
+            new SuggestionLoader().execute();
+            // Set categories on their own if loading suggestions takes too long.
+            mHandler.postDelayed(() -> {
+                updateCategoryAndSuggestion(null /* tiles */);
+            }, MAX_WAIT_MILLIS);
+        } else {
             updateCategoryAndSuggestion(null /* tiles */);
-        }, MAX_WAIT_MILLIS);
+        }
     }
 
     @Override
     public void onCategoriesChanged() {
-        rebuildUI();
+        rebuildUI(false /* rebuildSuggestions */);
     }
 
     @Override
@@ -264,7 +264,6 @@
     }
 
     private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> {
-
         @Override
         protected List<Tile> doInBackground(Void... params) {
             final Context context = getContext();
@@ -307,7 +306,7 @@
     }
 
     @VisibleForTesting
-    void updateCategoryAndSuggestion(List<Tile> tiles) {
+    void updateCategoryAndSuggestion(List<Tile> suggestions) {
         final Activity activity = getActivity();
         if (activity == null) {
             return;
@@ -319,10 +318,14 @@
             List<DashboardCategory> categories = new ArrayList<>();
             categories.add(mDashboardFeatureProvider.getTilesForCategory(
                     CategoryKey.CATEGORY_HOMEPAGE));
-            mAdapter.setCategoriesAndSuggestions(categories, tiles);
+            if (suggestions != null) {
+                mAdapter.setCategoriesAndSuggestions(categories, suggestions);
+            } else {
+                mAdapter.setCategory(categories);
+            }
         } else {
             mAdapter.setCategoriesAndSuggestions(
-                    ((SettingsActivity) activity).getDashboardCategories(), tiles);
+                    ((SettingsActivity) activity).getDashboardCategories(), suggestions);
         }
     }
 }
diff --git a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
index 3170a87..769b69b 100644
--- a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
@@ -16,14 +16,13 @@
 package com.android.settings.deviceinfo;
 
 import android.content.Context;
-import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceController;
 
 public class ManageStoragePreferenceController extends PreferenceController {
 
-    public static final String KEY_MANAGE_STORAGE = "footer_preference";
+    public static final String KEY_MANAGE_STORAGE = "manage_storage";
 
     public ManageStoragePreferenceController(Context context) {
         super(context);
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 6ec1b73..914a8fe 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -32,7 +32,6 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
-import com.android.settings.widget.FooterPreference;
 import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
 
 import java.util.ArrayList;
@@ -84,13 +83,6 @@
         mSummaryController.updateBytes(usedBytes, totalSize);
         mPreferenceController.setVolume(mVolume);
         mPreferenceController.setSystemSize(systemSize);
-
-        // Initialize the footer preference to go to the smart storage management.
-        final FooterPreference pref = mFooterPreferenceMixin.createFooterPreference();
-        pref.setTitle(R.string.storage_menu_manage);
-        pref.setFragment("com.android.settings.deletionhelper.AutomaticStorageManagerSettings");
-        pref.setIcon(R.drawable.ic_settings_storage);
-        pref.setEnabled(true);
     }
 
     @Override
diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
index d38902e..213259b 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
@@ -64,4 +64,14 @@
                 Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0);
         return cameraDisabled == 0;
     }
+
+    @Override
+    public ResultPayload getResultPayload() {
+        ArrayMap<Integer, Boolean> valueMap = new ArrayMap<>();
+        valueMap.put(0, true);
+        valueMap.put(1, false);
+
+        return new InlineSwitchPayload(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
+                ResultPayload.SettingsSource.SECURE, valueMap);
+    }
 }
diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
index 49e8f51..02d8dd7 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
@@ -70,4 +70,14 @@
     protected boolean isSwitchPrefEnabled() {
         return mAmbientConfig.pulseOnDoubleTapEnabled(mUserId);
     }
+
+    @Override
+    public ResultPayload getResultPayload() {
+        ArrayMap<Integer, Boolean> valueMap = new ArrayMap<>();
+        valueMap.put(1, true);
+        valueMap.put(0, false);
+
+        return new InlineSwitchPayload(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+                ResultPayload.SettingsSource.SECURE, valueMap);
+    }
 }
diff --git a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
index c5174fd..fea1c9d 100644
--- a/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTwistPreferenceController.java
@@ -85,4 +85,14 @@
         }
         return false;
     }
+
+    @Override
+    public ResultPayload getResultPayload() {
+        ArrayMap<Integer, Boolean> valueMap = new ArrayMap<>();
+        valueMap.put(1, true);
+        valueMap.put(0, false);
+
+        return new InlineSwitchPayload(Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+                ResultPayload.SettingsSource.SECURE, valueMap);
+    }
 }
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index 390fd4c..db6925e 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -170,5 +170,24 @@
                     }
                     return result;
                 }
+
+                @Override
+                public List<PreferenceController> getPreferenceControllers(Context context) {
+                    List<PreferenceController> controllers = new ArrayList<>();
+                    AmbientDisplayConfiguration ambientConfig
+                            = new AmbientDisplayConfiguration(context);
+
+                    controllers.add(new DoubleTapPowerPreferenceController(context,
+                            null /* lifecycle */));
+                    controllers.add(new PickupGesturePreferenceController(context,
+                            null /* lifecycle */, ambientConfig, UserHandle.myUserId()));
+                    controllers.add(new DoubleTapScreenPreferenceController(context,
+                            null /* lifecycle */, ambientConfig, UserHandle.myUserId()));
+                    controllers.add(new SwipeToNotificationPreferenceController(context,
+                            null /* lifecycle */));
+                    controllers.add(new DoubleTwistPreferenceController(context,
+                            null /* lifecycle */));
+                    return controllers;
+                }
             };
 }
diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
index ce20f15..f48551e 100644
--- a/src/com/android/settings/gestures/PickupGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
@@ -70,4 +70,14 @@
                 Settings.Secure.DOZE_PULSE_ON_PICK_UP, enabled ? 1 : 0);
         return true;
     }
+
+    @Override
+    public ResultPayload getResultPayload() {
+        ArrayMap<Integer, Boolean> valueMap = new ArrayMap<>();
+        valueMap.put(1, true);
+        valueMap.put(0, false);
+
+        return new InlineSwitchPayload(Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+                ResultPayload.SettingsSource.SECURE, valueMap);
+    }
 }
diff --git a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
index 22b88fc..67c8e14 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationPreferenceController.java
@@ -63,4 +63,14 @@
                 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 0)
                 == 1;
     }
+
+    @Override
+    public ResultPayload getResultPayload() {
+        ArrayMap<Integer, Boolean> valueMap = new ArrayMap<>();
+        valueMap.put(1, true);
+        valueMap.put(0, false);
+
+        return new InlineSwitchPayload(Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
+                ResultPayload.SettingsSource.SECURE, valueMap);
+    }
 }
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index c1a2159..c7b0384 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -57,7 +57,7 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mProgressiveDisclosureMixin.setTileLimit(5);
+        mProgressiveDisclosureMixin.setTileLimit(6);
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/LinkablePreference.java b/src/com/android/settings/wifi/LinkablePreference.java
index 6b1b87d..5bf51ed 100644
--- a/src/com/android/settings/wifi/LinkablePreference.java
+++ b/src/com/android/settings/wifi/LinkablePreference.java
@@ -55,11 +55,15 @@
         super.onBindViewHolder(view);
 
         TextView textView = (TextView) view.findViewById(android.R.id.title);
-        if (textView == null || mContentTitle == null || mClickListener == null) {
+        if (textView == null) {
+            return;
+        }
+        textView.setSingleLine(false);
+
+        if (mContentTitle == null || mClickListener == null) {
             return;
         }
 
-        textView.setSingleLine(false);
         StringBuilder contentBuilder = new StringBuilder().append(mContentTitle);
         if (mContentDescription != null) {
             contentBuilder.append("\n\n");
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index faf5ca4..c4b90c7 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -140,6 +140,10 @@
     // should Next button only be enabled when we have a connection?
     private boolean mEnableNextOnConnection;
 
+    // should see all networks instead of collapsing networks and showing mSeeAllNetworksPreference.
+    private boolean mSeeAllNetworks;
+    private static final int NETWORKS_TO_INITIALLY_SHOW = 5;
+
     // Save the dialog details
     private int mDialogMode;
     private AccessPoint mDlgAccessPoint;
@@ -157,6 +161,7 @@
     private PreferenceCategory mAccessPointsPreferenceCategory;
     private PreferenceCategory mAdditionalSettingsPreferenceCategory;
     private Preference mAddPreference;
+    private Preference mSeeAllNetworksPreference;
     private Preference mConfigureWifiSettingsPreference;
     private Preference mSavedNetworksPreference;
     private LinkablePreference mStatusMessagePreference;
@@ -174,7 +179,9 @@
         super.onViewCreated(view, savedInstanceState);
         final Activity activity = getActivity();
         if (activity != null) {
-            mProgressHeader = (ProgressBar) setPinnedHeaderView(R.layout.wifi_progress_header);
+            if (!isUiRestricted()) {
+                mProgressHeader = (ProgressBar) setPinnedHeaderView(R.layout.wifi_progress_header);
+            }
         }
     }
 
@@ -196,10 +203,18 @@
         mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS);
         mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS);
 
+        if (isUiRestricted()) {
+            getPreferenceScreen().removePreference(mAdditionalSettingsPreferenceCategory);
+        }
+
         Context prefContext = getPrefContext();
         mAddPreference = new Preference(prefContext);
         mAddPreference.setIcon(R.drawable.ic_menu_add_inset);
         mAddPreference.setTitle(R.string.wifi_add_network);
+        mSeeAllNetworksPreference = new Preference(prefContext);
+        mSeeAllNetworksPreference.setIcon(R.drawable.ic_arrow_down_24dp);
+        mSeeAllNetworksPreference.setTitle(R.string.wifi_see_all_networks_button_title);
+        mSeeAllNetworks = false;
         mStatusMessagePreference = new LinkablePreference(prefContext);
 
         mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager());
@@ -524,6 +539,9 @@
             }
         } else if (preference == mAddPreference) {
             onAddNetworkPressed();
+        } else if (preference == mSeeAllNetworksPreference) {
+            mSeeAllNetworks = true;
+            onAccessPointsChanged();
         } else {
             return super.onPreferenceTreeClick(preference);
         }
@@ -635,8 +653,12 @@
                 cacheRemoveAllPrefs(mAccessPointsPreferenceCategory);
 
                 int index = configureConnectedAccessPointPreferenceCategory(accessPoints) ? 1 : 0;
+                boolean fewerNetworksThanLimit =
+                        accessPoints.size() <= index + NETWORKS_TO_INITIALLY_SHOW;
+                int numAccessPointsToShow = mSeeAllNetworks || fewerNetworksThanLimit
+                        ? accessPoints.size() : index + NETWORKS_TO_INITIALLY_SHOW;
 
-                for (; index < accessPoints.size(); index++) {
+                for (; index < numAccessPointsToShow; index++) {
                     AccessPoint accessPoint = accessPoints.get(index);
                     // Ignore access points that are out of range.
                     if (accessPoint.getLevel() != -1) {
@@ -682,15 +704,19 @@
                     pref.setOrder(index++);
                     pref.setKey(PREF_KEY_EMPTY_WIFI_LIST);
                     mAccessPointsPreferenceCategory.addPreference(pref);
-                    mAddPreference.setOrder(index++);
-                    mAccessPointsPreferenceCategory.addPreference(mAddPreference);
-                    setConfigureWifiSettingsVisibility();
                 } else {
-                    mAddPreference.setOrder(index++);
-                    mAccessPointsPreferenceCategory.addPreference(mAddPreference);
-                    setConfigureWifiSettingsVisibility();
                     setProgressBarVisible(false);
                 }
+                if (mSeeAllNetworks || fewerNetworksThanLimit) {
+                    mAccessPointsPreferenceCategory.removePreference(mSeeAllNetworksPreference);
+                    mAddPreference.setOrder(index);
+                    mAccessPointsPreferenceCategory.addPreference(mAddPreference);
+                } else {
+                    mAccessPointsPreferenceCategory.removePreference(mAddPreference);
+                    mSeeAllNetworksPreference.setOrder(index);
+                    mAccessPointsPreferenceCategory.addPreference(mSeeAllNetworksPreference);
+                }
+                setConfigureWifiSettingsVisibility();
                 if (mScanMenuItem != null) {
                     mScanMenuItem.setEnabled(true);
                 }
@@ -798,11 +824,11 @@
 
     private void setOffMessage() {
         if (isUiRestricted()) {
+            removeConnectedAccessPointPreference();
+            mAccessPointsPreferenceCategory.removeAll();
             if (!isUiRestrictedByOnlyAdmin()) {
                 addMessagePreference(R.string.wifi_empty_list_user_restricted);
             }
-            removeConnectedAccessPointPreference();
-            mAccessPointsPreferenceCategory.removeAll();
             return;
         }
 
diff --git a/tests/app/src/com/android/settings/deviceinfo/StorageDashboardFragmentEspressoTest.java b/tests/app/src/com/android/settings/deviceinfo/StorageDashboardFragmentEspressoTest.java
new file mode 100644
index 0000000..b43a5ba
--- /dev/null
+++ b/tests/app/src/com/android/settings/deviceinfo/StorageDashboardFragmentEspressoTest.java
@@ -0,0 +1,40 @@
+package com.android.settings.deviceinfo;
+
+import android.support.test.espresso.intent.rule.IntentsTestRule;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnitRunner;
+import com.android.settings.R;
+import com.android.settings.Settings.StorageDashboardActivity;
+import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.intent.Intents.intended;
+import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+
+@SmallTest
+public class StorageDashboardFragmentEspressoTest {
+
+    public static final String EXTRA_KEY = ":settings:show_fragment";
+
+    @Rule
+    public IntentsTestRule<StorageDashboardActivity> mActivityRule =
+            new IntentsTestRule<>(StorageDashboardActivity.class, true, true);
+
+    @Test
+    public void testStorageManagePreference_canClickTextView() throws InterruptedException {
+        // Click on the actual textbox instead of just somewhere in the preference
+        onView(withText(R.string.storage_menu_manage)).perform(click());
+
+        // Check that it worked by seeing if we switched screens
+        intended(hasExtra(equalTo(EXTRA_KEY),
+                containsString(AutomaticStorageManagerSettings.class.getName())));
+
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
index 92214e3..51c0d9b 100644
--- a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
@@ -16,14 +16,14 @@
 
 package com.android.settings;
 
-import android.content.Context;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.IContentProvider;
-import android.provider.Settings;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
 import android.os.Bundle;
+import android.provider.Settings;
 
-import com.android.settings.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.drawer.DashboardCategory;
@@ -46,7 +46,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -121,6 +121,27 @@
     }
 
     @Test
+    @Config(shadows = {
+            ShadowSecureSettings.class,
+    })
+    public void testSummaryProvider_hasFingerPrint_hasStaticSummary() {
+        // Package verifier state is set to disabled.
+        ShadowSecureSettings.putInt(null, Settings.Secure.PACKAGE_VERIFIER_STATE, -1);
+        final FingerprintManager fpm = mock(FingerprintManager.class);
+        when(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+                .thenReturn(true);
+
+        // Cast to Object to workaround a robolectric casting bug
+        when((Object) mContext.getSystemService(FingerprintManager.class)).thenReturn(fpm);
+        when(fpm.isHardwareDetected()).thenReturn(true);
+
+        mSummaryProvider.setListening(true);
+
+        verify(mContext).getString(R.string.security_dashboard_summary);
+    }
+
+
+    @Test
     public void testGetPackageVerifierSummary_nullInput() {
         assertThat(mSummaryProvider.getPackageVerifierSummary(null)).isNull();
 
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
index 31090be..fd0ab4b 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.SettingsRobolectricTestRunner;
@@ -61,6 +62,8 @@
     private AccountManager mAccountManager;
     @Mock
     private Preference mPreference;
+    @Mock
+    private PreferenceScreen mScreen;
 
     private AccountDetailDashboardFragment mFragment;
     private Context mContext;
@@ -125,9 +128,10 @@
             new AuthenticatorDescription[0]);
         when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
         when(mFragment.getContext()).thenReturn(mContext);
+        doReturn(mScreen).when(mFragment).getPreferenceScreen();
         doReturn(mPreference).when(mFragment).findPreference(PREF_ACCOUNT_HEADER);
 
-        mFragment.updateAccountHeader();
+        mFragment.updateUi();
 
         verify(mPreference).setTitle("name1@abc.com");
     }
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountTypePreferenceLoaderTest.java b/tests/robotests/src/com/android/settings/accounts/AccountTypePreferenceLoaderTest.java
new file mode 100644
index 0000000..29f254d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/AccountTypePreferenceLoaderTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.accounts;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.shadow.ShadowAccountManager;
+import com.android.settings.testutils.shadow.ShadowContentResolver;
+import com.android.settingslib.accounts.AuthenticatorHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static org.mockito.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AccountTypePreferenceLoaderTest {
+
+    @Mock(answer = RETURNS_DEEP_STUBS)
+    private AccountManager mAccountManager;
+    @Mock(answer = RETURNS_DEEP_STUBS)
+    private PreferenceFragment mPreferenceFragment;
+    @Mock
+    private PackageManager mPackageManager;
+
+    private Context mContext;
+    private Account mAccount;
+    private AccountTypePreferenceLoader mPrefLoader;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowContext = ShadowApplication.getInstance();
+        shadowContext.setSystemService(Context.ACCOUNT_SERVICE, mAccountManager);
+        when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(
+            new AuthenticatorDescription[0]);
+        when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
+        when(mPreferenceFragment.getActivity().getPackageManager()).thenReturn(mPackageManager);
+        mContext = shadowContext.getApplicationContext();
+        mAccount = new Account("name", "type");
+        final AuthenticatorHelper helper = new AuthenticatorHelper(mContext, UserHandle.CURRENT,
+            null /* OnAccountsUpdateListener */);
+        mPrefLoader = spy(new AccountTypePreferenceLoader(mPreferenceFragment, helper,
+            UserHandle.CURRENT));
+    }
+
+    @Test
+    @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+    public void updatePreferenceIntents_shouldRunRecursively() {
+        final PreferenceManager preferenceManager = mock(PreferenceManager.class);
+        // Top level
+        PreferenceGroup prefRoot = spy(new PreferenceScreen(mContext, null));
+        when(prefRoot.getPreferenceManager()).thenReturn(preferenceManager);
+        Preference pref1 = mock(Preference.class);
+        PreferenceGroup prefGroup2 = spy(new PreferenceScreen(mContext, null));
+        when(prefGroup2.getPreferenceManager()).thenReturn(preferenceManager);
+        Preference pref3 = mock(Preference.class);
+        PreferenceGroup prefGroup4 = spy(new PreferenceScreen(mContext, null));
+        when(prefGroup4.getPreferenceManager()).thenReturn(preferenceManager);
+        prefRoot.addPreference(pref1);
+        prefRoot.addPreference(prefGroup2);
+        prefRoot.addPreference(pref3);
+        prefRoot.addPreference(prefGroup4);
+
+        // 2nd level
+        Preference pref21 = mock(Preference.class);
+        Preference pref22 = mock(Preference.class);
+        prefGroup2.addPreference(pref21);
+        prefGroup2.addPreference(pref22);
+        PreferenceGroup prefGroup41 = spy(new PreferenceScreen(mContext, null));
+        when(prefGroup41.getPreferenceManager()).thenReturn(preferenceManager);
+        Preference pref42 = mock(Preference.class);
+        prefGroup4.addPreference(prefGroup41);
+        prefGroup4.addPreference(pref42);
+
+        // 3rd level
+        Preference pref411 = mock(Preference.class);
+        Preference pref412 = mock(Preference.class);
+        prefGroup41.addPreference(pref411);
+        prefGroup41.addPreference(pref412);
+
+        final String acctType = "testType";
+        mPrefLoader.updatePreferenceIntents(prefRoot, acctType, mAccount);
+
+        verify(mPrefLoader).updatePreferenceIntents(prefGroup2, acctType, mAccount);
+        verify(mPrefLoader).updatePreferenceIntents(prefGroup4, acctType, mAccount);
+        verify(mPrefLoader).updatePreferenceIntents(prefGroup41, acctType, mAccount);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
index 9627e2c..62866c9 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
@@ -17,8 +17,8 @@
 package com.android.settings.dashboard;
 
 import android.app.Activity;
-
 import android.support.v7.widget.LinearLayoutManager;
+
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.conditional.ConditionManager;
@@ -33,6 +33,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
+import static org.mockito.Matchers.anyList;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -90,4 +91,13 @@
         mSummary.onConditionsChanged();
         verify(mDashboard, never()).scrollToPosition(0);
     }
+
+    @Test
+    public void onCategoryChanged_updateCategoryOnly() {
+        doReturn(mock(Activity.class)).when(mSummary).getActivity();
+        when(mDashboardFeatureProvider.isEnabled()).thenReturn(true);
+
+        mSummary.onCategoriesChanged();
+        verify(mAdapter).setCategory(anyList());
+    }
 }
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
index bdb3522..5f7d8b5 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
@@ -93,4 +93,23 @@
 
         assertThat(mController.isSwitchPrefEnabled()).isFalse();
     }
+
+    @Test
+    public void testPreferenceController_ProperResultPayloadType() {
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        mController = new DoubleTapPowerPreferenceController(context, null);
+        ResultPayload payload = mController.getResultPayload();
+        assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
+    }
+
+    @Test
+    public void testPreferenceController_CorrectPayload() {
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        mController = new DoubleTapPowerPreferenceController(context, null);
+        InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
+        assertThat(payload.settingsUri).isEqualTo("camera_double_tap_power_gesture_disabled");
+        assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SECURE);
+        assertThat(payload.valueMap.get(0)).isEqualTo(true);
+        assertThat(payload.valueMap.get(1)).isEqualTo(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
index adf8b75..2f922d5 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapScreenPreferenceControllerTest.java
@@ -81,4 +81,19 @@
 
         assertThat(mController.isSwitchPrefEnabled()).isFalse();
     }
+
+    @Test
+    public void testPreferenceController_ProperResultPayloadType() {
+        ResultPayload payload = mController.getResultPayload();
+        assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
+    }
+
+    @Test
+    public void testPreferenceController_CorrectPayload() {
+        InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
+        assertThat(payload.settingsUri).isEqualTo("doze_pulse_on_double_tap");
+        assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SECURE);
+        assertThat(payload.valueMap.get(1)).isEqualTo(true);
+        assertThat(payload.valueMap.get(0)).isEqualTo(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
index 9bf6655..ad682b2 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTwistPreferenceControllerTest.java
@@ -113,4 +113,19 @@
 
         assertThat(mController.isSwitchPrefEnabled()).isFalse();
     }
+
+    @Test
+    public void testPreferenceController_ProperResultPayloadType() {
+        ResultPayload payload = mController.getResultPayload();
+        assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
+    }
+
+    @Test
+    public void testPreferenceController_CorrectPayload() {
+        InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
+        assertThat(payload.settingsUri).isEqualTo("camera_double_twist_to_flip_enabled");
+        assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SECURE);
+        assertThat(payload.valueMap.get(1)).isEqualTo(true);
+        assertThat(payload.valueMap.get(0)).isEqualTo(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java
index 9dce074..f112b9e 100644
--- a/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/PIckupGesturePreferenceControllerTest.java
@@ -83,4 +83,19 @@
 
         assertThat(mController.isSwitchPrefEnabled()).isFalse();
     }
+
+    @Test
+    public void testPreferenceController_ProperResultPayloadType() {
+        ResultPayload payload = mController.getResultPayload();
+        assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
+    }
+
+    @Test
+    public void testPreferenceController_CorrectPayload() {
+        InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
+        assertThat(payload.settingsUri).isEqualTo("doze_pulse_on_pick_up");
+        assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SECURE);
+        assertThat(payload.valueMap.get(1)).isEqualTo(true);
+        assertThat(payload.valueMap.get(0)).isEqualTo(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
index e909667..49d73ea 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
@@ -89,4 +89,19 @@
 
         assertThat(mController.isSwitchPrefEnabled()).isFalse();
     }
+
+    @Test
+    public void testPreferenceController_ProperResultPayloadType() {
+        ResultPayload payload = mController.getResultPayload();
+        assertThat(payload).isInstanceOf(InlineSwitchPayload.class);
+    }
+
+    @Test
+    public void testPreferenceController_CorrectPayload() {
+        InlineSwitchPayload payload = (InlineSwitchPayload) mController.getResultPayload();
+        assertThat(payload.settingsUri).isEqualTo("system_navigation_keys_enabled");
+        assertThat(payload.settingSource).isEqualTo(ResultPayload.SettingsSource.SECURE);
+        assertThat(payload.valueMap.get(1)).isEqualTo(true);
+        assertThat(payload.valueMap.get(0)).isEqualTo(false);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
index f4370fc..a13a24e 100644
--- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
@@ -73,6 +73,14 @@
     }
 
     @Test
+    public void testGetPreferenceControllerUriMap_CompatibleClass_ReturnsNotNull() {
+        String className = "com.android.settings.gestures.GestureSettings";
+
+        Map map = DatabaseIndexingUtils.getPreferenceControllerUriMap(className, mContext);
+        assertThat(map).isNotNull();
+    }
+
+    @Test
     public void testGetPreferenceControllerUriMap_CompatibleClass_ReturnsValidMap() {
         String className = "com.android.settings.DisplaySettings";
 
@@ -88,7 +96,7 @@
     }
 
     @Test
-    public void testGetPayloadFromMap_MatchingKey_ReturnsPayload() {
+    public void testGetPayloadFromMap_MatchingKey_ReturnsPayloa() {
         final String key = "key";
         PreferenceController prefController = new PreferenceController(mContext) {
             @Override