Merge "Block sleep options in Settings app when DISALLOW_CONFIG_SCREEN_TIMEOUT is set."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 51a811d..9e4dc39 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -476,7 +476,7 @@
             </intent-filter>
         </activity>
 
-        <service android:name=".TetherService"
+        <service android:name=".wifi.tether.TetherService"
             android:exported="true"
             android:permission="android.permission.TETHER_PRIVILEGED" />
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 04c9235..4182fd9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6870,6 +6870,9 @@
     <!--  Do not disturb: Summary for the zen mode automation option Suggestion. [CHAR LIMIT=NONE] -->
     <string name="zen_mode_automation_suggestion_summary">Limit sounds &amp; vibrations at certain times</string>
 
+    <!--  Do not disturb: Switch toggle to toggle whether to use an automatic dnd rule or not [CHAR LIMIT=40] -->
+    <string name="zen_mode_use_automatic_rule">Use rule</string>
+
     <!--  Do not disturb: Zen mode option: Important interruptions [CHAR LIMIT=60] -->
     <string name="zen_mode_option_important_interruptions">Priority only</string>
 
diff --git a/res/xml/restricted_apps_detail.xml b/res/xml/restricted_apps_detail.xml
new file mode 100644
index 0000000..1e08a7e
--- /dev/null
+++ b/res/xml/restricted_apps_detail.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/restricted_app_title">
+
+    <PreferenceCategory
+        android:key="restrict_app_list"/>
+
+</PreferenceScreen>
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index 159dbe0..ea37855 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -28,12 +28,6 @@
         android:key="zen_automatic_rule_switch"
         android:layout="@layout/styled_switch_bar" />
 
-    <!-- Rule name -->
-    <Preference
-        android:key="rule_name"
-        android:title="@string/zen_mode_rule_name"
-        android:persistent="false" />
-
     <!-- During events for -->
     <DropDownPreference
         android:key="calendar"
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index a0c52c0..e201b87 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -28,12 +28,6 @@
         android:key="zen_automatic_rule_switch"
         android:layout="@layout/styled_switch_bar" />
 
-    <!-- Rule name -->
-    <Preference
-        android:key="rule_name"
-        android:title="@string/zen_mode_rule_name"
-        android:persistent="false" />
-
     <!-- Days -->
     <Preference
         android:key="days"
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index 4fc205d..5f93589 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -30,8 +30,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.PhoneStateIntentReceiver;
 import com.android.internal.telephony.TelephonyProperties;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener {
 
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index 9391439..bb53018 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -49,8 +49,9 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -63,8 +64,7 @@
 public class DeviceAdminSettings extends ListFragment implements Instrumentable {
     static final String TAG = "DeviceAdminSettings";
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
     private DevicePolicyManager mDPM;
     private UserManager mUm;
 
@@ -85,12 +85,6 @@
         }
     }
 
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
     /**
      * Internal collection of device admin info objects for all profiles associated with the current
      * user.
@@ -121,6 +115,8 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
     }
 
     @Override
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index d3580d1..5cb7c06 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -56,13 +56,13 @@
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.backup.BackupSettingsActivity;
 import com.android.settings.core.gateway.SettingsGateway;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.SharedPreferencesLogger;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardSummary;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.wfd.WifiDisplaySettings;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.SharedPreferencesLogger;
 import com.android.settingslib.development.DevelopmentSettingsEnabler;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.SettingsDrawerActivity;
@@ -93,11 +93,6 @@
     public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
 
     /**
-     * The metrics category constant for logging source when a setting fragment is opened.
-     */
-    public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics";
-
-    /**
      * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
      * this extra can also be specified to supply a Bundle of arguments to pass
      * to that fragment when it is instantiated during the initial creation
@@ -220,7 +215,8 @@
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         if (name.equals(getPackageName() + "_preferences")) {
-            return new SharedPreferencesLogger(this, getMetricsTag());
+            return new SharedPreferencesLogger(this, getMetricsTag(),
+                    FeatureFactory.getFactory(this).getMetricsFeatureProvider());
         }
         return super.getSharedPreferences(name, mode);
     }
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index d9e264b..c5d477a 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -45,7 +45,6 @@
 
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.InstrumentedPreferenceFragment;
-import com.android.settings.core.instrumentation.Instrumentable;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.search.actionbar.SearchMenuController;
 import com.android.settings.support.actionbar.HelpMenuController;
@@ -53,6 +52,7 @@
 import com.android.settings.widget.LoadingViewController;
 import com.android.settingslib.CustomDialogPreference;
 import com.android.settingslib.CustomEditTextPreference;
+import com.android.settingslib.core.instrumentation.Instrumentable;
 import com.android.settingslib.widget.FooterPreferenceMixin;
 
 import java.util.UUID;
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index ad95121..1c674b6 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -110,6 +110,7 @@
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.FingerprintManagerWrapper;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import java.net.InetAddress;
 import java.util.ArrayList;
@@ -576,7 +577,7 @@
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, titleResId);
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title);
         intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut);
-        intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
+        intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
         return intent;
     }
 
diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java
index c0bf7d2..6127ab9 100644
--- a/src/com/android/settings/accounts/AccountPreferenceController.java
+++ b/src/com/android/settings/accounts/AccountPreferenceController.java
@@ -51,12 +51,12 @@
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.accounts.AuthenticatorHelper;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index ee954ac..20c5581 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -44,6 +44,7 @@
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.AppPreference;
+import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
@@ -321,9 +322,13 @@
                 .setPackage(pkgName);
 
         if (mPm.resolveActivity(launchIntent, 0) == null) {
-            // Not visible on launcher -> likely not a user visible app, skip
-            Log.d(TAG, "Not a user visible app, skipping " + pkgName);
-            return false;
+            // Not visible on launcher -> likely not a user visible app, skip if non-instant.
+            final ApplicationsState.AppEntry appEntry =
+                    mApplicationsState.getEntry(pkgName, mUserId);
+            if (!AppUtils.isInstant(appEntry.info)) {
+                Log.d(TAG, "Not a user visible or instant app, skipping " + pkgName);
+                return false;
+            }
         }
         return true;
     }
diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java
index c10fb55..c172137 100644
--- a/src/com/android/settings/applications/UsageAccessDetails.java
+++ b/src/com/android/settings/applications/UsageAccessDetails.java
@@ -37,8 +37,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.applications.AppStateUsageBridge.UsageState;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
         OnPreferenceClickListener {
diff --git a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
index b10d06c..130138c 100644
--- a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
@@ -93,7 +93,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return AVAILABLE;
+        return AppUtils.isInstant(mParent.getPackageInfo().applicationInfo)
+            ? DISABLED_FOR_USER : AVAILABLE;
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index a0ce733..3fd7ced 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -33,10 +33,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.GearPreference;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
 
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
index a12d1a8..cea0147 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceRenamePreferenceController.java
@@ -23,9 +23,9 @@
 import android.text.TextUtils;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 public class BluetoothDeviceRenamePreferenceController extends
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 87fa43d..0f294bd 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -27,12 +27,12 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.WirelessUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox
diff --git a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
index 450c7b2..1ecfed4 100644
--- a/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
+++ b/src/com/android/settings/bluetooth/BluetoothFilesPreferenceController.java
@@ -23,9 +23,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Controller that shows received files
diff --git a/src/com/android/settings/core/InstrumentedActivity.java b/src/com/android/settings/core/InstrumentedActivity.java
index 9b24756..294de2c 100644
--- a/src/com/android/settings/core/InstrumentedActivity.java
+++ b/src/com/android/settings/core/InstrumentedActivity.java
@@ -16,8 +16,9 @@
 
 package com.android.settings.core;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableActivity;
 
 /**
@@ -27,7 +28,8 @@
 
     public InstrumentedActivity() {
         // Mixin that logs visibility change for activity.
-        getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
+        getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory(),
+              FeatureFactory.getFactory(this).getMetricsFeatureProvider()));
     }
 
 }
diff --git a/src/com/android/settings/core/InstrumentedFragment.java b/src/com/android/settings/core/InstrumentedFragment.java
index 45db836..b1215b9 100644
--- a/src/com/android/settings/core/InstrumentedFragment.java
+++ b/src/com/android/settings/core/InstrumentedFragment.java
@@ -18,30 +18,28 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.survey.SurveyMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableFragment;
 
 public abstract class InstrumentedFragment extends ObservableFragment implements Instrumentable {
 
     protected MetricsFeatureProvider mMetricsFeatureProvider;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin;
-
-    public InstrumentedFragment() {
-        // Mixin that logs visibility change for activity.
-        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory());
-        getLifecycle().addObserver(mVisibilityLoggerMixin);
-        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
-    }
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     @Override
     public void onAttach(Context context) {
-        super.onAttach(context);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider);
+        // Mixin that logs visibility change for activity.
+        getLifecycle().addObserver(mVisibilityLoggerMixin);
+        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
+        super.onAttach(context);
     }
 
     @Override
diff --git a/src/com/android/settings/core/InstrumentedPreferenceFragment.java b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
index 7e37115..278676c 100644
--- a/src/com/android/settings/core/InstrumentedPreferenceFragment.java
+++ b/src/com/android/settings/core/InstrumentedPreferenceFragment.java
@@ -23,11 +23,11 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.survey.SurveyMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
 
 /**
@@ -44,19 +44,17 @@
     // metrics placeholder value. Only use this for development.
     protected final int PLACEHOLDER_METRIC = 10000;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin;
-
-    public InstrumentedPreferenceFragment() {
-        // Mixin that logs visibility change for activity.
-        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory());
-        getLifecycle().addObserver(mVisibilityLoggerMixin);
-        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
-    }
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     @Override
     public void onAttach(Context context) {
-        super.onAttach(context);
         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        // Mixin that logs visibility change for activity.
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider);
+        getLifecycle().addObserver(mVisibilityLoggerMixin);
+        getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
+        super.onAttach(context);
     }
 
     @Override
diff --git a/src/com/android/settings/core/instrumentation/EventLogWriter.java b/src/com/android/settings/core/instrumentation/EventLogWriter.java
deleted file mode 100644
index 3196f76..0000000
--- a/src/com/android/settings/core/instrumentation/EventLogWriter.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import android.content.Context;
-import android.metrics.LogMaker;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-
-/**
- * {@link LogWriter} that writes data to eventlog.
- */
-public class EventLogWriter implements LogWriter {
-
-    private final MetricsLogger mMetricsLogger = new MetricsLogger();
-
-    public void visible(Context context, int source, int category) {
-        final LogMaker logMaker = new LogMaker(category)
-                .setType(MetricsProto.MetricsEvent.TYPE_OPEN)
-                .addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source);
-        MetricsLogger.action(logMaker);
-    }
-
-    public void hidden(Context context, int category) {
-        MetricsLogger.hidden(context, category);
-    }
-
-    public void action(int category, int value, Pair<Integer, Object>... taggedData) {
-        if (taggedData == null || taggedData.length == 0) {
-            mMetricsLogger.action(category, value);
-        } else {
-            final LogMaker logMaker = new LogMaker(category)
-                    .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
-                    .setSubtype(value);
-            for (Pair<Integer, Object> pair : taggedData) {
-                logMaker.addTaggedData(pair.first, pair.second);
-            }
-            mMetricsLogger.write(logMaker);
-        }
-    }
-
-    public void action(int category, boolean value, Pair<Integer, Object>... taggedData) {
-        action(category, value ? 1 : 0, taggedData);
-    }
-
-    public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
-        action(context, category, "", taggedData);
-    }
-
-    public void actionWithSource(Context context, int source, int category) {
-        final LogMaker logMaker = new LogMaker(category)
-                .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
-        if (source != MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
-            logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source);
-        }
-        MetricsLogger.action(logMaker);
-    }
-
-    /** @deprecated use {@link #action(int, int, Pair[])} */
-    @Deprecated
-    public void action(Context context, int category, int value) {
-        MetricsLogger.action(context, category, value);
-    }
-
-    /** @deprecated use {@link #action(int, boolean, Pair[])} */
-    @Deprecated
-    public void action(Context context, int category, boolean value) {
-        MetricsLogger.action(context, category, value);
-    }
-
-    public void action(Context context, int category, String pkg,
-            Pair<Integer, Object>... taggedData) {
-        if (taggedData == null || taggedData.length == 0) {
-            MetricsLogger.action(context, category, pkg);
-        } else {
-            final LogMaker logMaker = new LogMaker(category)
-                    .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
-                    .setPackageName(pkg);
-            for (Pair<Integer, Object> pair : taggedData) {
-                logMaker.addTaggedData(pair.first, pair.second);
-            }
-            MetricsLogger.action(logMaker);
-        }
-    }
-
-    public void count(Context context, String name, int value) {
-        MetricsLogger.count(context, name, value);
-    }
-
-    public void histogram(Context context, String name, int bucket) {
-        MetricsLogger.histogram(context, name, bucket);
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/Instrumentable.java b/src/com/android/settings/core/instrumentation/Instrumentable.java
deleted file mode 100644
index f58e140..0000000
--- a/src/com/android/settings/core/instrumentation/Instrumentable.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-public interface Instrumentable {
-
-    int METRICS_CATEGORY_UNKNOWN = 0;
-
-    /**
-     * Instrumented name for a view as defined in
-     * {@link com.android.internal.logging.nano.MetricsProto.MetricsEvent}.
-     */
-    int getMetricsCategory();
-}
diff --git a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
index 5a9ab56..0a214f1 100644
--- a/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
+++ b/src/com/android/settings/core/instrumentation/InstrumentedDialogFragment.java
@@ -19,6 +19,9 @@
 
 import com.android.settings.DialogCreatable;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.core.lifecycle.ObservableDialogFragment;
 
 public abstract class InstrumentedDialogFragment extends ObservableDialogFragment
@@ -38,13 +41,15 @@
     public InstrumentedDialogFragment(DialogCreatable dialogCreatable, int dialogId) {
         mDialogCreatable = dialogCreatable;
         mDialogId = dialogId;
-        mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
     }
 
-
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+        mMetricsFeatureProvider = FeatureFactory.getFactory(context)
+                .getMetricsFeatureProvider();
+        mLifecycle.addObserver(new VisibilityLoggerMixin(getMetricsCategory(),
+                mMetricsFeatureProvider));
+        mLifecycle.onAttach(context);
     }
 }
