OSDN Git Service

Fix crash when opening battery page
authorjackqdyulei <jackqdyulei@google.com>
Fri, 31 Mar 2017 21:26:38 +0000 (14:26 -0700)
committerjackqdyulei <jackqdyulei@google.com>
Fri, 31 Mar 2017 21:50:40 +0000 (14:50 -0700)
The settings crashes when opening battery usage detail page from
installed app page. Main reason is that it trying to open obsolete
page. This cl directs it to open AdvancedPowerUsageDetail instead.

Following cl will make InstalledAppDetail show calibrated percentage,
which is trakced in b/36816681

Bug: 36792973
Test: RunSettingsRoboTests
Change-Id: Ie63e64e543ed3b28974ffdda8b42c97e7749a0f7

res/values/strings.xml
src/com/android/settings/applications/InstalledAppDetails.java
tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java

index 7f59c70..41bec73 100644 (file)
         Allowing <xliff:g id="app_name" example="Settings">%1$s</xliff:g> to always run in the background may reduce battery life.
         \n\nYou can change this later from Settings > Apps &amp; notifications.</string>
     <!-- Summary of power usage for an app [CHAR LIMIT=NONE] -->
-    <string name="battery_summary"><xliff:g id="percentage" example="2">%1$d</xliff:g>%% use since last full charge</string>
+    <string name="battery_summary"><xliff:g id="percentage" example="2">%1$s</xliff:g> use since last full charge</string>
 
     <!-- Title of a group of settings that let you manage settings that affect battery life [CHAR LIMIT=60] -->
     <string name="battery_power_management">Power management</string>
index 6bec2dd..34df448 100755 (executable)
@@ -88,6 +88,7 @@ import com.android.settings.applications.defaultapps.DefaultSmsPreferenceControl
 import com.android.settings.datausage.AppDataUsage;
 import com.android.settings.datausage.DataUsageList;
 import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
 import com.android.settings.fuelgauge.BatteryEntry;
 import com.android.settings.fuelgauge.PowerUsageDetail;
 import com.android.settings.notification.AppNotificationSettings;
@@ -182,15 +183,18 @@ public class InstalledAppDetails extends AppInfoBase
     private ChartData mChartData;
     private INetworkStatsSession mStatsSession;
 
-    private Preference mBatteryPreference;
-
-    private BatteryStatsHelper mBatteryHelper;
-    private BatterySipper mSipper;
+    @VisibleForTesting
+    Preference mBatteryPreference;
+    @VisibleForTesting
+    BatterySipper mSipper;
+    @VisibleForTesting
+    BatteryStatsHelper mBatteryHelper;
 
     protected ProcStatsData mStatsManager;
     protected ProcStatsPackageEntry mStats;
 
     private AppStorageStats mLastResult;
+    private String mBatteryPercent;
 
     private boolean handleDisableable(Button button) {
         boolean disableable = false;
@@ -683,7 +687,8 @@ public class InstalledAppDetails extends AppInfoBase
                     BatteryStats.STATS_SINCE_CHARGED);
             final int percentOfMax = (int) ((mSipper.totalPowerMah)
                     / mBatteryHelper.getTotalPower() * dischargeAmount + .5f);
-            mBatteryPreference.setSummary(getString(R.string.battery_summary, percentOfMax));
+            mBatteryPercent = Utils.formatPercentage(percentOfMax);
+            mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent));
         } else {
             mBatteryPreference.setEnabled(false);
             mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
@@ -954,9 +959,9 @@ public class InstalledAppDetails extends AppInfoBase
         } else if (preference == mDataPreference) {
             startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage));
         } else if (preference == mBatteryPreference) {
-            BatteryEntry entry = new BatteryEntry(getActivity(), null, mUserManager, mSipper);
-            PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this,
-                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, true, false);
+            BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
+            AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this,
+                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent);
         } else {
             return false;
         }
index da8831d..82067ae 100644 (file)
@@ -22,12 +22,16 @@ import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.os.BatteryStats;
 import android.os.UserManager;
 import android.support.v7.preference.Preference;
 import android.view.View;
 import android.widget.Button;
 
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.instantapps.InstantAppButtonsController;
@@ -48,10 +52,13 @@ import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -61,23 +68,37 @@ import static org.mockito.Mockito.when;
 public final class InstalledAppDetailsTest {
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
-
     @Mock
     ApplicationFeatureProvider mApplicationFeatureProvider;
-
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private UserManager mUserManager;
     @Mock
-    private Activity mActivity;
+    private SettingsActivity mActivity;
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private Preference mBatteryPreference;
+    @Mock
+    private BatterySipper mBatterySipper;
+    @Mock
+    private BatteryStatsHelper mBatteryStatsHelper;
+    @Mock
+    private BatteryStats.Uid mUid;
 
     private InstalledAppDetails mAppDetail;
+    private Context mShadowContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mAppDetail = new InstalledAppDetails();
+        mShadowContext = RuntimeEnvironment.application;
+
+        mAppDetail = spy(new InstalledAppDetails());
+
+        mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
+        mBatterySipper.uidObj = mUid;
+        doReturn(mActivity).when(mAppDetail).getActivity();
+        doReturn(mShadowContext).when(mAppDetail).getContext();
 
         // Default to not considering any apps to be instant (individual tests can override this).
         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
@@ -154,6 +175,16 @@ public final class InstalledAppDetailsTest {
         verify(mActivity, never()).finishAndRemoveTask();
     }
 
+    @Test
+    public void launchPowerUsageDetailFragment_shouldNotCrash() {
+        mAppDetail.mBatteryPreference = mBatteryPreference;
+        mAppDetail.mSipper = mBatterySipper;
+        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
+
+        // Should not crash
+        mAppDetail.onPreferenceClick(mBatteryPreference);
+    }
+
     // Tests that we don't show the "uninstall for all users" button for instant apps.
     @Test
     public void instantApps_noUninstallForAllButton() {
@@ -181,7 +212,7 @@ public final class InstalledAppDetailsTest {
     public void instantApps_noUninstallButton() {
         // Make this app appear to be instant.
         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                                         (InstantAppDataProvider) (i -> true));
+                (InstantAppDataProvider) (i -> true));
         final ApplicationInfo info = new ApplicationInfo();
         info.flags = ApplicationInfo.FLAG_INSTALLED;
         info.enabled = true;