Merge "Display anomaly in battery usage page" into oc-dr1-dev
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/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/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);
+    }
+
 }