diff --git a/src/com/android/settings/core/instrumentation/LogWriter.java b/src/com/android/settings/core/instrumentation/LogWriter.java
deleted file mode 100644
index 062d46f..0000000
--- a/src/com/android/settings/core/instrumentation/LogWriter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import android.content.Context;
-import android.util.Pair;
-
-/**
- * Generic log writer interface.
- */
-public interface LogWriter {
-
-    /**
-     * Logs a visibility event when view becomes visible.
-     */
-    void visible(Context context, int source, int category);
-
-    /**
-     * Logs a visibility event when view becomes hidden.
-     */
-    void hidden(Context context, int category);
-
-    /**
-     * Logs a user action.
-     */
-    void action(int category, int value, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs a user action.
-     */
-    void action(int category, boolean value, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs an user action.
-     */
-    void action(Context context, int category, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs an user action.
-     */
-    void actionWithSource(Context context, int source, int category);
-
-    /**
-     * Logs an user action.
-     * @deprecated use {@link #action(int, int, Pair[])}
-     */
-    @Deprecated
-    void action(Context context, int category, int value);
-
-    /**
-     * Logs an user action.
-     * @deprecated use {@link #action(int, boolean, Pair[])}
-     */
-    @Deprecated
-    void action(Context context, int category, boolean value);
-
-    /**
-     * Logs an user action.
-     */
-    void action(Context context, int category, String pkg, Pair<Integer, Object>... taggedData);
-
-    /**
-     * Logs a count.
-     */
-    void count(Context context, String name, int value);
-
-    /**
-     * Logs a histogram event.
-     */
-    void histogram(Context context, String name, int bucket);
-}
diff --git a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java b/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java
deleted file mode 100644
index 166cbb8..0000000
--- a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * FeatureProvider for metrics.
- */
-public class MetricsFeatureProvider {
-    private List<LogWriter> mLoggerWriters;
-
-    public MetricsFeatureProvider() {
-        mLoggerWriters = new ArrayList<>();
-        installLogWriters();
-    }
-
-    protected void installLogWriters() {
-        mLoggerWriters.add(new EventLogWriter());
-    }
-
-    public void visible(Context context, int source, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.visible(context, source, category);
-        }
-    }
-
-    public void hidden(Context context, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.hidden(context, category);
-        }
-    }
-
-    public void actionWithSource(Context context, int source, int category) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.actionWithSource(context, source, category);
-        }
-    }
-
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, boolean value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
-    public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, taggedData);
-        }
-    }
-
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, int)} */
-    @Deprecated
-    public void action(Context context, int category, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, value);
-        }
-    }
-
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, boolean)} */
-    @Deprecated
-    public void action(Context context, int category, boolean value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, value);
-        }
-    }
-
-    public void action(Context context, int category, String pkg,
-            Pair<Integer, Object>... taggedData) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(context, category, pkg, taggedData);
-        }
-    }
-
-    public void count(Context context, String name, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.count(context, name, value);
-        }
-    }
-
-    public void histogram(Context context, String name, int bucket) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.histogram(context, name, bucket);
-        }
-    }
-
-    public int getMetricsCategory(Object object) {
-        if (object == null || !(object instanceof Instrumentable)) {
-            return MetricsEvent.VIEW_UNKNOWN;
-        }
-        return ((Instrumentable) object).getMetricsCategory();
-    }
-
-    public void logDashboardStartIntent(Context context, Intent intent,
-            int sourceMetricsCategory) {
-        if (intent == null) {
-            return;
-        }
-        final ComponentName cn = intent.getComponent();
-        if (cn == null) {
-            final String action = intent.getAction();
-            if (TextUtils.isEmpty(action)) {
-                // Not loggable
-                return;
-            }
-            action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action,
-                    Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
-            return;
-        } else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) {
-            // Going to a Setting internal page, skip click logging in favor of page's own
-            // visibility logging.
-            return;
-        }
-        action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(),
-                Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
-    }
-
-    private Pair<Integer, Object> sinceVisibleTaggedData(long timestamp) {
-        return Pair.create(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, timestamp);
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java b/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java
deleted file mode 100644
index dee40c0..0000000
--- a/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.os.AsyncTask;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.overlay.FeatureFactory;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-public class SharedPreferencesLogger implements SharedPreferences {
-
-    private static final String LOG_TAG = "SharedPreferencesLogger";
-
-    private final String mTag;
-    private final Context mContext;
-    private final MetricsFeatureProvider mMetricsFeature;
-    private final Set<String> mPreferenceKeySet;
-
-    public SharedPreferencesLogger(Context context, String tag) {
-        mContext = context;
-        mTag = tag;
-        mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-        mPreferenceKeySet = new ConcurrentSkipListSet<>();
-    }
-
-    @Override
-    public Map<String, ?> getAll() {
-        return null;
-    }
-
-    @Override
-    public String getString(String key, @Nullable String defValue) {
-        return defValue;
-    }
-
-    @Override
-    public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
-        return defValues;
-    }
-
-    @Override
-    public int getInt(String key, int defValue) {
-        return defValue;
-    }
-
-    @Override
-    public long getLong(String key, long defValue) {
-        return defValue;
-    }
-
-    @Override
-    public float getFloat(String key, float defValue) {
-        return defValue;
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return defValue;
-    }
-
-    @Override
-    public boolean contains(String key) {
-        return false;
-    }
-
-    @Override
-    public Editor edit() {
-        return new EditorLogger();
-    }
-
-    @Override
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    @Override
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    private void logValue(String key, Object value) {
-        logValue(key, value, false /* forceLog */);
-    }
-
-    private void logValue(String key, Object value, boolean forceLog) {
-        final String prefKey = buildPrefKey(mTag, key);
-        if (!forceLog && !mPreferenceKeySet.contains(prefKey)) {
-            // Pref key doesn't exist in set, this is initial display so we skip metrics but
-            // keeps track of this key.
-            mPreferenceKeySet.add(prefKey);
-            return;
-        }
-        // TODO: Remove count logging to save some resource.
-        mMetricsFeature.count(mContext, buildCountName(prefKey, value), 1);
-
-        final Pair<Integer, Object> valueData;
-        if (value instanceof Long) {
-            final Long longVal = (Long) value;
-            final int intVal;
-            if (longVal > Integer.MAX_VALUE) {
-                intVal = Integer.MAX_VALUE;
-            } else if (longVal < Integer.MIN_VALUE) {
-                intVal = Integer.MIN_VALUE;
-            } else {
-                intVal = longVal.intValue();
-            }
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    intVal);
-        } else if (value instanceof Integer) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    value);
-        } else if (value instanceof Boolean) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
-                    (Boolean) value ? 1 : 0);
-        } else if (value instanceof Float) {
-            valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE,
-                    value);
-        } else if (value instanceof String) {
-            Log.d(LOG_TAG, "Tried to log string preference " + prefKey + " = " + value);
-            valueData = null;
-        } else {
-            Log.w(LOG_TAG, "Tried to log unloggable object" + value);
-            valueData = null;
-        }
-        if (valueData != null) {
-            // Pref key exists in set, log it's change in metrics.
-            mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE,
-                    Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey),
-                    valueData);
-        }
-    }
-
-    @VisibleForTesting
-    void logPackageName(String key, String value) {
-        final String prefKey = mTag + "/" + key;
-        mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, value,
-                Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey));
-    }
-
-    private void safeLogValue(String key, String value) {
-        new AsyncPackageCheck().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, key, value);
-    }
-
-    public static String buildCountName(String prefKey, Object value) {
-        return prefKey + "|" + value;
-    }
-
-    public static String buildPrefKey(String tag, String key) {
-        return tag + "/" + key;
-    }
-
-    private class AsyncPackageCheck extends AsyncTask<String, Void, Void> {
-        @Override
-        protected Void doInBackground(String... params) {
-            String key = params[0];
-            String value = params[1];
-            PackageManager pm = mContext.getPackageManager();
-            try {
-                // Check if this might be a component.
-                ComponentName name = ComponentName.unflattenFromString(value);
-                if (value != null) {
-                    value = name.getPackageName();
-                }
-            } catch (Exception e) {
-            }
-            try {
-                pm.getPackageInfo(value, PackageManager.MATCH_ANY_USER);
-                logPackageName(key, value);
-            } catch (PackageManager.NameNotFoundException e) {
-                // Clearly not a package, and it's unlikely this preference is in prefSet, so
-                // lets force log it.
-                logValue(key, value, true /* forceLog */);
-            }
-            return null;
-        }
-    }
-
-    public class EditorLogger implements Editor {
-        @Override
-        public Editor putString(String key, @Nullable String value) {
-            safeLogValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putStringSet(String key, @Nullable Set<String> values) {
-            safeLogValue(key, TextUtils.join(",", values));
-            return this;
-        }
-
-        @Override
-        public Editor putInt(String key, int value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putLong(String key, long value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putFloat(String key, float value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor putBoolean(String key, boolean value) {
-            logValue(key, value);
-            return this;
-        }
-
-        @Override
-        public Editor remove(String key) {
-            return this;
-        }
-
-        @Override
-        public Editor clear() {
-            return this;
-        }
-
-        @Override
-        public boolean commit() {
-            return true;
-        }
-
-        @Override
-        public void apply() {
-        }
-    }
-}
diff --git a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java b/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java
deleted file mode 100644
index 2fe2a3b..0000000
--- a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-
-import android.os.SystemClock;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.SettingsActivity;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnAttach;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
-
-import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
-
-/**
- * Logs visibility change of a fragment.
- */
-public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPause, OnAttach {
-
-    private static final String TAG = "VisibilityLoggerMixin";
-
-    private final int mMetricsCategory;
-
-    private MetricsFeatureProvider mMetricsFeature;
-    private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
-    private long mVisibleTimestamp;
-
-    public VisibilityLoggerMixin(int metricsCategory) {
-        // MetricsFeature will be set during onAttach.
-        this(metricsCategory, null /* metricsFeature */);
-    }
-
-    public VisibilityLoggerMixin(int metricsCategory, MetricsFeatureProvider metricsFeature) {
-        mMetricsCategory = metricsCategory;
-        mMetricsFeature = metricsFeature;
-    }
-
-    @Override
-    public void onAttach(Context context) {
-        mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-    }
-
-    @Override
-    public void onResume() {
-        mVisibleTimestamp = SystemClock.elapsedRealtime();
-        if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
-            mMetricsFeature.visible(null /* context */, mSourceMetricsCategory, mMetricsCategory);
-        }
-    }
-
-    @Override
-    public void onPause() {
-        mVisibleTimestamp = 0;
-        if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
-            mMetricsFeature.hidden(null /* context */, mMetricsCategory);
-        }
-    }
-
-    /**
-     * Sets source metrics category for this logger. Source is the caller that opened this UI.
-     */
-    public void setSourceMetricsCategory(Activity activity) {
-        if (mSourceMetricsCategory != MetricsProto.MetricsEvent.VIEW_UNKNOWN || activity == null) {
-            return;
-        }
-        final Intent intent = activity.getIntent();
-        if (intent == null) {
-            return;
-        }
-        mSourceMetricsCategory = intent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
-                MetricsProto.MetricsEvent.VIEW_UNKNOWN);
-    }
-
-    /** Returns elapsed time since onResume() */
-    public long elapsedTimeSinceVisible() {
-        if (mVisibleTimestamp == 0) {
-            return 0;
-        }
-        return SystemClock.elapsedRealtime() - mVisibleTimestamp;
-    }
-}
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 97eef13..2d35ea7 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -41,7 +41,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.R.id;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderData;
 import com.android.settings.dashboard.conditional.Condition;
 import com.android.settings.dashboard.conditional.ConditionAdapter;
@@ -50,6 +49,7 @@
 import com.android.settings.dashboard.suggestions.SuggestionDismissController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.Utils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 
diff --git a/src/com/android/settings/dashboard/DashboardAdapterV2.java b/src/com/android/settings/dashboard/DashboardAdapterV2.java
index a422ae4..ad93e4c 100644
--- a/src/com/android/settings/dashboard/DashboardAdapterV2.java
+++ b/src/com/android/settings/dashboard/DashboardAdapterV2.java
@@ -39,13 +39,13 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.R.id;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardDataV2.ConditionHeaderData;
 import com.android.settings.dashboard.conditional.Condition;
 import com.android.settings.dashboard.conditional.ConditionAdapterV2;
 import com.android.settings.dashboard.suggestions.SuggestionAdapterV2;
 import com.android.settings.dashboard.suggestions.SuggestionControllerMixin;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index a06fee9..a14d9e9 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -41,8 +41,9 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.FeatureFlags;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.CategoryManager;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.ProfileSelectDialog;
@@ -159,7 +160,8 @@
             pref.setFragment(clsName);
         } else if (tile.intent != null) {
             final Intent intent = new Intent(tile.intent);
-            intent.putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, sourceMetricsCategory);
+            intent.putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY,
+                    sourceMetricsCategory);
             if (action != null) {
                 intent.setAction(action);
             }
@@ -208,7 +210,7 @@
             return;
         }
         final Intent intent = new Intent(tile.intent)
-                .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
+                .putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY,
                         MetricsEvent.DASHBOARD_SUMMARY)
                 .putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true)
                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
diff --git a/src/com/android/settings/dashboard/conditional/Condition.java b/src/com/android/settings/dashboard/conditional/Condition.java
index 05783bd..d66440e 100644
--- a/src/com/android/settings/dashboard/conditional/Condition.java
+++ b/src/com/android/settings/dashboard/conditional/Condition.java
@@ -24,8 +24,8 @@
 
 import android.support.annotation.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public abstract class Condition {
 
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
index eb768e5..d84aa7c 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
@@ -27,13 +27,13 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapter;
 import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardData;
 import com.android.settings.dashboard.DashboardData.HeaderMode;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
index 3f3e5c9..8db57f7 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
@@ -27,10 +27,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.WirelessUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index fc11029..2b79a9b 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -27,10 +27,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardAdapter.IconCache;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.List;
 import java.util.Objects;
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
index afd0e08..e04ae93 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
@@ -31,10 +31,10 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
 import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index fe19b95..8cd1675 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -36,7 +36,6 @@
 import com.android.settings.Settings.DoubleTwistSuggestionActivity;
 import com.android.settings.Settings.NightDisplaySuggestionActivity;
 import com.android.settings.Settings.SwipeToNotificationSuggestionActivity;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
 import com.android.settings.fingerprint.FingerprintSuggestionActivity;
 import com.android.settings.gestures.DoubleTapPowerPreferenceController;
@@ -49,6 +48,7 @@
 import com.android.settings.support.NewDeviceIntroSuggestionActivity;
 import com.android.settings.wallpaper.WallpaperSuggestionActivity;
 import com.android.settings.wifi.WifiCallingSuggestionActivity;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.drawer.Tile;
 
 import java.util.List;
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index ff568c7..b59da9d 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -25,8 +25,8 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/datetime/ZonePicker.java b/src/com/android/settings/datetime/ZonePicker.java
index 57c340c..dc69127 100644
--- a/src/com/android/settings/datetime/ZonePicker.java
+++ b/src/com/android/settings/datetime/ZonePicker.java
@@ -35,8 +35,9 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.datetime.ZoneGetter;
 
 import java.text.Collator;
@@ -57,8 +58,7 @@
 
     private static final int MENU_TIMEZONE = Menu.FIRST+1;
     private static final int MENU_ALPHABETICAL = Menu.FIRST;
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     private boolean mSortedByTimezone;
 
@@ -145,12 +145,6 @@
     }
 
     @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
-    @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.ZONE_PICKER;
     }
@@ -170,6 +164,13 @@
     }
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+            FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
+    }
+
+    @Override
     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         final View view = super.onCreateView(inflater, container, savedInstanceState);
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
index 8ab1a07..a20afa1 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java
@@ -23,10 +23,10 @@
 import android.support.v7.preference.Preference;
 import android.widget.Switch;
 
