Merge "Update wakelock detector" into oc-dr1-dev
diff --git a/res/drawable/ic_settings_night_display.xml b/res/drawable/ic_settings_night_display.xml
index 7f161e2..178b131 100644
--- a/res/drawable/ic_settings_night_display.xml
+++ b/res/drawable/ic_settings_night_display.xml
@@ -16,12 +16,10 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
     android:tint="?android:attr/colorControlNormal">
-
     <path
         android:fillColor="#FFF"
-        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
+        android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z" />
+</vector>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2bbcbc4..774491f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1255,11 +1255,11 @@
     <!-- Title of a dialog shown when the user only has one attempt left to provide the lock before the device, one of its users, or a work profile is wiped. [CHAR LIMIT=NONE] -->
     <string name="lock_last_attempt_before_wipe_warning_title">Your data will be deleted</string>
     <!-- Content of the dialog shown when the user only has one attempt left to provide the device lock pattern before the device is wiped. [CHAR LIMIT=NONE] -->
-    <string name="lock_last_pattern_attempt_before_wipe_device">If you enter an incorrect pattern on the next attempt, this device's data will be deleted</string>
+    <string name="lock_last_pattern_attempt_before_wipe_device">If you enter an incorrect pattern on the next attempt, this device\'s data will be deleted</string>
     <!-- Content of the dialog shown when the user only has one attempt left to provide the device lock PIN before the device is wiped. [CHAR LIMIT=NONE] -->
-    <string name="lock_last_pin_attempt_before_wipe_device">If you enter an incorrect PIN on the next attempt, this device's data will be deleted</string>
+    <string name="lock_last_pin_attempt_before_wipe_device">If you enter an incorrect PIN on the next attempt, this device\'s data will be deleted</string>
     <!-- Content of the dialog shown when the user only has one attempt left to provide the device lock password before the device is wiped. [CHAR LIMIT=NONE] -->
-    <string name="lock_last_password_attempt_before_wipe_device">If you enter an incorrect password on the next attempt, this device's data will be deleted</string>
+    <string name="lock_last_password_attempt_before_wipe_device">If you enter an incorrect password on the next attempt, this device\'s data will be deleted</string>
     <!-- Content of the dialog shown when the user only has one attempt left to provide the user lock pattern before the user is removed. [CHAR LIMIT=NONE] -->
     <string name="lock_last_pattern_attempt_before_wipe_user">If you enter an incorrect pattern on the next attempt, this user will be deleted</string>
     <!-- Content of the dialog shown when the user only has one attempt left to provide the user lock PIN before the user is removed. [CHAR LIMIT=NONE] -->
@@ -1274,7 +1274,7 @@
     <string name="lock_last_password_attempt_before_wipe_profile">If you enter an incorrect password on the next attempt, your work profile and its data will be deleted</string>
 
     <!-- Content of the dialog shown when the user has failed to provide the device lock too many times and the device is wiped. [CHAR LIMIT=NONE] -->
-    <string name="lock_failed_attempts_now_wiping_device">Too many incorrect attempts. This device's data will be deleted.</string>
+    <string name="lock_failed_attempts_now_wiping_device">Too many incorrect attempts. This device\'s data will be deleted.</string>
     <!-- Content of the dialog shown when the user has failed to provide the user lock too many times and the user is removed. [CHAR LIMIT=NONE] -->
     <string name="lock_failed_attempts_now_wiping_user">Too many incorrect attempts. This user will be deleted.</string>
     <!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is removed. [CHAR LIMIT=NONE] -->
diff --git a/res/xml/power_usage_detail.xml b/res/xml/power_usage_detail.xml
index b7865d2..aa1540d 100644
--- a/res/xml/power_usage_detail.xml
+++ b/res/xml/power_usage_detail.xml
@@ -29,6 +29,11 @@
         android:selectable="false"
         android:order="-9999"/>
 
+    <Preference
+        android:key="high_usage"
+        android:icon="@drawable/ic_battery_alert_24dp"
+        android:title="@string/power_high_usage_title"/>
+
     <PreferenceCategory
         android:title="@string/battery_detail_info_title">
 
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index e66463d..b3aacb2 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -1052,7 +1052,7 @@
                 BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
                 AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
                         this, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry,
-                        mBatteryPercent);
+                        mBatteryPercent, null /* mAnomalies */);
             } else {
                 AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
                         this, mPackageName);
diff --git a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
index 26b3427..e668812 100644
--- a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
@@ -28,9 +28,9 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
-import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
 import com.android.settings.password.SetupChooseLockGeneric;
+import com.android.settings.password.SetupSkipDialog;
 
 public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
 
