Merge "Renamed Storage Access to Directory Access."
diff --git a/res/layout/suggestion_container.xml b/res/layout/suggestion_container.xml
index 2aa1043..e01a590 100644
--- a/res/layout/suggestion_container.xml
+++ b/res/layout/suggestion_container.xml
@@ -57,8 +57,6 @@
         android:layout_height="wrap_content"
         android:paddingTop="20dp"
         android:paddingBottom="16dp"
-        android:paddingStart="16dp"
-        android:paddingEnd="16dp"
         android:scrollbars="none"/>
 
 </LinearLayout>
diff --git a/res/layout/suggestion_tile_v2.xml b/res/layout/suggestion_tile_v2.xml
index e180897..27b3c34 100644
--- a/res/layout/suggestion_tile_v2.xml
+++ b/res/layout/suggestion_tile_v2.xml
@@ -21,7 +21,8 @@
     android:layout_width="328dp"
     android:layout_height="wrap_content"
     app:cardUseCompatPadding="true"
-    app:cardElevation="2dp">
+    app:cardElevation="2dp"
+    app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
 
     <LinearLayout
         android:layout_width="match_parent"
@@ -38,7 +39,7 @@
                 android:id="@android:id/icon"
                 android:layout_width="@dimen/dashboard_tile_image_size"
                 android:layout_height="@dimen/dashboard_tile_image_size"
-                android:layout_centerHorizontal = "true"
+                style="@style/SuggestionCardIcon"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="8dp" />
 
@@ -55,21 +56,23 @@
 
         <TextView
             android:id="@android:id/title"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
             android:singleLine="true"
-            android:layout_marginLeft="12dp"
-            android:layout_marginRight="12dp"
             android:textAppearance="@style/TextAppearance.TileTitle"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal" />
 
         <TextView
             android:id="@android:id/summary"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
             android:textAppearance="@style/TextAppearance.SuggestionSummary" />
 
     </LinearLayout>
diff --git a/res/layout/suggestion_tile_with_button_v2.xml b/res/layout/suggestion_tile_with_button_v2.xml
index 01be236..5f4ed18 100644
--- a/res/layout/suggestion_tile_with_button_v2.xml
+++ b/res/layout/suggestion_tile_with_button_v2.xml
@@ -21,14 +21,14 @@
     android:layout_width="328dp"
     android:layout_height="wrap_content"
     app:cardUseCompatPadding="true"
-    app:cardElevation="2dp">
+    app:cardElevation="2dp"
+    app:cardCornerRadius="@dimen/suggestion_card_corner_radius">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:minHeight="112dp"
-        android:orientation="vertical"
-        android:background="@android:color/white">
+        android:orientation="vertical">
 
         <RelativeLayout
             android:layout_width="match_parent"
@@ -39,7 +39,7 @@
                 android:id="@android:id/icon"
                 android:layout_width="@dimen/dashboard_tile_image_size"
                 android:layout_height="@dimen/dashboard_tile_image_size"
-                android:layout_centerHorizontal = "true"
+                style="@style/SuggestionCardIcon"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="8dp" />
 
@@ -56,9 +56,11 @@
 
         <TextView
             android:id="@android:id/title"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
             android:singleLine="true"
             android:textAppearance="@style/TextAppearance.TileTitle"
             android:ellipsize="marquee"
@@ -66,9 +68,11 @@
 
         <TextView
             android:id="@android:id/summary"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            style="@style/SuggestionCardText"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
             android:textAppearance="@style/TextAppearance.SuggestionSummary" />
 
         <Button
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f8205e3..339eaf2 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -300,11 +300,15 @@
     <dimen name="suggestion_condition_header_padding_collapsed">10dp</dimen>
     <dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
 
-    <!-- Suggestion cards-->
+    <!-- Suggestion cards size and padding -->
     <dimen name="suggestion_card_width_one_card">328dp</dimen>
     <dimen name="suggestion_card_width_two_cards">158dp</dimen>
     <dimen name="suggestion_card_width_multiple_cards">152dp</dimen>
-    <dimen name="suggestion_card_margin_end">12dp</dimen>
+    <dimen name="suggestion_card_outer_margin">16dp</dimen>
+    <dimen name="suggestion_card_inner_margin">12dp</dimen>
     <dimen name="suggestion_card_padding_bottom_one_card">16dp</dimen>
+    <dimen name="suggestion_card_corner_radius">2dp</dimen>
+    <dimen name="suggestion_card_title_padding_bottom_one_card">6dp</dimen>
+    <dimen name="suggestion_card_title_padding_bottom_multiple_cards">8dp</dimen>
 
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fabd32d..04c9235 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9198,4 +9198,11 @@
     <!-- Keywords for Directory Access settings -->
     <string name="keywords_directory_access">directory access</string>
 
+    <!-- Account type associated with the backup account. Empty for AOSP. [DO NOT TRANSLATE] -->
+    <string name="account_type"></string>
+    <!-- Package to target for Account credential confirmation. This will allow users to
+         remind/rediscover their backup account password prior to a reset. Empty for AOSP.
+         [DO NOT TRANSLATE] -->
+    <string name="account_confirmation_package"></string>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9555d5e..7764e74 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -323,6 +323,15 @@
         <item name="android:textColor">?android:attr/colorAccent</item>
     </style>
 
+    <style name="SuggestionCardText">
+        <item name="android:textAlignment">viewStart</item>
+    </style>
+
+    <style name="SuggestionCardIcon">
+        <item name="android:layout_centerHorizontal">false</item>
+        <item name="android:layout_alignParentStart">true</item>
+    </style>
+
     <style name="TextAppearance.SuggestionTitle"
            parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:fontFamily">sans-serif-medium</item>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 1daeb49..9d85ec9 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -203,11 +203,6 @@
             android:summary="@string/wifi_verbose_logging_summary"/>
 
         <SwitchPreference
-            android:key="wifi_allow_scan_with_traffic"
-            android:title="@string/wifi_allow_scan_with_traffic"
-            android:summary="@string/wifi_allow_scan_with_traffic_summary"/>
-
-        <SwitchPreference
             android:key="mobile_data_always_on"
             android:title="@string/mobile_data_always_on"
             android:summary="@string/mobile_data_always_on_summary"/>
diff --git a/res/xml/security_settings_v2.xml b/res/xml/security_settings_v2.xml
index 571e51f..dafd36c 100644
--- a/res/xml/security_settings_v2.xml
+++ b/res/xml/security_settings_v2.xml
@@ -158,14 +158,4 @@
         android:summary="@string/summary_placeholder"
         android:fragment="com.android.settings.security.ScreenPinningSettings" />
 
-    <Preference
-        android:order="90"
-        android:key="security_misc_usage_access"
-        android:title="@string/usage_access_title"
-        android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
-        <extra
-            android:name="classname"
-            android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
-    </Preference>
-
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 7a6f966..3cc722b 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -28,6 +28,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
@@ -39,6 +40,7 @@
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 import android.telephony.euicc.EuiccManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -74,6 +76,7 @@
     private static final String TAG = "MasterClear";
 
     private static final int KEYGUARD_REQUEST = 55;
+    private static final int CREDENTIAL_CONFIRM_REQUEST = 56;
 
     static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
     static final String ERASE_ESIMS_EXTRA = "erase_esim";
@@ -114,7 +117,7 @@
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
 
-        if (requestCode != KEYGUARD_REQUEST) {
+        if (requestCode != KEYGUARD_REQUEST || requestCode != CREDENTIAL_CONFIRM_REQUEST) {
             return;
         }
 
@@ -138,6 +141,33 @@
                 args, R.string.master_clear_confirm_title, null, null, 0);
     }
 
+    @VisibleForTesting
+    boolean tryShowAccountConfirmation() {
+        final Context context = getActivity();
+        final String accountType = context.getString(R.string.account_type);
+        final String packageName = context.getString(R.string.account_confirmation_package);
+        if (TextUtils.isEmpty(accountType) || TextUtils.isEmpty(packageName)) {
+            return false;
+        }
+        final AccountManager am = AccountManager.get(context);
+        Account[] accounts = am.getAccountsByType(accountType);
+        if (accounts != null && accounts.length > 0) {
+            final Intent requestAccountConfirmation = new Intent()
+                .setPackage(packageName)
+                .setAction("android.accounts.action.PRE_FACTORY_RESET");
+            // Check to make sure that the intent is supported.
+            final PackageManager pm = context.getPackageManager();
+            final List<ResolveInfo> resolutions =
+                pm.queryIntentActivities(requestAccountConfirmation, 0);
+            if (resolutions != null && resolutions.size() > 0) {
+                getActivity().startActivityForResult(
+                    requestAccountConfirmation, CREDENTIAL_CONFIRM_REQUEST);
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * If the user clicks to begin the reset sequence, we next require a
      * keyguard confirmation if the user has currently enabled one.  If there
@@ -158,7 +188,10 @@
                             .setAction(Intent.ACTION_FACTORY_RESET);
                     context.startActivity(requestFactoryReset);
                 }
-            } else if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
+                return;
+            }
+
+            if (!tryShowAccountConfirmation() && !runKeyguardConfirmation(KEYGUARD_REQUEST)) {
                 showFinalConfirmation();
             }
         }