-import com.android.internal.util.Preconditions;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
-import com.android.settings.widget.SwitchBar;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
+import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /** Handles the logic for flipping the storage management toggle on a {@link SwitchBar}. */
 public class AutomaticStorageManagerSwitchBarController
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index 2641f5d..0f3bfb8 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -34,11 +34,11 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
index 717d765..8ab21b3 100644
--- a/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceController.java
@@ -25,12 +25,12 @@
 import android.support.v7.preference.PreferenceScreen;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnResume;
 
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 1149b99..3623298 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -38,11 +38,11 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deviceinfo.PrivateVolumeSettings.SystemInfoFragment;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageMeasurement;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index 68a21ce..f3d17d5 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -27,11 +27,11 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class AmbientDisplayNotificationsPreferenceController extends
         AbstractPreferenceController implements PreferenceControllerMixin,
diff --git a/src/com/android/settings/display/AmbientDisplaySettings.java b/src/com/android/settings/display/AmbientDisplaySettings.java
index 24aede0..187325c 100644
--- a/src/com/android/settings/display/AmbientDisplaySettings.java
+++ b/src/com/android/settings/display/AmbientDisplaySettings.java
@@ -23,13 +23,13 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.gestures.DoubleTapScreenPreferenceController;
 import com.android.settings.gestures.PickupGesturePreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index c7f6af1..2134b88 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -20,9 +20,9 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.view.RotationPolicy;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java
index d1341dd74..9c1314e 100644
--- a/src/com/android/settings/display/ThemePreferenceController.java
+++ b/src/com/android/settings/display/ThemePreferenceController.java
@@ -29,9 +29,9 @@
 
 import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import libcore.util.Objects;
 
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
index c034746..a52433b 100644
--- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -48,7 +48,6 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
@@ -56,6 +55,7 @@
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
diff --git a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
index 6323715..8286774 100644
--- a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
@@ -54,9 +54,10 @@
     private final int mUid;
     @VisibleForTesting
     DevicePolicyManagerWrapper mDpm;
+    @VisibleForTesting
+    BatteryUtils mBatteryUtils;
     private Fragment mFragment;
     private String mTargetPackage;
-    private boolean mIsPreOApp;
     private PowerWhitelistBackend mPowerWhitelistBackend;
 
     public BackgroundActivityPreferenceController(Context context, Fragment fragment,
@@ -77,7 +78,7 @@
         mUid = uid;
         mFragment = fragment;
         mTargetPackage = packageName;
-        mIsPreOApp = isLegacyApp(packageName);
+        mBatteryUtils = BatteryUtils.getInstance(context);
     }
 
     @Override
@@ -109,12 +110,7 @@
      * activity for this package
      */
     public void setUnchecked(Preference preference) {
-        if (mIsPreOApp) {
-            mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
-                    AppOpsManager.MODE_IGNORED);
-        }
-        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage,
-                AppOpsManager.MODE_IGNORED);
+        mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_IGNORED);
         ((SwitchPreference) preference).setChecked(false);
         updateSummary(preference);
     }
@@ -133,31 +129,12 @@
             dialogFragment.show(mFragment.getFragmentManager(), TAG);
             return false;
         }
-        if (mIsPreOApp) {
-            mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, mUid, mTargetPackage,
-                    AppOpsManager.MODE_ALLOWED);
-        }
-        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage,
-                AppOpsManager.MODE_ALLOWED);
+        mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_ALLOWED);
         updateSummary(preference);
         return true;
     }
 
     @VisibleForTesting
-    boolean isLegacyApp(final String packageName) {
-        try {
-            ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
-                    PackageManager.GET_META_DATA);
-
-            return info.targetSdkVersion < Build.VERSION_CODES.O;
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Cannot find package: " + packageName, e);
-        }
-
-        return false;
-    }
-
-    @VisibleForTesting
     void updateSummary(Preference preference) {
         if (mPowerWhitelistBackend.isWhitelisted(mTargetPackage)) {
             preference.setSummary(R.string.background_activity_summary_whitelisted);
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 5d95dd2..91f35e2 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -49,10 +49,10 @@
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.Utils;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 0952f1f..5738c29 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -398,6 +398,19 @@
         return timeMs * 1000;
     }
 
+    public void setForceAppStandby(int uid, String packageName,
+            int mode) {
+        final boolean isPreOApp = isLegacyApp(packageName);
+        if (isPreOApp) {
+            // Control whether app could run in the background if it is pre O app
+            mAppOpsManager.setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName,
+                    mode);
+        }
+        // Control whether app could run jobs in the background
+        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName,
+                mode);
+    }
+
     public void initBatteryStatsHelper(BatteryStatsHelper statsHelper, Bundle bundle,
             UserManager userManager) {
         statsHelper.create(bundle);
@@ -481,5 +494,18 @@
         return 0;
     }
 
+    public boolean isLegacyApp(final String packageName) {
+        try {
+            ApplicationInfo info = mPackageManager.getApplicationInfo(packageName,
+                    PackageManager.GET_META_DATA);
+
+            return info.targetSdkVersion < Build.VERSION_CODES.O;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Cannot find package: " + packageName, e);
+        }
+
+        return false;
+    }
+
 }
 
diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java
index cbd9c3f..063185e 100644
--- a/src/com/android/settings/fuelgauge/FakeUid.java
+++ b/src/com/android/settings/fuelgauge/FakeUid.java
@@ -363,6 +363,16 @@
     }
 
     @Override
+    public long getCpuActiveTime() {
+        return 0;
+    }
+
+    @Override
+    public long[] getCpuClusterTimes() {
+        return null;
+    }
+
+    @Override
     public long[] getCpuFreqTimes(int procState, int which) {
         return null;
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index ec54291..e0954e5 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -47,7 +47,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.display.AmbientDisplayPreferenceController;
 import com.android.settings.display.AutoBrightnessPreferenceController;
@@ -61,6 +60,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
index c50d580..605591d 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacy.java
@@ -54,7 +54,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.display.AmbientDisplayPreferenceController;
 import com.android.settings.display.AutoBrightnessPreferenceController;
@@ -67,6 +66,7 @@
 import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
 import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
index 7df0fb1..0a40f1e 100644
--- a/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
@@ -20,9 +20,11 @@
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.Preference;
 
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.BasePreferenceController;
 
@@ -37,12 +39,21 @@
 
     private AppOpsManager mAppOpsManager;
     private List<AppOpsManager.PackageOps> mPackageOps;
+    private SettingsActivity mSettingsActivity;
+    private PreferenceFragment mPreferenceFragment;
 
     public RestrictAppPreferenceController(Context context) {
         super(context, KEY_RESTRICT_APP);
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     }
 
+    public RestrictAppPreferenceController(SettingsActivity settingsActivity,
+            PreferenceFragment preferenceFragment) {
+        this(settingsActivity.getApplicationContext());
+        mSettingsActivity = settingsActivity;
+        mPreferenceFragment = preferenceFragment;
+    }
+
     @Override
     public int getAvailabilityStatus() {
         return AVAILABLE;
@@ -51,13 +62,27 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
+
         mPackageOps = mAppOpsManager.getPackagesForOps(
                 new int[]{AppOpsManager.OP_RUN_ANY_IN_BACKGROUND});
         final int num = mPackageOps != null ? mPackageOps.size() : 0;
 
+        // Enable the preference if some apps already been restricted, otherwise disable it
+        preference.setEnabled(num > 0);
         preference.setSummary(
                 mContext.getResources().getQuantityString(R.plurals.restricted_app_summary, num,
                         num));
     }
 
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        if (getPreferenceKey().equals(preference.getKey())) {
+            // start fragment
+            RestrictedAppDetails.startRestrictedAppDetails(mSettingsActivity, mPreferenceFragment,
+                    mPackageOps);
+            return true;
+        }
+
+        return super.handlePreferenceTreeClick(preference);
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/RestrictedAppDetails.java b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
new file mode 100644
index 0000000..bdaaa3a
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
@@ -0,0 +1,147 @@
+/*
+ * 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.fuelgauge;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.util.IconDrawableFactory;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment;
+import com.android.settings.fuelgauge.anomaly.AnomalyPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.List;
+
+/**
+ * Fragment to show a list of anomaly apps, where user could handle these anomalies
+ */
+public class RestrictedAppDetails extends DashboardFragment {
+
+    public static final String TAG = "RestrictedAppDetails";
+
+    private static final String EXTRA_PACKAGE_OPS_LIST = "package_ops_list";
+    private static final String KEY_PREF_RESTRICTED_APP_LIST = "restrict_app_list";
+
+    @VisibleForTesting
+    List<AppOpsManager.PackageOps> mPackageOpsList;
+    @VisibleForTesting
+    IconDrawableFactory mIconDrawableFactory;
+    @VisibleForTesting
+    PreferenceGroup mRestrictedAppListGroup;
+    @VisibleForTesting
+    BatteryUtils mBatteryUtils;
+    @VisibleForTesting
+    PackageManager mPackageManager;
+
+    public static void startRestrictedAppDetails(SettingsActivity caller,
+            PreferenceFragment fragment, List<AppOpsManager.PackageOps> packageOpsList) {
+        Bundle args = new Bundle();
+        args.putParcelableList(EXTRA_PACKAGE_OPS_LIST, packageOpsList);
+
+        caller.startPreferencePanelAsUser(fragment, RestrictedAppDetails.class.getName(), args,
+                R.string.restricted_app_title, null /* titleText */,
+                new UserHandle(UserHandle.myUserId()));
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Context context = getContext();
+
+        mRestrictedAppListGroup = (PreferenceGroup) findPreference(KEY_PREF_RESTRICTED_APP_LIST);
+        mPackageOpsList = getArguments().getParcelableArrayList(EXTRA_PACKAGE_OPS_LIST);
+        mPackageManager = context.getPackageManager();
+        mIconDrawableFactory = IconDrawableFactory.newInstance(context);
+        mBatteryUtils = BatteryUtils.getInstance(context);
+
+        refreshUi();
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(Preference preference) {
+
+        return super.onPreferenceTreeClick(preference);
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.restricted_apps_detail;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+        return null;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.FUELGAUGE_RESTRICTED_APP_DETAILS;
+    }
+
+    @VisibleForTesting
+    void refreshUi() {
+        mRestrictedAppListGroup.removeAll();
+        final Context context = getPrefContext();
+
+        for (int i = 0, size = mPackageOpsList.size(); i < size; i++) {
+            final CheckBoxPreference checkBoxPreference = new CheckBoxPreference(context);
+            final AppOpsManager.PackageOps packageOps = mPackageOpsList.get(i);
+            try {
+                final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
+                        packageOps.getPackageName(), 0 /* flags */);
+                checkBoxPreference.setChecked(true);
+                checkBoxPreference.setTitle(mPackageManager.getApplicationLabel(applicationInfo));
+                checkBoxPreference.setKey(packageOps.getPackageName());
+                checkBoxPreference.setOnPreferenceChangeListener((pref, value) -> {
+                    // change the toggle
+                    final int mode = (Boolean) value ? AppOpsManager.MODE_IGNORED
+                            : AppOpsManager.MODE_ALLOWED;
+                    final String packageName = pref.getKey();
+                    final int uid = mBatteryUtils.getPackageUid(packageName);
+                    mBatteryUtils.setForceAppStandby(uid, packageName, mode);
+                    return true;
+                });
+                mRestrictedAppListGroup.addPreference(checkBoxPreference);
+            } catch (PackageManager.NameNotFoundException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+}
diff --git a/src/com/android/settings/fuelgauge/SmartBatterySettings.java b/src/com/android/settings/fuelgauge/SmartBatterySettings.java
index 5faaef4..52c0cef 100644
--- a/src/com/android/settings/fuelgauge/SmartBatterySettings.java
+++ b/src/com/android/settings/fuelgauge/SmartBatterySettings.java
@@ -19,9 +19,11 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.SearchIndexableResource;
+import android.support.v14.preference.PreferenceFragment;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -63,14 +65,20 @@
 
     @Override
     protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context);
+        return buildPreferenceControllers(context, (SettingsActivity) getActivity(), this);
     }
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(
-            Context context) {
+            Context context, SettingsActivity settingsActivity, PreferenceFragment fragment) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new SmartBatteryPreferenceController(context));
-        controllers.add(new RestrictAppPreferenceController(context));
+        if (settingsActivity != null && fragment != null) {
+            controllers.add(
+                    new RestrictAppPreferenceController(settingsActivity, fragment));
+        } else {
+            controllers.add(new RestrictAppPreferenceController(context));
+        }
+
         return controllers;
     }
 
@@ -92,7 +100,7 @@
                 @Override
                 public List<AbstractPreferenceController> getPreferenceControllers(
                         Context context) {
-                    return buildPreferenceControllers(context);
+                    return buildPreferenceControllers(context, null, null);
                 }
             };
 }
diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
index 39d51dc0..3dde95e 100644
--- a/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
+++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyUtils.java
@@ -24,7 +24,6 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.action.AnomalyAction;
 import com.android.settings.fuelgauge.anomaly.action.ForceStopAction;
 import com.android.settings.fuelgauge.anomaly.action.LocationCheckAction;
@@ -33,6 +32,7 @@
 import com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector;
 import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector;
 import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
index 3ee89d1..d7de5a7 100644
--- a/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
+++ b/src/com/android/settings/fuelgauge/anomaly/action/AnomalyAction.java
@@ -20,9 +20,9 @@
 import android.util.Pair;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for anomaly action, which is triggered if we need to handle the anomaly
diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
index 9fa69fd..1bf08b7 100644
--- a/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
+++ b/src/com/android/settings/fuelgauge/batterytip/actions/BatteryTipAction.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for battery tip action, which is triggered if we need to handle the battery tip
diff --git a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
index a19471e..cbd1581 100644
--- a/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
+++ b/src/com/android/settings/fuelgauge/batterytip/actions/SmartBatteryAction.java
@@ -22,8 +22,8 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.SmartBatterySettings;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class SmartBatteryAction extends BatteryTipAction {
     private SettingsActivity mSettingsActivity;
diff --git a/src/com/android/settings/inputmethod/UserDictionarySettings.java b/src/com/android/settings/inputmethod/UserDictionarySettings.java
index 9680af1..3bbc581 100644
--- a/src/com/android/settings/inputmethod/UserDictionarySettings.java
+++ b/src/com/android/settings/inputmethod/UserDictionarySettings.java
@@ -42,10 +42,11 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.core.instrumentation.Instrumentable;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
+import com.android.settingslib.core.instrumentation.Instrumentable;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 public class UserDictionarySettings extends ListFragment implements Instrumentable,
         LoaderManager.LoaderCallbacks<Cursor> {
@@ -59,8 +60,7 @@
     private static final int OPTIONS_MENU_ADD = Menu.FIRST;
     private static final int LOADER_ID = 1;
 
-    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
-            new VisibilityLoggerMixin(getMetricsCategory());
+    private VisibilityLoggerMixin mVisibilityLoggerMixin;
 
     private Cursor mCursor;
     private String mLocale;
@@ -71,15 +71,12 @@
     }
 
     @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mVisibilityLoggerMixin.onAttach(context);
-    }
-
-    @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(),
+                FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider());
+
         final Intent intent = getActivity().getIntent();
         final String localeFromIntent =
                 null == intent ? null : intent.getStringExtra("locale");
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index 17cf211..0b77179 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -28,10 +28,10 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.settings.AirplaneModeEnabler;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.R;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 4b1da31..74c1910 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -31,13 +31,13 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.network.MobilePlanPreferenceController.MobilePlanPreferenceHost;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
index 81ceca1..9180791 100644
--- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -34,9 +34,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
index 8494998..39cbf5d 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -19,6 +19,7 @@
 import static com.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
 
 import android.app.AutomaticZenRule;
