Merge "Change UI for wireless AP tether band selection"
diff --git a/res/drawable/ic_signal_flashlight.xml b/res/drawable/ic_signal_flashlight.xml
new file mode 100644
index 0000000..e635953
--- /dev/null
+++ b/res/drawable/ic_signal_flashlight.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18,2H6v6l2,3v11h8V11l2,-3L18,2zM16,4l0,1H8V4H16zM14,10.4V20h-4v-9.61l-2,-3V7h8l0,0.39L14,10.4z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,14m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+</vector>
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index f563643..fbb464c 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -56,6 +56,7 @@
         android:title="@string/zen_mode_settings_title"
         settings:useAdminDisabledSummary="true"
         android:fragment="com.android.settings.notification.ZenModeSettings"
+        settings:controller="com.android.settings.notification.ZenModePreferenceController"
         settings:allowDividerAbove="false" />
 
     <!-- Empty category to draw divider -->
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index 650b1c4..9f69102 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -67,6 +67,6 @@
         android:key="gesture_prevent_ringing_summary"
         android:title="@string/gesture_prevent_ringing_screen_title"
         android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
-        settings:controller="com.android.settings.gestures.PreventRingingPreferenceController" />
+        settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
 
 </PreferenceScreen>
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 54a4190..d38a8e4 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -94,14 +94,15 @@
         android:order="-120"
         settings:useAdminDisabledSummary="true"
         settings:keywords="@string/keywords_sounds_and_notifications_interruptions"
-        settings:allowDividerAbove="true"/>
+        settings:allowDividerAbove="true"
+        settings:controller="com.android.settings.notification.ZenModePreferenceController" />
 
     <Preference
         android:key="gesture_prevent_ringing_sound"
         android:title="@string/gesture_prevent_ringing_sound_title"
         android:order="-110"
         android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
-        settings:controller="com.android.settings.gestures.PreventRingingPreferenceController" />
+        settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
 
     <!-- Phone ringtone -->
     <com.android.settings.DefaultRingtonePreference
diff --git a/src/com/android/settings/accounts/AccountSyncSettings.java b/src/com/android/settings/accounts/AccountSyncSettings.java
index 66f9179..66e8d22 100644
--- a/src/com/android/settings/accounts/AccountSyncSettings.java
+++ b/src/com/android/settings/accounts/AccountSyncSettings.java
@@ -247,10 +247,13 @@
         }
         if (preference instanceof SyncStateSwitchPreference) {
             SyncStateSwitchPreference syncPref = (SyncStateSwitchPreference) preference;
-            String authority = syncPref.getAuthority();
-            Account account = syncPref.getAccount();
+            final String authority = syncPref.getAuthority();
+            if (TextUtils.isEmpty(authority)) {
+                return false;
+            }
+            final Account account = syncPref.getAccount();
             final int userId = mUserHandle.getIdentifier();
-            String packageName = syncPref.getPackageName();
+            final String packageName = syncPref.getPackageName();
 
             boolean syncAutomatically = ContentResolver.getSyncAutomaticallyAsUser(account,
                     authority, userId);
diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java
index 8153be2..c243970 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultBrowserPicker.java
@@ -17,9 +17,11 @@
 package com.android.settings.applications.defaultapps;
 
 import android.content.Context;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 
+import android.util.ArraySet;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 
@@ -27,6 +29,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Fragment for choosing default browser.
@@ -62,14 +65,20 @@
                 DefaultBrowserPreferenceController.BROWSE_PROBE, PackageManager.MATCH_ALL, mUserId);
 
         final int count = list.size();
+        final Set<String> addedPackages = new ArraySet<>();
         for (int i = 0; i < count; i++) {
             ResolveInfo info = list.get(i);
             if (info.activityInfo == null || !info.handleAllWebDataURI) {
                 continue;
             }
+            final String packageName = info.activityInfo.packageName;
+            if (addedPackages.contains(packageName)) {
+                continue;
+            }
             try {
                 candidates.add(new DefaultAppInfo(context, mPm,
-                        mPm.getApplicationInfoAsUser(info.activityInfo.packageName, 0, mUserId)));
+                        mPm.getApplicationInfoAsUser(packageName, 0, mUserId)));
+                addedPackages.add(packageName);
             } catch (PackageManager.NameNotFoundException e) {
                 // Skip unknown packages.
             }
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
index bb60df9..27b7676 100644
--- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
@@ -21,11 +21,13 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
+
 import com.android.settings.bluetooth.BluetoothDeviceUpdater;
 import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater;
+import com.android.settings.connecteddevice.dock.DockUpdater;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
-
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -35,10 +37,14 @@
 
     private Preference mPreference;
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
+    private DockUpdater mSavedDockUpdater;
     private int mPreferenceSize;
 
     public PreviouslyConnectedDevicePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
+
+        mSavedDockUpdater = FeatureFactory.getFactory(
+            context).getDockUpdaterFeatureProvider().getSavedDockUpdater(context, this);
     }
 
     @Override
