Merge "Add logging when entity header buttons are clicked" into oc-dr1-dev
diff --git a/res/layout/fingerprint_enroll_enrolling_base.xml b/res/layout/fingerprint_enroll_enrolling_base.xml
index 7f8eb1b..e312c50 100644
--- a/res/layout/fingerprint_enroll_enrolling_base.xml
+++ b/res/layout/fingerprint_enroll_enrolling_base.xml
@@ -34,14 +34,14 @@
              switch the text -->
         <FrameLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/suw_description_glif_margin_top">
+            android:layout_height="wrap_content">
 
             <TextView
                 style="@style/SuwDescription.Glif"
                 android:id="@+id/start_message"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:minLines="3"
                 android:text="@string/security_settings_fingerprint_enroll_start_message"/>
 
             <TextView
@@ -49,27 +49,36 @@
                 android:id="@+id/repeat_message"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:minLines="3"
                 android:text="@string/security_settings_fingerprint_enroll_repeat_message"
                 android:visibility="invisible"/>
 
         </FrameLayout>
 
-        <include layout="@layout/fingerprint_enroll_enrolling_content"
-            android:layout_width="@dimen/fingerprint_progress_bar_max_size"
+        <FrameLayout
+            android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="1"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginTop="@dimen/fingerprint_enrolling_content_margin_top"/>
+            android:paddingBottom="80dp">
 
-        <TextView
-            style="@style/TextAppearance.FingerprintErrorText"
-            android:id="@+id/error_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="24dp"
-            android:layout_gravity="center_horizontal"
-            android:accessibilityLiveRegion="polite"
-            android:visibility="invisible"/>
+            <include layout="@layout/fingerprint_enroll_enrolling_content"
+                android:layout_width="@dimen/fingerprint_progress_bar_max_size"
+                android:layout_height="@dimen/fingerprint_progress_bar_max_size"
+                android:layout_gravity="center"
+                android:layout_marginVertical="24dp"/>
+
+            <TextView
+                style="@style/TextAppearance.FingerprintErrorText"
+                android:id="@+id/error_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="24dp"
+                android:layout_gravity="center_horizontal|bottom"
+                android:accessibilityLiveRegion="polite"
+                android:gravity="center"
+                android:visibility="invisible"/>
+
+        </FrameLayout>
 
     </LinearLayout>
 
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index f666942..ba3d07f 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -38,12 +38,15 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/suw_description_glif_margin_top"
+            android:minLines="3"
             android:text="@string/security_settings_fingerprint_enroll_finish_message"/>
 
         <com.android.setupwizardlib.view.FillContentLayout
             android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:maxWidth="@dimen/fingerprint_finish_max_size"
+            android:maxHeight="@dimen/fingerprint_finish_max_size">
 
             <ImageView
                 android:id="@+id/fingerprint_in_app_indicator"
diff --git a/res/values-sw400dp/dimens.xml b/res/values-sw400dp/dimens.xml
index 0c35d84..35a25d8 100755
--- a/res/values-sw400dp/dimens.xml
+++ b/res/values-sw400dp/dimens.xml
@@ -16,7 +16,7 @@
   -->
 
 <resources>
-    <dimen name="fingerprint_enrolling_content_margin_top">56dp</dimen>
+    <dimen name="fingerprint_enrolling_content_margin_vertical">56dp</dimen>
     <dimen name="fingerprint_find_sensor_graphic_size">240dp</dimen>
 
     <dimen name="support_escalation_card_padding_start">56dp</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e3c7032..76dacb3 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -225,9 +225,13 @@
     <dimen name="fingerprint_error_text_appear_distance">16dp</dimen>
     <dimen name="fingerprint_error_text_disappear_distance">-8dp</dimen>
     <dimen name="fingerprint_animation_size">88dp</dimen>
-    <dimen name="fingerprint_progress_bar_max_size">220dp</dimen>
+    <dimen name="fingerprint_progress_bar_max_size">240dp</dimen>
     <dimen name="fingerprint_progress_bar_min_size">120dp</dimen>