@@ -98,9 +98,8 @@
             setResult(RESULT_SKIP);
             finish();
         } else {
-            SetupSkipDialog dialog = SetupSkipDialog.newInstance(
-                    getIntent().getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
-            dialog.show(getFragmentManager());
+            setResult(SetupSkipDialog.RESULT_SKIP);
+            finish();
         }
     }
 
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 016690c..0b1d4a8 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -17,9 +17,11 @@
 package com.android.settings.fuelgauge;
 
 import android.app.Activity;
+import android.app.LoaderManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Loader;
 import android.content.pm.PackageManager;
 import android.os.BatteryStats;
 import android.os.Bundle;
@@ -43,6 +45,10 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.enterprise.DevicePolicyManagerWrapper;
 import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment;
+import com.android.settings.fuelgauge.anomaly.AnomalyLoader;
+import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
@@ -55,10 +61,11 @@
  *
  * 1. Detail battery usage information for app(i.e. usage time, usage amount)
  * 2. Battery related controls for app(i.e uninstall, force stop)
- *
  */
 public class AdvancedPowerUsageDetail extends DashboardFragment implements
-        ButtonActionDialogFragment.AppButtonsDialogListener {
+        ButtonActionDialogFragment.AppButtonsDialogListener,
+        AnomalyDialogFragment.AnomalyDialogListener,
+        LoaderManager.LoaderCallbacks<List<Anomaly>> {
 
     public static final String TAG = "AdvancedPowerUsageDetail";
     public static final String EXTRA_UID = "extra_uid";
@@ -69,6 +76,7 @@
     public static final String EXTRA_ICON_ID = "extra_icon_id";
     public static final String EXTRA_POWER_USAGE_PERCENT = "extra_power_usage_percent";
     public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";
+    public static final String EXTRA_ANOMALY_LIST = "extra_anomaly_list";
 
     private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
     private static final String KEY_PREF_BACKGROUND = "app_usage_background";
@@ -78,6 +86,8 @@
     private static final int REQUEST_UNINSTALL = 0;
     private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
 
+    private static final int ANOMALY_LOADER = 0;
+
     @VisibleForTesting
     LayoutPreference mHeaderPreference;
     @VisibleForTesting
@@ -93,14 +103,19 @@
     Preference mBackgroundPreference;
     @VisibleForTesting
     Preference mPowerUsagePreference;
+    @VisibleForTesting
+    AnomalySummaryPreferenceController mAnomalySummaryPreferenceController;
     private AppButtonsPreferenceController mAppButtonsPreferenceController;
 
     private DevicePolicyManagerWrapper mDpm;
     private UserManager mUserManager;
     private PackageManager mPackageManager;
+    private List<Anomaly> mAnomalies;
+    private String mPackageName;
 
     public static void startBatteryDetailPage(SettingsActivity caller, PreferenceFragment fragment,
-            BatteryStatsHelper helper, int which, BatteryEntry entry, String usagePercent) {
+            BatteryStatsHelper helper, int which, BatteryEntry entry, String usagePercent,
+            List<Anomaly> anomalies) {
         // Initialize mStats if necessary.
         helper.getStats();
 
@@ -130,6 +145,7 @@
         args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs);
         args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent);
         args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah);
+        args.putParcelableList(EXTRA_ANOMALY_LIST, anomalies);
 
         caller.startPreferencePanelAsUser(fragment, AdvancedPowerUsageDetail.class.getName(), args,
                 R.string.battery_details_title, null,
@@ -162,14 +178,17 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        mPackageName = getArguments().getString(EXTRA_PACKAGE_NAME);
+        mAnomalySummaryPreferenceController = new AnomalySummaryPreferenceController(
+                (SettingsActivity) getActivity(), this, MetricsEvent.FUELGAUGE_POWER_USAGE_DETAIL);
         mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
         mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
         mPowerUsagePreference = findPreference(KEY_PREF_POWER_USAGE);
         mHeaderPreference = (LayoutPreference) findPreference(KEY_PREF_HEADER);
 
-        final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
-        if (packageName != null) {
-            mAppEntry = mState.getEntry(packageName, UserHandle.myUserId());
+        if (mPackageName != null) {
+            mAppEntry = mState.getEntry(mPackageName, UserHandle.myUserId());
+            initAnomalyInfo();
         }
     }
 
@@ -182,6 +201,16 @@
     }
 
     @VisibleForTesting
+    void initAnomalyInfo() {
+        mAnomalies = getArguments().getParcelableArrayList(EXTRA_ANOMALY_LIST);
+        if (mAnomalies == null) {
+            getLoaderManager().initLoader(ANOMALY_LOADER, Bundle.EMPTY, this);
+        } else if (mAnomalies != null){
+            mAnomalySummaryPreferenceController.updateAnomalySummaryPreference(mAnomalies);
+        }
+    }
+
+    @VisibleForTesting
     void initHeader() {
         final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header);
         final Activity context = getActivity();