@@ -60,12 +66,14 @@
     @Override
     public void onStart() {
         mBluetoothDeviceUpdater.registerCallback();
+        mSavedDockUpdater.registerCallback();
         updatePreferenceOnSizeChanged();
     }
 
     @Override
     public void onStop() {
         mBluetoothDeviceUpdater.unregisterCallback();
+        mSavedDockUpdater.unregisterCallback();
     }
 
     public void init(DashboardFragment fragment) {
@@ -91,6 +99,11 @@
     }
 
     @VisibleForTesting
+    void setSavedDockUpdater(DockUpdater savedDockUpdater) {
+        mSavedDockUpdater = savedDockUpdater;
+    }
+
+    @VisibleForTesting
     void setPreferenceSize(int size) {
         mPreferenceSize = size;
     }
@@ -105,4 +118,4 @@
             mPreference.setEnabled(mPreferenceSize != 0);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
index 95a534c..03bba42 100644
--- a/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/fingerprint/FingerprintEnrollFindSensor.java
@@ -24,6 +24,7 @@
 import android.view.View;
 import android.widget.Button;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -35,7 +36,8 @@
  */
 public class FingerprintEnrollFindSensor extends FingerprintEnrollBase {
 
-    private static final int CONFIRM_REQUEST = 1;
+    @VisibleForTesting
+    static final int CONFIRM_REQUEST = 1;
     private static final int ENROLLING = 2;
     public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock";
 
@@ -170,7 +172,7 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == CONFIRM_REQUEST) {
-            if (resultCode == RESULT_OK) {
+            if (resultCode == RESULT_OK && data != null) {
                 mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
                 overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
                 getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
diff --git a/src/com/android/settings/flashlight/FlashlightSliceBuilder.java b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
new file mode 100644
index 0000000..6317ce7
--- /dev/null
+++ b/src/com/android/settings/flashlight/FlashlightSliceBuilder.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 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.flashlight;
+
+import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
+import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
+
+import android.annotation.ColorInt;
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.net.Uri;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.provider.SettingsSlicesContract;
+import android.util.Log;
+
+import androidx.core.graphics.drawable.IconCompat;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.SliceBroadcastReceiver;
+
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import android.app.StatusBarManager;
+
+
+/**
+ * Utility class to build a Flashlight Slice, and handle all associated actions.
+ */
+public class FlashlightSliceBuilder {
+
+    private static final String TAG = "FlashlightSliceBuilder";
+
+    public static final String KEY_FLASHLIGHT = "flashlight";
+
+    /**
+     * Backing Uri for the Flashlight Slice.
+     */
+    public static final Uri FLASHLIGHT_URI = new Uri.Builder()
+        .scheme(ContentResolver.SCHEME_CONTENT)
+        .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+        .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+        .appendPath(KEY_FLASHLIGHT)
+        .build();
+
+    /**
+     * Action notifying a change on the Flashlight Slice.
+     */
+    public static final String ACTION_FLASHLIGHT_SLICE_CHANGED =
+        "com.android.settings.flashlight.action.FLASHLIGHT_SLICE_CHANGED";
+
+    /**
+     * Action broadcasting a change on whether flashlight is on or off.
+     */
+    public static final String ACTION_FLASHLIGHT_CHANGED =
+        "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
+
+    public static final IntentFilter INTENT_FILTER = new IntentFilter(ACTION_FLASHLIGHT_CHANGED);
+
+    private FlashlightSliceBuilder() {}
+
+    /**
+     * Return a Flashlight Slice bound to {@link #FLASHLIGHT_URI}.
+     */
+    public static Slice getSlice(Context context) {
+        if (!isFlashlightAvailable(context)) {
+            return null;
+        }
+        final PendingIntent toggleAction = getBroadcastIntent(context);
+        @ColorInt final int color = Utils.getColorAccentDefaultColor(context);
+        final IconCompat icon =
+                IconCompat.createWithResource(context, R.drawable.ic_signal_flashlight);
+        return new ListBuilder(context, FLASHLIGHT_URI, ListBuilder.INFINITY)
+            .setAccentColor(color)
+            .addRow(b -> b
+                .setTitle(context.getText(R.string.power_flashlight))
+                .setTitleItem(icon, ICON_IMAGE)
+                .setPrimaryAction(
+                        new SliceAction(toggleAction, null, isFlashlightEnabled(context))))
+            .build();
+    }
+
+    /**
+     * Update the current flashlight status to the boolean value keyed by
+     * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
+     */
+    public static void handleUriChange(Context context, Intent intent) {
+        try {
+            final String cameraId = getCameraId(context);
+            if (cameraId != null) {
+                final boolean state = intent.getBooleanExtra(
+                        EXTRA_TOGGLE_STATE, isFlashlightEnabled(context));
+                final CameraManager cameraManager = context.getSystemService(CameraManager.class);
+                cameraManager.setTorchMode(cameraId, state);
+            }
+        } catch (CameraAccessException e) {
+            Log.e(TAG, "Camera couldn't set torch mode.", e);
+        }
+        context.getContentResolver().notifyChange(FLASHLIGHT_URI, null);
+    }
+
+    private static String getCameraId(Context context) throws CameraAccessException {
+        final CameraManager cameraManager = context.getSystemService(CameraManager.class);
+        final String[] ids = cameraManager.getCameraIdList();
+        for (String id : ids) {
+            CameraCharacteristics c = cameraManager.getCameraCharacteristics(id);
+            Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
+            Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
+            if (flashAvailable != null && flashAvailable
+                  && lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+                return id;
+            }
+        }
+        return null;
+    }
+
+    private static PendingIntent getBroadcastIntent(Context context) {
+        final Intent intent = new Intent(ACTION_FLASHLIGHT_SLICE_CHANGED);
+        intent.setClass(context, SliceBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
+            PendingIntent.FLAG_CANCEL_CURRENT);
+    }
+
+    private static boolean isFlashlightAvailable(Context context) {
+        return Settings.Secure.getInt(
+            context.getContentResolver(), Secure.FLASHLIGHT_AVAILABLE, 0) == 1;
+    }
+
+    private static boolean isFlashlightEnabled(Context context) {
+        return Settings.Secure.getInt(
+            context.getContentResolver(), Secure.FLASHLIGHT_ENABLED, 0) == 1;
+    }
+}
diff --git a/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java
new file mode 100644
index 0000000..8814765
--- /dev/null
+++ b/src/com/android/settings/gestures/PreventRingingParentPreferenceController.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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.gestures;
+
+import android.content.Context;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class PreventRingingParentPreferenceController extends BasePreferenceController {
+
+    public PreventRingingParentPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_volumeHushGestureEnabled)
+                ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+}
diff --git a/src/com/android/settings/gestures/PreventRingingPreferenceController.java b/src/com/android/settings/gestures/PreventRingingPreferenceController.java
index c6bc3aa..be55151 100644
--- a/src/com/android/settings/gestures/PreventRingingPreferenceController.java
+++ b/src/com/android/settings/gestures/PreventRingingPreferenceController.java
@@ -24,14 +24,8 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.VideoPreference;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnCreate;
@@ -39,8 +33,13 @@
 import com.android.settingslib.core.lifecycle.events.OnResume;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
 
-public class PreventRingingPreferenceController extends BasePreferenceController
-        implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+public class PreventRingingPreferenceController extends PreventRingingParentPreferenceController
+        implements Preference.OnPreferenceChangeListener,
         LifecycleObserver, OnResume, OnPause, OnCreate, OnSaveInstanceState {
 
     private static final String PREF_KEY_VIDEO = "gesture_prevent_ringing_video";
@@ -59,9 +58,11 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_volumeHushGestureEnabled)
-                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        final int status = super.getAvailabilityStatus();
+        if (status == AVAILABLE_UNSEARCHABLE) {
+            return AVAILABLE;
+        }
+        return status;
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index cdc02c0..96a4eb6 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -24,8 +24,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -42,6 +40,9 @@
 import java.util.Arrays;
 import java.util.List;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
 @SearchIndexable
 public class ConfigureNotificationSettings extends DashboardFragment {
     private static final String TAG = "ConfigNotiSettings";
@@ -57,7 +58,6 @@
     static final String KEY_SWIPE_DOWN = "gesture_swipe_down_fingerprint_notifications";
 
     private static final String KEY_NOTI_DEFAULT_RINGTONE = "notification_default_ringtone";
-    private static final String KEY_ZEN_MODE = "zen_mode_notifications";
 
     private RingtonePreference mRequestPreference;
     private static final int REQUEST_CODE = 200;
@@ -111,7 +111,6 @@
             }
 
         });