-    <dimen name="fingerprint_enrolling_content_margin_top">36dp</dimen>
+    <dimen name="fingerprint_enrolling_content_margin_vertical">24dp</dimen>
+    <!-- To be the same size as fingerprint progress bar:
+         fingerprint_finish_max_size = fingerprint_progress_bar_max_size
+                  + (fingerprint_enrolling_content_margin_vertical x 2) -->
+    <dimen name="fingerprint_finish_max_size">288dp</dimen>
 
     <dimen name="confirm_credentials_security_method_margin">48dp</dimen>
     <dimen name="confirm_credentials_layout_width">@dimen/match_parent</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7771ac0..f7dc03b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4853,8 +4853,8 @@
     <string name="battery_detail_since_full_charge">Breakdown since last full charge</string>
     <!-- Title for usage time since last full charge. [CHAR LIMIT=60] -->
     <string name="battery_last_full_charge">Last full charge</string>
-    <!-- Description for text in battery footer. [CHAR LIMIT=120] -->
-    <string name="battery_footer_summary">Remaining battery time is approximate and can change based on usage</string>
+    <!-- Description for text in battery footer. [CHAR LIMIT=NONE] -->
+    <string name="battery_footer_summary">Battery estimates are approximate and can change based on usage</string>
     <!-- Title for text that shows the amount of time an app has been running while in the foreground. [CHAR LIMIT=80] -->
     <string name="battery_detail_foreground">While in active use</string>
     <!-- Title for text that shows the amount of time an app has been running while in the background. [CHAR LIMIT=80] -->
diff --git a/src/com/android/settings/SetupWizardUtils.java b/src/com/android/settings/SetupWizardUtils.java
index 7edffed..d53abae 100644
--- a/src/com/android/settings/SetupWizardUtils.java
+++ b/src/com/android/settings/SetupWizardUtils.java
@@ -17,13 +17,21 @@
 package com.android.settings;
 
 import android.content.Intent;
+import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
 
 import com.android.setupwizardlib.util.WizardManagerHelper;
 
 public class SetupWizardUtils {
 
+    @VisibleForTesting
+    static final String SYSTEM_PROP_SETUPWIZARD_THEME = "setupwizard.theme";
+
     public static int getTheme(Intent intent) {
         String theme = intent.getStringExtra(WizardManagerHelper.EXTRA_THEME);
+        if (theme == null) {
+            theme = SystemProperties.get(SYSTEM_PROP_SETUPWIZARD_THEME);
+        }
         if (theme != null) {
             switch (theme) {
                 case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 0aad7ba..64039ef 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -21,6 +21,7 @@
 import android.os.SystemClock;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
 import android.support.annotation.VisibleForTesting;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -29,6 +30,8 @@
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.internal.util.ArrayUtils;
+import com.android.settings.R;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.overlay.FeatureFactory;
 
 import java.lang.annotation.Retention;
@@ -138,8 +141,10 @@
                 sippers.remove(i);
                 if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
                         && sipper.drainType != BatterySipper.DrainType.SCREEN
-                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED) {
-                    // Don't add it if it is overcounted, unaccounted or screen
+                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
+                        && sipper.drainType != BatterySipper.DrainType.BLUETOOTH
+                        && sipper.drainType != BatterySipper.DrainType.WIFI) {
+                    // Don't add it if it is overcounted, unaccounted, wifi, bluetooth, or screen
                     proportionalSmearPowerMah += sipper.totalPowerMah;
                 }
             }
@@ -193,6 +198,8 @@
                 || drainType == BatterySipper.DrainType.SCREEN
                 || drainType == BatterySipper.DrainType.UNACCOUNTED
                 || drainType == BatterySipper.DrainType.OVERCOUNTED
+                || drainType == BatterySipper.DrainType.BLUETOOTH
+                || drainType == BatterySipper.DrainType.WIFI
                 || (sipper.totalPowerMah * SECONDS_IN_HOUR) < MIN_POWER_THRESHOLD_MILLI_AMP
                 || mPowerUsageFeatureProvider.isTypeService(sipper)
                 || mPowerUsageFeatureProvider.isTypeSystem(sipper);
@@ -291,6 +298,20 @@
         }
     }
 