@@ -235,6 +264,15 @@
     }
 
     @Override
+    public boolean onPreferenceTreeClick(Preference preference) {
+        if (TextUtils.equals(preference.getKey(), AnomalySummaryPreferenceController.ANOMALY_KEY)) {
+            mAnomalySummaryPreferenceController.onPreferenceTreeClick(preference);
+            return true;
+        }
+        return super.onPreferenceTreeClick(preference);
+    }
+
+    @Override
     public int getMetricsCategory() {
         return MetricsEvent.FUELGAUGE_POWER_USAGE_DETAIL;
     }
@@ -281,4 +319,24 @@
             mAppButtonsPreferenceController.handleDialogClick(id);
         }
     }
+
+    @Override
+    public void onAnomalyHandled(Anomaly anomaly) {
+        mAnomalySummaryPreferenceController.hideHighUsagePreference();
+    }
+
+    @Override
+    public Loader<List<Anomaly>> onCreateLoader(int id, Bundle args) {
+        return new AnomalyLoader(getContext(), mPackageName);
+    }
+
+    @Override
+    public void onLoadFinished(Loader<List<Anomaly>> loader, List<Anomaly> data) {
+        mAnomalySummaryPreferenceController.updateAnomalySummaryPreference(data);
+    }
+
+    @Override
+    public void onLoaderReset(Loader<List<Anomaly>> loader) {
+
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 1e4302a..0149e22 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -286,7 +286,8 @@
         PowerGaugePreference pgp = (PowerGaugePreference) preference;
         BatteryEntry entry = pgp.getInfo();
         AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
-                this, mStatsHelper, mStatsType, entry, pgp.getPercent());
+                this, mStatsHelper, mStatsType, entry, pgp.getPercent(),
+                mAnomalySparseArray.get(entry.sipper.getUid()));
         return super.onPreferenceTreeClick(preference);
     }
 
diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalySummaryPreferenceController.java b/src/com/android/settings/fuelgauge/anomaly/AnomalySummaryPreferenceController.java
index 23b4e77..47c2d2b 100644
--- a/src/com/android/settings/fuelgauge/anomaly/AnomalySummaryPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/anomaly/AnomalySummaryPreferenceController.java
@@ -32,8 +32,9 @@
  */
 public class AnomalySummaryPreferenceController {
     private static final String TAG = "HighUsagePreferenceController";
-    @VisibleForTesting
-    static final String ANOMALY_KEY = "high_usage";
+
+    public static final String ANOMALY_KEY = "high_usage";
+
     private static final int REQUEST_ANOMALY_ACTION = 0;
     private PreferenceFragment mFragment;
     @VisibleForTesting
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index d4bc076..b41a40f 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -201,7 +201,7 @@
         private String mFirstPin;
         private RecyclerView mPasswordRestrictionView;
         protected boolean mIsAlphaMode;
-        private Button mCancelButton;
+        protected Button mCancelButton;
         private Button mNextButton;
 
         private TextChangedHandler mTextChangedHandler;
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 4e73b87..179bd79 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -35,7 +35,6 @@
 import com.android.settings.SetupEncryptionInterstitial;
 import com.android.settings.SetupWizardUtils;
 import com.android.settings.fingerprint.SetupFingerprintEnrollFindSensor;
-import com.android.settings.fingerprint.SetupSkipDialog;
 import com.android.settings.utils.SettingsDividerItemDecoration;
 import com.android.setupwizardlib.GlifPreferenceLayout;
 
diff --git a/src/com/android/settings/password/SetupChooseLockPassword.java b/src/com/android/settings/password/SetupChooseLockPassword.java
index 0c62c7c..bd935a2 100644
--- a/src/com/android/settings/password/SetupChooseLockPassword.java
+++ b/src/com/android/settings/password/SetupChooseLockPassword.java
@@ -84,6 +84,9 @@
         @Override
         public void onViewCreated(View view, Bundle savedInstanceState) {
             super.onViewCreated(view, savedInstanceState);
+
+            mCancelButton.setText(R.string.skip_label);
+
             boolean showOptionsButton = getActivity().getIntent().getBooleanExtra(
                     ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
             if (showOptionsButton) {
@@ -99,6 +102,12 @@
                 case R.id.screen_lock_options:
                     launchChooseLockGeneric();
                     break;
+                case R.id.cancel_button:
+                    SetupSkipDialog dialog = SetupSkipDialog.newInstance(
+                            getActivity().getIntent()
+                                    .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
+                    dialog.show(getFragmentManager());
+                    break;
                 default:
                     super.onClick(v);
             }
diff --git a/src/com/android/settings/fingerprint/SetupSkipDialog.java b/src/com/android/settings/password/SetupSkipDialog.java
similarity index 94%
rename from src/com/android/settings/fingerprint/SetupSkipDialog.java
rename to src/com/android/settings/password/SetupSkipDialog.java
index 842e69c..36646b7 100644
--- a/src/com/android/settings/fingerprint/SetupSkipDialog.java
+++ b/src/com/android/settings/password/SetupSkipDialog.java
@@ -14,12 +14,11 @@
  * limitations under the License
  */
 
-package com.android.settings.fingerprint;
+package com.android.settings.password;
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.app.FragmentManager;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -36,7 +35,7 @@
 
     private static final String ARG_FRP_SUPPORTED = "frp_supported";
     private static final String TAG_SKIP_DIALOG = "skip_dialog";
-    private static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10;
+    public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10;
 
     public static SetupSkipDialog newInstance(boolean isFrpSupported) {
         SetupSkipDialog dialog = new SetupSkipDialog();
diff --git a/src/com/android/settings/search/AppSearchResult.java b/src/com/android/settings/search/AppSearchResult.java
index fcb83dc..b59e32e 100644
--- a/src/com/android/settings/search/AppSearchResult.java
+++ b/src/com/android/settings/search/AppSearchResult.java
@@ -18,6 +18,7 @@
 package com.android.settings.search;
 
 import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
 
 public class AppSearchResult extends SearchResult {
     /**
@@ -30,6 +31,10 @@
         info = builder.mInfo;
     }
 
+    public UserHandle getAppUserHandle() {
+        return new UserHandle(UserHandle.getUserId(info.uid));
+    }
+
     public static class Builder extends SearchResult.Builder {
         protected ApplicationInfo mInfo;
 
diff --git a/src/com/android/settings/search/InstalledAppResultLoader.java b/src/com/android/settings/search/InstalledAppResultLoader.java
index 81b96a1..70a39ee 100644
--- a/src/com/android/settings/search/InstalledAppResultLoader.java
+++ b/src/com/android/settings/search/InstalledAppResultLoader.java
@@ -40,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -99,7 +100,7 @@
 
                 final AppSearchResult.Builder builder = new AppSearchResult.Builder();
                 builder.setAppInfo(info)
-                        .setStableId(info.packageName.hashCode())
+                        .setStableId(Objects.hash(info.packageName, user.id))
                         .setTitle(info.loadLabel(pm))
                         .setRank(getRank(wordDiff))
                         .addBreadcrumbs(getBreadCrumb())
diff --git a/src/com/android/settings/search/IntentSearchViewHolder.java b/src/com/android/settings/search/IntentSearchViewHolder.java
index 11adaef..2722d56 100644
--- a/src/com/android/settings/search/IntentSearchViewHolder.java
+++ b/src/com/android/settings/search/IntentSearchViewHolder.java
@@ -16,9 +16,11 @@
  */
 package com.android.settings.search;
 
+import android.content.Intent;
+import android.os.UserHandle;
 import android.view.View;
 
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.logging.nano.MetricsProto;
 
 /**
  * ViewHolder for intent based search results.
@@ -32,7 +34,7 @@
 
     @Override
     public int getClickActionMetricName() {
-        return MetricsEvent.ACTION_CLICK_SETTINGS_SEARCH_RESULT;
+        return MetricsProto.MetricsEvent.ACTION_CLICK_SETTINGS_SEARCH_RESULT;
     }
 
     @Override
@@ -41,7 +43,15 @@
 
         itemView.setOnClickListener(v -> {
            fragment.onSearchResultClicked(this, result);
-           fragment.startActivity(result.payload.getIntent());
+            final Intent intent = result.payload.getIntent();
+            // Use app user id to support work profile use case.
+            if (result instanceof AppSearchResult) {
+                AppSearchResult appResult = (AppSearchResult) result;
+                UserHandle userHandle = appResult.getAppUserHandle();
+                fragment.getActivity().startActivityAsUser(intent, userHandle);
+            } else {
+                fragment.startActivity(intent);
+            }
         });
     }
 }
diff --git a/src/com/android/settings/search/SearchViewHolder.java b/src/com/android/settings/search/SearchViewHolder.java
index 72fd02320..ed72940 100644
--- a/src/com/android/settings/search/SearchViewHolder.java
+++ b/src/com/android/settings/search/SearchViewHolder.java
@@ -18,8 +18,11 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
+import android.util.IconDrawableFactory;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -46,6 +49,7 @@
 
     protected final MetricsFeatureProvider mMetricsFeatureProvider;
     protected final SearchFeatureProvider mSearchFeatureProvider;
+    private final IconDrawableFactory mIconDrawableFactory;
 
     public SearchViewHolder(View view) {
         super(view);
@@ -59,6 +63,7 @@
         breadcrumbView = view.findViewById(R.id.breadcrumb);
 
         mPlaceholderSummary = view.getContext().getString(R.string.summary_placeholder);
+        mIconDrawableFactory = IconDrawableFactory.newInstance(view.getContext());
     }
 
     public abstract int getClickActionMetricName();
@@ -78,7 +83,12 @@
         if (result instanceof AppSearchResult) {
             AppSearchResult appResult = (AppSearchResult) result;
             PackageManager pm = fragment.getActivity().getPackageManager();
-            iconView.setImageDrawable(appResult.info.loadIcon(pm));
+            UserHandle userHandle = appResult.getAppUserHandle();
+            Drawable badgedIcon =
+                    mIconDrawableFactory.getBadgedIcon(appResult.info, userHandle.getIdentifier());
+            iconView.setImageDrawable(badgedIcon);
+            titleView.setContentDescription(
+                    pm.getUserBadgedLabel(appResult.info.loadLabel(pm), userHandle));
         } else {
             // Valid even when result.icon is null.
             iconView.setImageDrawable(result.icon);
diff --git a/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java b/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java
new file mode 100644
index 0000000..78acc3e
--- /dev/null
+++ b/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.password;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.settings.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class SetupChooseLockPasswordAppTest {
+
+    @Rule
+    public ActivityTestRule<SetupChooseLockPassword> mActivityTestRule =
+            new ActivityTestRule<>(
+                    SetupChooseLockPassword.class,
+                    true /* enable touch at launch */,
+                    false /* don't launch at every test */);
+
+    @Test
+    public void testSkipDialogIsShown() throws Throwable {
+        SetupChooseLockPassword activity = mActivityTestRule.launchActivity(null);
+
+        onView(withId(R.id.cancel_button))
+                .check(matches(withText(R.string.skip_label)))
+                .check(matches(isDisplayed()))
+                .perform(click());
+        onView(withId(android.R.id.button1)).check(matches(isDisplayed())).perform(click());
+
+        assertThat(activity.isFinishing()).named("Is finishing").isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
new file mode 100644
index 0000000..9ee53ef
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.fingerprint;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.app.KeyguardManager;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.password.SetupSkipDialog;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowEventLogWriter;
+import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
+import com.android.settings.testutils.shadow.ShadowUserManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.shadows.ShadowKeyguardManager;
+import org.robolectric.util.ActivityController;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+        manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {
+                ShadowEventLogWriter.class,
+                ShadowLockPatternUtils.class,
+                ShadowUserManager.class
+        })
+public class SetupFingerprintEnrollIntroductionTest {
+
+    @Mock
+    private UserInfo mUserInfo;
+
+    private ActivityController<SetupFingerprintEnrollIntroduction> mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        final Intent intent = new Intent();
+        mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
+
+        ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
+    }
+
+    @Test
+    public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() {
+        getShadowKeyguardManager().setIsKeyguardSecure(false);
+
+        mController.create().resume();
+
+        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
+        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
+        skipButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
+        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
+        assertThat(shadowActivity.getResultCode()).named("Result code")
+                .isEqualTo(SetupSkipDialog.RESULT_SKIP);
+    }
+
+    @Test
+    public void testKeyguardSecure_shouldFinishWithFingerprintResultSkip() {
+        getShadowKeyguardManager().setIsKeyguardSecure(true);
+
+        mController.create().resume();
+
+        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
+        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
+        skipButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
+        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
+        assertThat(shadowActivity.getResultCode()).named("Result code")
+                .isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
+    }
+
+    private ShadowKeyguardManager getShadowKeyguardManager() {
+        return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index d837c40..a78c385 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
@@ -30,6 +31,7 @@
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.app.LoaderManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -43,6 +45,8 @@
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.SettingsActivity;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
+import com.android.settings.fuelgauge.anomaly.AnomalySummaryPreferenceController;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.LayoutPreference;
@@ -68,6 +72,9 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
         shadows = ShadowEntityHeaderController.class)
@@ -108,6 +115,10 @@
     private BatteryStats.Uid mUid;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private LoaderManager mLoaderManager;
+    @Mock
+    private AnomalySummaryPreferenceController mAnomalySummaryPreferenceController;
     private Context mContext;
     private Preference mForegroundPreference;
     private Preference mBackgroundPreference;
@@ -115,6 +126,7 @@
     private AdvancedPowerUsageDetail mFragment;
     private FakeFeatureFactory mFeatureFactory;
     private SettingsActivity mTestActivity;
+    private List<Anomaly> mAnomalies;
 
     @Before
     public void setUp() {
@@ -130,6 +142,7 @@
         doReturn(SUMMARY).when(mFragment).getString(anyInt());
         doReturn(APP_LABEL).when(mBundle).getString(nullable(String.class));
         doReturn(mBundle).when(mFragment).getArguments();
+        doReturn(mLoaderManager).when(mFragment).getLoaderManager();
 
         ShadowEntityHeaderController.setUseMock(mEntityHeaderController);
         doReturn(mEntityHeaderController).when(mEntityHeaderController)
@@ -184,6 +197,11 @@
         mFragment.mForegroundPreference = mForegroundPreference;
         mFragment.mBackgroundPreference = mBackgroundPreference;
         mFragment.mPowerUsagePreference = mPowerUsagePreference;
+        mFragment.mAnomalySummaryPreferenceController = mAnomalySummaryPreferenceController;
+
+        mAnomalies = new ArrayList<>();
+        mAnomalies.add(new Anomaly.Builder().setUid(UID).setType(
+                Anomaly.AnomalyType.WAKE_LOCK).build());
     }
 
     @After
@@ -238,7 +256,7 @@
     @Test
     public void testStartBatteryDetailPage_hasBasicData() {
         AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
-                mBatteryEntry, USAGE_PERCENT);
+                mBatteryEntry, USAGE_PERCENT, mAnomalies);
 
         assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
         assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)).isEqualTo(
@@ -247,6 +265,8 @@
                 FOREGROUND_TIME_MS);
         assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)).isEqualTo(
                 USAGE_PERCENT);