-        controllers.add(new ZenModePreferenceController(context, lifecycle, KEY_ZEN_MODE));
         return controllers;
     }
 
@@ -220,7 +219,6 @@
                     keys.add(KEY_LOCKSCREEN);
                     keys.add(KEY_LOCKSCREEN_WORK_PROFILE);
                     keys.add(KEY_LOCKSCREEN_WORK_PROFILE_HEADER);
-                    keys.add(KEY_ZEN_MODE);
                     return keys;
                 }
             };
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 7ad22a9..dbac1c2 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -27,10 +27,6 @@
 import android.provider.SearchIndexableResource;
 import android.text.TextUtils;
 
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -50,13 +46,16 @@
 import java.util.Arrays;
 import java.util.List;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
 @SearchIndexable
 public class SoundSettings extends DashboardFragment {
     private static final String TAG = "SoundSettings";
 
     private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
     private static final int REQUEST_CODE = 200;
-    private static final String KEY_ZEN_MODE = "zen_mode";
     private static final int SAMPLE_CUTOFF = 2000;  // manually cap sample playback at 2 seconds
 
     @VisibleForTesting
@@ -190,7 +189,7 @@
                 onPreferenceDataChanged(listPreference));
         mMediaOutputControllerKey = use(MediaOutputPreferenceController.class).getPreferenceKey();
         use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