+    @StringRes
+    public int getSummaryResIdFromAnomalyType(@Anomaly.AnomalyType int type) {
+        switch (type) {
+            case Anomaly.AnomalyType.WAKE_LOCK:
+                return R.string.battery_abnormal_wakelock_summary;
+            case Anomaly.AnomalyType.WAKEUP_ALARM:
+                return R.string.battery_abnormal_wakeup_alarm_summary;
+            case Anomaly.AnomalyType.BLUETOOTH_SCAN:
+                return R.string.battery_abnormal_location_summary;
+            default:
+                throw new IllegalArgumentException("Incorrect anomaly type: " + type);
+        }
+    }
+
     public long convertUsToMs(long timeUs) {
         return timeUs / 1000;
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java b/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java
index 085b88f..59662b1 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java
@@ -57,6 +57,8 @@
     PreferenceGroup mAbnormalListGroup;
     @VisibleForTesting
     PackageManager mPackageManager;
+    @VisibleForTesting
+    BatteryUtils mBatteryUtils;
     IconDrawableFactory mIconDrawableFactory;
 
     public static void startBatteryAbnormalPage(SettingsActivity caller,
@@ -78,6 +80,7 @@
         mAbnormalListGroup = (PreferenceGroup) findPreference(KEY_PREF_ANOMALY_LIST);
         mPackageManager = context.getPackageManager();
         mIconDrawableFactory = IconDrawableFactory.newInstance(context, false /* EmbedShadow */);
+        mBatteryUtils = BatteryUtils.getInstance(context);
     }
 
     @Override
@@ -126,16 +129,16 @@
     }
 
     void refreshUi() {
-        //TODO(b/37681665): cache the preference so we don't need to create new one every time.
         mAbnormalListGroup.removeAll();
         for (int i = 0, size = mAnomalies.size(); i < size; i++) {
             final Anomaly anomaly = mAnomalies.get(i);
             Preference pref = new AnomalyPreference(getPrefContext(), anomaly);
-
+            pref.setSummary(mBatteryUtils.getSummaryResIdFromAnomalyType(anomaly.type));
             Drawable icon = getIconFromPackageName(anomaly.packageName);
             if (icon != null) {
                 pref.setIcon(icon);
             }
+
             mAbnormalListGroup.addPreference(pref);
         }
     }
diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java
index d874494..9884fbd 100644
--- a/src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java
+++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java
@@ -14,7 +14,6 @@
     public AnomalyPreference(Context context, Anomaly anomaly) {
         super(context);
         mAnomaly = anomaly;
-        setLayoutResource(R.layout.preference_app);
 
         if (anomaly != null) {
             setTitle(anomaly.displayName);
diff --git a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
index 115bc8a..21061c1 100644
--- a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
@@ -16,21 +16,35 @@
 
 package com.android.settings;
 
+import static com.android.settings.testutils.ResIdSubject.assertResId;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.Intent;
 
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.setupwizardlib.util.WizardManagerHelper;
 
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(
+        manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {
+                SettingsShadowSystemProperties.class
+        })
 public class SetupWizardUtilsTest {
 
+    @After
+    public void tearDown() {
+        SettingsShadowSystemProperties.clear();
+    }
+
     @Test
     public void testCopySetupExtras() throws Throwable {
         Intent fromIntent = new Intent();
@@ -44,4 +58,24 @@
         assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, false))
                 .isTrue();
     }
+
+    @Test
+    public void testGetTheme_withIntentExtra_shouldReturnExtraTheme() {
+        SettingsShadowSystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
+                WizardManagerHelper.THEME_GLIF);
+        Intent intent = new Intent();
+        intent.putExtra(WizardManagerHelper.EXTRA_THEME, WizardManagerHelper.THEME_GLIF_V2);
+
+        assertResId(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme);
+    }
+
+    @Test
+    public void testGetTheme_withEmptyIntent_shouldReturnSystemProperty() {
+        SettingsShadowSystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
+                WizardManagerHelper.THEME_GLIF_V2_LIGHT);
+        Intent intent = new Intent();
+
+        assertResId(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme_Light);
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 053cc98..d23301d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -22,6 +22,8 @@
 
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
+import com.android.settings.R;
+import com.android.settings.fuelgauge.anomaly.Anomaly;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -82,6 +84,8 @@
     private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
     private static final double BATTERY_UNACCOUNTED_USAGE = 700;
     private static final double BATTERY_APP_USAGE = 100;
+    private static final double BATTERY_WIFI_USAGE = 200;
+    private static final double BATTERY_BLUETOOTH_USAGE = 300;
     private static final double TOTAL_BATTERY_USAGE = 1000;
     private static final double HIDDEN_USAGE = 200;
     private static final int DISCHARGE_AMOUNT = 80;
@@ -93,6 +97,10 @@
     @Mock
     private BatterySipper mNormalBatterySipper;
     @Mock