diff --git a/src/com/android/settings/dashboard/DashboardAdapterV2.java b/src/com/android/settings/dashboard/DashboardAdapterV2.java
index cc511c5..a422ae4 100644
--- a/src/com/android/settings/dashboard/DashboardAdapterV2.java
+++ b/src/com/android/settings/dashboard/DashboardAdapterV2.java
@@ -305,7 +305,8 @@
     void onBindSuggestion(final SuggestionContainerHolder holder, int position) {
         // If there is suggestions to show, it will be at position 0 as we don't show the suggestion
         // header anymore.
-        final List<Suggestion> suggestions = mDashboardData.getSuggestions();
+        final List<Suggestion> suggestions =
+            (List<Suggestion>) mDashboardData.getItemEntityByPosition(position);
         final int suggestionCount = suggestions.size();
         if (suggestions != null && suggestionCount > 0) {
             holder.summary.setText(""+suggestionCount);
diff --git a/src/com/android/settings/dashboard/SiteMapManager.java b/src/com/android/settings/dashboard/SiteMapManager.java
deleted file mode 100644
index b54e061..0000000
--- a/src/com/android/settings/dashboard/SiteMapManager.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.dashboard;
-
-import static android.provider.SearchIndexablesContract.SITE_MAP_COLUMNS;
-import static com.android.settings.dashboard.DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.provider.SearchIndexablesContract.SiteMapColumns;
-import android.support.annotation.VisibleForTesting;
-import android.support.annotation.WorkerThread;
-import android.support.v4.util.ArrayMap;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.settings.SettingsActivity;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.IndexDatabaseHelper;
-import com.android.settings.search.IndexDatabaseHelper.IndexColumns;
-import com.android.settingslib.drawer.DashboardCategory;
-import com.android.settingslib.drawer.Tile;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A manager class that maintains a "site map" and look up breadcrumb for a certain page on demand.
- * <p/>
- * The methods on this class can only be called on a background thread.
- */
-public class SiteMapManager {
-
-    private static final String TAG = "SiteMapManager";
-    private static final boolean DEBUG_TIMING = false;
-
-    private static final String[] CLASS_TO_SCREEN_TITLE_COLUMNS = {
-            IndexColumns.CLASS_NAME,
-            IndexColumns.SCREEN_TITLE,
-    };
-
-    private final List<SiteMapPair> mPairs = new ArrayList<>();
-
-    private boolean mInitialized;
-
-    /**
-     * Given a fragment class name and its screen title, build a breadcrumb from Settings root to
-     * this screen.
-     * <p/>
-     * Not all screens have a full breadcrumb path leading up to root, it's because either some
-     * page in the breadcrumb path is not indexed, or it's only reachable via search.
-     */
-    @WorkerThread
-    public synchronized List<String> buildBreadCrumb(Context context, String clazz,
-            String screenTitle) {
-        init(context);
-        final long startTime = System.currentTimeMillis();
-        final List<String> breadcrumbs = new ArrayList<>();
-        if (!mInitialized) {
-            Log.w(TAG, "SiteMap is not initialized yet, skipping");
-            return breadcrumbs;
-        }
-        breadcrumbs.add(screenTitle);
-        String currentClass = clazz;
-        String currentTitle = screenTitle;
-        // Look up current page's parent, if found add it to breadcrumb string list, and repeat.
-        while (true) {
-            final SiteMapPair pair = lookUpParent(currentClass, currentTitle);
-            if (pair == null) {
-                if (DEBUG_TIMING) {
-                    Log.d(TAG, "BreadCrumb timing: " + (System.currentTimeMillis() - startTime));
-                }
-                return breadcrumbs;
-            }
-            breadcrumbs.add(0, pair.parentTitle);
-            currentClass = pair.parentClass;
-            currentTitle = pair.parentTitle;
-        }
-    }
-
-    /**
-     * Initialize a list of {@link SiteMapPair}s. Each pair knows about a single parent-child
-     * page relationship.
-     *
-     * We get the knowledge of such mPairs from 2 sources:
-     * 1. Static indexing time: we know which page(s) a parent can open by parsing its pref xml.
-     * 2. IA: We know from {@link DashboardFeatureProvider} which page can be dynamically
-     * injected to where.
-     */
-    @VisibleForTesting
-    @WorkerThread
-    synchronized void init(Context context) {
-        if (mInitialized) {
-            // Make sure only init once.
-            return;
-        }
-        final long startTime = System.currentTimeMillis();
-        // First load site map from static index table.
-        final Context appContext = context.getApplicationContext();
-        final SQLiteDatabase db = IndexDatabaseHelper.getInstance(appContext).getReadableDatabase();
-        Cursor sitemap = db.query(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, SITE_MAP_COLUMNS, null,
-                null, null, null, null);
-        while (sitemap.moveToNext()) {
-            final SiteMapPair pair = new SiteMapPair(
-                    sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_CLASS)),
-                    sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_TITLE)),
-                    sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_CLASS)),
-                    sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_TITLE)));
-            mPairs.add(pair);
-        }
-        sitemap.close();
-
-        // Then prepare a local map that contains class name -> screen title mapping. This is needed
-        // to figure out the display name for any fragment if it's injected dynamically through IA.
-        final Map<String, String> classToTitleMap = new ArrayMap<>();
-        final Cursor titleQuery = db.query(IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX,
-                CLASS_TO_SCREEN_TITLE_COLUMNS, null, null, null, null, null);
-        while (titleQuery.moveToNext()) {
-            classToTitleMap.put(
-                    titleQuery.getString(titleQuery.getColumnIndex(IndexColumns.CLASS_NAME)),
-                    titleQuery.getString(titleQuery.getColumnIndex(IndexColumns.SCREEN_TITLE)));
-        }
-        titleQuery.close();
-
-        // Loop through all IA categories and pages and build additional SiteMapPairs
-        List<DashboardCategory> categories = FeatureFactory.getFactory(context)
-                .getDashboardFeatureProvider(context).getAllCategories();
-
-        for (DashboardCategory category : categories) {
-            // Find the category key first.
-            final String parentClass = CATEGORY_KEY_TO_PARENT_MAP.get(category.key);
-            if (parentClass == null) {
-                continue;
-            }
-            // Use the key to look up parent (which page hosts this key)
-            final String parentName = classToTitleMap.get(parentClass);
-            if (parentName == null) {
-                continue;
-            }
-            // Build parent-child mPairs for all children listed under this key.
-            for (Tile tile : category.getTiles()) {
-                final String childTitle = tile.title.toString();
-                String childClass = null;
-                if (tile.metaData != null) {
-                    childClass = tile.metaData.getString(
-                            SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
-                }
-                if (childClass == null) {
-                    continue;
-                }
-                mPairs.add(new SiteMapPair(parentClass, parentName, childClass, childTitle));
-            }
-        }
-        // Done.
-        mInitialized = true;
-        if (DEBUG_TIMING) {
-            Log.d(TAG, "Init timing: " + (System.currentTimeMillis() - startTime));
-        }
-    }
-
-    @WorkerThread
-    private SiteMapPair lookUpParent(String clazz, String title) {
-        for (SiteMapPair pair : mPairs) {
-            if (TextUtils.equals(pair.childClass, clazz)
-                    && TextUtils.equals(title, pair.childTitle)) {
-                return pair;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Data model for a parent-child page pair.
-     */
-    private static class SiteMapPair {
-        public final String parentClass;
-        public final String parentTitle;
-        public final String childClass;
-        public final String childTitle;
-
-        public SiteMapPair(String parentClass, String parentTitle, String childClass,
-                String childTitle) {
-            this.parentClass = parentClass;
-            this.parentTitle = parentTitle;
-            this.childClass = childClass;
-            this.childTitle = childTitle;
-        }
-    }
-}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
index 89c731f..afd0e08 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
@@ -56,10 +56,7 @@
     private final ArrayList<String> mSuggestionsShownLogged;
     private final SuggestionControllerMixin mSuggestionControllerMixin;
     private final Callback mCallback;
-    private final int mMultipleCardsMarginEnd;
-    private final int mWidthSingleCard;
-    private final int mWidthTwoCards;
-    private final int mWidthMultipleCards;
+    private final CardConfig mConfig;
 
     private List<Suggestion> mSuggestions;
 
@@ -89,13 +86,7 @@
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
-
-        final Resources res = mContext.getResources();
-        mMultipleCardsMarginEnd = res.getDimensionPixelOffset(R.dimen.suggestion_card_margin_end);
-        mWidthSingleCard = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_one_card);
-        mWidthTwoCards = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_two_cards);
-        mWidthMultipleCards =
-            res.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards);
+        mConfig = CardConfig.get(context);
 
         setHasStableIds(true);
     }