-            onPreferenceDataChanged(listPreference));
+                onPreferenceDataChanged(listPreference));
         mHfpOutputControllerKey =
                 use(HandsFreeProfileOutputPreferenceController.class).getPreferenceKey();
 
@@ -235,7 +234,6 @@
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
             SoundSettings fragment, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new ZenModePreferenceController(context, lifecycle, KEY_ZEN_MODE));
 
         // Volumes are added via xml
 
@@ -309,15 +307,6 @@
                     return buildPreferenceControllers(context, null /* fragment */,
                             null /* lifecycle */);
                 }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    List<String> keys = super.getNonIndexableKeys(context);
-                    // Duplicate results
-                    keys.add((new ZenModePreferenceController(context, null, KEY_ZEN_MODE))
-                            .getPreferenceKey());
-                    return keys;
-                }
             };
 
     // === Work Sound Settings ===
diff --git a/src/com/android/settings/notification/ZenModePreferenceController.java b/src/com/android/settings/notification/ZenModePreferenceController.java
index 0d94029..d70ffe2 100644
--- a/src/com/android/settings/notification/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/ZenModePreferenceController.java
@@ -23,38 +23,30 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import android.util.Slog;
 
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
-public class ZenModePreferenceController extends AbstractPreferenceController
-        implements LifecycleObserver, OnResume, OnPause, PreferenceControllerMixin {
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
 
-    private final String mKey;
+public class ZenModePreferenceController extends BasePreferenceController
+        implements LifecycleObserver, OnResume, OnPause {
+
     private SettingObserver mSettingObserver;
     private ZenModeSettings.SummaryBuilder mSummaryBuilder;
 
-    public ZenModePreferenceController(Context context, Lifecycle lifecycle, String key) {
-        super(context);
+    public ZenModePreferenceController(Context context, String key) {
+        super(context, key);
         mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
-
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
-        mKey = key;
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        mSettingObserver = new SettingObserver(screen.findPreference(mKey));
+        mSettingObserver = new SettingObserver(screen.findPreference(getPreferenceKey()));
     }
 
     @Override
@@ -72,13 +64,8 @@
     }
 
     @Override
-    public String getPreferenceKey() {
-        return mKey;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return true;
+    public int getAvailabilityStatus() {
+        return AVAILABLE_UNSEARCHABLE;
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
index 28475b6..10a7b56 100644
--- a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
@@ -68,7 +68,10 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mPreference = screen.findPreference(KEY);
-        mPreference.setOnPreferenceClickListener(this);
+
+        if (mPreference != null) {
+            mPreference.setOnPreferenceClickListener(this);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ZenOnboardingActivity.java b/src/com/android/settings/notification/ZenOnboardingActivity.java
index 7b50dde..99bc172 100644
--- a/src/com/android/settings/notification/ZenOnboardingActivity.java
+++ b/src/com/android/settings/notification/ZenOnboardingActivity.java
@@ -157,6 +157,12 @@
         // ZEN_SETTINGS_UPDATED is true for:
         // - fresh P+ device
         // - if zen visual effects values were changed by the user in Settings
+        NotificationManager nm = context.getSystemService(NotificationManager.class);
+        if (NotificationManager.Policy.areAllVisualEffectsSuppressed(
+                nm.getNotificationPolicy().suppressedVisualEffects)) {
+            Settings.Global.putInt(context.getContentResolver(),
+                    Settings.Global.ZEN_SETTINGS_UPDATED, 1);
+        }
         return Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
     }
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index db09a37..7eda82b 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -34,6 +34,7 @@
 
 import com.android.settings.bluetooth.BluetoothSliceBuilder;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
 import com.android.settings.location.LocationSliceBuilder;
 import com.android.settings.notification.ZenModeSliceBuilder;
 import com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper;
@@ -160,6 +161,10 @@
         } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
             registerIntentToUri(BluetoothSliceBuilder.INTENT_FILTER, sliceUri);
             return;
+        } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+            registerIntentToUri(FlashlightSliceBuilder.INTENT_FILTER , sliceUri);
+            mRegisteredUris.add(sliceUri);
+            return;
         }
 
         // Start warming the slice, we expect someone will want it soon.
@@ -191,32 +196,35 @@
                 Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
                 return null;
             }