+import android.app.Fragment;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -28,6 +29,7 @@
 import android.util.Slog;
 import android.view.View;
 
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
@@ -40,6 +42,7 @@
     private final String KEY = PREF_KEY_APP_HEADER;
     private final PreferenceFragment mFragment;
     private AutomaticZenRule mRule;
+    private String mId;
     private EntityHeaderController mController;
 
     public ZenAutomaticRuleHeaderPreferenceController(Context context, PreferenceFragment fragment,
@@ -70,6 +73,14 @@
                 mController = EntityHeaderController
                         .newInstance(mFragment.getActivity(), mFragment,
                                 pref.findViewById(R.id.entity_header));
+
+                mController.setEditZenRuleNameListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        ZenRuleNameDialog.show(mFragment, mRule.getName(), null,
+                                new RuleNameChangeListener());
+                    }
+                });
             }
 
             pref = mController.setIcon(getIcon())
@@ -77,7 +88,7 @@
                     .setPackageName(mRule.getOwner().getPackageName())
                     .setUid(mContext.getUserId())
                     .setHasAppInfoLink(false)
-                    .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+                    .setButtonActions(EntityHeaderController.ActionType.ACTION_DND_RULE_PREFERENCE,
                             EntityHeaderController.ActionType.ACTION_NONE)
                     .done(mFragment.getActivity(), mContext);
 
@@ -98,7 +109,20 @@
         return null;
     }
 
-    protected void onResume(AutomaticZenRule rule) {
+    protected void onResume(AutomaticZenRule rule, String id) {
         mRule = rule;
+        mId = id;
+    }
+
+    public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
+        public RuleNameChangeListener() {}
+
+        @Override
+        public void onOk(String ruleName, Fragment parent) {
+            mMetricsFeatureProvider.action(mContext,
+                    MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
+            mRule.setName(ruleName);
+            mBackend.setZenRule(mId, mRule);
+        }
     }
 }
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
index bc3fa25..a684d3e 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleSwitchPreferenceController.java
@@ -20,6 +20,7 @@
 import android.app.Fragment;
 import android.content.Context;
 import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
 import android.widget.Switch;
 import android.widget.Toast;
 
@@ -37,6 +38,7 @@
     private String mId;
     private Toast mEnabledToast;
     private int mToastTextResource;
+    private SwitchBar mSwitchBar;
 
     public ZenAutomaticRuleSwitchPreferenceController(Context context, Fragment parent,
             int toastTextResource, Lifecycle lifecycle) {
@@ -54,26 +56,34 @@
         return mRule != null && mId != null;
     }
 
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        LayoutPreference pref = (LayoutPreference) screen.findPreference(KEY);
+        mSwitchBar = pref.findViewById(R.id.switch_bar);
+
+        if (mSwitchBar != null) {
+            mSwitchBar.setSwitchBarText(R.string.zen_mode_use_automatic_rule,
+                    R.string.zen_mode_use_automatic_rule);
+            try {
+                mSwitchBar.addOnSwitchChangeListener(this);
+            } catch (IllegalStateException e) {
+                // an exception is thrown if you try to add the listener twice
+            }
+            mSwitchBar.show();
+        }
+    }
+
+
     public void onResume(AutomaticZenRule rule, String id) {
         mRule = rule;
         mId = id;
     }
 
     public void updateState(Preference preference) {
-        LayoutPreference pref = (LayoutPreference) preference;
-        SwitchBar bar = pref.findViewById(R.id.switch_bar);
         if (mRule != null) {
-            bar.setChecked(mRule.isEnabled());
+            mSwitchBar.setChecked(mRule.isEnabled());
         }
-        if (bar != null) {
-            bar.show();
-            try {
-                bar.addOnSwitchChangeListener(this);
-            } catch (IllegalStateException e) {
-                // an exception is thrown if you try to add the listener twice
-            }
-        }
-        bar.show();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
index 158f9ac..e8f103e 100644
--- a/src/com/android/settings/notification/ZenModeBackend.java
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -173,8 +173,8 @@
         savePolicy(getNewPriorityCategories(allowSenders, category),
             priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects);
 
-        if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow=" +
-                stringCategory + allowSenders + " allow" + stringCategory + "From="
+        if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" +
+                stringCategory + "=" + allowSenders + " allow" + stringCategory + "From="
                 + ZenModeConfig.sourceToString(allowSendersFrom));
     }
 
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 0234c8e..b5ea9c4 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -17,7 +17,6 @@
 package com.android.settings.notification;
 
 import android.app.AutomaticZenRule;
-import android.app.Fragment;
 import android.app.NotificationManager;
 import android.content.Context;
 import android.content.Intent;
@@ -25,12 +24,10 @@
 import android.os.Bundle;
 import android.service.notification.ConditionProviderService;
 import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
 import android.support.v7.preference.PreferenceScreen;
 import android.util.Log;
 import android.widget.Toast;
 
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -39,14 +36,11 @@
     protected static final String TAG = ZenModeSettingsBase.TAG;
     protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
 
-    private static final String KEY_RULE_NAME = "rule_name";
-
     protected Context mContext;
     protected boolean mDisableListeners;
     protected AutomaticZenRule mRule;
     protected String mId;
 
-    private Preference mRuleName;
     protected ZenAutomaticRuleHeaderPreferenceController mHeader;
     protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
 
@@ -79,18 +73,7 @@
         }
 
         super.onCreate(icicle);
-
         onCreateInternal();
-
-        final PreferenceScreen root = getPreferenceScreen();
-        mRuleName = root.findPreference(KEY_RULE_NAME);
-        mRuleName.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-            @Override
-            public boolean onPreferenceClick(Preference preference) {
-                showRuleNameDialog();
-                return true;
-            }
-        });
     }
 
     @Override
@@ -113,11 +96,11 @@
     protected void updateHeader() {
         final PreferenceScreen screen = getPreferenceScreen();
 
-        mSwitch.onResume(mRule,mId);
+        mSwitch.onResume(mRule, mId);
         mSwitch.displayPreference(screen);
         updatePreference(mSwitch);
 
-        mHeader.onResume(mRule);
+        mHeader.onResume(mRule, mId);
         mHeader.displayPreference(screen);
         updatePreference(mHeader);
     }
@@ -161,46 +144,20 @@
         return false;
     }
 
-    private void showRuleNameDialog() {
-        ZenRuleNameDialog.show(this, mRule.getName(), null, new RuleNameChangeListener());
-    }
-
     private void toastAndFinish() {
         Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
                     .show();
         getActivity().finish();
     }
 
-    private void updateRuleName() {
-        if (mRule != null) {
-            mRuleName.setSummary(mRule.getName());
-        } else {
-            if (DEBUG) Log.d(TAG, "updateRuleName - mRuleName "
-                    + "not updated; mRuleName returned null");
-        }
-    }
-
     private AutomaticZenRule getZenRule() {
         return NotificationManager.from(mContext).getAutomaticZenRule(mId);
     }
 
     private void updateControls() {
         mDisableListeners = true;
-        updateRuleName();
         updateControlsInternal();
         updateHeader();
         mDisableListeners = false;
     }
-
-    public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
-        public RuleNameChangeListener() {}
-
-        @Override
-        public void onOk(String ruleName, Fragment parent) {
-            mMetricsFeatureProvider.action(mContext,
-                    MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
-            mRule.setName(ruleName);
-            mBackend.setZenRule(mId, mRule);
-        }
-    }
 }
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
index 7193873..fee390f 100644
--- a/src/com/android/settings/notification/ZenRulePreference.java
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -30,10 +30,10 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.utils.ManagedServiceSettings;
 import com.android.settings.utils.ZenServiceListing;
 import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.Map;
 
@@ -145,4 +145,4 @@
                 ? mContext.getResources().getString(R.string.switch_off_text)
                 : mContext.getResources().getString(R.string.switch_on_text);
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index dc9df83..0805766 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -24,7 +24,6 @@
 import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.datausage.DataPlanFeatureProvider;
@@ -36,6 +35,7 @@
 import com.android.settings.search.SearchFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
  * Abstract class for creating feature controllers. Allows OEM implementations to define their own
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 275ebb6..f817d4b 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -29,7 +29,6 @@
 import com.android.settings.bluetooth.BluetoothFeatureProviderImpl;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProviderImpl;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProviderImpl;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
@@ -55,6 +54,7 @@
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.IPackageManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 /**
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 878bbfd..cbe49f8 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -48,6 +48,11 @@
 
     DatabaseIndexingManager getIndexingManager(Context context);
 
+    /**
+     * @return a {@link SearchIndexableResources} to be used for indexing search results.
+     */
+    SearchIndexableResources getSearchIndexableResources();
+
     default String getSettingsIntelligencePkgName() {
         return "com.android.settings.intelligence";
     }
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index ccd4ff1..78c47ed 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -36,6 +36,7 @@
 
     private static final String METRICS_ACTION_SETTINGS_INDEX = "search_synchronous_indexing";
     private DatabaseIndexingManager mDatabaseIndexingManager;
+    private SearchIndexableResources mSearchIndexableResources;
 
     @Override
     public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
@@ -72,6 +73,14 @@
                 .histogram(context, METRICS_ACTION_SETTINGS_INDEX, indexingTime);
     }
 
+    @Override
+    public SearchIndexableResources getSearchIndexableResources() {
+        if (mSearchIndexableResources == null) {
+            mSearchIndexableResources = new SearchIndexableResourcesImpl();
+        }
+        return mSearchIndexableResources;
+    }
+
     protected boolean isSignatureWhitelisted(Context context, String callerPackage) {
         return false;
     }
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index b0159cf..5a0a131 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -16,170 +16,14 @@
 
 package com.android.settings.search;
 
-import android.support.annotation.VisibleForTesting;
-
-import com.android.settings.DateTimeSettings;
-import com.android.settings.DisplaySettings;
-import com.android.settings.LegalSettings;
-import com.android.settings.accessibility.AccessibilitySettings;
-import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
-import com.android.settings.accessibility.MagnificationPreferenceFragment;
-import com.android.settings.accounts.UserAndAccountDashboardFragment;
-import com.android.settings.applications.AppAndNotificationDashboardFragment;
-import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.SpecialAccessSettings;
-import com.android.settings.applications.assist.ManageAssist;
-import com.android.settings.backup.BackupSettingsActivity;
-import com.android.settings.backup.BackupSettingsFragment;
-import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
-import com.android.settings.datausage.DataUsageSummary;
-import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
-import com.android.settings.development.DevelopmentSettingsDashboardFragment;
-import com.android.settings.deviceinfo.DeviceInfoSettings;
-import com.android.settings.deviceinfo.StorageDashboardFragment;
-import com.android.settings.deviceinfo.StorageSettings;
-import com.android.settings.display.AmbientDisplaySettings;
-import com.android.settings.display.NightDisplaySettings;
-import com.android.settings.display.ScreenZoomSettings;
-import com.android.settings.dream.DreamSettings;
-import com.android.settings.enterprise.EnterprisePrivacySettings;
-import com.android.settings.fuelgauge.BatterySaverSettings;
-import com.android.settings.fuelgauge.PowerUsageAdvanced;
-import com.android.settings.fuelgauge.PowerUsageSummary;
-import com.android.settings.fuelgauge.SmartBatterySettings;
-import com.android.settings.gestures.AssistGestureSettings;
-import com.android.settings.gestures.DoubleTapPowerSettings;
-import com.android.settings.gestures.DoubleTapScreenSettings;
-import com.android.settings.gestures.DoubleTwistGestureSettings;
-import com.android.settings.gestures.GestureSettings;
-import com.android.settings.gestures.PickupGestureSettings;
-import com.android.settings.gestures.SwipeToNotificationSettings;
-import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
-import com.android.settings.inputmethod.PhysicalKeyboardFragment;
-import com.android.settings.inputmethod.VirtualKeyboardFragment;
-import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.location.LocationMode;
-import com.android.settings.location.LocationSettings;
-import com.android.settings.location.ScanningSettings;
-import com.android.settings.network.NetworkDashboardFragment;
-import com.android.settings.nfc.PaymentSettings;
-import com.android.settings.notification.ConfigureNotificationSettings;
-import com.android.settings.notification.SoundSettings;
-import com.android.settings.notification.ZenModeAutomationSettings;
-import com.android.settings.notification.ZenModeBehaviorSettings;
-import com.android.settings.notification.ZenModeSettings;
-import com.android.settings.print.PrintSettingsFragment;
-import com.android.settings.security.EncryptionAndCredential;
-import com.android.settings.security.LockscreenDashboardFragment;
-import com.android.settings.security.ScreenPinningSettings;
-import com.android.settings.security.SecuritySettingsV2;
-import com.android.settings.security.screenlock.ScreenLockSettings;
-import com.android.settings.sim.SimSettings;
-import com.android.settings.support.SupportDashboardActivity;
-import com.android.settings.system.ResetDashboardFragment;
-import com.android.settings.system.SystemDashboardFragment;
-import com.android.settings.tts.TextToSpeechSettings;
-import com.android.settings.tts.TtsEnginePreferenceFragment;
-import com.android.settings.users.UserSettings;
-import com.android.settings.wallpaper.WallpaperTypeSettings;
-import com.android.settings.wfd.WifiDisplaySettings;
-import com.android.settings.wifi.ConfigureWifiSettings;
-import com.android.settings.wifi.WifiSettings;
-
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
 