@@ -116,7 +107,7 @@
                     mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, id);
             mSuggestionsShownLogged.add(id);
         }
-        setCardWidthAndMargin(holder, suggestionCount);
+        mConfig.setCardLayout(holder, suggestionCount, position);
         holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
         holder.title.setText(suggestion.getTitle());
         holder.title.setSingleLine(suggestionCount == 1);
@@ -220,12 +211,61 @@
         return mSuggestions;
     }
 
-    private void setCardWidthAndMargin(DashboardItemHolder holder, int suggestionCount) {
-        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
-            suggestionCount == 1
-                ? mWidthSingleCard : suggestionCount == 2 ? mWidthTwoCards : mWidthMultipleCards,
-            LinearLayout.LayoutParams.WRAP_CONTENT);
-        params.setMarginEnd(suggestionCount == 1 ? 0 : mMultipleCardsMarginEnd);
-        holder.itemView.setLayoutParams(params);
+    private static class CardConfig {
+        // Card start/end margin
+        private final int mMarginInner;
+        private final int mMarginOuter;
+        // Card width for different numbers of cards
+        private final int mWidthSingleCard;
+        private final int mWidthTwoCards;
+        private final int mWidthMultipleCards;
+        // padding between icon and title
+        private final int mPaddingTitleTopSingleCard;
+        private final int mPaddingTitleTopMultipleCards;
+
+        private static CardConfig sConfig;
+
+        private CardConfig(Context context) {
+            final Resources res = context.getResources();
+            mMarginInner =
+                res.getDimensionPixelOffset(R.dimen.suggestion_card_inner_margin);
+            mMarginOuter =
+                res.getDimensionPixelOffset(R.dimen.suggestion_card_outer_margin);
+            mWidthSingleCard = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_one_card);
+            mWidthTwoCards = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_two_cards);
+            mWidthMultipleCards =
+                res.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards);
+            mPaddingTitleTopSingleCard =
+                res.getDimensionPixelOffset(R.dimen.suggestion_card_title_padding_bottom_one_card);
+            mPaddingTitleTopMultipleCards = res.getDimensionPixelOffset(
+                R.dimen.suggestion_card_title_padding_bottom_multiple_cards);
+        }
+
+        public static CardConfig get(Context context) {
+            if (sConfig == null) {
+                sConfig = new CardConfig(context);
+            }
+            return sConfig;
+        }
+
+        private void setCardLayout(DashboardItemHolder holder, int suggestionCount,
+            int position) {
+            final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+                suggestionCount == 1
+                    ? mWidthSingleCard : suggestionCount == 2
+                    ? mWidthTwoCards : mWidthMultipleCards,
+                LinearLayout.LayoutParams.WRAP_CONTENT);
+            if (suggestionCount == 1) {
+                params.setMarginStart(mMarginOuter);
+                params.setMarginEnd(mMarginOuter);
+            } else {
+                params.setMarginStart(
+                    position == 0 ? mMarginOuter : mMarginInner);
+                params.setMarginEnd(position == suggestionCount - 1 ? mMarginOuter : 0);
+            }
+            holder.itemView.setLayoutParams(params);
+        }
+
     }
+
 }
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index 041a81f..ff568c7 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -204,6 +204,10 @@
         public void onRestrictBackgroundChanged(final boolean isDataSaving) throws RemoteException {
             ThreadUtils.postOnMainThread(() -> handleRestrictBackgroundChanged(isDataSaving));
         }