-        // If adding a new Slice, do not directly match Slice URIs.
-        // Use {@link SlicesDatabaseAccessor}.
-        if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
-            return FeatureFactory.getFactory(getContext())
-                    .getSlicesFeatureProvider()
-                    .getNewWifiCallingSliceHelper(getContext())
-                    .createWifiCallingSlice(sliceUri);
-        } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
-            return WifiSliceBuilder.getSlice(getContext());
-        } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
-            return ZenModeSliceBuilder.getSlice(getContext());
-        } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
-            return BluetoothSliceBuilder.getSlice(getContext());
-        } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
-            return LocationSliceBuilder.getSlice(getContext());
-        } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
-            return FeatureFactory.getFactory(getContext())
-                    .getSlicesFeatureProvider()
-                    .getNewEnhanced4gLteSliceHelper(getContext())
-                    .createEnhanced4gLteSlice(sliceUri);
-        } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
-            return FeatureFactory.getFactory(getContext())
-                    .getSlicesFeatureProvider()
-                    .getNewWifiCallingSliceHelper(getContext())
-                    .createWifiCallingPreferenceSlice(sliceUri);
-        }
+
+            // If adding a new Slice, do not directly match Slice URIs.
+            // Use {@link SlicesDatabaseAccessor}.
+            if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
+                return FeatureFactory.getFactory(getContext())
+                        .getSlicesFeatureProvider()
+                        .getNewWifiCallingSliceHelper(getContext())
+                        .createWifiCallingSlice(sliceUri);
+            } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
+                return WifiSliceBuilder.getSlice(getContext());
+            } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+                return ZenModeSliceBuilder.getSlice(getContext());
+            } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+                return BluetoothSliceBuilder.getSlice(getContext());
+            } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
+                return LocationSliceBuilder.getSlice(getContext());
+            } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
+                return FeatureFactory.getFactory(getContext())
+                        .getSlicesFeatureProvider()
+                        .getNewEnhanced4gLteSliceHelper(getContext())
+                        .createEnhanced4gLteSlice(sliceUri);
+            } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
+                return FeatureFactory.getFactory(getContext())
+                        .getSlicesFeatureProvider()
+                        .getNewWifiCallingSliceHelper(getContext())
+                        .createWifiCallingPreferenceSlice(sliceUri);
+            } else if (FlashlightSliceBuilder.FLASHLIGHT_URI.equals(sliceUri)) {
+                return FlashlightSliceBuilder.getSlice(getContext());
+            }
 
             SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
             if (cachedSliceData == null) {
@@ -381,7 +389,8 @@
 
     private List<Uri> getSpecialCaseOemUris() {
         return Arrays.asList(
-                ZenModeSliceBuilder.ZEN_MODE_URI
+                ZenModeSliceBuilder.ZEN_MODE_URI,
+                FlashlightSliceBuilder.FLASHLIGHT_URI
         );
     }
 
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index 9f1ef76..95f0538 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -17,6 +17,7 @@
 package com.android.settings.slices;
 
 import static com.android.settings.bluetooth.BluetoothSliceBuilder.ACTION_BLUETOOTH_SLICE_CHANGED;
+import static com.android.settings.flashlight.FlashlightSliceBuilder.ACTION_FLASHLIGHT_SLICE_CHANGED;
 import static com.android.settings.notification.ZenModeSliceBuilder.ACTION_ZEN_MODE_SLICE_CHANGED;
 import static com.android.settings.slices.SettingsSliceProvider.ACTION_SLIDER_CHANGED;
 import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
@@ -45,6 +46,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.SliderPreferenceController;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
 import com.android.settings.notification.ZenModeSliceBuilder;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wifi.WifiSliceBuilder;
@@ -102,6 +104,9 @@
                         .getNewWifiCallingSliceHelper(context)
                         .handleWifiCallingPreferenceChanged(intent);
                 break;
+            case ACTION_FLASHLIGHT_SLICE_CHANGED:
+                FlashlightSliceBuilder.handleUriChange(context, intent);
+                break;
             default:
                 final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
                 if (!TextUtils.isEmpty(uriString)) {
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 52a3692..a33561b 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -42,13 +42,6 @@
 import android.os.UserManager;
 import android.provider.ContactsContract;
 import android.provider.SearchIndexableResource;
-import android.provider.Settings.Global;
-import androidx.annotation.VisibleForTesting;
-import androidx.annotation.WorkerThread;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceClickListener;
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceScreen;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Menu;
@@ -82,6 +75,13 @@
 import java.util.HashMap;
 import java.util.List;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceClickListener;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
+
 /**
  * Screen that manages the list of users on the device.
  * Guest user is an always visible entry, even if the guest is not currently
@@ -109,6 +109,8 @@
 
     private static final int MENU_REMOVE_USER = Menu.FIRST;
 
+    private static final IntentFilter USER_REMOVED_INTENT_FILTER;
+
     private static final int DIALOG_CONFIRM_REMOVE = 1;
     private static final int DIALOG_ADD_USER = 2;
     private static final int DIALOG_SETUP_USER = 3;
@@ -134,6 +136,11 @@
     private static final String KEY_TITLE = "title";
     private static final String KEY_SUMMARY = "summary";
 
+    static {
+        USER_REMOVED_INTENT_FILTER = new IntentFilter(Intent.ACTION_USER_REMOVED);
+        USER_REMOVED_INTENT_FILTER.addAction(Intent.ACTION_USER_INFO_CHANGED);
+    }
+
     private PreferenceGroup mUserListCategory;
     private UserPreference mMePreference;
     private RestrictedPreference mAddUser;
@@ -195,13 +202,14 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         addPreferencesFromResource(R.xml.user_settings);
-        if (Global.getInt(getContext().getContentResolver(), Global.DEVICE_PROVISIONED, 0) == 0) {
-            getActivity().finish();
+        final Activity activity = getActivity();
+        if (!Utils.isDeviceProvisioned(getActivity())) {
+            activity.finish();
             return;
         }
-        final Context context = getActivity();
+
         mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
-                context, KEY_ADD_USER_WHEN_LOCKED, getLifecycle());
+                activity, KEY_ADD_USER_WHEN_LOCKED, getLifecycle());
         final PreferenceScreen screen = getPreferenceScreen();
         mAddUserWhenLockedPreferenceController.displayPreference(screen);
 
@@ -218,8 +226,8 @@
             mEditUserInfoController.onRestoreInstanceState(icicle);
         }
 
-        mUserCaps = UserCapabilities.create(context);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mUserCaps = UserCapabilities.create(activity);
+        mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
         if (!mUserCaps.mEnabled) {
             return;
         }
@@ -248,9 +256,10 @@
         } else {
             mAddUser.setVisible(false);
         }
-        final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
-        filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
-        context.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, mHandler);
+
+        activity.registerReceiverAsUser(
+                mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
+
         loadProfile();
         updateUserList();
         mShouldUpdateUserList = false;
@@ -762,9 +771,11 @@
     }
 
     private void updateUserList() {
-        if (getActivity() == null) return;
-        List<UserInfo> users = mUserManager.getUsers(true);
         final Context context = getActivity();
+        if (context == null) {
+            return;
+        }
+        final List<UserInfo> users = mUserManager.getUsers(true);
 
         final boolean voiceCapable = Utils.isVoiceCapable(context);
         final ArrayList<Integer> missingIcons = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java b/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java
new file mode 100644
index 0000000..da36185
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accounts/AccountSyncSettingsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.app.Activity;
+import android.content.Context;
+import android.os.UserHandle;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowContentResolver;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowContentResolver.class})
+public class AccountSyncSettingsTest {
+
+    @After
+    public void tearDown() {
+        ShadowContentResolver.reset();
+    }
+
+    @Test
+    public void onPreferenceTreeClick_nullAuthority_shouldNotCrash() {
+        final Context context = RuntimeEnvironment.application;
+        final AccountSyncSettings settings = spy(new AccountSyncSettings());
+        when(settings.getActivity()).thenReturn(mock(Activity.class));
+        final SyncStateSwitchPreference preference = new SyncStateSwitchPreference(context,
+                new Account("acct1", "type1"), "" /* authority */, "testPackage", 1 /* uid */);
+        preference.setOneTimeSyncMode(false);
+        ReflectionHelpers.setField(settings, "mUserHandle", UserHandle.CURRENT);
+
+        settings.onPreferenceTreeClick(preference);
+        // no crash
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java
index f7a21d8..bdf249d 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.applications.defaultapps;
 
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
@@ -23,10 +25,20 @@
 
 import android.app.Activity;
 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.os.UserManager;
 
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.applications.DefaultAppInfo;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -53,6 +65,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest();
         when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
 
         mPicker = new DefaultBrowserPicker();
@@ -72,4 +85,39 @@
         mPicker.getDefaultKey();
         verify(mPackageManager).getDefaultBrowserPackageNameAsUser(anyInt());
     }