-public final class SearchIndexableResources {
+public interface SearchIndexableResources {
 
-    @VisibleForTesting
-    static final Set<Class> sProviders = new HashSet<>();
-
-    @VisibleForTesting
-    static void addIndex(Class indexClass) {
-        sProviders.add(indexClass);
-    }
-
-    static {
-        addIndex(WifiSettings.class);
-        addIndex(NetworkDashboardFragment.class);
-        addIndex(ConfigureWifiSettings.class);
-        addIndex(BluetoothSettings.class);
-        addIndex(SimSettings.class);
-        addIndex(DataUsageSummary.class);
-        addIndex(ScreenZoomSettings.class);
-        addIndex(DisplaySettings.class);
-        addIndex(AmbientDisplaySettings.class);
-        addIndex(WallpaperTypeSettings.class);
-        addIndex(AppAndNotificationDashboardFragment.class);
-        addIndex(SoundSettings.class);
-        addIndex(ZenModeSettings.class);
-        addIndex(StorageSettings.class);
-        addIndex(PowerUsageAdvanced.class);
-        addIndex(DefaultAppSettings.class);
-        addIndex(ManageAssist.class);
-        addIndex(SpecialAccessSettings.class);
-        addIndex(UserSettings.class);
-        addIndex(AssistGestureSettings.class);
-        addIndex(PickupGestureSettings.class);
-        addIndex(DoubleTapScreenSettings.class);
-        addIndex(DoubleTapPowerSettings.class);
-        addIndex(DoubleTwistGestureSettings.class);
-        addIndex(SwipeToNotificationSettings.class);
-        addIndex(GestureSettings.class);
-        addIndex(LanguageAndInputSettings.class);
-        addIndex(LocationSettings.class);
-        addIndex(LocationMode.class);
-        addIndex(ScanningSettings.class);
-        addIndex(SecuritySettingsV2.class);
-        addIndex(ScreenLockSettings.class);
-        addIndex(EncryptionAndCredential.class);
-        addIndex(ScreenPinningSettings.class);
-        addIndex(UserAndAccountDashboardFragment.class);
-        addIndex(VirtualKeyboardFragment.class);
-        addIndex(AvailableVirtualKeyboardFragment.class);
-        addIndex(PhysicalKeyboardFragment.class);
-        addIndex(BackupSettingsActivity.class);
-        addIndex(BackupSettingsFragment.class);
-        addIndex(DateTimeSettings.class);
-        addIndex(AccessibilitySettings.class);
-        addIndex(PrintSettingsFragment.class);
-        addIndex(DevelopmentSettingsDashboardFragment.class);
-        addIndex(DeviceInfoSettings.class);
-        addIndex(LegalSettings.class);
-        addIndex(SystemDashboardFragment.class);
-        addIndex(ResetDashboardFragment.class);
-        addIndex(StorageDashboardFragment.class);
-        addIndex(ConnectedDeviceDashboardFragment.class);
-        addIndex(ConnectedDeviceDashboardFragmentOld.class);
-        addIndex(AdvancedConnectedDeviceDashboardFragment.class);
-        addIndex(EnterprisePrivacySettings.class);
-        addIndex(PaymentSettings.class);
-        addIndex(TextToSpeechSettings.class);
-        addIndex(TtsEnginePreferenceFragment.class);
-        addIndex(MagnificationPreferenceFragment.class);
-        addIndex(AccessibilityShortcutPreferenceFragment.class);
-        addIndex(DreamSettings.class);
-        addIndex(SupportDashboardActivity.class);
-        addIndex(AutomaticStorageManagerSettings.class);
-        addIndex(ConfigureNotificationSettings.class);
-        addIndex(PowerUsageSummary.class);
-        addIndex(BatterySaverSettings.class);
-        addIndex(LockscreenDashboardFragment.class);
-        addIndex(WifiDisplaySettings.class);
-        addIndex(ZenModeBehaviorSettings.class);
-        addIndex(ZenModeAutomationSettings.class);
-        addIndex(NightDisplaySettings.class);
-        addIndex(SmartBatterySettings.class);
-    }
-
-    private SearchIndexableResources() {
-    }
-
-    public static Collection<Class> providerValues() {
-        return sProviders;
-    }
-}
\ No newline at end of file
+    /**
+     * Returns a collection of classes that should be indexed for search.
+     *
+     * Each class should have the SEARCH_INDEX_DATA_PROVIDER public static member.
+     */
+    Collection<Class> getProviderValues();
+}
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
new file mode 100644
index 0000000..2c20703
--- /dev/null
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014 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.search;
+
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.DateTimeSettings;
+import com.android.settings.DisplaySettings;
+import com.android.settings.LegalSettings;
+import com.android.settings.accessibility.AccessibilitySettings;
+import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
+import com.android.settings.accessibility.MagnificationPreferenceFragment;
+import com.android.settings.accounts.UserAndAccountDashboardFragment;
+import com.android.settings.applications.AppAndNotificationDashboardFragment;
+import com.android.settings.applications.DefaultAppSettings;
+import com.android.settings.applications.SpecialAccessSettings;
+import com.android.settings.applications.assist.ManageAssist;
+import com.android.settings.backup.BackupSettingsActivity;
+import com.android.settings.backup.BackupSettingsFragment;
+import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.deviceinfo.DeviceInfoSettings;
+import com.android.settings.deviceinfo.StorageDashboardFragment;
+import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.display.AmbientDisplaySettings;
+import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.display.ScreenZoomSettings;
+import com.android.settings.dream.DreamSettings;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
+import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.PowerUsageAdvanced;
+import com.android.settings.fuelgauge.PowerUsageSummary;
+import com.android.settings.fuelgauge.SmartBatterySettings;
+import com.android.settings.gestures.AssistGestureSettings;
+import com.android.settings.gestures.DoubleTapPowerSettings;
+import com.android.settings.gestures.DoubleTapScreenSettings;
+import com.android.settings.gestures.DoubleTwistGestureSettings;
+import com.android.settings.gestures.GestureSettings;
+import com.android.settings.gestures.PickupGestureSettings;
+import com.android.settings.gestures.SwipeToNotificationSettings;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import com.android.settings.inputmethod.VirtualKeyboardFragment;
+import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.location.LocationMode;
+import com.android.settings.location.LocationSettings;
+import com.android.settings.location.ScanningSettings;
+import com.android.settings.network.NetworkDashboardFragment;
+import com.android.settings.nfc.PaymentSettings;
+import com.android.settings.notification.ConfigureNotificationSettings;
+import com.android.settings.notification.SoundSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
+import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeSettings;
+import com.android.settings.print.PrintSettingsFragment;
+import com.android.settings.security.EncryptionAndCredential;
+import com.android.settings.security.LockscreenDashboardFragment;
+import com.android.settings.security.ScreenPinningSettings;
+import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.sim.SimSettings;
+import com.android.settings.support.SupportDashboardActivity;
+import com.android.settings.system.ResetDashboardFragment;
+import com.android.settings.system.SystemDashboardFragment;
+import com.android.settings.tts.TextToSpeechSettings;
+import com.android.settings.tts.TtsEnginePreferenceFragment;
+import com.android.settings.users.UserSettings;
+import com.android.settings.wallpaper.WallpaperTypeSettings;
+import com.android.settings.wfd.WifiDisplaySettings;
+import com.android.settings.wifi.ConfigureWifiSettings;
+import com.android.settings.wifi.WifiSettings;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SearchIndexableResourcesImpl implements SearchIndexableResources {
+
+    private final Set<Class> sProviders = new HashSet<>();
+
+    @VisibleForTesting
+    void addIndex(Class indexClass) {
+        sProviders.add(indexClass);
+    }
+
+    public SearchIndexableResourcesImpl() {
+        addIndex(WifiSettings.class);
+        addIndex(NetworkDashboardFragment.class);
+        addIndex(ConfigureWifiSettings.class);
+        addIndex(BluetoothSettings.class);
+        addIndex(SimSettings.class);
+        addIndex(DataUsageSummary.class);
+        addIndex(ScreenZoomSettings.class);
+        addIndex(DisplaySettings.class);
+        addIndex(AmbientDisplaySettings.class);
+        addIndex(WallpaperTypeSettings.class);
+        addIndex(AppAndNotificationDashboardFragment.class);
+        addIndex(SoundSettings.class);
+        addIndex(ZenModeSettings.class);
+        addIndex(StorageSettings.class);
+        addIndex(PowerUsageAdvanced.class);
+        addIndex(DefaultAppSettings.class);
+        addIndex(ManageAssist.class);
+        addIndex(SpecialAccessSettings.class);
+        addIndex(UserSettings.class);
+        addIndex(AssistGestureSettings.class);
+        addIndex(PickupGestureSettings.class);
+        addIndex(DoubleTapScreenSettings.class);
+        addIndex(DoubleTapPowerSettings.class);
+        addIndex(DoubleTwistGestureSettings.class);
+        addIndex(SwipeToNotificationSettings.class);
+        addIndex(GestureSettings.class);
+        addIndex(LanguageAndInputSettings.class);
+        addIndex(LocationSettings.class);
+        addIndex(LocationMode.class);
+        addIndex(ScanningSettings.class);
+        addIndex(SecuritySettingsV2.class);
+        addIndex(ScreenLockSettings.class);
+        addIndex(EncryptionAndCredential.class);
+        addIndex(ScreenPinningSettings.class);
+        addIndex(UserAndAccountDashboardFragment.class);
+        addIndex(VirtualKeyboardFragment.class);
+        addIndex(AvailableVirtualKeyboardFragment.class);
+        addIndex(PhysicalKeyboardFragment.class);
+        addIndex(BackupSettingsActivity.class);
+        addIndex(BackupSettingsFragment.class);
+        addIndex(DateTimeSettings.class);
+        addIndex(AccessibilitySettings.class);
+        addIndex(PrintSettingsFragment.class);
+        addIndex(DevelopmentSettingsDashboardFragment.class);
+        addIndex(DeviceInfoSettings.class);
+        addIndex(LegalSettings.class);
+        addIndex(SystemDashboardFragment.class);
+        addIndex(ResetDashboardFragment.class);
+        addIndex(StorageDashboardFragment.class);
+        addIndex(ConnectedDeviceDashboardFragment.class);
+        addIndex(ConnectedDeviceDashboardFragmentOld.class);
+        addIndex(AdvancedConnectedDeviceDashboardFragment.class);
+        addIndex(EnterprisePrivacySettings.class);
+        addIndex(PaymentSettings.class);
+        addIndex(TextToSpeechSettings.class);
+        addIndex(TtsEnginePreferenceFragment.class);
+        addIndex(MagnificationPreferenceFragment.class);
+        addIndex(AccessibilityShortcutPreferenceFragment.class);
+        addIndex(DreamSettings.class);
+        addIndex(SupportDashboardActivity.class);
+        addIndex(AutomaticStorageManagerSettings.class);
+        addIndex(ConfigureNotificationSettings.class);
+        addIndex(PowerUsageSummary.class);
+        addIndex(BatterySaverSettings.class);
+        addIndex(LockscreenDashboardFragment.class);
+        addIndex(WifiDisplaySettings.class);
+        addIndex(ZenModeBehaviorSettings.class);
+        addIndex(ZenModeAutomationSettings.class);
+        addIndex(NightDisplaySettings.class);
+        addIndex(SmartBatterySettings.class);
+    }
+
+    @Override
+    public Collection<Class> getProviderValues() {
+        return sProviders;
+    }
+}
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 0c98b9c..3ef1b85 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -175,7 +175,8 @@
     }
 
     private List<String> getNonIndexableKeysFromProvider(Context context) {
-        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         final List<String> nonIndexableKeys = new ArrayList<>();
 
         for (Class<?> clazz : values) {
@@ -209,7 +210,8 @@
     }
 
     private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
-        Collection<Class> values = SearchIndexableResources.providerValues();
+        Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         List<SearchIndexableResource> resourceList = new ArrayList<>();
 
         for (Class<?> clazz : values) {
@@ -236,7 +238,8 @@
     }
 
     private List<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
-        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final Collection<Class> values = FeatureFactory.getFactory(context)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
         final List<SearchIndexableRaw> rawList = new ArrayList<>();
 
         for (Class<?> clazz : values) {
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index c10753f..e5a21e4 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -27,9 +27,9 @@
 import android.util.Xml;
 
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable.SearchIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
 import com.android.settings.search.XmlParserUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -62,7 +62,8 @@
      * @return a list of {@link SliceData} to be indexed and later referenced as a Slice.
      *
      * The collection works as follows:
-     * - Collects a list of Fragments from {@link SearchIndexableResources}.
+     * - Collects a list of Fragments from
+     * {@link FeatureFactory#getSearchFeatureProvider()}.
      * - From each fragment, grab a {@link SearchIndexProvider}.
      * - For each provider, collect XML resource layout and a list of
      * {@link com.android.settings.core.BasePreferenceController}.
@@ -72,7 +73,8 @@
             return mSliceData;
         }
 
-        final Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+        final Collection<Class> indexableClasses = FeatureFactory.getFactory(mContext)
+                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
 
         for (Class clazz : indexableClasses) {
             final String fragmentName = clazz.getName();
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 9b2c529..8607211 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -63,12 +63,14 @@
 
     @IntDef({ActionType.ACTION_NONE,
             ActionType.ACTION_APP_PREFERENCE,
-            ActionType.ACTION_NOTIF_PREFERENCE})
+            ActionType.ACTION_NOTIF_PREFERENCE,
+            ActionType.ACTION_DND_RULE_PREFERENCE,})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionType {
         int ACTION_NONE = 0;
         int ACTION_APP_PREFERENCE = 1;
         int ACTION_NOTIF_PREFERENCE = 2;
+        int ACTION_DND_RULE_PREFERENCE = 3;
     }
 
     public static final String PREF_KEY_APP_HEADER = "pref_app_header";
@@ -99,6 +101,8 @@
 
     private boolean mIsInstantApp;
 
+    private View.OnClickListener mEditRuleNameOnClickListener;
+
     /**
      * Creates a new instance of the controller.
      *
@@ -212,6 +216,11 @@
         return this;
     }
 
+    public EntityHeaderController setEditZenRuleNameListener(View.OnClickListener listener) {
+        this.mEditRuleNameOnClickListener = listener;
+        return this;
+    }
+
     /**
      * Done mutating entity header, rebinds everything and return a new {@link LayoutPreference}.
      */
@@ -330,6 +339,16 @@
             return;
         }
         switch (action) {
+            case ActionType.ACTION_DND_RULE_PREFERENCE: {
+                if (mEditRuleNameOnClickListener == null) {
+                    button.setVisibility(View.GONE);
+                } else {
+                    button.setImageResource(R.drawable.ic_mode_edit);
+                    button.setVisibility(View.VISIBLE);
+                    button.setOnClickListener(mEditRuleNameOnClickListener);
+                }
+                return;
+            }
             case ActionType.ACTION_NOTIF_PREFERENCE: {
                 if (mAppNotifPrefIntent == null) {
                     button.setVisibility(View.GONE);
diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java
index 749ec0a..3be5eca 100644
--- a/src/com/android/settings/widget/SwitchBar.java
+++ b/src/com/android/settings/widget/SwitchBar.java
@@ -39,9 +39,9 @@
 import android.widget.TextView;
 
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index 9c43142..c5e79b2 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -33,9 +33,9 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.WirelessUtils;
diff --git a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
index de1b030..8843d93 100644
--- a/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiMasterSwitchPreferenceController.java
@@ -19,12 +19,12 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.R;
 import com.android.settings.widget.SummaryUpdater;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 70ee20d..13ffd5b 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -54,7 +54,6 @@
 import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.ActionButtonPreference;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settings.wifi.WifiDetailPreference;
@@ -63,6 +62,7 @@
 import com.android.settings.wifi.WifiUtils;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
diff --git a/src/com/android/settings/HotspotOffReceiver.java b/src/com/android/settings/wifi/tether/HotspotOffReceiver.java
similarity index 97%
rename from src/com/android/settings/HotspotOffReceiver.java
rename to src/com/android/settings/wifi/tether/HotspotOffReceiver.java
index 4083082..fcbf888 100644
--- a/src/com/android/settings/HotspotOffReceiver.java
+++ b/src/com/android/settings/wifi/tether/HotspotOffReceiver.java
@@ -1,5 +1,5 @@
 
-package com.android.settings;
+package com.android.settings.wifi.tether;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
diff --git a/src/com/android/settings/TetherService.java b/src/com/android/settings/wifi/tether/TetherService.java
similarity index 98%
rename from src/com/android/settings/TetherService.java
rename to src/com/android/settings/wifi/tether/TetherService.java
index fce3f27..e491de8 100644
--- a/src/com/android/settings/TetherService.java
+++ b/src/com/android/settings/wifi/tether/TetherService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.wifi.tether;
 
 import android.app.Activity;
 import android.app.AlarmManager;
@@ -167,11 +167,16 @@
         SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
         prefs.edit().putString(KEY_TETHERS, tethersToString(mCurrentTethers)).commit();
 
+        unregisterReceivers();
         if (DEBUG) Log.d(TAG, "Destroying TetherService");
-        unregisterReceiver(mReceiver);
         super.onDestroy();
     }
 
+    private void unregisterReceivers() {
+        unregisterReceiver(mReceiver);
+        mHotspotReceiver.unregister();
+    }
+
     private void removeTypeAtIndex(int index) {
         mCurrentTethers.remove(index);
         // If we are currently in the middle of a check, we may need to adjust the
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index ebcea43..be910e1 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -24,3 +24,4 @@
 com.android.settings.wifi.SavedAccessPointsWifiSettings
 com.android.settings.notification.ZenModeEventRuleSettings
 com.android.settings.notification.ZenModeScheduleRuleSettings
+com.android.settings.fuelgauge.RestrictedAppDetails
diff --git a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
index 942634a..3a7d094 100644
--- a/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsDialogFragmentTest.java
@@ -17,6 +17,7 @@
 
 import android.app.Dialog;
 import android.app.Fragment;
+import android.content.Context;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -39,6 +40,8 @@
     private static final int DIALOG_ID = 15;
 
     @Mock
+    private Context mContext;
+    @Mock
     private DialogCreatableFragment mDialogCreatable;
     private SettingsPreferenceFragment.SettingsDialogFragment mDialogFragment;
 
@@ -53,9 +56,10 @@
 
         mDialogFragment =
                 new SettingsPreferenceFragment.SettingsDialogFragment(mDialogCreatable, DIALOG_ID);
+        mDialogFragment.onAttach(mContext);
         mDialogFragment.getMetricsCategory();
 
-        // getDialogMetricsCategory called in constructor, and explicitly in test.
+        // getDialogMetricsCategory called in onAttach, and explicitly in test.
         verify(mDialogCreatable, times(2)).getDialogMetricsCategory(DIALOG_ID);
     }
 
@@ -66,6 +70,7 @@
         try {
             mDialogFragment = new SettingsPreferenceFragment.SettingsDialogFragment(
                     mDialogCreatable, DIALOG_ID);
+            mDialogFragment.onAttach(mContext);
         } catch (IllegalStateException e) {
             // getDialogMetricsCategory called in constructor
             verify(mDialogCreatable).getDialogMetricsCategory(DIALOG_ID);
diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
index 84a121f..bd57211 100644
--- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java
@@ -50,16 +50,21 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -194,6 +199,55 @@
     }
 
     @Test
+    public void display_showRecentsWithInstantApp() {
+        // Regular app.
+        final List<UsageStats> stats = new ArrayList<>();
+        final UsageStats stat1 = new UsageStats();
+        stat1.mLastTimeUsed = System.currentTimeMillis();
+        stat1.mPackageName = "com.foo.bar";
+        stats.add(stat1);
+
+        // Instant app.
+        final UsageStats stat2 = new UsageStats();
+        stat2.mLastTimeUsed = System.currentTimeMillis() + 200;
+        stat2.mPackageName = "com.foo.barinstant";
+        stats.add(stat2);
+
+        ApplicationsState.AppEntry stat1Entry = mock(ApplicationsState.AppEntry.class);
+        ApplicationsState.AppEntry stat2Entry = mock(ApplicationsState.AppEntry.class);
+        stat1Entry.info = mApplicationInfo;
+        stat2Entry.info = mApplicationInfo;
+
+        when(mAppState.getEntry(stat1.mPackageName, UserHandle.myUserId())).thenReturn(stat1Entry);
+        when(mAppState.getEntry(stat2.mPackageName, UserHandle.myUserId())).thenReturn(stat2Entry);
+
+        // Only the regular app stat1 should have its intent resolve.
+        when(mPackageManager.resolveActivity(argThat(intentMatcher(stat1.mPackageName)),
+                anyInt())).thenReturn(new ResolveInfo());
+
+        when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong()))
+                .thenReturn(stats);
+
+        // Make sure stat2 is considered an instant app.
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+                (InstantAppDataProvider) (ApplicationInfo info) -> {
+                    if (info == stat2Entry.info) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                });
+
+        mController.displayPreference(mScreen);
+
+        ArgumentCaptor<Preference> prefCaptor = ArgumentCaptor.forClass(Preference.class);
+        verify(mCategory, times(2)).addPreference(prefCaptor.capture());
+        List<Preference> prefs = prefCaptor.getAllValues();
+        assertThat(prefs.get(1).getKey()).isEqualTo(stat1.mPackageName);
+        assertThat(prefs.get(0).getKey()).isEqualTo(stat2.mPackageName);
+    }
+
+    @Test
     public void display_hasRecentButNoneDisplayable_showAppInfo() {
         final List<UsageStats> stats = new ArrayList<>();
         final UsageStats stat1 = new UsageStats();
@@ -249,4 +303,8 @@
         return preference -> TextUtils.equals(expected, preference.getSummary());
     }
 