+        assertThat(mBundle.getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST)).isEqualTo(mAnomalies);
     }
 
     @Test
@@ -255,7 +275,7 @@
         mBatterySipper.usageTimeMs = PHONE_FOREGROUND_TIME_MS;
 
         AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
-                mBatteryEntry, USAGE_PERCENT);
+                mBatteryEntry, USAGE_PERCENT, null);
 
         assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
         assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)).isEqualTo(
@@ -264,6 +284,8 @@
                 PHONE_BACKGROUND_TIME_MS);
         assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)).isEqualTo(
                 USAGE_PERCENT);
+        assertThat(mBundle.getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST)).isNull();
     }
 
     @Test
@@ -271,21 +293,25 @@
         mBatterySipper.mPackages = PACKAGE_NAME;
         mBatteryEntry.defaultPackageName = PACKAGE_NAME[0];
         AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
-                mBatteryEntry, USAGE_PERCENT);
+                mBatteryEntry, USAGE_PERCENT, mAnomalies);
 
         assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(
                 PACKAGE_NAME[0]);
+        assertThat(mBundle.getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST)).isEqualTo(mAnomalies);
     }
 
     @Test
     public void testStartBatteryDetailPage_SystemApp() {
         mBatterySipper.mPackages = null;
         AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
-                mBatteryEntry, USAGE_PERCENT);
+                mBatteryEntry, USAGE_PERCENT, null);
 
         assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL);
         assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID);