+
+    @Test
+    public void getCandidates_shouldNotIncludeDuplicatePackageName() throws NameNotFoundException {
+        final List<ResolveInfo> resolveInfos = new ArrayList<>();
+        final String PACKAGE_ONE = "com.first.package";
+        final String PACKAGE_TWO = "com.second.package";
+        resolveInfos.add(createResolveInfo(PACKAGE_ONE));
+        resolveInfos.add(createResolveInfo(PACKAGE_TWO));
+        resolveInfos.add(createResolveInfo(PACKAGE_ONE));
+        resolveInfos.add(createResolveInfo(PACKAGE_TWO));
+        when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
+            .thenReturn(resolveInfos);
+        when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_ONE), anyInt(), anyInt()))
+            .thenReturn(createApplicationInfo(PACKAGE_ONE));
+        when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_TWO), anyInt(), anyInt()))
+            .thenReturn(createApplicationInfo(PACKAGE_TWO));
+
+        final List<DefaultAppInfo> defaultBrowserInfo = mPicker.getCandidates();
+
+        assertThat(defaultBrowserInfo.size()).isEqualTo(2);
+    }
+
+    private ResolveInfo createResolveInfo(String packageName) {
+        final ResolveInfo info = new ResolveInfo();
+        info.handleAllWebDataURI = true;
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = packageName;
+        return info;
+    }
+
+    private ApplicationInfo createApplicationInfo(String packageName) {
+        final ApplicationInfo info = new ApplicationInfo();
+        info.packageName = packageName;
+        return info;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
index fd2ff0d..6e69e67 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
@@ -20,6 +20,7 @@
 import androidx.preference.Preference;
 
 import com.android.settings.bluetooth.BluetoothDeviceUpdater;
+import com.android.settings.connecteddevice.dock.DockUpdater;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -45,6 +46,8 @@
     @Mock
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
     @Mock
+    private DockUpdater mDockUpdater;
+    @Mock
     private PackageManager mPackageManager;
 
     private Context mContext;
@@ -60,6 +63,7 @@
         mPreConnectedDeviceController =
                 new PreviouslyConnectedDevicePreferenceController(mContext, KEY);
         mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater);