+    // Used for matching an intent with a specific package name.
+    private static ArgumentMatcher<Intent> intentMatcher(String packageName) {
+        return intent -> packageName.equals(intent.getPackage());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
index 17b7a22..7d5eb31 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
@@ -79,6 +79,8 @@
     private DevicePolicyManagerWrapper mDevicePolicyManager;
     @Mock
     private AppInfoDashboardFragment mFragment;
+    @Mock
+    private ApplicationInfo mAppInfo;
 
     private Context mContext;
     private AppActionButtonPreferenceController mController;
@@ -96,6 +98,25 @@
         ReflectionHelpers.setField(mController, "mApplicationFeatureProvider",
                 mFeatureFactory.applicationFeatureProvider);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        final PackageInfo packageInfo = mock(PackageInfo.class);
+        packageInfo.applicationInfo = mAppInfo;
+        when(mFragment.getPackageInfo()).thenReturn(packageInfo);
+    }
+
+    @Test
+    public void getAvailabilityStatus_notInstantApp_shouldReturnAvailable() {
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+            (InstantAppDataProvider) (i -> false));
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_isInstantApp_shouldReturnDisabled() {
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+            (InstantAppDataProvider) (i -> true));
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(mController.DISABLED_FOR_USER);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
index 5c0badc..f85d43a 100644
--- a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
@@ -42,9 +42,9 @@
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
index e9d37f6..71020be 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -32,11 +32,11 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
index b973edb..828b5a1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothEnablerTest.java
@@ -29,13 +29,13 @@
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.widget.MasterSwitchController;
 import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
index 8666ce3..c3b22b3 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
@@ -26,11 +26,11 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
index c561d0d..8ded9d6 100644
--- a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
+++ b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
@@ -2,6 +2,8 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.provider.SearchIndexableResource;
@@ -13,10 +15,12 @@
 import com.android.settings.TestConfig;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
 import com.android.settings.search.XmlParserUtils;
 import com.android.settings.security.SecuritySettings;
 import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -82,19 +86,21 @@
                     + "IllegalAccessException. Please fix the following classes:\n";
 
     Context mContext;
-
-    private Set<Class> mProviderClassesCopy;
+    SearchFeatureProvider mSearchProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
+        mSearchProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
@@ -156,7 +162,8 @@
     private Set<Integer> getIndexableXml() {
         Set<Integer> xmlResSet = new HashSet();
 
-        Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+        Collection<Class> indexableClasses =
+                mSearchProvider.getSearchIndexableResources().getProviderValues();
         indexableClasses.removeAll(illegalClasses);
 
         for (Class clazz : indexableClasses) {
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
index 4455549..867b5df 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java
@@ -20,6 +20,7 @@
 import android.util.ArraySet;
 
 import com.android.settings.core.codeinspection.CodeInspector;
+import com.android.settingslib.core.instrumentation.Instrumentable;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
index 9e37896..8ad2d69 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/InstrumentedDialogFragmentTest.java
@@ -21,6 +21,7 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
index da48f15..2950c07 100644
--- a/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFeatureProviderTest.java
@@ -31,6 +31,9 @@
 import com.android.settings.TestConfig;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.LogWriter;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +61,6 @@
     @Mock private VisibilityLoggerMixin mockVisibilityLogger;
 
     private Context mContext;
-    private MetricsFeatureProvider mProvider;
 
     @Captor
     private ArgumentCaptor<Pair> mPairCaptor;
@@ -67,12 +69,6 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mProvider = new MetricsFeatureProvider();
-        List<LogWriter> writers = new ArrayList<>();
-        writers.add(mockLogWriter);
-        ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
-
-        when(mockVisibilityLogger.elapsedTimeSinceVisible()).thenReturn(ELAPSED_TIME);
     }
 
     @Test
@@ -84,60 +80,4 @@
 
         assertThat(feature1 == feature2).isTrue();
     }