+    private BatterySipper mWifiBatterySipper;
+    @Mock
+    private BatterySipper mBluetoothBatterySipper;
+    @Mock
     private BatterySipper mScreenBatterySipper;
     @Mock
     private BatterySipper mOvercountedBatterySipper;
@@ -134,6 +142,12 @@
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         mNormalBatterySipper.totalPowerMah = TOTAL_BATTERY_USAGE;
 
+        mWifiBatterySipper.drainType = BatterySipper.DrainType.WIFI;
+        mWifiBatterySipper.totalPowerMah = BATTERY_WIFI_USAGE;
+
+        mBluetoothBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
+        mBluetoothBatterySipper.totalPowerMah = BATTERY_BLUETOOTH_USAGE;
+
         mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
         mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE;
 
@@ -193,6 +207,8 @@
         sippers.add(mSystemBatterySipper);
         sippers.add(mOvercountedBatterySipper);
         sippers.add(mUnaccountedBatterySipper);
+        sippers.add(mWifiBatterySipper);
+        sippers.add(mBluetoothBatterySipper);
         when(mProvider.isTypeSystem(mSystemBatterySipper))
                 .thenReturn(true);
         doNothing().when(mBatteryUtils).smearScreenBatterySipper(any(), any());
@@ -234,6 +250,18 @@
     }
 
     @Test
+    public void testShouldHideSipper_TypeWifi_ReturnTrue() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.WIFI;
+        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
+    }
+
+    @Test
+    public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
+        assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
+    }
+
+    @Test
     public void testShouldHideSipper_TypeSystem_ReturnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
@@ -315,6 +343,16 @@
                 mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
     }
 
+    @Test
+    public void testGetSummaryResIdFromAnomalyType() {
+        assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKE_LOCK))
+                .isEqualTo(R.string.battery_abnormal_wakelock_summary);
+        assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKEUP_ALARM))
+                .isEqualTo(R.string.battery_abnormal_wakeup_alarm_summary);
+        assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.BLUETOOTH_SCAN))
+                .isEqualTo(R.string.battery_abnormal_location_summary);
+    }
+
     private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
             int uidCode, boolean isUidNull) {
         final BatterySipper sipper = mock(BatterySipper.class);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java
index 7845870..71aa295 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java
@@ -60,8 +60,10 @@
 public class PowerUsageAnomalyDetailsTest {
     private static final String NAME_APP_1 = "app1";
     private static final String NAME_APP_2 = "app2";
+    private static final String NAME_APP_3 = "app3";
     private static final String PACKAGE_NAME_1 = "com.android.app1";
     private static final String PACKAGE_NAME_2 = "com.android.app2";
+    private static final String PACKAGE_NAME_3 = "com.android.app3";
 
     @Mock
     private SettingsActivity mSettingsActivity;
@@ -71,6 +73,8 @@
     private Drawable mDrawable1;
     @Mock
     private Drawable mDrawable2;
+    @Mock
+    private Drawable mDrawable3;
     private Context mContext;
     private PowerUsageAnomalyDetails mFragment;
     private PreferenceGroup mAbnormalListGroup;
@@ -92,30 +96,36 @@
                 .build();
         mAnomalyList.add(anomaly1);
         Anomaly anomaly2 = new Anomaly.Builder()
-                .setType(Anomaly.AnomalyType.WAKE_LOCK)
+                .setType(Anomaly.AnomalyType.WAKEUP_ALARM)
                 .setPackageName(PACKAGE_NAME_2)
                 .setDisplayName(NAME_APP_2)
                 .build();
         mAnomalyList.add(anomaly2);
+        Anomaly anomaly3 = new Anomaly.Builder()
+                .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN)
+                .setPackageName(PACKAGE_NAME_3)
+                .setDisplayName(NAME_APP_3)
+                .build();
+        mAnomalyList.add(anomaly3);
 
         mFragment = spy(new PowerUsageAnomalyDetails());
         doReturn(null).when(mFragment).getIconFromPackageName(any());
         mFragment.mAbnormalListGroup = mAbnormalListGroup;
         mFragment.mAnomalies = mAnomalyList;
+        mFragment.mBatteryUtils = new BatteryUtils(mContext);
         doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
         doReturn(mContext).when(mPreferenceManager).getContext();
     }
 
     @Test