+        mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater);
 
         mPreference = new Preference(mContext);
         mPreConnectedDeviceController.setPreference(mPreference);
@@ -70,10 +74,12 @@
         // register the callback in onStart()
         mPreConnectedDeviceController.onStart();
         verify(mBluetoothDeviceUpdater).registerCallback();
+        verify(mDockUpdater).registerCallback();
 
         // unregister the callback in onStop()
         mPreConnectedDeviceController.onStop();
         verify(mBluetoothDeviceUpdater).unregisterCallback();
+        verify(mDockUpdater).unregisterCallback();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
index e83e93d..1fe0931 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.verify;
 import static org.robolectric.RuntimeEnvironment.application;
 
+import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.hardware.fingerprint.FingerprintManager;
@@ -151,4 +152,12 @@
 
         return callbackCaptor.getValue();
     }
+
+    @Test
+    public void onActivityResult_withNullIntentShouldNotCrash() {
+        // this should not crash
+        mActivity.onActivityResult(FingerprintEnrollFindSensor.CONFIRM_REQUEST, Activity.RESULT_OK,
+            null);
+        assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
new file mode 100644
index 0000000..5862ab3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceBuilderTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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.flashlight;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.SliceTester;
+
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceItem;
+import androidx.slice.SliceMetadata;
+import androidx.slice.SliceProvider;
+import androidx.slice.core.SliceAction;
+import androidx.slice.widget.SliceLiveData;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class FlashlightSliceBuilderTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = spy(RuntimeEnvironment.application);
+
+        // Prevent crash in SliceMetadata.
+        Resources resources = spy(mContext.getResources());
+        doReturn(60).when(resources).getDimensionPixelSize(anyInt());
+        doReturn(resources).when(mContext).getResources();
+
+        // Set-up specs for SliceMetadata.
+        SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+    }
+
+    @Test
+    public void getFlashlightSlice_correctData() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+        final Slice slice = FlashlightSliceBuilder.getSlice(mContext);
+        final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+
+        final List<SliceAction> toggles = metadata.getToggles();
+        assertThat(toggles).hasSize(1);
+
+        final List<SliceItem> sliceItems = slice.getItems();
+        SliceTester.assertTitle(sliceItems, mContext.getString(R.string.power_flashlight));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java
new file mode 100644
index 0000000..33a00fa
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingParentPreferenceControllerTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 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.gestures;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class PreventRingingParentPreferenceControllerTest {
+
+    @Mock
+    private Resources mResources;
+
+    private Context mContext;
+    private PreventRingingParentPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getResources()).thenReturn(mResources);
+
+        mController = new PreventRingingParentPreferenceController(mContext, "test_key");
+    }
+
+    @Test
+    public void testIsAvailable_configIsTrue_shouldAvailableUnSearchable() {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
+    public void testIsAvailable_configIsFalse_shouldReturnFalse() {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
index 3ea4471..ece25e2 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification;
 
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
@@ -27,7 +28,6 @@
 import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.content.Context;
-import androidx.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -40,6 +40,8 @@
 import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.util.ReflectionHelpers;
 
+import androidx.preference.Preference;
+
 @RunWith(SettingsRobolectricTestRunner.class)
 public class ZenModePreferenceControllerTest {
 
@@ -61,7 +63,7 @@
         ShadowApplication shadowApplication = ShadowApplication.getInstance();
         shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
         mContext = shadowApplication.getApplicationContext();
-        mController = new ZenModePreferenceController(mContext, null, KEY_ZEN_MODE);
+        mController = new ZenModePreferenceController(mContext, KEY_ZEN_MODE);
         when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
         mSummaryBuilder = spy(new ZenModeSettings.SummaryBuilder(mContext));
         ReflectionHelpers.setField(mController, "mSummaryBuilder", mSummaryBuilder);
@@ -69,8 +71,8 @@
     }
 
     @Test
-    public void isAlwaysAvailable() {
-        assertThat(mController.isAvailable()).isTrue();
+    public void isAvailable_unsearchable() {
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
index 064c091..ad8e0de 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
@@ -190,4 +190,13 @@
             assertThat(contacts.get(i)).isNotNull();
         }
     }
+
+    @Test
+    public void nullPreference_displayPreference() {
+        when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+                .thenReturn(null);
+
+        // should not throw a null pointer
+        mMessagesController.displayPreference(mPreferenceScreen);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
index e09dc0d..3ca9fda 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenOnboardingActivityTest.java
@@ -51,6 +51,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class ZenOnboardingActivityTest {
@@ -68,6 +69,8 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowApplication = ShadowApplication.getInstance();
+        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
 
         mActivity = Robolectric.buildActivity(ZenOnboardingActivity.class)
                 .create()
@@ -124,6 +127,9 @@
 
     @Test
     public void isSuggestionComplete_zenUpdated() {
+        Policy policy = new Policy(0, 0, 0, 0);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
         setZenUpdated(true);
         setShowSettingsSuggestion(false);
         setWithinTimeThreshold(true);
@@ -132,6 +138,9 @@
 
     @Test
     public void isSuggestionComplete_withinTimeThreshold() {
+        Policy policy = new Policy(0, 0, 0, 0);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
         setZenUpdated(false);
         setShowSettingsSuggestion(false);
         setWithinTimeThreshold(true);
@@ -140,6 +149,9 @@
 
     @Test
     public void isSuggestionComplete_showSettingsSuggestionTrue() {
+        Policy policy = new Policy(0, 0, 0, 0);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
         setZenUpdated(false);
         setShowSettingsSuggestion(true);
         setWithinTimeThreshold(false);
@@ -148,17 +160,33 @@
 
     @Test
     public void isSuggestionComplete_showSettingsSuggestionFalse_notWithinTimeThreshold() {
+        Policy policy = new Policy(0, 0, 0, 0);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
         setZenUpdated(false);
         setShowSettingsSuggestion(false);
         setWithinTimeThreshold(false);
         assertThat(isSuggestionComplete(mContext)).isTrue();
     }
 
+
+    @Test
+    public void isSuggestionComplete_visualEffectsUpdated() {
+        // all values suppressed
+        Policy policy = new Policy(0, 0, 0, 511);
+        when(mNm.getNotificationPolicy()).thenReturn(policy);
+
+        setZenUpdated(false);
+        setShowSettingsSuggestion(true);
+        setWithinTimeThreshold(true);
+        assertThat(isSuggestionComplete(mContext)).isTrue();
+        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_SETTINGS_UPDATED, -1)).isEqualTo(1);
+    }
+
+
     private void setZenUpdated(boolean updated) {
-        int zenUpdated = 0;
-        if (updated) {
-            zenUpdated = 1;
-        }
+        int zenUpdated = updated ? 1 : 0;
 
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated);
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 6b1262a..c72e9f6 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -33,10 +33,12 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.net.Uri;
 import android.os.StrictMode;
+import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
 import android.util.ArraySet;
 
 import com.android.settings.bluetooth.BluetoothSliceBuilder;
+import com.android.settings.flashlight.FlashlightSliceBuilder;
 import com.android.settings.location.LocationSliceBuilder;
 import com.android.settings.notification.ZenModeSliceBuilder;
 import com.android.settings.testutils.DatabaseTestUtils;
@@ -95,7 +97,8 @@
     );
 
     private static final List<Uri> SPECIAL_CASE_OEM_URIS = Arrays.asList(
-            ZenModeSliceBuilder.ZEN_MODE_URI
+            ZenModeSliceBuilder.ZEN_MODE_URI,
+            FlashlightSliceBuilder.FLASHLIGHT_URI
     );
 
     @Before
@@ -445,6 +448,16 @@
     }
 
     @Test
+    public void bindSlice_flashlightSlice_returnsFlashlightSlice() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+
+        final Slice flashlightSlice = mProvider.onBindSlice(FlashlightSliceBuilder.FLASHLIGHT_URI);
+
+        assertThat(flashlightSlice.getUri()).isEqualTo(FlashlightSliceBuilder.FLASHLIGHT_URI);
+    }
+
+    @Test
     public void onSlicePinned_noIntentRegistered_specialCaseUri_doesNotCrash() {
         final Uri uri = new Uri.Builder()
                 .scheme(ContentResolver.SCHEME_CONTENT)
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
index 50c0330..928779b 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
@@ -24,6 +24,7 @@
 import android.database.MatrixCursor;
 import android.net.Uri;
 import android.provider.SearchIndexablesContract;
+import android.text.TextUtils;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.annotation.Resetter;
@@ -67,6 +68,14 @@
     }
 
     @Implementation
+    public static void setSyncAutomaticallyAsUser(Account account, String authority, boolean sync,
+            int userId) {
+        if (TextUtils.isEmpty(authority)) {
+            throw new IllegalArgumentException("Authority must be non-empty");
+        }
+    }
+
+    @Implementation
     public static boolean getMasterSyncAutomaticallyAsUser(int userId) {
         return sMasterSyncAutomatically.containsKey(userId)
                 ? sMasterSyncAutomatically.get(userId) : true;