-
-    @Test
-    public void logDashboardStartIntent_intentEmpty_shouldNotLog() {
-        mProvider.logDashboardStartIntent(mContext, null /* intent */,
-                MetricsEvent.SETTINGS_GESTURES);
-
-        verifyNoMoreInteractions(mockLogWriter);
-    }
-
-    @Test
-    public void logDashboardStartIntent_intentHasNoComponent_shouldLog() {
-        final Intent intent = new Intent(Intent.ACTION_ASSIST);
-
-        mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
-
-        verify(mockLogWriter).action(
-                eq(mContext),
-                eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
-                anyString(),
-                eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
-    }
-
-    @Test
-    public void logDashboardStartIntent_intentIsExternal_shouldLog() {
-        final Intent intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
-
-        mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
-
-        verify(mockLogWriter).action(
-                eq(mContext),
-                eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
-                anyString(),
-                eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
-    }
-
-    @Test
-    public void action_BooleanLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_BOOLEAN);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_BOOLEAN), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
-
-    @Test
-    public void action_IntegerLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_INTEGER);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_INTEGER), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
deleted file mode 100644
index c80e3a8..0000000
--- a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Pair;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import com.google.common.truth.Platform;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SharedPreferenceLoggerTest {
-
-    private static final String TEST_TAG = "tag";
-    private static final String TEST_KEY = "key";
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-
-    private ArgumentMatcher<Pair<Integer, Object>> mNamePairMatcher;
-    private FakeFeatureFactory mFactory;
-    private MetricsFeatureProvider mMetricsFeature;
-    private SharedPreferencesLogger mSharedPrefLogger;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-        mFactory = FakeFeatureFactory.setupForTest();
-        mMetricsFeature = mFactory.metricsFeatureProvider;
-
-        mSharedPrefLogger = new SharedPreferencesLogger(mContext, TEST_TAG);
-        mNamePairMatcher = pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, String.class);
-    }
-
-    @Test
-    public void putInt_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 1);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-        editor.putInt(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(6)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class)));
-    }
-
-    @Test
-    public void putBoolean_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putBoolean(TEST_KEY, true);
-        editor.putBoolean(TEST_KEY, true);
-        editor.putBoolean(TEST_KEY, false);
-        editor.putBoolean(TEST_KEY, false);
-        editor.putBoolean(TEST_KEY, false);
-
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, true)));
-        verify(mMetricsFeature, times(3)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, false)));
-    }
-
-    @Test
-    public void putLong_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class)));
-    }
-
-    @Test
-    public void putLong_biggerThanIntMax_shouldLogIntMax() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        final long veryBigNumber = 500L + Integer.MAX_VALUE;
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, veryBigNumber);
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(
-                        FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MAX_VALUE)));
-    }
-
-    @Test
-    public void putLong_smallerThanIntMin_shouldLogIntMin() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        final long veryNegativeNumber = -500L + Integer.MIN_VALUE;
-        editor.putLong(TEST_KEY, 1);
-        editor.putLong(TEST_KEY, veryNegativeNumber);
-
-        verify(mMetricsFeature).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(
-                        FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MIN_VALUE)));
-    }
-
-    @Test
-    public void putFloat_shouldNotLogInitialPut() {
-        final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 1);
-        editor.putFloat(TEST_KEY, 2);
-
-        verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(),
-                argThat(mNamePairMatcher),
-                argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, Float.class)));
-    }
-
-    @Test
-    public void logPackage_shouldUseLogPackageApi() {
-        mSharedPrefLogger.logPackageName("key", "com.android.settings");
-        verify(mMetricsFeature).action(any(Context.class),
-                eq(ACTION_SETTINGS_PREFERENCE_CHANGE),
-                eq("com.android.settings"),
-                any(Pair.class));
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, Class clazz) {
-        return pair -> pair.first == tag && Platform.isInstanceOfType(pair.second, clazz);
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, boolean bool) {
-        return pair -> pair.first == tag
-                && Platform.isInstanceOfType(pair.second, Integer.class)
-                && pair.second.equals((bool ? 1 : 0));
-    }
-
-    private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, int val) {
-        return pair -> pair.first == tag
-                && Platform.isInstanceOfType(pair.second, Integer.class)
-                && pair.second.equals(val);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
deleted file mode 100644
index 1a47a66..0000000
--- a/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016 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.core.instrumentation;
-
-import static com.android.settings.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
-
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.SettingsActivity;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-
-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;
-
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class VisibilityLoggerMixinTest {
-
-    @Mock
-    private MetricsFeatureProvider mMetricsFeature;
-
-    private VisibilityLoggerMixin mMixin;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-        mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC, mMetricsFeature);
-    }
-
-    @Test
-    public void shouldLogVisibleOnResume() {
-        mMixin.onResume();
-
-        verify(mMetricsFeature, times(1))
-                .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.VIEW_UNKNOWN),
-                        eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldLogVisibleWithSource() {
-        final Intent sourceIntent = new Intent()
-                .putExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
-                        MetricsProto.MetricsEvent.SETTINGS_GESTURES);
-        final Activity activity = mock(Activity.class);
-        when(activity.getIntent()).thenReturn(sourceIntent);
-        mMixin.setSourceMetricsCategory(activity);
-        mMixin.onResume();
-
-        verify(mMetricsFeature, times(1))
-                .visible(nullable(Context.class), eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES),
-                        eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldLogHideOnPause() {
-        mMixin.onPause();
-
-        verify(mMetricsFeature, times(1))
-                .hidden(nullable(Context.class), eq(TestInstrumentable.TEST_METRIC));
-    }
-
-    @Test
-    public void shouldNotLogIfMetricsFeatureIsNull() {
-        mMixin = new VisibilityLoggerMixin(TestInstrumentable.TEST_METRIC);
-        mMixin.onResume();
-        mMixin.onPause();
-
-        verify(mMetricsFeature, never())
-                .hidden(nullable(Context.class), anyInt());
-    }
-
-    @Test
-    public void shouldNotLogIfMetricsCategoryIsUnknown() {
-        mMixin = new VisibilityLoggerMixin(METRICS_CATEGORY_UNKNOWN, mMetricsFeature);
-
-        mMixin.onResume();
-        mMixin.onPause();
-
-        verify(mMetricsFeature, never())
-                .hidden(nullable(Context.class), anyInt());
-    }
-
-    private final class TestInstrumentable implements Instrumentable {
-
-        public static final int TEST_METRIC = 12345;
-
-        @Override
-        public int getMetricsCategory() {
-            return TEST_METRIC;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 741f2bc..afa914c 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -51,6 +51,7 @@
 import com.android.settings.testutils.shadow.ShadowThreadUtils;
 import com.android.settings.testutils.shadow.ShadowTileUtils;
 import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.CategoryManager;
 import com.android.settingslib.drawer.DashboardCategory;
@@ -372,7 +373,7 @@
         final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent;
         assertThat(launchIntent.getAction())
                 .isEqualTo("TestAction");
-        assertThat(launchIntent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, 0))
+        assertThat(launchIntent.getIntExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, 0))
                 .isEqualTo(MetricsProto.MetricsEvent.SETTINGS_GESTURES);
     }
 
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 6c663ab..40e590a 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -33,10 +33,10 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.drawer.TileUtils;
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
index d077e6f..1a3fa5e 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
@@ -22,7 +22,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
index 9ab88d3..8b3c770 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageListTest.java
@@ -60,6 +60,7 @@
 
     @Test
     public void resumePause_shouldListenUnlistenDataStateChange() {
+        mDataUsageList.onAttach(mContext);
         mDataUsageList.onResume();
 
         verify(mListener).setListener(true, 0, mContext);
diff --git a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
index 92807e9..9f6d0ef 100644
--- a/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/ZonePickerTest.java
@@ -28,8 +28,8 @@
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
 import com.android.settings.testutils.shadow.ShadowZoneGetter;
+import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
index 66ccc6e..ab32fa2 100644
--- a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java
@@ -31,11 +31,11 @@
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
index 90ce395..9c56611 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/AutomaticStorageManagementSwitchPreferenceControllerTest.java
@@ -37,13 +37,13 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.RoSystemProperties;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deletionhelper.ActivationWarningFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 1a3139d..2da756f 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -50,13 +50,13 @@
 import com.android.settings.SubSettings;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.manageapplications.ManageApplications;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.deviceinfo.PrivateVolumeSettings;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settingslib.applications.StorageStatsSource;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.After;
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
index 6ad37ce..e251be0 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
@@ -38,10 +38,10 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.After;
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
index e1ce694..c003f17 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
@@ -32,11 +32,11 @@
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.InlinePayload;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
index c590fd3..5418ead 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -36,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settings.testutils.shadow.ShadowVibrator;
@@ -69,12 +70,15 @@
 
     private FingerprintEnrollEnrolling mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
         ShadowVibrator.addToServiceMap();
 
+        mFactory = FakeFeatureFactory.setupForTest();
         mActivity = Robolectric.buildActivity(
                 FingerprintEnrollEnrolling.class,
                 new Intent()
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
index d495b74..be53aa5 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -33,6 +33,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
@@ -69,10 +70,13 @@
 
     private FingerprintEnrollFindSensor mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
+        mFactory = FakeFeatureFactory.setupForTest();
 
         mActivity = Robolectric.buildActivity(
                 FingerprintEnrollFindSensor.class,
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
index 0254bcb..f52f437 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintSuggestionActivityTest.java
@@ -30,6 +30,7 @@
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
 import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
@@ -63,9 +64,12 @@
 
     private ActivityController<FingerprintSuggestionActivity> mController;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mFactory = FakeFeatureFactory.setupForTest();
 
         final Intent intent = new Intent();
         mController = Robolectric.buildActivity(FingerprintSuggestionActivity.class, intent);
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
index c3899e9..c786608 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
@@ -27,6 +27,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
@@ -61,10 +62,13 @@
 
     private SetupFingerprintEnrollFindSensor mActivity;
 
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         ShadowUtils.setFingerprintManager(mFingerprintManager);
+        mFactory = FakeFeatureFactory.setupForTest();
     }
 
     private void createActivity(Intent intent) {
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
index 2d98bf4..f5b0c8a 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
@@ -35,6 +35,7 @@
 import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
 import com.android.settings.password.SetupSkipDialog;
 import com.android.settings.password.StorageManagerWrapper;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowEventLogWriter;
 import com.android.settings.testutils.shadow.ShadowFingerprintManager;
@@ -72,6 +73,7 @@
 
     @Mock
     private UserInfo mUserInfo;
+    private FakeFeatureFactory mFactory;
 
     private ActivityController<SetupFingerprintEnrollIntroduction> mController;
 
@@ -83,6 +85,8 @@
                 .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
         ShadowFingerprintManager.addToServiceMap();
 
+        mFactory = FakeFeatureFactory.setupForTest();
+
         final Intent intent = new Intent();
         mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
index 3d04ac5..0c9e394 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -18,6 +18,10 @@
 
 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.anyString;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -38,6 +42,7 @@
 
 import com.android.settings.R;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
 import com.android.settings.testutils.shadow.ShadowFragment;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
@@ -94,12 +99,14 @@
     private BackgroundActivityPreferenceController mController;
     private SwitchPreference mPreference;
     private Context mShadowContext;
+    private BatteryUtils mBatteryUtils;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
         mShadowContext = RuntimeEnvironment.application;
+        FakeFeatureFactory.setupForTest();
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -115,21 +122,22 @@
         mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
         mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;
 
+        mBatteryUtils = spy(new BatteryUtils(mShadowContext));
+        doNothing().when(mBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
+
         mPreference = new SwitchPreference(mShadowContext);
         mController = spy(new BackgroundActivityPreferenceController(
                 mContext, mFragment, UID_LOW_SDK, LOW_SDK_PACKAGE, mPowerWhitelistBackend));
         mController.mDpm = mDevicePolicyManagerWrapper;
+        mController.mBatteryUtils = mBatteryUtils;
     }
 
     @Test
     public void testOnPreferenceChange_TurnOnCheck_MethodInvoked() {
         mController.onPreferenceChange(mPreference, true);
 
-        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_LOW_SDK,
-                LOW_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
-        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
-                LOW_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
-
+        verify(mBatteryUtils).setForceAppStandby(UID_LOW_SDK, LOW_SDK_PACKAGE,
+                AppOpsManager.MODE_ALLOWED);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mShadowContext.getText(R.string.background_activity_summary_on));
     }
@@ -138,11 +146,12 @@
     public void testOnPreferenceChange_TurnOnCheckHighSDK_MethodInvoked() {
         mController = new BackgroundActivityPreferenceController(mContext, mFragment, UID_HIGH_SDK,
                 HIGH_SDK_PACKAGE, mPowerWhitelistBackend);
+        mController.mBatteryUtils = mBatteryUtils;
+
         mController.onPreferenceChange(mPreference, true);
-        verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_HIGH_SDK,
-                HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
-        verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID_HIGH_SDK,
-                HIGH_SDK_PACKAGE, AppOpsManager.MODE_ALLOWED);
+
+        verify(mBatteryUtils).setForceAppStandby(UID_HIGH_SDK, HIGH_SDK_PACKAGE,
+                AppOpsManager.MODE_ALLOWED);
         assertThat(mPreference.getSummary())
                 .isEqualTo(mShadowContext.getText(R.string.background_activity_summary_on));
     }
@@ -217,16 +226,6 @@
     }
 
     @Test
-    public void testIsLegacyApp_SdkLowerThanO_ReturnTrue() {
-        assertThat(mController.isLegacyApp(LOW_SDK_PACKAGE)).isTrue();
-    }
-
-    @Test
-    public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() {
-        assertThat(mController.isLegacyApp(HIGH_SDK_PACKAGE)).isFalse();
-    }
-
-    @Test
     public void testIsAvailable_ReturnTrue() {
         assertThat(mController.isAvailable()).isTrue();
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 844aca4..fe90751 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -103,6 +103,8 @@
     private static final double PRECISION = 0.001;
     private static final int SDK_VERSION = Build.VERSION_CODES.L;
     private static final String PACKAGE_NAME = "com.android.app";
+    private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
+    private static final String LOW_SDK_PACKAGE = "com.android.package.low";
 
     @Mock
     private BatteryStats.Uid mUid;
@@ -137,16 +139,18 @@
     @Mock
     private ApplicationInfo mApplicationInfo;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private BatteryStatsHelper mBatteryStatsHelper;
+    @Mock
+    private ApplicationInfo mHighApplicationInfo;
+    @Mock
+    private ApplicationInfo mLowApplicationInfo;
     private BatteryUtils mBatteryUtils;
     private FakeFeatureFactory mFeatureFactory;
     private PowerUsageFeatureProvider mProvider;
     private List<BatterySipper> mUsageList;
 
     @Before
-    public void setUp() {
+    public void setUp() throws PackageManager.NameNotFoundException {
         MockitoAnnotations.initMocks(this);
 
         mFeatureFactory = FakeFeatureFactory.setupForTest();
@@ -165,6 +169,14 @@
         when(mBatteryStatsHelper.getStats().computeBatteryRealtime(anyLong(), anyInt())).thenReturn(
                 TIME_SINCE_LAST_FULL_CHARGE_US);
 
+        when(mPackageManager.getApplicationInfo(HIGH_SDK_PACKAGE, PackageManager.GET_META_DATA))
+                .thenReturn(mHighApplicationInfo);
+        when(mPackageManager.getApplicationInfo(LOW_SDK_PACKAGE, PackageManager.GET_META_DATA))
+                .thenReturn(mLowApplicationInfo);
+        mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+        mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;
+
+
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         mNormalBatterySipper.totalPowerMah = TOTAL_BATTERY_USAGE;
 
@@ -501,4 +513,14 @@
         assertThat(mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper)).isEqualTo(
                 TIME_EXPECTED_FOREGROUND);
     }
+
+    @Test
+    public void testIsLegacyApp_SdkLowerThanO_ReturnTrue() {
+        assertThat(mBatteryUtils.isLegacyApp(LOW_SDK_PACKAGE)).isTrue();
+    }
+
+    @Test
+    public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() {
+        assertThat(mBatteryUtils.isLegacyApp(HIGH_SDK_PACKAGE)).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
index c944148..5e43d1d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
@@ -19,13 +19,18 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 import android.app.AppOpsManager;
 import android.content.Context;
+import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.Preference;
 
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.TestConfig;
 
 import org.junit.Before;
@@ -48,6 +53,10 @@
     private AppOpsManager mAppOpsManager;
     @Mock
     private AppOpsManager.PackageOps mPackageOps;
+    @Mock
+    private SettingsActivity mSettingsActivity;
+    @Mock
+    private PreferenceFragment mFragment;
     private List<AppOpsManager.PackageOps> mPackageOpsList;
     private RestrictAppPreferenceController mRestrictAppPreferenceController;
     private Preference mPreference;
@@ -59,9 +68,12 @@
 
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
-        mRestrictAppPreferenceController = new RestrictAppPreferenceController(mContext);
+        doReturn(mContext).when(mSettingsActivity).getApplicationContext();
+        mRestrictAppPreferenceController = new RestrictAppPreferenceController(mSettingsActivity,
+                mFragment);
         mPackageOpsList = new ArrayList<>();
         mPreference = new Preference(mContext);
+        mPreference.setKey(mRestrictAppPreferenceController.getPreferenceKey());
     }
 
     @Test
@@ -85,4 +97,22 @@
         assertThat(mPreference.getSummary()).isEqualTo("2 apps");
     }
 
+    @Test
+    public void testUpdateState_zeroApp_disabled() {
+        doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
+
+        mRestrictAppPreferenceController.updateState(mPreference);
+
+        assertThat(mPreference.isEnabled()).isFalse();
+    }
+
+    @Test
+    public void testHandlePreferenceTreeClick_startFragment() {
+        mRestrictAppPreferenceController.handlePreferenceTreeClick(mPreference);
+
+        verify(mSettingsActivity).startPreferencePanelAsUser(eq(mFragment),
+                eq(RestrictedAppDetails.class.getName()), any(), eq(R.string.restricted_app_title),
+                any(), any());
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
new file mode 100644
index 0000000..a9de061
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceManager;
+
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class RestrictedAppDetailsTest {
+    private static final String PACKAGE_NAME = "com.android.app";
+    private static final String APP_NAME = "app";
+    private static final int UID = 1234;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private ApplicationInfo mApplicationInfo;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private PreferenceManager mPreferenceManager;
+    private RestrictedAppDetails mFragment;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        mFragment = spy(new RestrictedAppDetails());
+
+        doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
+        doReturn(mContext).when(mPreferenceManager).getContext();
+        mFragment.mPackageManager = mPackageManager;
+        mFragment.mPackageOpsList = new ArrayList<>();
+        mFragment.mPackageOpsList.add(
+                new AppOpsManager.PackageOps(PACKAGE_NAME, UID, null /* entries */));
+        mFragment.mRestrictedAppListGroup = spy(new PreferenceCategory(mContext));
+        doReturn(mPreferenceManager).when(mFragment.mRestrictedAppListGroup).getPreferenceManager();
+    }
+
+    @Test
+    public void testRefreshUi_displayPreference() throws Exception {
+        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME, 0);
+        doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(mApplicationInfo);
+
+        mFragment.refreshUi();
+
+        assertThat(mFragment.mRestrictedAppListGroup.getPreferenceCount()).isEqualTo(1);
+        final Preference preference = mFragment.mRestrictedAppListGroup.getPreference(0);
+        assertThat(preference.getKey()).isEqualTo(PACKAGE_NAME);
+        assertThat(preference.getTitle()).isEqualTo(APP_NAME);
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
index 38391c9..3e33823 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyUtilsTest.java
@@ -24,7 +24,6 @@
 import android.util.Pair;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.fuelgauge.anomaly.action.StopAndBackgroundCheckAction;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
@@ -32,6 +31,7 @@
 import com.android.settings.fuelgauge.anomaly.checker.WakeLockAnomalyDetector;
 import com.android.settings.testutils.shadow.ShadowKeyValueListParserWrapperImpl;
 import com.android.settings.fuelgauge.anomaly.checker.WakeupAlarmAnomalyDetector;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
index 1ee52ca..737c16d 100644
--- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
+++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java
@@ -20,6 +20,7 @@
 import android.view.View;
 import android.widget.TextView;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
 
@@ -27,6 +28,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
@@ -39,6 +41,11 @@
 
     private LocaleListEditor mLocaleListEditor;
 
+    @Mock
+    private Context mContext;
+
+    private FakeFeatureFactory mFactory;
+
     @Before
     public void setUp() {
         mLocaleListEditor = new LocaleListEditor();
@@ -48,11 +55,13 @@
                 RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE));
         ReflectionHelpers.setField(mLocaleListEditor, "mUserManager",
                 RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE));