-        assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(null);
+        assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isNull();
+        assertThat(mBundle.getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST)).isNull();
     }
 
     @Test
@@ -294,7 +320,7 @@
         mBatterySipper.mPackages = PACKAGE_NAME;
         doReturn(appUid).when(mBatterySipper).getUid();
         AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
-                mBatteryEntry, USAGE_PERCENT);
+                mBatteryEntry, USAGE_PERCENT, null);
 
         verify(mTestActivity).startPreferencePanelAsUser(
                 nullable(Fragment.class), nullable(String.class), nullable(Bundle.class), anyInt(),
@@ -344,4 +370,24 @@
         assertThat(mPowerUsagePreference.getSummary()).isEqualTo("16% of total app usage (150mAh)");
     }
 
+    @Test
+    public void testInitAnomalyInfo_anomalyNull_startAnomalyLoader() {
+        doReturn(null).when(mBundle).getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST);
+
+        mFragment.initAnomalyInfo();
+
+        verify(mLoaderManager).initLoader(eq(0), eq(Bundle.EMPTY), any());
+    }
+
+    @Test
+    public void testInitAnomalyInfo_anomalyExisted_updateAnomaly() {
+        doReturn(mAnomalies).when(mBundle).getParcelableArrayList(
+                AdvancedPowerUsageDetail.EXTRA_ANOMALY_LIST);
+
+        mFragment.initAnomalyInfo();
+
+        verify(mAnomalySummaryPreferenceController).updateAnomalySummaryPreference(mAnomalies);
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java b/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java
index 645b986..d0a200d 100644
--- a/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java
@@ -22,6 +22,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.os.UserHandle;
 import android.os.UserManager;
 
 import com.android.settings.R;
@@ -47,6 +48,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
 import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
@@ -387,4 +389,41 @@
 
         assertThat(mLoader.loadInBackground().size()).isEqualTo(0);
     }
