Add log for BatteryUtils

This cl add logs to get more data for app usage time.

Also refactor BatteryUtils to singleton pattern because we need
to extract package name from uid.

Bug: 36909166
Test: RunSettingsRoboTests
Change-Id: I6ede354035c46e46cb856b7cf57bd1b7ccbd6d4f
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 8be3b14..f3eec4c 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -105,10 +105,11 @@
         final Bundle args = new Bundle();
         final BatterySipper sipper = entry.sipper;
         final BatteryStats.Uid uid = sipper.uidObj;
+        final BatteryUtils batteryUtils = BatteryUtils.getInstance(caller);
 
-        final long backgroundTimeMs = BatteryUtils.getProcessTimeMs(
+        final long backgroundTimeMs = batteryUtils.getProcessTimeMs(
                 BatteryUtils.StatusType.BACKGROUND, uid, which);
-        final long foregroundTimeMs = BatteryUtils.getProcessTimeMs(
+        final long foregroundTimeMs = batteryUtils.getProcessTimeMs(
                 BatteryUtils.StatusType.FOREGROUND, uid, which);
 
         if (ArrayUtils.isEmpty(sipper.mPackages)) {
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 85bc0fd..a3ea5cd 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -16,9 +16,13 @@
 package com.android.settings.fuelgauge;
 
 import android.annotation.IntDef;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.BatteryStats;
 import android.os.SystemClock;
 import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -38,7 +42,23 @@
         int ALL = 2;
     }
 
-    public static long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
+    private static final String TAG = "BatteryUtils";
+    private static BatteryUtils sInstance;
+
+    private PackageManager mPackageManager;
+
+    public static BatteryUtils getInstance(Context context) {
+        if (sInstance == null || sInstance.isDataCorrupted()) {
+            sInstance = new BatteryUtils(context);
+        }
+        return sInstance;
+    }
+
+    private BatteryUtils(Context context) {
+        mPackageManager = context.getPackageManager();
+    }
+
+    public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
             int which) {
         if (uid == null) {
             return 0;
@@ -56,34 +76,46 @@
         return 0;
     }
 
-    private static long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) {
+    private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) {
         final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
         final long timeUs = uid.getProcessStateTime(
                 BatteryStats.Uid.PROCESS_STATE_BACKGROUND, rawRealTimeUs, which);
-        return  convertUsToMs(timeUs);
+
+        Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid()));
+        Log.v(TAG, "background time(us): " + timeUs);
+        return convertUsToMs(timeUs);
     }
 
-    private static long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
+    private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
         final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
         final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP,
                 BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
                 BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING,
                 BatteryStats.Uid.PROCESS_STATE_FOREGROUND};
+        Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid()));
+
         long timeUs = 0;
         for (int type : foregroundTypes) {
-            timeUs += uid.getProcessStateTime(type, rawRealTimeUs, which);
+            final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
+            Log.v(TAG, "type: " + type + " time(us): " + localTime);
+            timeUs += localTime;
         }
+        Log.v(TAG, "foreground time(us): " + timeUs);
 
         return convertUsToMs(timeUs);
     }
 
-    private static long convertUsToMs(long timeUs) {
+    private long convertUsToMs(long timeUs) {
         return timeUs / 1000;
     }
 
-    private static long convertMsToUs(long timeMs) {
+    private long convertMsToUs(long timeMs) {
         return timeMs * 1000;
     }
 
+    private boolean isDataCorrupted() {
+        return mPackageManager == null;
+    }
+
 }
 
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index fe0cf4d..328260e 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -73,6 +73,7 @@
     private PackageManager mPackageManager;
     private UserManager mUserManager;
     private Map<Integer, PowerUsageData> mBatteryDataMap;
+    private BatteryUtils mBatteryUtils;
 
     Handler mHandler = new Handler() {
 
@@ -116,6 +117,7 @@
                 .getPowerUsageFeatureProvider(context);
         mPackageManager = context.getPackageManager();
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mBatteryUtils = BatteryUtils.getInstance(context);
     }
 
     @Override
@@ -223,8 +225,8 @@
             final PowerUsageData usageData = batteryDataMap.get(extractUsageType(sipper));
             usageData.totalPowerMah += sipper.totalPowerMah;
             if (sipper.drainType == DrainType.APP && sipper.usageTimeMs != 0) {
-                sipper.usageTimeMs = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL,
-                        sipper.uidObj, STATUS_TYPE);
+                sipper.usageTimeMs = mBatteryUtils.getProcessTimeMs(
+                        BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, STATUS_TYPE);
             }
             usageData.totalUsageTimeMs += sipper.usageTimeMs;
             usageData.usageList.add(sipper);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 2c1fd78..face564 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -110,6 +110,8 @@
     PowerGaugePreference mLastFullChargePref;
     @VisibleForTesting
     PowerUsageFeatureProvider mPowerFeatureProvider;