-    public void testRefreshUi_dataCorrect() {
-        final List<Anomaly> testAnomalyList = new ArrayList<>();
+    public void testRefreshUi_displayCorrectTitleAndSummary() {
+        final List<Preference> testPreferences = new ArrayList<>();
         final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(
                 Preference.class);
         Answer<Void> prefCallable = new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                testAnomalyList.add(
-                        ((AnomalyPreference) preferenceCaptor.getValue()).getAnomaly());
+                testPreferences.add(preferenceCaptor.getValue());
                 return null;
             }
         };
@@ -123,13 +133,22 @@
 
         mFragment.refreshUi();
 
-        assertThat(testAnomalyList).containsExactlyElementsIn(mAnomalyList);
+        final Preference wakelockPreference = testPreferences.get(0);
+        assertThat(wakelockPreference.getTitle()).isEqualTo(NAME_APP_1);
+        assertThat(wakelockPreference.getSummary()).isEqualTo("Keeping device awake");
+        final Preference wakeupPreference = testPreferences.get(1);
+        assertThat(wakeupPreference.getTitle()).isEqualTo(NAME_APP_2);
+        assertThat(wakeupPreference.getSummary()).isEqualTo("Waking up device in background");
+        final Preference bluetoothPreference = testPreferences.get(2);
+        assertThat(bluetoothPreference.getTitle()).isEqualTo(NAME_APP_3);
+        assertThat(bluetoothPreference.getSummary()).isEqualTo("Requesting location frequently");
     }
 
     @Test
     public void testRefreshUi_iconCorrect() {
         doReturn(mDrawable1).when(mFragment).getIconFromPackageName(PACKAGE_NAME_1);
         doReturn(mDrawable2).when(mFragment).getIconFromPackageName(PACKAGE_NAME_2);
+        doReturn(mDrawable3).when(mFragment).getIconFromPackageName(PACKAGE_NAME_3);
 
         final List<Drawable> testIcons = new ArrayList<>();
         final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(
@@ -145,7 +164,7 @@
 
         mFragment.refreshUi();
 
-        assertThat(testIcons).containsExactly(mDrawable1, mDrawable2);
+        assertThat(testIcons).containsExactly(mDrawable1, mDrawable2, mDrawable3);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/testutils/ResIdSubject.java b/tests/robotests/src/com/android/settings/testutils/ResIdSubject.java
new file mode 100644
index 0000000..2305edb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/ResIdSubject.java
@@ -0,0 +1,81 @@
+/*
+ * 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.testutils;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.support.annotation.Nullable;
+
+import com.google.common.truth.ComparableSubject;
+import com.google.common.truth.FailureStrategy;
+import com.google.common.truth.SubjectFactory;
+
+/**
+ * Custom subject for use with {@link com.google.common.truth.Truth}, to provide a more readable
+ * error message, so that instead of "Not true that 2130706432 equals to 17170444", it will say
+ * "Not true that color/my_color equals to android:color/black".
+ *
+ * <p>Usage:
+ * <pre>{@code
+ *     ResIdSubject.assertResId(activity.getThemeResId()).isEqualTo(android.R.style.Theme_Material)
+ * }</pre>
+ */
+public class ResIdSubject extends ComparableSubject<ResIdSubject, Integer> {
+
+    public static final SubjectFactory<ResIdSubject, Integer> FACTORY =
+            new SubjectFactory<ResIdSubject, Integer>() {
+                @Override
+                public ResIdSubject getSubject(
+                        FailureStrategy failureStrategy, Integer integer) {
+                    return new ResIdSubject(failureStrategy, integer);
+                }
+            };
+
+    public static ResIdSubject assertResId(int resId) {
+        return assertAbout(ResIdSubject.FACTORY).that(resId);
+    }
+
+    public ResIdSubject(
+            FailureStrategy failureStrategy,
+            @Nullable Integer integer) {
+        super(failureStrategy, integer);
+    }
+
+    public void isEqualTo(int other) {
+        Integer subject = getSubject();
+        if (subject == null || subject != other) {
+            fail("equals to", resIdToString(other));
+        }
+    }
+
+    @Override
+    protected String getDisplaySubject() {
+        String resourceName = "<" + resIdToString(getSubject()) + ">";
+        String customName = internalCustomName();
+        if (customName != null) {
+            return customName + " " + resourceName;
+        } else {
+            return resourceName;
+        }
+    }
+
+    private static String resIdToString(int resId) {
+        return application.getResources().getResourceName(resId);
+    }
+}