+
+        @Override
+        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) {
+        }
     };
 
     public interface Listener {
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 5cd80c9..0420ecf 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -398,7 +398,6 @@
         controllers.add(new CameraLaserSensorPreferenceController(context));
         controllers.add(new WifiDisplayCertificationPreferenceController(context));
         controllers.add(new WifiVerboseLoggingPreferenceController(context));
-        controllers.add(new WifiRoamScansPreferenceController(context));
         controllers.add(new MobileDataAlwaysOnPreferenceController(context));
         controllers.add(new TetheringHardwareAccelPreferenceController(context));
         controllers.add(new SelectUsbConfigPreferenceController(context, lifecycle));
diff --git a/src/com/android/settings/development/WifiRoamScansPreferenceController.java b/src/com/android/settings/development/WifiRoamScansPreferenceController.java
deleted file mode 100644
index b3ff400..0000000
--- a/src/com/android/settings/development/WifiRoamScansPreferenceController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.DeveloperOptionsPreferenceController;
-
-public class WifiRoamScansPreferenceController extends
-        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
-        PreferenceControllerMixin {
-
-    private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
-
-    @VisibleForTesting
-    static final int SETTING_VALUE_ON = 1;
-    @VisibleForTesting
-    static final int SETTING_VALUE_OFF = 0;
-
-    private final WifiManager mWifiManager;
-    private SwitchPreference mPreference;
-
-    public WifiRoamScansPreferenceController(Context context) {
-        super(context);
-
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-
-        mPreference = (SwitchPreference) screen.findPreference(getPreferenceKey());
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean isEnabled = (Boolean) newValue;
-        mWifiManager.setAllowScansWithTraffic(isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
-        return true;
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        final boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
-        mPreference.setChecked(enabled);
-    }
-
-    @Override
-    protected void onDeveloperOptionsSwitchEnabled() {
-        mPreference.setEnabled(true);
-    }
-
-    @Override
-    protected void onDeveloperOptionsSwitchDisabled() {
-        mWifiManager.setAllowScansWithTraffic(SETTING_VALUE_OFF);
-        mPreference.setEnabled(false);
-        mPreference.setChecked(false);
-    }
-}
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java
new file mode 100644
index 0000000..a13df25
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDatabaseHelper.java
@@ -0,0 +1,114 @@
+/*
+ * 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.batterytip;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+
+/**
+ * Database controls the anomaly logging(e.g. packageName, anomalyType and time)
+ */
+public class AnomalyDatabaseHelper extends SQLiteOpenHelper {
+    private static final String TAG = "BatteryDatabaseHelper";
+
+    private static final String DATABASE_NAME = "battery_settings.db";
+    private static final int DATABASE_VERSION = 1;
+
+    public interface Tables {
+        String TABLE_ANOMALY = "anomaly";
+    }
+
+    public interface AnomalyColumns {
+        /**
+         * The package name of the anomaly app
+         */
+        String PACKAGE_NAME = "package_name";
+        /**
+         * The type of the anomaly app
+         * @see Anomaly.AnomalyType
+         */
+        String ANOMALY_TYPE = "anomaly_type";
+        /**
+         * The time when anomaly happens
+         */
+        String TIME_STAMP_MS = "time_stamp_ms";
+    }
+
+    private static final String CREATE_ANOMALY_TABLE =
+            "CREATE TABLE " + Tables.TABLE_ANOMALY +
+                    "(" +
+                    AnomalyColumns.PACKAGE_NAME +
+                    " TEXT, " +
+                    AnomalyColumns.ANOMALY_TYPE +
+                    " INTEGER, " +
+                    AnomalyColumns.TIME_STAMP_MS +
+                    " INTEGER)";
+
+    private static AnomalyDatabaseHelper sSingleton;
+
+    public static synchronized AnomalyDatabaseHelper getInstance(Context context) {
+        if (sSingleton == null) {
+            sSingleton = new AnomalyDatabaseHelper(context.getApplicationContext());
+        }
+        return sSingleton;
+    }
+
+    private AnomalyDatabaseHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        bootstrapDB(db);
+    }
+
+    private void bootstrapDB(SQLiteDatabase db) {
+        db.execSQL(CREATE_ANOMALY_TABLE);
+        Log.i(TAG, "Bootstrapped database");
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        if (oldVersion < DATABASE_VERSION) {
+            Log.w(TAG, "Detected schema version '" + oldVersion + "'. " +
+                    "Index needs to be rebuilt for schema version '" + newVersion + "'.");
+            // We need to drop the tables and recreate them
+            reconstruct(db);
+        }
+    }
+
+    @Override
+    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        Log.w(TAG, "Detected schema version '" + oldVersion + "'. " +
+                "Index needs to be rebuilt for schema version '" + newVersion + "'.");
+        // We need to drop the tables and recreate them
+        reconstruct(db);
+    }
+
+    public void reconstruct(SQLiteDatabase db) {
+        dropTables(db);
+        bootstrapDB(db);
+    }
+
+    private void dropTables(SQLiteDatabase db) {
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_ANOMALY);
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batterytip/AppInfo.java b/src/com/android/settings/fuelgauge/batterytip/AppInfo.java
new file mode 100644
index 0000000..1daff36
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/AppInfo.java
@@ -0,0 +1,101 @@
+/*
+ * 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.batterytip;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+
+/**
+ * Model class stores app info(e.g. package name, type..) that used in battery tip
+ */
+public class AppInfo implements Comparable<AppInfo>, Parcelable {
+    public final String packageName;
+    /**
+     * Anomaly type of the app
+     * @see Anomaly.AnomalyType
+     */
+    public final int anomalyType;
+    public final long screenOnTimeMs;
+
+    private AppInfo(AppInfo.Builder builder) {
+        packageName = builder.mPackageName;
+        anomalyType = builder.mAnomalyType;
+        screenOnTimeMs = builder.mScreenOnTimeMs;
+    }
+
+    @VisibleForTesting
+    AppInfo(Parcel in) {
+        packageName = in.readString();
+        anomalyType = in.readInt();
+        screenOnTimeMs = in.readLong();
+    }
+
+    @Override
+    public int compareTo(AppInfo o) {
+        return Long.compare(screenOnTimeMs, o.screenOnTimeMs);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(packageName);
+        dest.writeInt(anomalyType);
+        dest.writeLong(screenOnTimeMs);
+    }
+
+    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+        public AppInfo createFromParcel(Parcel in) {
+            return new AppInfo(in);
+        }
+
+        public AppInfo[] newArray(int size) {
+            return new AppInfo[size];
+        }
+    };
+
+    public static final class Builder {
+        private int mAnomalyType;
+        private String mPackageName;
+        private long mScreenOnTimeMs;
+
+        public Builder setAnomalyType(int type) {
+            mAnomalyType = type;
+            return this;
+        }
+
+        public Builder setPackageName(String packageName) {
+            mPackageName = packageName;
+            return this;
+        }
+
+        public Builder setScreenOnTimeMs(long screenOnTimeMs) {
+            mScreenOnTimeMs = screenOnTimeMs;
+            return this;
+        }
+
+        public AppInfo build() {
+            return new AppInfo(this);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java
new file mode 100644
index 0000000..f87501f
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryDatabaseManager.java
@@ -0,0 +1,93 @@
+/*
+ * 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.batterytip;
+
+import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
+        .PACKAGE_NAME;
+import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
+        .ANOMALY_TYPE;
+import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
+        .TIME_STAMP_MS;
+import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.Tables.TABLE_ANOMALY;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Database manager for battery data. Now it only contains anomaly data stored in {@link AppInfo}.
+ */
+public class BatteryDatabaseManager {
+    private final AnomalyDatabaseHelper mDatabaseHelper;
+
+    public BatteryDatabaseManager(Context context) {
+        mDatabaseHelper = AnomalyDatabaseHelper.getInstance(context);
+    }
+
+    /**
+     * Insert an anomaly log to database.
+     *
+     * @param packageName the package name of the app
+     * @param type        the type of the anomaly
+     * @param timestampMs the time when it is happened
+     */
+    public void insertAnomaly(String packageName, int type, long timestampMs) {
+        try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
+            ContentValues values = new ContentValues();
+            values.put(PACKAGE_NAME, packageName);
+            values.put(ANOMALY_TYPE, type);
+            values.put(TIME_STAMP_MS, timestampMs);
+
+            db.insert(TABLE_ANOMALY, null, values);
+        }
+    }
+
+    /**
+     * Query all the anomalies that happened after {@code timestampMs}.
+     */
+    public List<AppInfo> queryAllAnomaliesAfter(long timestampMs) {
+        final List<AppInfo> appInfos = new ArrayList<>();
+        try (SQLiteDatabase db = mDatabaseHelper.getReadableDatabase()) {
+            final String[] projection = {PACKAGE_NAME, ANOMALY_TYPE};
+            final String orderBy = AnomalyDatabaseHelper.AnomalyColumns.TIME_STAMP_MS + " DESC";
+
+            try (Cursor cursor = db.query(TABLE_ANOMALY, projection, TIME_STAMP_MS + " > ?",
+                    new String[]{String.valueOf(timestampMs)}, null, null, orderBy)) {
+                while (cursor.moveToNext()) {
+                    AppInfo appInfo = new AppInfo.Builder()
+                            .setPackageName(cursor.getString(cursor.getColumnIndex(PACKAGE_NAME)))
+                            .setAnomalyType(cursor.getInt(cursor.getColumnIndex(ANOMALY_TYPE)))
+                            .build();
+                    appInfos.add(appInfo);
+                }
+            }
+        }
+
+        return appInfos;
+    }
+
+    public void deleteAllAnomaliesBeforeTimeStamp(long timestampMs) {
+        try (SQLiteDatabase db = mDatabaseHelper.getWritableDatabase()) {
+            db.delete(TABLE_ANOMALY, TIME_STAMP_MS + " < ?",
+                    new String[]{String.valueOf(timestampMs)});
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
index 942c42b..b51474d 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
@@ -28,6 +28,7 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController.BatteryTipListener;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
@@ -78,7 +79,8 @@
 
                 return new AlertDialog.Builder(context)
                         .setMessage(getString(R.string.battery_tip_dialog_message,
-                                highUsageTip.getScreenTimeMs()))
+                                Utils.formatElapsedTime(context, highUsageTip.getScreenTimeMs(),
+                                        false /* withSeconds */)))
                         .setView(view)
                         .setPositiveButton(android.R.string.ok, null)
                         .create();
diff --git a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
index 8b74394..60aa6c8 100644
--- a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
+++ b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
@@ -39,7 +39,7 @@
     private final Context mContext;
     private final IconDrawableFactory mIconDrawableFactory;
     private final PackageManager mPackageManager;
-    private final List<HighUsageApp> mHighUsageAppList;
+    private final List<AppInfo> mHighUsageAppList;
 
     public static class ViewHolder extends RecyclerView.ViewHolder {
         public View view;
@@ -56,7 +56,7 @@
         }
     }
 
-    public HighUsageAdapter(Context context, List<HighUsageApp> highUsageAppList) {
+    public HighUsageAdapter(Context context, List<AppInfo> highUsageAppList) {
         mContext = context;
         mHighUsageAppList = highUsageAppList;
         mIconDrawableFactory = IconDrawableFactory.newInstance(context);
@@ -72,7 +72,7 @@
 
     @Override
     public void onBindViewHolder(ViewHolder holder, int position) {
-        final HighUsageApp app = mHighUsageAppList.get(position);
+        final AppInfo app = mHighUsageAppList.get(position);
         holder.appIcon.setImageDrawable(
                 Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, app.packageName,
                         UserHandle.myUserId()));
diff --git a/src/com/android/settings/fuelgauge/batterytip/HighUsageApp.java b/src/com/android/settings/fuelgauge/batterytip/HighUsageApp.java
deleted file mode 100644
index f75ecf0..0000000
--- a/src/com/android/settings/fuelgauge/batterytip/HighUsageApp.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.batterytip;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Class representing app with high screen usage
- */
-public class HighUsageApp implements Comparable<HighUsageApp>, Parcelable {
-    public final String packageName;
-    public final long screenOnTimeMs;
-
-    public HighUsageApp(String packageName, long screenOnTimeMs) {
-        this.packageName = packageName;
-        this.screenOnTimeMs = screenOnTimeMs;
-    }
-
-    private HighUsageApp(Parcel in) {
-        packageName = in.readString();
-        screenOnTimeMs = in.readLong();
-    }
-
-    @Override
-    public int compareTo(HighUsageApp o) {
-        return Long.compare(screenOnTimeMs, o.screenOnTimeMs);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(packageName);
-        dest.writeLong(screenOnTimeMs);
-    }
-
-    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-        public HighUsageApp createFromParcel(Parcel in) {
-            return new HighUsageApp(in);
-        }
-
-        public HighUsageApp[] newArray(int size) {
-            return new HighUsageApp[size];
-        }
-    };
-}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
index 237f430..3c69667 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
@@ -23,13 +23,11 @@
 
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.Utils;
 import com.android.settings.fuelgauge.BatteryUtils;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
-import com.android.settings.fuelgauge.batterytip.HighUsageApp;
+import com.android.settings.fuelgauge.batterytip.AppInfo;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
-import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -42,7 +40,7 @@
 public class HighUsageDetector implements BatteryTipDetector {
     private BatteryTipPolicy mPolicy;
     private BatteryStatsHelper mBatteryStatsHelper;
-    private List<HighUsageApp> mHighUsageAppList;
+    private List<AppInfo> mHighUsageAppList;
     private Context mContext;
     @VisibleForTesting
     BatteryUtils mBatteryUtils;
@@ -68,9 +66,10 @@
                     final long foregroundTimeMs = mBatteryUtils.getProcessTimeMs(
                             BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
                             BatteryStats.STATS_SINCE_CHARGED);
-                    mHighUsageAppList.add(new HighUsageApp(
-                            mBatteryUtils.getPackageName(batterySipper.getUid()),
-                            foregroundTimeMs));
+                    mHighUsageAppList.add(new AppInfo.Builder()
+                            .setPackageName(mBatteryUtils.getPackageName(batterySipper.getUid()))
+                            .setScreenOnTimeMs(foregroundTimeMs)
+                            .build());
                 }
             }
 
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTip.java
index 0316832..2aabf98 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTip.java
@@ -23,7 +23,7 @@
 
 import com.android.settings.R;
 import com.android.settings.Utils;
-import com.android.settings.fuelgauge.batterytip.HighUsageApp;
+import com.android.settings.fuelgauge.batterytip.AppInfo;
 
 import java.util.List;
 
@@ -34,9 +34,9 @@
 
     private final long mScreenTimeMs;
     @VisibleForTesting
-    final List<HighUsageApp> mHighUsageAppList;
+    final List<AppInfo> mHighUsageAppList;
 
-    public HighUsageTip(long screenTimeMs, List<HighUsageApp> appList) {
+    public HighUsageTip(long screenTimeMs, List<AppInfo> appList) {
         super(TipType.HIGH_DEVICE_USAGE, appList.isEmpty() ? StateType.INVISIBLE : StateType.NEW,
                 true /* showDialog */);
         mScreenTimeMs = screenTimeMs;
@@ -47,7 +47,7 @@
     HighUsageTip(Parcel in) {
         super(in);
         mScreenTimeMs = in.readLong();
-        mHighUsageAppList = in.createTypedArrayList(HighUsageApp.CREATOR);
+        mHighUsageAppList = in.createTypedArrayList(AppInfo.CREATOR);
     }
 
     @Override
@@ -82,7 +82,7 @@
         return mScreenTimeMs;
     }
 
-    public List<HighUsageApp> getHighUsageAppList() {
+    public List<AppInfo> getHighUsageAppList() {
         return mHighUsageAppList;
     }
 
diff --git a/src/com/android/settings/search/CursorToSearchResultConverter.java b/src/com/android/settings/search/CursorToSearchResultConverter.java
index 8528c56..8e5577d 100644
--- a/src/com/android/settings/search/CursorToSearchResultConverter.java
+++ b/src/com/android/settings/search/CursorToSearchResultConverter.java
@@ -17,6 +17,9 @@
 
 package com.android.settings.search;
 
+import static com.android.settings.search.DatabaseResultLoader.BASE_RANKS;
+import static com.android.settings.search.SearchResult.TOP_RANK;
+
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
@@ -26,18 +29,12 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.settings.dashboard.SiteMapManager;
-
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static com.android.settings.search.DatabaseResultLoader.BASE_RANKS;
-import static com.android.settings.search.SearchResult.TOP_RANK;
-
 /**
  * Controller to Build search results from {@link Cursor} Objects.
  *
@@ -94,8 +91,7 @@
         mContext = context;
     }
 
-    public Set<SearchResult> convertCursor(SiteMapManager sitemapManager,
-            Cursor cursorResults, int baseRank) {
+    public Set<SearchResult> convertCursor(Cursor cursorResults, int baseRank) {
         if (cursorResults == null) {
             return null;
         }
@@ -103,8 +99,8 @@
         final Set<SearchResult> results = new HashSet<>();
 
         while (cursorResults.moveToNext()) {
-            SearchResult result = buildSingleSearchResultFromCursor(sitemapManager,
-                    contextMap, cursorResults, baseRank);
+            SearchResult result = buildSingleSearchResultFromCursor(contextMap, cursorResults,
+                    baseRank);
             if (result != null) {
                 results.add(result);
             }
@@ -132,8 +128,8 @@
         return null;
     }
 
-    private SearchResult buildSingleSearchResultFromCursor(SiteMapManager sitemapManager,
-            Map<String, Context> contextMap, Cursor cursor, int baseRank) {
+    private SearchResult buildSingleSearchResultFromCursor(Map<String, Context> contextMap,
+            Cursor cursor, int baseRank) {
         final int docId = cursor.getInt(COLUMN_INDEX_ID);
         final String pkgName = cursor.getString(COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE);
         final String title = cursor.getString(COLUMN_INDEX_TITLE);
@@ -145,14 +141,12 @@
         final byte[] marshalledPayload = cursor.getBlob(COLUMN_INDEX_PAYLOAD);
         final ResultPayload payload = getUnmarshalledPayload(marshalledPayload, payloadType);
 
-        final List<String> breadcrumbs = getBreadcrumbs(sitemapManager, cursor);
         final int rank = getRank(title, baseRank, key);
 
         final SearchResult.Builder builder = new SearchResult.Builder()
                 .setStableId(docId)
                 .setTitle(title)
                 .setSummary(summaryOn)
-                .addBreadcrumbs(breadcrumbs)
                 .setRank(rank)
                 .setIcon(getIconForPackage(contextMap, pkgName, className, iconResStr))
                 .setPayload(payload);
@@ -191,12 +185,6 @@
         return icon;
     }
 
-    private List<String> getBreadcrumbs(SiteMapManager siteMapManager, Cursor cursor) {
-        final String screenTitle = cursor.getString(COLUMN_INDEX_SCREEN_TITLE);
-        final String screenClass = cursor.getString(COLUMN_INDEX_CLASS_NAME);
-        return siteMapManager == null ? null : siteMapManager.buildBreadCrumb(mContext, screenClass,
-                screenTitle);
-    }
 
     /** Uses the breadcrumbs to determine the offset to the base rank.
      *  There are three checks
diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java
index 0aeda66..7b9a635 100644
--- a/src/com/android/settings/search/DatabaseIndexingManager.java
+++ b/src/com/android/settings/search/DatabaseIndexingManager.java
@@ -19,7 +19,8 @@
 
 
 import static com.android.settings.search.CursorToSearchResultConverter.COLUMN_INDEX_ID;
-import static com.android.settings.search.CursorToSearchResultConverter.COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE;
+import static com.android.settings.search.CursorToSearchResultConverter
+        .COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE;
 import static com.android.settings.search.CursorToSearchResultConverter.COLUMN_INDEX_KEY;
 import static com.android.settings.search.DatabaseResultLoader.SELECT_COLUMNS;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
@@ -27,7 +28,8 @@
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEY_REF;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns
+        .DATA_SUMMARY_ON_NORMALIZED;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DOCID;
@@ -50,7 +52,6 @@
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.provider.SearchIndexablesContract;
 import android.provider.SearchIndexablesContract.SiteMapColumns;
@@ -58,7 +59,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.indexing.IndexData;
 import com.android.settings.search.indexing.IndexDataConverter;
 import com.android.settings.search.indexing.PreIndexData;
@@ -68,7 +68,6 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Consumes the SearchIndexableProvider content providers.
@@ -80,15 +79,6 @@
 
     private static final String LOG_TAG = "DatabaseIndexingManager";
 
-    private static final String METRICS_ACTION_SETTINGS_ASYNC_INDEX =
-            "search_asynchronous_indexing";
-
-    public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
-            "SEARCH_INDEX_DATA_PROVIDER";
-
-    @VisibleForTesting
-    final AtomicBoolean mIsIndexingComplete = new AtomicBoolean(false);
-
     private PreIndexDataCollector mCollector;
     private IndexDataConverter mConverter;
 
@@ -98,15 +88,6 @@
         mContext = context;
     }
 
-    public boolean isIndexingComplete() {
-        return mIsIndexingComplete.get();
-    }
-
-    public void indexDatabase(IndexingCallback callback) {
-        IndexingTask task = new IndexingTask(callback);
-        task.execute();
-    }
-
     /**
      * Accumulate all data and non-indexable keys from each of the content-providers.
      * Only the first indexing for the default language gets static search results - subsequent
@@ -363,39 +344,4 @@
             return null;
         }
     }
-
-    public class IndexingTask extends AsyncTask<Void, Void, Void> {
-
-        @VisibleForTesting
-        IndexingCallback mCallback;
-        private long mIndexStartTime;
-
-        public IndexingTask(IndexingCallback callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        protected void onPreExecute() {
-            mIndexStartTime = System.currentTimeMillis();
-            mIsIndexingComplete.set(false);
-        }
-
-        @Override
-        protected Void doInBackground(Void... voids) {
-            performIndexing();
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Void aVoid) {
-            int indexingTime = (int) (System.currentTimeMillis() - mIndexStartTime);
-            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
-                    .histogram(mContext, METRICS_ACTION_SETTINGS_ASYNC_INDEX, indexingTime);
-
-            mIsIndexingComplete.set(true);
-            if (mCallback != null) {
-                mCallback.onIndexingFinished();
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/src/com/android/settings/search/IndexingCallback.java b/src/com/android/settings/search/IndexingCallback.java
deleted file mode 100644
index b4b6eab..0000000
--- a/src/com/android/settings/search/IndexingCallback.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.android.settings.search;
-
-/**
- * Callback for Settings search indexing.
- */
-public interface IndexingCallback {
-
-    /**
-     * Called when Indexing is finished.
-     */
-    void onIndexingFinished();
-}
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 76da18e..878bbfd 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -23,11 +23,8 @@
 import android.content.Intent;
 import android.widget.Toolbar;
 
-import com.android.settings.dashboard.SiteMapManager;
 import com.android.settings.overlay.FeatureFactory;
 
-import java.util.concurrent.ExecutorService;
-
 /**
  * FeatureProvider for Settings Search
  */
@@ -45,27 +42,12 @@
             throws SecurityException, IllegalArgumentException;
 
     /**
-     * Returns the manager for looking up breadcrumbs.
-     */
-    SiteMapManager getSiteMapManager();
-
-    /**
      * Synchronously updates the Settings database.
      */
     void updateIndex(Context context);
 
     DatabaseIndexingManager getIndexingManager(Context context);
 
-    /**
-     * @returns true when indexing is complete.
-     */
-    boolean isIndexingComplete(Context context);
-
-    /**
-     * @return a {@link ExecutorService} to be shared between search tasks.
-     */
-    ExecutorService getExecutorService();
-
     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 d17c033..ccd4ff1 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -22,13 +22,10 @@
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.dashboard.SiteMapManager;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.indexing.IndexData;
 
 import java.util.Locale;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
 /**
  * FeatureProvider for the refactored search code.
@@ -39,8 +36,6 @@
 
     private static final String METRICS_ACTION_SETTINGS_INDEX = "search_synchronous_indexing";
     private DatabaseIndexingManager mDatabaseIndexingManager;
-    private SiteMapManager mSiteMapManager;
-    private ExecutorService mExecutorService;
 
     @Override
     public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
@@ -69,18 +64,6 @@
     }
 
     @Override
-    public boolean isIndexingComplete(Context context) {
-        return getIndexingManager(context).isIndexingComplete();
-    }
-
-    public SiteMapManager getSiteMapManager() {
-        if (mSiteMapManager == null) {
-            mSiteMapManager = new SiteMapManager();
-        }
-        return mSiteMapManager;
-    }
-
-    @Override
     public void updateIndex(Context context) {
         long indexStartTime = System.currentTimeMillis();
         getIndexingManager(context).performIndexing();
@@ -89,14 +72,6 @@
                 .histogram(context, METRICS_ACTION_SETTINGS_INDEX, indexingTime);
     }
 
-    @Override
-    public ExecutorService getExecutorService() {
-        if (mExecutorService == null) {
-            mExecutorService = Executors.newCachedThreadPool();
-        }
-        return mExecutorService;
-    }
-
     protected boolean isSignatureWhitelisted(Context context, String callerPackage) {
         return false;
     }
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 838b1e8..361bc8f 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -160,6 +160,13 @@
         assertThat(componentName.getPackageName()).isEqualTo(intent.getPackage());
     }
 
+    @Test
+    public void testTryShowAccountConfirmation_unsupported() {
+      doReturn(mActivity).when(mMasterClear).getActivity();
+      /* Using the default resources, account confirmation shouldn't trigger */
+      assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
+    }
+
     private void initScrollView(int height, int scrollY, int childBottom) {
         when(mScrollView.getHeight()).thenReturn(height);
         when(mScrollView.getScrollY()).thenReturn(scrollY);
diff --git a/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java
deleted file mode 100644
index 60e5e49..0000000
--- a/tests/robotests/src/com/android/settings/development/WifiRoamScansPreferenceControllerTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class WifiRoamScansPreferenceControllerTest {
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private WifiManager mWifiManager;
-    @Mock
-    private SwitchPreference mPreference;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-
-    private WifiRoamScansPreferenceController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
-        mController = new WifiRoamScansPreferenceController(mContext);
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
-                mPreference);
-        mController.displayPreference(mPreferenceScreen);
-    }
-
-    @Test
-    public void onPreferenceChange_shouldEnableRoamScanning() {
-        mController.onPreferenceChange(mPreference, true /* new value */);
-
-        verify(mWifiManager).setAllowScansWithTraffic(
-                WifiRoamScansPreferenceController.SETTING_VALUE_ON);
-    }
-
-    @Test
-    public void onPreferenceChange_shouldDisableRoamScanning() {
-        mController.onPreferenceChange(mPreference, false /* new value */);
-
-        verify(mWifiManager).setAllowScansWithTraffic(
-                WifiRoamScansPreferenceController.SETTING_VALUE_OFF);
-    }
-
-    @Test
-    public void updateState_shouldEnablePreference() {
-        when(mWifiManager.getAllowScansWithTraffic()).thenReturn(1);
-        mController.updateState(mPreference);
-
-        verify(mPreference).setChecked(true);
-    }
-
-    @Test
-    public void updateState_shouldDisablePreference() {
-        when(mWifiManager.getAllowScansWithTraffic()).thenReturn(0);
-        mController.updateState(mPreference);
-
-        verify(mPreference).setChecked(false);
-    }
-
-    @Test
-    public void onDeveloperOptionsSwitchEnabled_shouldEnablePreference() {
-        mController.onDeveloperOptionsSwitchEnabled();
-
-        verify(mPreference).setEnabled(true);
-    }
-
-    @Test
-    public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
-        mController.onDeveloperOptionsSwitchDisabled();
-
-        verify(mWifiManager).setAllowScansWithTraffic(
-                WifiRoamScansPreferenceController.SETTING_VALUE_OFF);
-        verify(mPreference).setEnabled(false);
-        verify(mPreference).setChecked(false);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java
new file mode 100644
index 0000000..ac8800e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDatabaseManagerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.spy;
+
+import android.content.Context;
+import android.text.format.DateUtils;
+
+import com.android.settings.TestConfig;
+import com.android.settings.fuelgauge.batterytip.AppInfo;
+import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
+import com.android.settings.testutils.DatabaseTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BatteryDatabaseManagerTest {
+    private static String PACKAGE_NAME_NEW = "com.android.app1";
+    private static int TYPE_NEW = 1;
+    private static String PACKAGE_NAME_OLD = "com.android.app2";
+    private static int TYPE_OLD = 2;
+    private static long NOW = System.currentTimeMillis();
+    private static long ONE_DAY_BEFORE = NOW - DateUtils.DAY_IN_MILLIS;
+    private static long TWO_DAYS_BEFORE = NOW - 2 * DateUtils.DAY_IN_MILLIS;
+    private Context mContext;
+    private BatteryDatabaseManager mBatteryDatabaseManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+        mBatteryDatabaseManager = spy(new BatteryDatabaseManager(mContext));
+    }
+
+    @After
+    public void cleanUp() {
+        DatabaseTestUtils.clearDb(mContext);
+    }
+
+    @Test
+    public void testAllFunctions() {
+        mBatteryDatabaseManager.insertAnomaly(PACKAGE_NAME_NEW, TYPE_NEW, NOW);
+        mBatteryDatabaseManager.insertAnomaly(PACKAGE_NAME_OLD, TYPE_OLD, TWO_DAYS_BEFORE);
+
+        // In database, it contains two record
+        List<AppInfo> totalAppInfos = mBatteryDatabaseManager.queryAllAnomaliesAfter(0);
+        assertThat(totalAppInfos).hasSize(2);
+        verifyAppInfo(totalAppInfos.get(0), PACKAGE_NAME_NEW, TYPE_NEW);
+        verifyAppInfo(totalAppInfos.get(1), PACKAGE_NAME_OLD, TYPE_OLD);
+
+        // Only one record shows up if we query by timestamp
+        List<AppInfo> appInfos = mBatteryDatabaseManager.queryAllAnomaliesAfter(ONE_DAY_BEFORE);
+        assertThat(appInfos).hasSize(1);
+        verifyAppInfo(appInfos.get(0), PACKAGE_NAME_NEW, TYPE_NEW);
+
+        mBatteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp(ONE_DAY_BEFORE);
+
+        // The obsolete record is removed from database
+        List<AppInfo> appInfos1 = mBatteryDatabaseManager.queryAllAnomaliesAfter(0);
+        assertThat(appInfos1).hasSize(1);
+        verifyAppInfo(appInfos1.get(0), PACKAGE_NAME_NEW, TYPE_NEW);
+
+    }
+
+    private void verifyAppInfo(final AppInfo appInfo, String packageName, int type) {
+        assertThat(appInfo.packageName).isEqualTo(packageName);
+        assertThat(appInfo.anomalyType).isEqualTo(type);
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java
new file mode 100644
index 0000000..16b45df
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.batterytip;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.text.format.DateUtils;
+
+import com.android.settings.TestConfig;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AppInfoTest {
+    private static final String PACKAGE_NAME = "com.android.app";
+    private static final int ANOMALY_TYPE = Anomaly.AnomalyType.WAKE_LOCK;
+    private static final long SCREEN_TIME_MS = DateUtils.HOUR_IN_MILLIS;
+
+    private AppInfo mAppInfo;
+
+    @Before
+    public void setUp() {
+        mAppInfo = new AppInfo.Builder()
+                .setPackageName(PACKAGE_NAME)
+                .setAnomalyType(ANOMALY_TYPE)
+                .setScreenOnTimeMs(SCREEN_TIME_MS)
+                .build();
+    }
+
+    @Test
+    public void testParcel() {
+        Parcel parcel = Parcel.obtain();
+        mAppInfo.writeToParcel(parcel, mAppInfo.describeContents());
+        parcel.setDataPosition(0);
+
+        final AppInfo appInfo = new AppInfo(parcel);
+
+        assertThat(appInfo.packageName).isEqualTo(PACKAGE_NAME);
+        assertThat(appInfo.anomalyType).isEqualTo(ANOMALY_TYPE);
+        assertThat(appInfo.screenOnTimeMs).isEqualTo(SCREEN_TIME_MS);
+    }
+
+    @Test
+    public void testCompareTo_hasCorrectOrder() {
+        final AppInfo appInfo = new AppInfo.Builder()
+                .setPackageName(PACKAGE_NAME)
+                .setAnomalyType(ANOMALY_TYPE)
+                .setScreenOnTimeMs(SCREEN_TIME_MS + 100)
+                .build();
+
+        List<AppInfo> appInfos = new ArrayList<>();
+        appInfos.add(appInfo);
+        appInfos.add(mAppInfo);
+
+        Collections.sort(appInfos);
+        assertThat(appInfos.get(0).screenOnTimeMs).isLessThan(appInfos.get(1).screenOnTimeMs);
+    }
+
+    @Test
+    public void testBuilder() {
+        assertThat(mAppInfo.packageName).isEqualTo(PACKAGE_NAME);
+        assertThat(mAppInfo.anomalyType).isEqualTo(ANOMALY_TYPE);
+        assertThat(mAppInfo.screenOnTimeMs).isEqualTo(SCREEN_TIME_MS);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
new file mode 100644
index 0000000..ddee314
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.batterytip;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.text.format.DateUtils;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowRuntimePermissionPresenter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowAlertDialog;
+import org.robolectric.shadows.ShadowDialog;
+import org.robolectric.util.FragmentTestUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+        shadows = ShadowRuntimePermissionPresenter.class)
+public class BatteryTipDialogFragmentTest {
+    private static final String PACKAGE_NAME = "com.android.app";
+    private static final long SCREEN_TIME_MS = DateUtils.HOUR_IN_MILLIS;
+
+    private BatteryTipDialogFragment mDialogFragment;
+    private Context mContext;
+    private HighUsageTip mHighUsageTip;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        FakeFeatureFactory.setupForTest();
+
+        List<AppInfo> highUsageTips = new ArrayList<>();
+        highUsageTips.add(new AppInfo.Builder().setScreenOnTimeMs(SCREEN_TIME_MS).setPackageName(
+                PACKAGE_NAME).build());
+        mHighUsageTip = new HighUsageTip(SCREEN_TIME_MS, highUsageTips);
+    }
+
+    @Test
+    public void testOnCreateDialog_highUsageTip_fireHighUsageDialog() {
+        mDialogFragment = BatteryTipDialogFragment.newInstance(mHighUsageTip);
+
+        FragmentTestUtil.startFragment(mDialogFragment);
+
+        final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
+        ShadowAlertDialog shadowDialog = shadowOf(dialog);
+
+        assertThat(shadowDialog.getMessage()).isEqualTo(
+                mContext.getString(R.string.battery_tip_dialog_message, "1h"));
+    }
+
+
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTipTest.java
index e2f8a26..0689778 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/HighUsageTipTest.java
@@ -22,7 +22,7 @@
 import android.text.format.DateUtils;
 
 import com.android.settings.TestConfig;
-import com.android.settings.fuelgauge.batterytip.HighUsageApp;
+import com.android.settings.fuelgauge.batterytip.AppInfo;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
@@ -42,14 +42,17 @@
 
     private Context mContext;
     private HighUsageTip mBatteryTip;
-    private List<HighUsageApp> mUsageAppList;
+    private List<AppInfo> mUsageAppList;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
 
         mUsageAppList = new ArrayList<>();
-        mUsageAppList.add(new HighUsageApp(PACKAGE_NAME, SCREEN_TIME));
+        mUsageAppList.add(new AppInfo.Builder()
+                .setPackageName(PACKAGE_NAME)
+                .setScreenOnTimeMs(SCREEN_TIME)
+                .build());
         mBatteryTip = new HighUsageTip(SCREEN_TIME, mUsageAppList);
     }
 
@@ -67,7 +70,7 @@
         assertThat(parcelTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
         assertThat(parcelTip.getScreenTimeMs()).isEqualTo(SCREEN_TIME);
         assertThat(parcelTip.mHighUsageAppList.size()).isEqualTo(1);
-        final HighUsageApp app = parcelTip.mHighUsageAppList.get(0);
+        final AppInfo app = parcelTip.mHighUsageAppList.get(0);
         assertThat(app.packageName).isEqualTo(PACKAGE_NAME);
         assertThat(app.screenOnTimeMs).isEqualTo(SCREEN_TIME);
     }
diff --git a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java
index cd62c15..a1cafc5 100644
--- a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java
+++ b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java
@@ -29,7 +29,6 @@
 import com.android.settings.DisplaySettings;
 import com.android.settings.R;
 import com.android.settings.TestConfig;
-import com.android.settings.dashboard.SiteMapManager;
 import com.android.settings.gestures.SwipeToNotificationSettings;
 import com.android.settings.search.ResultPayload.Availability;
 import com.android.settings.search.ResultPayload.PayloadType;
@@ -40,8 +39,6 @@
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
@@ -69,8 +66,6 @@
         sIntent = new Intent("com.android.settings");
     }
 
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private SiteMapManager mSiteMapManager;
     private Drawable mDrawable;
     private CursorToSearchResultConverter mConverter;
 
@@ -83,52 +78,11 @@
     }
 
     @Test
-    public void testParseNullResults_ReturnsNull() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, null, BASE_RANK);
-        assertThat(results).isNull();
-    }
-
-    @Test
-    public void testParseCursor_NotNull() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
-        assertThat(results).isNotNull();
-    }
-
-    @Test
-    public void testParseCursor_MatchesRank() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
-        for (SearchResult result : results) {
-            assertThat(result.rank).isEqualTo(BASE_RANK);
-        }
-    }
-
-    @Test
-    public void testParseCursor_MatchesTitle() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
-        for (SearchResult result : results) {
-            assertThat(TITLES).contains(result.title);
-        }
-    }
-
-    @Test
-    public void testParseCursor_MatchesSummary() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
-        for (SearchResult result : results) {
-            assertThat(result.summary).isEqualTo(SUMMARY);
-        }
-    }
-
-    @Test
     public void testParseCursor_MatchesIcon() {
         final MatrixCursor cursor = new MatrixCursor(DatabaseResultLoader.SELECT_COLUMNS);
         final byte[] payload = ResultPayloadUtils.marshall(new ResultPayload(sIntent));
         final String BLANK = "";
-        cursor.addRow(new Object[]{
+        cursor.addRow(new Object[] {
                 KEY.hashCode(),      // Doc ID
                 "Longer than 20 characters", // Title
                 SUMMARY, // Summary on
@@ -144,8 +98,7 @@
                 payload     // Payload
         });
 
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, cursor, BASE_RANK);
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             Drawable resultDrawable = result.icon;
@@ -157,7 +110,7 @@
     @Test
     public void testParseCursor_NoIcon() {
         final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor("noIcon" /* key */, "" /* className */), BASE_RANK);
+                getDummyCursor("noIcon" /* key */, "" /* className */), BASE_RANK);
         for (SearchResult result : results) {
             assertThat(result.icon).isNull();
         }
@@ -165,8 +118,7 @@
 
     @Test
     public void testParseCursor_MatchesPayloadType() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
+        final Set<SearchResult> results = mConverter.convertCursor(getDummyCursor(), BASE_RANK);
         ResultPayload payload;
         for (SearchResult result : results) {
             payload = result.payload;
@@ -179,7 +131,7 @@
         final MatrixCursor cursor = new MatrixCursor(DatabaseResultLoader.SELECT_COLUMNS);
         final byte[] payload = ResultPayloadUtils.marshall(new ResultPayload(sIntent));
         final String BLANK = "";
-        cursor.addRow(new Object[]{
+        cursor.addRow(new Object[] {
                 KEY.hashCode(),      // Doc ID
                 "Longer than 20 characters", // Title
                 SUMMARY, // Summary on
@@ -194,8 +146,7 @@
                 PayloadType.INTENT,       // Payload Type
                 payload     // Payload
         });
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(BASE_RANK + 1);
         }
@@ -203,8 +154,7 @@
 
     @Test
     public void testParseCursor_MatchesResultPayload() {
-        final Set<SearchResult> results = mConverter.convertCursor(
-                mSiteMapManager, getDummyCursor(), BASE_RANK);
+        final Set<SearchResult> results = mConverter.convertCursor(getDummyCursor(), BASE_RANK);
         ResultPayload payload;
         for (SearchResult result : results) {
             payload = result.payload;
@@ -228,7 +178,7 @@
         final InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, 1 /* onValue */,
                 intent, true /* isDeviceSupported */, 0 /* defautValue */);
 
-        cursor.addRow(new Object[]{
+        cursor.addRow(new Object[] {
                 KEY.hashCode(),      // Doc ID
                 TITLES.get(0), // Title
                 SUMMARY, // Summary on
@@ -243,8 +193,7 @@
                 type,    // Payload Type
                 ResultPayloadUtils.marshall(payload) // Payload
         });
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             final InlineSwitchPayload newPayload = (InlineSwitchPayload) result.payload;
@@ -264,9 +213,8 @@
     @Test
     public void testWifiKey_PrioritizedResult() {
         final String key = "main_toggle_wifi";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -276,9 +224,8 @@
     @Test
     public void testBluetoothKey_PrioritizedResult() {
         final String key = "main_toggle_bluetooth";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -288,8 +235,8 @@
     @Test
     public void testAirplaneKey_PrioritizedResult() {
         final String key = "toggle_airplane";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor, BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
         }
@@ -298,9 +245,8 @@
     @Test
     public void testHotspotKey_PrioritizedResult() {
         final String key = "tether_settings";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -310,9 +256,8 @@
     @Test
     public void testBatterySaverKey_PrioritizedResult() {
         final String key = "battery_saver";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -322,9 +267,8 @@
     @Test
     public void testNFCKey_PrioritizedResult() {
         final String key = "toggle_nfc";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -334,9 +278,8 @@
     @Test
     public void testDataSaverKey_PrioritizedResult() {
         final String key = "restrict_background";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
@@ -346,9 +289,8 @@
     @Test
     public void testDataUsageKey_PrioritizedResult() {
         final String key = "data_usage_enable";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
         }
@@ -357,9 +299,8 @@
     @Test
     public void testRoamingKey_PrioritizedResult() {
         final String key = "button_roaming_key";
-        final Cursor cursor = getDummyCursor(key,  WifiSettings.class.getName());
-        final Set<SearchResult> results = mConverter.convertCursor(mSiteMapManager, cursor,
-                BASE_RANK);
+        final Cursor cursor = getDummyCursor(key, WifiSettings.class.getName());
+        final Set<SearchResult> results = mConverter.convertCursor(cursor, BASE_RANK);
 
         for (SearchResult result : results) {
             assertThat(result.rank).isEqualTo(SearchResult.TOP_RANK);
diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java
index 464e9d3..2687041 100644
--- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java
+++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java
@@ -23,9 +23,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyList;
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -55,7 +53,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
@@ -166,33 +163,6 @@
         assertThat(columnNames).containsAllIn(expColumnNames);
     }
 
-    // Tests for the flow: IndexOneRaw -> UpdateOneRowWithFilteredData -> UpdateOneRow
-
-    @Test
-    public void testAddResource_withChildFragment_shouldUpdateSiteMapDb() {
-        // FIXME: This test was failing. (count = 6 at the end)
-
-//        SearchIndexableResource resource = getFakeResource(R.xml.network_and_internet);
-//        mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
-//                new HashMap<>());
-//        Cursor query = mDb.query(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, SITE_MAP_COLUMNS,
-//                null, null, null, null, null);
-//        query.moveToPosition(-1);
-//        int count = 0;
-//        while (query.moveToNext()) {
-//            count++;
-//            assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_CLASS)))
-//                    .isEqualTo(className);
-//            assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_TITLE)))
-//                    .isEqualTo(mContext.getString(R.string.network_dashboard_title));
-//            assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_CLASS)))
-//                    .isNotEmpty();
-//            assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_TITLE)))
-//                    .isNotEmpty();
-//        }
-//        assertThat(count).isEqualTo(5);
-    }
-
     // Test new public indexing flow
 
     @Test
@@ -363,31 +333,6 @@
         assertThat(cursor.getString(2)).isEqualTo(TITLE_ONE);
     }
 
-    @Test
-    public void testUpdateAsyncTask_onPostExecute_performsCallback() {
-        IndexingCallback callback = mock(IndexingCallback.class);
-
-        DatabaseIndexingManager.IndexingTask task = mManager.new IndexingTask(callback);
-        task.execute();
-
-        Robolectric.flushForegroundThreadScheduler();
-
-        verify(callback).onIndexingFinished();
-    }
-
-    @Test
-    public void testUpdateAsyncTask_onPostExecute_setsIndexingComplete() {
-        SearchFeatureProviderImpl provider = new SearchFeatureProviderImpl();
-        DatabaseIndexingManager manager = spy(provider.getIndexingManager(mContext));
-        DatabaseIndexingManager.IndexingTask task = manager.new IndexingTask(null);
-        doNothing().when(manager).performIndexing();
-
-        task.execute();
-        Robolectric.flushForegroundThreadScheduler();
-
-        assertThat(provider.isIndexingComplete(mContext)).isTrue();
-    }
-
     // Util functions
 
     private SearchIndexableRaw getFakeRaw() {
diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
index 9584e42..aa35f9f 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
@@ -27,7 +27,6 @@
 import android.widget.Toolbar;
 
 import com.android.settings.TestConfig;
-import com.android.settings.dashboard.SiteMapManager;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 
@@ -61,14 +60,6 @@
     }
 
     @Test
-    public void getSiteMapManager_shouldCacheInstance() {
-        final SiteMapManager manager1 = mProvider.getSiteMapManager();
-        final SiteMapManager manager2 = mProvider.getSiteMapManager();
-
-        assertThat(manager1).isSameAs(manager2);
-    }
-
-    @Test
     public void initSearchToolbar_shouldInitWithOnClickListener() {
         mProvider.initSearchToolbar(mActivity, null);
         // Should not crash.
diff --git a/tests/robotests/src/com/android/settings/testutils/DatabaseTestUtils.java b/tests/robotests/src/com/android/settings/testutils/DatabaseTestUtils.java
index 11e740a..499a2f7 100644
--- a/tests/robotests/src/com/android/settings/testutils/DatabaseTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/DatabaseTestUtils.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 
+import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
 import com.android.settings.search.IndexDatabaseHelper;
 import com.android.settings.slices.SlicesDatabaseHelper;
 
@@ -28,6 +29,7 @@
     public static void clearDb(Context context) {
         clearSearchDb(context);
         clearSlicesDb(context);
+        clearAnomalyDb(context);
     }
 
     private static void clearSlicesDb(Context context) {
@@ -45,6 +47,21 @@
         }
     }
 
+    private static void clearAnomalyDb(Context context) {
+        AnomalyDatabaseHelper helper = AnomalyDatabaseHelper.getInstance(context);
+        helper.close();
+
+        Field instance;
+        Class clazz = AnomalyDatabaseHelper.class;
+        try {
+            instance = clazz.getDeclaredField("sSingleton");
+            instance.setAccessible(true);
+            instance.set(null, null);
+        } catch (Exception e) {
+            throw new RuntimeException();
+        }
+    }
+
     private static void clearSearchDb(Context context) {
         IndexDatabaseHelper helper = IndexDatabaseHelper.getInstance(context);
         helper.close();