+    @VisibleForTesting
+    BatteryUtils mBatteryUtils;
 
     private LayoutPreference mBatteryLayoutPref;
     private PreferenceGroup mAppListGroup;
@@ -127,6 +129,8 @@
                 KEY_TIME_SINCE_LAST_FULL_CHARGE);
         mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary);
 
+        mBatteryUtils = BatteryUtils.getInstance(getContext());
+
         initFeatureProvider();
     }
 
@@ -494,7 +498,7 @@
                 pref.setOrder(i + 1);
                 pref.setPercent(percentOfTotal);
                 if (sipper.usageTimeMs == 0 && sipper.drainType == DrainType.APP) {
-                    sipper.usageTimeMs = BatteryUtils.getProcessTimeMs(
+                    sipper.usageTimeMs = mBatteryUtils.getProcessTimeMs(
                             BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, mStatsType);
                 }
                 setUsageSummary(pref, usedTime, sipper.usageTimeMs);
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
index a33a8c8..5b1019e 100644
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
@@ -74,7 +74,7 @@
     ApplicationFeatureProvider mApplicationFeatureProvider;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private UserManager mUserManager;
-    @Mock
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private SettingsActivity mActivity;
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index 8b5ce19..03892a3 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -21,6 +21,7 @@
 import android.app.Fragment;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
 import android.os.BatteryStats;
 import android.os.Bundle;
@@ -96,7 +97,8 @@
     private BatteryStatsHelper mBatteryStatsHelper;
     @Mock
     private BatteryStats.Uid mUid;
-    private Bundle mTestBundle;
+    @Mock
+    private PackageManager mPackageManager;
     private AdvancedPowerUsageDetail mFragment;
     private FakeFeatureFactory mFeatureFactory;
     private SettingsActivity mTestActivity;
@@ -141,6 +143,7 @@
         mAppEntry.info = mock(ApplicationInfo.class);
 
         mTestActivity = spy(new SettingsActivity());
+        doReturn(mPackageManager).when(mTestActivity).getPackageManager();
 
         final ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 672cc90..3699147 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -25,6 +25,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
@@ -56,7 +57,8 @@
     private static final long TIME_EXPECTED_ALL = 15000;
 
     @Mock
-    BatteryStats.Uid mUid;
+    private BatteryStats.Uid mUid;
+    private BatteryUtils mBatteryUtils;
 
     @Before
     public void setUp() {
@@ -72,11 +74,13 @@
                 anyLong(), anyInt());
         doReturn(TIME_STATE_BACKGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_BACKGROUND),
                 anyLong(), anyInt());
+
+        mBatteryUtils = BatteryUtils.getInstance(RuntimeEnvironment.application);
     }
 
     @Test
     public void testGetProcessTimeMs_typeForeground_timeCorrect() {
-        final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid,
+        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid,
                 BatteryStats.STATS_SINCE_CHARGED);
 
         assertThat(time).isEqualTo(TIME_EXPECTED_FOREGROUND);
@@ -84,7 +88,7 @@
 
     @Test
     public void testGetProcessTimeMs_typeBackground_timeCorrect() {
-        final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid,
+        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid,
                 BatteryStats.STATS_SINCE_CHARGED);
 
         assertThat(time).isEqualTo(TIME_EXPECTED_BACKGROUND);
@@ -92,7 +96,7 @@
 
     @Test
     public void testGetProcessTimeMs_typeAll_timeCorrect() {
-        final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid,
+        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid,
                 BatteryStats.STATS_SINCE_CHARGED);
 
         assertThat(time).isEqualTo(TIME_EXPECTED_ALL);
@@ -100,7 +104,7 @@
 
     @Test
     public void testGetProcessTimeMs_uidNull_returnZero() {
-        final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null,
+        final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null,
                 BatteryStats.STATS_SINCE_CHARGED);
 
         assertThat(time).isEqualTo(0);