+
+    @Test
+    public void query_appExistsInBothProfiles() {
+        final String query = "carrot";
+        final String packageName = "carrot";
+        final int user1 = 0;
+        final int user2 = 10;
+        final int uid = 67672;
+        List<UserInfo> infos = new ArrayList<>();
+        infos.add(new UserInfo(user1, "user 1", 0));
+        infos.add(new UserInfo(user2, "user 2", UserInfo.FLAG_MANAGED_PROFILE));
+
+        when(mUserManager.getProfiles(anyInt())).thenReturn(infos);
+
+        when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), eq(user1)))
+                .thenReturn(Arrays.asList(
+                        ApplicationTestUtils.buildInfo(UserHandle.getUid(user1, uid) /* uid */,
+                                packageName, 0 /* flags */,
+                                0 /* targetSdkVersion */)));
+        when(mPackageManagerWrapper.getInstalledApplicationsAsUser(anyInt(), eq(user2)))
+                .thenReturn(Arrays.asList(
+                        ApplicationTestUtils.buildInfo(UserHandle.getUid(user2, uid) /* uid */,
+                                packageName, 0 /* flags */,
+                                0 /* targetSdkVersion */)));
+
+        mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
+                mSiteMapManager);
+
+        Set<AppSearchResult> searchResults = (Set<AppSearchResult>) mLoader.loadInBackground();
+        assertThat(searchResults).hasSize(2);
+
+        Set<Integer> uidResults = searchResults.stream().map(result -> result.info.uid).collect(
+                Collectors.toSet());
+        assertThat(uidResults).containsExactly(
+                UserHandle.getUid(user1, uid),
+                UserHandle.getUid(user2, uid));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
index 574e4f7..cee3c78 100644
--- a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
+++ b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
@@ -17,18 +17,30 @@
 
 package com.android.settings.search;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
 import android.view.LayoutInflater;
 import android.view.View;
 
 import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.search.SearchResult.Builder;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,25 +55,25 @@
 import java.util.List;
 import java.util.Objects;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class IntentSearchViewHolderTest {
 
     private static final String TITLE = "title";
     private static final String SUMMARY = "summary";
+    private static final int USER_ID = 10;
+    private static final String BADGED_LABEL = "work title";
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private SearchFragment mFragment;
+    @Mock
+    private PackageManager mPackageManager;
     private FakeFeatureFactory mFeatureFactory;
     private IntentSearchViewHolder mHolder;
     private Drawable mIcon;
+    private Drawable mBadgedIcon;
 
     @Before
     public void setUp() {
@@ -74,6 +86,8 @@
         mHolder = new IntentSearchViewHolder(view);
 
         mIcon = context.getDrawable(R.drawable.ic_search_history);
+        mBadgedIcon = context.getDrawable(R.drawable.ic_add);
+        when(mFragment.getActivity().getPackageManager()).thenReturn(mPackageManager);
     }
 
     @Test
@@ -172,6 +186,27 @@
         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.GONE);
     }
 
+    @Test
+    public void testBindViewElements_appSearchResult() {
+        when(mPackageManager.getUserBadgedLabel(any(CharSequence.class),
+                eq(new UserHandle(USER_ID)))).thenReturn(BADGED_LABEL);
+
+        SearchResult result = getAppSearchResult(
+                TITLE, SUMMARY, mIcon, getApplicationInfo(USER_ID, TITLE, mIcon));
+        mHolder.onBind(mFragment, result);
+        mHolder.itemView.performClick();
+
+        assertThat(mHolder.titleView.getText()).isEqualTo(TITLE);
+        assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
+        assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mHolder.breadcrumbView.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mHolder.titleView.getContentDescription()).isEqualTo(BADGED_LABEL);
+
+        verify(mFragment).onSearchResultClicked(eq(mHolder), any(SearchResult.class));
+        verify(mFragment.getActivity()).startActivityAsUser(
+                any(Intent.class), eq(new UserHandle(USER_ID)));
+    }
+
     private SearchResult getSearchResult(String title, String summary, Drawable icon) {
         Builder builder = new Builder();
         builder.setStableId(Objects.hash(title, summary, icon))
@@ -186,4 +221,26 @@
 
         return builder.build();
     }