+        mFactory = FakeFeatureFactory.setupForTest();
     }
 
     @Test
     public void testDisallowConfigLocale_unrestrict() {
         ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", true);
+        mLocaleListEditor.onAttach(mContext);
         mLocaleListEditor.onResume();
         Assert.assertEquals(View.GONE, mLocaleListEditor.getEmptyTextView().getVisibility());
     }
@@ -60,6 +69,7 @@
     @Test
     public void testDisallowConfigLocale_restrict() {
         ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", false);
+        mLocaleListEditor.onAttach(mContext);
         mLocaleListEditor.onResume();
         Assert.assertEquals(View.VISIBLE, mLocaleListEditor.getEmptyTextView().getVisibility());
     }
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
index f84f9a2..d610363 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
@@ -121,7 +121,8 @@
                 continue;
             }
             // Must be in SearchProviderRegistry
-            if (!SearchIndexableResources.providerValues().contains(clazz)) {
+            SearchFeatureProvider provider = new SearchFeatureProviderImpl();
+            if (!provider.getSearchIndexableResources().getProviderValues().contains(clazz)) {
                 if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) {
                     notInSearchProviderRegistry.add(className);
                 }
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
index eedb324..72dd94c 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
@@ -21,12 +21,14 @@
 
 import static junit.framework.Assert.fail;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.database.Cursor;
 import android.text.TextUtils;
 
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.wifi.WifiSettings;
 
@@ -36,49 +38,56 @@
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SearchIndexableResourcesTest {
 
-    Set<Class> sProviderClassCopy;
+    SearchFeatureProviderImpl mSearchProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
-        sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders);
+        mSearchProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.addAll(sProviderClassCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
     public void testAddIndex() {
         final Class stringClass = java.lang.String.class;
         // Confirms that String.class isn't contained in SearchIndexableResources.
-        assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass);
-        final int beforeCount = SearchIndexableResources.providerValues().size();
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .doesNotContain(stringClass);
+        final int beforeCount =
+                mSearchProvider.getSearchIndexableResources().getProviderValues().size();
 
-        SearchIndexableResources.addIndex(java.lang.String.class);
+        ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+                .addIndex(java.lang.String.class);
 
-        assertThat(SearchIndexableResources.sProviders).contains(stringClass);
-        final int afterCount = SearchIndexableResources.providerValues().size();
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .contains(stringClass);
+        final int afterCount =
+                mSearchProvider.getSearchIndexableResources().getProviderValues().size();
         assertThat(afterCount).isEqualTo(beforeCount + 1);
     }
 
     @Test
     public void testIndexHasWifiSettings() {
-        assertThat(sProviderClassCopy).contains(WifiSettings.class);
+        assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+                .contains(WifiSettings.class);
     }
 
     @Test
     public void testNonIndexableKeys_GetsKeyFromProvider() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.addIndex(FakeIndexProvider.class);
+        mSearchProvider.getSearchIndexableResources().getProviderValues().clear();
+        ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+                .addIndex(FakeIndexProvider.class);
 
         SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider());
 
@@ -97,7 +106,7 @@
 
     @Test
     public void testAllClassNamesHaveProviders() {
-        for (Class clazz: sProviderClassCopy) {
+        for (Class clazz: mSearchProvider.getSearchIndexableResources().getProviderValues()) {
             if(DatabaseIndexingUtils.getSearchIndexProvider(clazz) == null) {
                 fail(clazz.getName() + "is not an index provider");
             }
diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
index efeaed7..cca2794 100644
--- a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
+++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
@@ -2,6 +2,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.Manifest;
@@ -14,6 +15,7 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.search.indexing.FakeSettingsFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -23,9 +25,6 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SettingsSearchIndexablesProviderTest {
@@ -33,8 +32,8 @@
     private final String BASE_AUTHORITY = "com.android.settings";
 
     private SettingsSearchIndexablesProvider mProvider;
-
-    Set<Class> sProviderClasses;
+    private SearchFeatureProvider mFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
     Context mContext;
 
     @Before
@@ -49,15 +48,18 @@
         info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES;
         mProvider.attachInfo(mContext, info);
 
-        sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders);
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.add(FakeSettingsFragment.class);
+        mFeatureProvider = new SearchFeatureProviderImpl();
+        mFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+        mFeatureProvider.getSearchIndexableResources().getProviderValues()
+                .add(FakeSettingsFragment.class);
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.sProviders.clear();
-        SearchIndexableResources.sProviders.addAll(sProviderClasses);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index efd1cc5..f5d5ff0 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -19,6 +19,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -26,8 +28,9 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
-import com.android.settings.testutils.DatabaseTestUtils;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -37,9 +40,6 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
-import java.util.Set;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SliceBroadcastReceiverTest {
@@ -54,30 +54,30 @@
     private Context mContext;
     private SQLiteDatabase mDb;
     private SliceBroadcastReceiver mReceiver;
-
-    private Set<Class> mProviderClassesCopy;
+    private SearchFeatureProvider mSearchFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
         mReceiver = new SliceBroadcastReceiver();
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
         SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
         helper.setIndexedState();
+        mSearchFeatureProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        DatabaseTestUtils.clearDb(mContext);
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(SearchFeatureProvider.class);
     }
 
     @Test
     public void testOnReceive_toggleChanged() {
         String key = "key";
-        SearchIndexableResources.providerValues().clear();
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
         insertSpecialCase(key);
         // Turn on toggle setting
         FakeToggleController fakeToggleController = new FakeToggleController(mContext, key);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
index b5c0b5f..1d0ac41 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
@@ -18,11 +18,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+
 import android.content.Context;
 
 import com.android.settings.TestConfig;
 import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.After;
@@ -32,9 +36,7 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -49,28 +51,31 @@
 
     Context mContext;
 
-    private Set<Class> mProviderClassesCopy;
-
     SliceDataConverter mSliceDataConverter;
+    SearchFeatureProvider mSearchFeatureProvider;
+    private FakeFeatureFactory mFakeFeatureFactory;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-        mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
         mSliceDataConverter = new SliceDataConverter(mContext);
+        mSearchFeatureProvider = new SearchFeatureProviderImpl();
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+        mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
     }
 
     @After
     public void cleanUp() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+        mFakeFeatureFactory.searchFeatureProvider = mock(
+                SearchFeatureProvider.class);
     }
 
     @Test
     @Config(qualifiers = "mcc999")
     public void testFakeProvider_convertsFakeData() {
-        SearchIndexableResources.providerValues().clear();
-        SearchIndexableResources.providerValues().add(FakeIndexProvider.class);
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+        mSearchFeatureProvider.getSearchIndexableResources().getProviderValues()
+                .add(FakeIndexProvider.class);
 
         List<SliceData> sliceDataList = mSliceDataConverter.getSliceData();
 
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index fb2b62e..3325332 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -24,7 +24,6 @@
 import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
 import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.datausage.DataPlanFeatureProvider;
@@ -39,6 +38,7 @@
 import com.android.settings.security.SecurityFeatureProvider;
 import com.android.settings.slices.SlicesFeatureProvider;
 import com.android.settings.users.UserFeatureProvider;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.mockito.Answers;
 
@@ -55,7 +55,6 @@
     public final LocaleFeatureProvider localeFeatureProvider;
     public final ApplicationFeatureProvider applicationFeatureProvider;
     public final EnterprisePrivacyFeatureProvider enterprisePrivacyFeatureProvider;
-    public final SearchFeatureProvider searchFeatureProvider;
     public final SurveyFeatureProvider surveyFeatureProvider;
     public final SecurityFeatureProvider securityFeatureProvider;
     public final SuggestionFeatureProvider suggestionsFeatureProvider;
@@ -65,6 +64,7 @@
     public final DataPlanFeatureProvider dataPlanFeatureProvider;
     public final SmsMirroringFeatureProvider smsMirroringFeatureProvider;
     public final SlicesFeatureProvider slicesFeatureProvider;
+    public SearchFeatureProvider searchFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
index dcced4e..9caf09f 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowEventLogWriter.java
@@ -19,7 +19,7 @@
 
 import android.content.Context;
 
-import com.android.settings.core.instrumentation.EventLogWriter;
+import com.android.settingslib.core.instrumentation.EventLogWriter;
 
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index e44be0e..59a08ae 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -44,10 +44,10 @@
 
 import com.android.settings.TestConfig;
 import com.android.settings.applications.defaultapps.DefaultAppInfo;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.RadioButtonPreference;
 import com.android.settings.wrapper.UserPackageWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
index daa42b4..06b4d55 100644
--- a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
@@ -165,6 +165,57 @@
     }
 
     @Test
+    public void bindButton_hasEditRuleNameClickListener_shouldShowButton() {
+        final ResolveInfo info = new ResolveInfo();
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = "123";
+        info.activityInfo.name = "321";
+        final View view = mLayoutInflater
+                .inflate(R.layout.settings_entity_header, null /* root */);
+        when(mActivity.getApplicationContext()).thenReturn(mContext);
+
+        mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
+        mController.setEditZenRuleNameListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                // do nothing
+            }
+        });
+        mController.setButtonActions(
+                EntityHeaderController.ActionType.ACTION_DND_RULE_PREFERENCE,
+                EntityHeaderController.ActionType.ACTION_NONE);
+        mController.done(mActivity);
+
+        final ImageButton button1 = view.findViewById(android.R.id.button1);
+        assertThat(button1.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(button1.getDrawable()).isNotNull();
+        assertThat(view.findViewById(android.R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void bindButton_noEditRuleNameClickListener_shouldNotShowButton() {
+        final ResolveInfo info = new ResolveInfo();
+        info.activityInfo = new ActivityInfo();
+        info.activityInfo.packageName = "123";
+        info.activityInfo.name = "321";
+        final View view = mLayoutInflater
+                .inflate(R.layout.settings_entity_header, null /* root */);
+        when(mActivity.getApplicationContext()).thenReturn(mContext);
+
+        mController = EntityHeaderController.newInstance(mActivity, mFragment, view);
+        mController.setButtonActions(
+                EntityHeaderController.ActionType.ACTION_DND_RULE_PREFERENCE,
+                EntityHeaderController.ActionType.ACTION_NONE);
+        mController.done(mActivity);
+
+        assertThat(view.findViewById(android.R.id.button1).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(view.findViewById(android.R.id.button2).getVisibility())
+                .isEqualTo(View.GONE);
+    }
+
+
+    @Test
     public void bindButton_noAppPref_shouldNotShowButton() {
         final View appLinks = mLayoutInflater
                 .inflate(R.layout.settings_entity_header, null /* root */);
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
index 63f89e6..84549a6 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java
@@ -22,9 +22,9 @@
 
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.widget.SwitchWidgetController;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
index 1708e36..82569c7 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
@@ -30,10 +30,10 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 4f77435..ca2cac0 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -65,7 +65,6 @@
 import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.LayoutPreference;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowBidiFormatter;
 import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper;
@@ -76,6 +75,7 @@
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settings.wifi.WifiDetailPreference;
 import com.android.settings.wrapper.ConnectivityManagerWrapper;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.wifi.AccessPoint;
 
diff --git a/tests/robotests/src/com/android/settings/TetherServiceTest.java b/tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
similarity index 72%
rename from tests/robotests/src/com/android/settings/TetherServiceTest.java
rename to tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
index 0275c15..583bd52 100644
--- a/tests/robotests/src/com/android/settings/TetherServiceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
@@ -13,17 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.settings;
+package com.android.settings.wifi.tether;
 
 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.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.net.wifi.WifiManager;
 
+import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import java.util.ArrayList;
@@ -87,4 +93,22 @@
         mService.cancelAlarmIfNecessary();
         verify(mContext).unregisterReceiver(any(HotspotOffReceiver.class));
     }
+
+    @Test
+    public void onDestroy_shouldUnregisterReceiver() {
+        final ArrayList<Integer> tethers = new ArrayList<>();
+        ReflectionHelpers.setField(mService, "mCurrentTethers", tethers);
+        ReflectionHelpers.setField(mService, "mBase", mContext);
+        final SharedPreferences prefs = mock(SharedPreferences .class);
+        final SharedPreferences.Editor editor = mock(SharedPreferences.Editor.class);
+        when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(prefs);
+        when(prefs.edit()).thenReturn(editor);
+        when(editor.putString(anyString(), anyString())).thenReturn(editor);
+        final HotspotOffReceiver hotspotOffReceiver = mock(HotspotOffReceiver.class);
+        mService.setHotspotOffReceiver(hotspotOffReceiver);
+
+        mService.onDestroy();
+
+        verify(hotspotOffReceiver).unregister();
+    }
 }
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index 86e8dc1..b16c700 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -26,6 +26,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArraySet;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableResources;
@@ -54,7 +55,10 @@
     public void controllersInSearchShouldImplementPreferenceControllerMixin() {
         final Set<String> errorClasses = new ArraySet<>();
 
-        for (Class clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
 
             final Indexable.SearchIndexProvider provider =
                     DatabaseIndexingUtils.getSearchIndexProvider(clazz);
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 36865a4..8fe2358 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -31,6 +31,7 @@
 import android.util.Log;
 import android.util.Xml;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
@@ -100,7 +101,10 @@
         final Set<String> uniqueKeys = new HashSet<>();
         final Set<String> nullKeyClasses = new HashSet<>();
         final Set<String> duplicatedKeys = new HashSet<>();
-        for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
             verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
         }
 
diff --git a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
index 7282f74..6d6f06c 100644
--- a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
+++ b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 import android.util.Xml;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableResources;
@@ -80,7 +81,10 @@
     @Test
     public void userRestrictionAttributeShouldBeValid()
             throws IOException, XmlPullParserException, Resources.NotFoundException {
-        for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+        final SearchIndexableResources resources =
+                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+                        .getSearchIndexableResources();
+        for (Class<?> clazz : resources.getProviderValues()) {
             verifyUserRestriction(clazz);
         }
     }
diff --git a/tests/unit/src/com/android/settings/TetherServiceTest.java b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
similarity index 98%
rename from tests/unit/src/com/android/settings/TetherServiceTest.java
rename to tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
index 899ea7a..7bf5798 100644
--- a/tests/unit/src/com/android/settings/TetherServiceTest.java
+++ b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.wifi.tether;
 
 import static org.junit.Assert.*;
 import static org.mockito.Matchers.*;
@@ -49,17 +49,13 @@
 import android.content.SharedPreferences.Editor;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
-import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.test.ServiceTestCase;
-import android.test.mock.MockResources;
 import android.util.Log;
 
-import com.android.settings.TetherService;
-
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;