+
+    private SearchResult getAppSearchResult(
+            String title, String summary, Drawable icon, ApplicationInfo applicationInfo) {
+        AppSearchResult.Builder builder = new AppSearchResult.Builder();
+        builder.setTitle(title)
+                .setSummary(summary)
+                .setRank(1)
+                .setPayload(new ResultPayload(
+                        new Intent().setComponent(new ComponentName("pkg", "class"))))
+                .addBreadcrumbs(new ArrayList<>())
+                .setIcon(icon);
+        builder.setAppInfo(applicationInfo);
+        return builder.build();
+    }
+
+    private ApplicationInfo getApplicationInfo(int userId, CharSequence appLabel, Drawable icon) {
+        ApplicationInfo applicationInfo = spy(new ApplicationInfo());
+        applicationInfo.uid = UserHandle.getUid(userId, 12345);
+        doReturn(icon).when(applicationInfo).loadIcon(any(PackageManager.class));
+        doReturn(appLabel).when(applicationInfo).loadLabel(any(PackageManager.class));
+        return applicationInfo;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index b1419ba..7c56dc6 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.testutils.shadow;
 
+import android.app.admin.DevicePolicyManager;
+
 import com.android.internal.widget.LockPatternUtils;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
@@ -27,4 +29,9 @@
     public boolean isSecure(int id) {
         return true;
     }
+
+    @Implementation
+    public int getActivePasswordQuality(int userId) {
+        return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index c67ad36..61346bc 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -16,11 +16,19 @@
 
 package com.android.settings.testutils.shadow;
 
+import android.annotation.UserIdInt;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.UserManager;
+import android.util.SparseArray;
 
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.internal.ShadowExtractor;
+
+import java.util.Collections;
+import java.util.List;
 
 /**
  * This class provides the API 24 implementation of UserManager.get(Context).
@@ -28,8 +36,34 @@
 @Implements(UserManager.class)
 public class ShadowUserManager {
 
+    private SparseArray<UserInfo> mUserInfos = new SparseArray<>();
+
+    public void setUserInfo(int userHandle, UserInfo userInfo) {
+        mUserInfos.put(userHandle, userInfo);
+    }
+
+    @Implementation
+    public UserInfo getUserInfo(int userHandle) {
+        return mUserInfos.get(userHandle);
+    }
+
+    @Implementation
+    public List<UserInfo> getProfiles(@UserIdInt int userHandle) {
+        return Collections.emptyList();
+    }
+
+    @Implementation
+    public int getCredentialOwnerProfile(@UserIdInt int userHandle) {
+        return userHandle;
+    }
+
     @Implementation
     public static UserManager get(Context context) {
         return (UserManager) context.getSystemService(Context.USER_SERVICE);
     }
+
+    public static ShadowUserManager getShadow() {
+        return (ShadowUserManager) ShadowExtractor.extract(
+                RuntimeEnvironment.application.getSystemService(UserManager.class));
+    }
 }
diff --git a/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
deleted file mode 100644
index 8afed18..0000000
--- a/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
+++ /dev/null
@@ -1,109 +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.fingerprint;
-
-
-import static org.mockito.Mockito.doReturn;
-
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.test.ActivityUnitTestCase;
-import android.view.View;
-import android.widget.Button;
-
-import com.android.settings.R;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class SetupFingerprintEnrollIntroductionTest
-        extends ActivityUnitTestCase<SetupFingerprintEnrollIntroduction> {
-
-    private TestContext mContext;
-
-    @Mock
-    private KeyguardManager mKeyguardManager;
-
-    private SetupFingerprintEnrollIntroduction mActivity;
-
-    public SetupFingerprintEnrollIntroductionTest() {
-        super(SetupFingerprintEnrollIntroduction.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = new TestContext(getInstrumentation().getTargetContext());
-        setActivityContext(mContext);
-
-        getInstrumentation().runOnMainSync(() -> {
-            final Intent intent = new Intent();
-            mActivity = startActivity(intent,
-                    null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
-        });
-    }
-
-    public void testKeyguardNotSecure_shouldShowSkipDialog() {
-        doReturn(false).when(mKeyguardManager).isKeyguardSecure();
-
-        getInstrumentation().runOnMainSync(() -> {
-            getInstrumentation().callActivityOnCreate(mActivity, null);
-            getInstrumentation().callActivityOnResume(mActivity);
-
-            final Button skipButton =
-                    (Button) mActivity.findViewById(R.id.fingerprint_cancel_button);
-            assertEquals(View.VISIBLE, skipButton.getVisibility());
-            skipButton.performClick();
-        });
-
-        assertFalse(isFinishCalled());
-    }
-
-    public void testKeyguardSecure_shouldNotShowSkipDialog() {
-        doReturn(true).when(mKeyguardManager).isKeyguardSecure();
-
-        getInstrumentation().runOnMainSync(() -> {
-            getInstrumentation().callActivityOnCreate(mActivity, null);
-            getInstrumentation().callActivityOnResume(mActivity);
-
-            final Button skipButton =
-                    (Button) mActivity.findViewById(R.id.fingerprint_cancel_button);
-            assertEquals(View.VISIBLE, skipButton.getVisibility());
-            skipButton.performClick();
-        });
-
-        assertTrue(isFinishCalled());
-    }
-
-    public class TestContext extends ContextWrapper {
-
-        public TestContext(Context base) {
-            super(base);
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            if (Context.KEYGUARD_SERVICE.equals(name)) {
-                return mKeyguardManager;
-            }
-            return super.getSystemService(name);
-        }
-    }
-}