Loading src/com/android/settings/fuelgauge/BatteryMeterView.java +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public class BatteryMeterView extends ImageView { @VisibleForTesting ColorFilter mAccentColorFilter; private int mLevel; public BatteryMeterView(Context context) { this(context, null, 0); } Loading @@ -64,6 +66,7 @@ public class BatteryMeterView extends ImageView { } public void setBatteryLevel(int level) { mLevel = level; mDrawable.setBatteryLevel(level); if (level < mDrawable.getCriticalLevel()) { mDrawable.setBatteryColorFilter(mErrorColorFilter); Loading @@ -72,6 +75,10 @@ public class BatteryMeterView extends ImageView { } } public int getBatteryLevel() { return mLevel; } public void setCharging(boolean charging) { mDrawable.setCharging(charging); } Loading src/com/android/settings/fuelgauge/PowerUsageSummary.java +61 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.fuelgauge; import android.animation.Animator; import android.animation.ValueAnimator; import android.app.Activity; import android.app.LoaderManager; import android.content.Context; Loading Loading @@ -48,6 +50,7 @@ import android.util.SparseArray; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.animation.AnimationUtils; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; Loading Loading @@ -96,6 +99,10 @@ public class PowerUsageSummary extends PowerUsageBase implements private static final String KEY_BATTERY_HEADER = "battery_header"; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10; private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10; private static final int BATTERY_ANIMATION_DURATION_MS_PER_LEVEL = 30; @VisibleForTesting static final String ARG_BATTERY_LEVEL = "key_battery_level"; private static final String KEY_SCREEN_USAGE = "screen_usage"; private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge"; Loading @@ -119,6 +126,8 @@ public class PowerUsageSummary extends PowerUsageBase implements private final FooterPreferenceMixin mFooterPreferenceMixin = new FooterPreferenceMixin(this, getLifecycle()); @VisibleForTesting int mBatteryLevel; @VisibleForTesting boolean mShowAllApps = false; @VisibleForTesting Loading Loading @@ -209,6 +218,8 @@ public class PowerUsageSummary extends PowerUsageBase implements super.onCreate(icicle); setAnimationAllowed(true); mBatteryLevel = getContext().getResources().getInteger( com.android.internal.R.integer.config_criticalBatteryWarningLevel) + 1; mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE); Loading @@ -227,6 +238,14 @@ public class PowerUsageSummary extends PowerUsageBase implements } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (savedInstanceState != null) { mBatteryLevel = savedInstanceState.getInt(ARG_BATTERY_LEVEL); } } @Override public int getMetricsCategory() { return MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY; Loading @@ -235,6 +254,8 @@ public class PowerUsageSummary extends PowerUsageBase implements @Override public void onResume() { super.onResume(); initHeaderPreference(); } @Override Loading @@ -252,6 +273,12 @@ public class PowerUsageSummary extends PowerUsageBase implements } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(ARG_BATTERY_LEVEL, mBatteryLevel); } @Override public boolean onPreferenceTreeClick(Preference preference) { if (mAnomalySummaryPreferenceController.onPreferenceTreeClick(preference)) { Loading Loading @@ -681,15 +708,46 @@ public class PowerUsageSummary extends PowerUsageBase implements .findViewById(R.id.battery_header_icon); final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent); final TextView summary1 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1); timeText.setText(Utils.formatPercentage(info.batteryLevel)); if (info.remainingLabel == null ) { summary1.setText(info.statusLabel); } else { summary1.setText(info.remainingLabel); } batteryView.setBatteryLevel(info.batteryLevel); batteryView.setCharging(!info.discharging); startBatteryHeaderAnimationIfNecessary(batteryView, timeText, mBatteryLevel, info.batteryLevel); } @VisibleForTesting void initHeaderPreference() { final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref .findViewById(R.id.battery_header_icon); final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent); batteryView.setBatteryLevel(mBatteryLevel); timeText.setText(Utils.formatPercentage(mBatteryLevel)); } @VisibleForTesting void startBatteryHeaderAnimationIfNecessary(BatteryMeterView batteryView, TextView timeTextView, int prevLevel, int currentLevel) { mBatteryLevel = currentLevel; final int diff = Math.abs(prevLevel - currentLevel); if (diff != 0) { final ValueAnimator animator = ValueAnimator.ofInt(prevLevel, currentLevel); animator.setDuration(BATTERY_ANIMATION_DURATION_MS_PER_LEVEL * diff); animator.setInterpolator(AnimationUtils.loadInterpolator(getContext(), android.R.interpolator.fast_out_slow_in)); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { final Integer level = (Integer) animation.getAnimatedValue(); batteryView.setBatteryLevel(level); timeTextView.setText(Utils.formatPercentage(level)); } }); animator.start(); } } @VisibleForTesting Loading tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +47 −3 Original line number Diff line number Diff line Loading @@ -131,8 +131,6 @@ public class PowerUsageSummaryTest { @Mock private LayoutPreference mBatteryLayoutPref; @Mock private TextView mBatteryPercentText; @Mock private TextView mSummary1; @Mock private BatteryInfo mBatteryInfo; Loading @@ -147,6 +145,7 @@ public class PowerUsageSummaryTest { @Mock private ContentResolver mContentResolver; private TextView mBatteryPercentText; private List<BatterySipper> mUsageList; private Context mRealContext; private TestFragment mFragment; Loading @@ -171,7 +170,7 @@ public class PowerUsageSummaryTest { mLastFullChargePref = new PowerGaugePreference(mRealContext); mFragment = spy(new TestFragment(mContext)); mFragment.initFeatureProvider(); mBatteryMeterView = new BatteryMeterView(mRealContext); mBatteryMeterView = spy(new BatteryMeterView(mRealContext)); mBatteryMeterView.mDrawable = new BatteryMeterView.BatteryMeterDrawable(mRealContext, 0); when(mFragment.getActivity()).thenReturn(mSettingsActivity); Loading @@ -193,6 +192,7 @@ public class PowerUsageSummaryTest { mCellBatterySipper.drainType = BatterySipper.DrainType.CELL; mCellBatterySipper.totalPowerMah = POWER_MAH; mBatteryPercentText = new TextView(mRealContext); when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1); when(mBatteryLayoutPref.findViewById(R.id.battery_percent)).thenReturn(mBatteryPercentText); when(mBatteryLayoutPref.findViewById(R.id.battery_header_icon)) Loading Loading @@ -285,6 +285,50 @@ public class PowerUsageSummaryTest { testToggleAllApps(false); } @Test public void testInitHeaderPreference_initCorrectly() { mFragment.mBatteryLevel = 100; mFragment.initHeaderPreference(); assertThat(mBatteryMeterView.getBatteryLevel()).isEqualTo(100); assertThat(mBatteryPercentText.getText().toString()).isEqualTo("100%"); } @Test public void testStartBatteryHeaderAnimationIfNecessary_batteryLevelChanged_animationStarted() { final int prevLevel = 100; final int curLevel = 80; mFragment.startBatteryHeaderAnimationIfNecessary(mBatteryMeterView, mBatteryPercentText, prevLevel, curLevel); assertThat(mBatteryMeterView.getBatteryLevel()).isEqualTo(curLevel); assertThat(mBatteryPercentText.getText().toString()).isEqualTo("80%"); } @Test public void testOnSaveInstanceState_saveBatteryLevel() { Bundle bundle = new Bundle(); mFragment.mBatteryLevel = BATTERY_LEVEL; // mock it to stop crash in getPreferenceScreen doReturn(null).when(mFragment).getPreferenceScreen(); mFragment.onSaveInstanceState(bundle); assertThat(bundle.getInt(PowerUsageSummary.ARG_BATTERY_LEVEL)).isEqualTo(BATTERY_LEVEL); } @Test public void testOnActivityCreated_setBatteryLevel() { Bundle bundle = new Bundle(); bundle.putInt(PowerUsageSummary.ARG_BATTERY_LEVEL, BATTERY_LEVEL); mFragment.onActivityCreated(bundle); assertThat(mFragment.mBatteryLevel).isEqualTo(BATTERY_LEVEL); } @Test public void testExtractKeyFromSipper_typeAPPUidObjectNull_returnPackageNames() { mNormalBatterySipper.uidObj = null; Loading Loading
src/com/android/settings/fuelgauge/BatteryMeterView.java +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public class BatteryMeterView extends ImageView { @VisibleForTesting ColorFilter mAccentColorFilter; private int mLevel; public BatteryMeterView(Context context) { this(context, null, 0); } Loading @@ -64,6 +66,7 @@ public class BatteryMeterView extends ImageView { } public void setBatteryLevel(int level) { mLevel = level; mDrawable.setBatteryLevel(level); if (level < mDrawable.getCriticalLevel()) { mDrawable.setBatteryColorFilter(mErrorColorFilter); Loading @@ -72,6 +75,10 @@ public class BatteryMeterView extends ImageView { } } public int getBatteryLevel() { return mLevel; } public void setCharging(boolean charging) { mDrawable.setCharging(charging); } Loading
src/com/android/settings/fuelgauge/PowerUsageSummary.java +61 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.fuelgauge; import android.animation.Animator; import android.animation.ValueAnimator; import android.app.Activity; import android.app.LoaderManager; import android.content.Context; Loading Loading @@ -48,6 +50,7 @@ import android.util.SparseArray; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.animation.AnimationUtils; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; Loading Loading @@ -96,6 +99,10 @@ public class PowerUsageSummary extends PowerUsageBase implements private static final String KEY_BATTERY_HEADER = "battery_header"; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10; private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10; private static final int BATTERY_ANIMATION_DURATION_MS_PER_LEVEL = 30; @VisibleForTesting static final String ARG_BATTERY_LEVEL = "key_battery_level"; private static final String KEY_SCREEN_USAGE = "screen_usage"; private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge"; Loading @@ -119,6 +126,8 @@ public class PowerUsageSummary extends PowerUsageBase implements private final FooterPreferenceMixin mFooterPreferenceMixin = new FooterPreferenceMixin(this, getLifecycle()); @VisibleForTesting int mBatteryLevel; @VisibleForTesting boolean mShowAllApps = false; @VisibleForTesting Loading Loading @@ -209,6 +218,8 @@ public class PowerUsageSummary extends PowerUsageBase implements super.onCreate(icicle); setAnimationAllowed(true); mBatteryLevel = getContext().getResources().getInteger( com.android.internal.R.integer.config_criticalBatteryWarningLevel) + 1; mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE); Loading @@ -227,6 +238,14 @@ public class PowerUsageSummary extends PowerUsageBase implements } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (savedInstanceState != null) { mBatteryLevel = savedInstanceState.getInt(ARG_BATTERY_LEVEL); } } @Override public int getMetricsCategory() { return MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY; Loading @@ -235,6 +254,8 @@ public class PowerUsageSummary extends PowerUsageBase implements @Override public void onResume() { super.onResume(); initHeaderPreference(); } @Override Loading @@ -252,6 +273,12 @@ public class PowerUsageSummary extends PowerUsageBase implements } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(ARG_BATTERY_LEVEL, mBatteryLevel); } @Override public boolean onPreferenceTreeClick(Preference preference) { if (mAnomalySummaryPreferenceController.onPreferenceTreeClick(preference)) { Loading Loading @@ -681,15 +708,46 @@ public class PowerUsageSummary extends PowerUsageBase implements .findViewById(R.id.battery_header_icon); final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent); final TextView summary1 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1); timeText.setText(Utils.formatPercentage(info.batteryLevel)); if (info.remainingLabel == null ) { summary1.setText(info.statusLabel); } else { summary1.setText(info.remainingLabel); } batteryView.setBatteryLevel(info.batteryLevel); batteryView.setCharging(!info.discharging); startBatteryHeaderAnimationIfNecessary(batteryView, timeText, mBatteryLevel, info.batteryLevel); } @VisibleForTesting void initHeaderPreference() { final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref .findViewById(R.id.battery_header_icon); final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent); batteryView.setBatteryLevel(mBatteryLevel); timeText.setText(Utils.formatPercentage(mBatteryLevel)); } @VisibleForTesting void startBatteryHeaderAnimationIfNecessary(BatteryMeterView batteryView, TextView timeTextView, int prevLevel, int currentLevel) { mBatteryLevel = currentLevel; final int diff = Math.abs(prevLevel - currentLevel); if (diff != 0) { final ValueAnimator animator = ValueAnimator.ofInt(prevLevel, currentLevel); animator.setDuration(BATTERY_ANIMATION_DURATION_MS_PER_LEVEL * diff); animator.setInterpolator(AnimationUtils.loadInterpolator(getContext(), android.R.interpolator.fast_out_slow_in)); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { final Integer level = (Integer) animation.getAnimatedValue(); batteryView.setBatteryLevel(level); timeTextView.setText(Utils.formatPercentage(level)); } }); animator.start(); } } @VisibleForTesting Loading
tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +47 −3 Original line number Diff line number Diff line Loading @@ -131,8 +131,6 @@ public class PowerUsageSummaryTest { @Mock private LayoutPreference mBatteryLayoutPref; @Mock private TextView mBatteryPercentText; @Mock private TextView mSummary1; @Mock private BatteryInfo mBatteryInfo; Loading @@ -147,6 +145,7 @@ public class PowerUsageSummaryTest { @Mock private ContentResolver mContentResolver; private TextView mBatteryPercentText; private List<BatterySipper> mUsageList; private Context mRealContext; private TestFragment mFragment; Loading @@ -171,7 +170,7 @@ public class PowerUsageSummaryTest { mLastFullChargePref = new PowerGaugePreference(mRealContext); mFragment = spy(new TestFragment(mContext)); mFragment.initFeatureProvider(); mBatteryMeterView = new BatteryMeterView(mRealContext); mBatteryMeterView = spy(new BatteryMeterView(mRealContext)); mBatteryMeterView.mDrawable = new BatteryMeterView.BatteryMeterDrawable(mRealContext, 0); when(mFragment.getActivity()).thenReturn(mSettingsActivity); Loading @@ -193,6 +192,7 @@ public class PowerUsageSummaryTest { mCellBatterySipper.drainType = BatterySipper.DrainType.CELL; mCellBatterySipper.totalPowerMah = POWER_MAH; mBatteryPercentText = new TextView(mRealContext); when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1); when(mBatteryLayoutPref.findViewById(R.id.battery_percent)).thenReturn(mBatteryPercentText); when(mBatteryLayoutPref.findViewById(R.id.battery_header_icon)) Loading Loading @@ -285,6 +285,50 @@ public class PowerUsageSummaryTest { testToggleAllApps(false); } @Test public void testInitHeaderPreference_initCorrectly() { mFragment.mBatteryLevel = 100; mFragment.initHeaderPreference(); assertThat(mBatteryMeterView.getBatteryLevel()).isEqualTo(100); assertThat(mBatteryPercentText.getText().toString()).isEqualTo("100%"); } @Test public void testStartBatteryHeaderAnimationIfNecessary_batteryLevelChanged_animationStarted() { final int prevLevel = 100; final int curLevel = 80; mFragment.startBatteryHeaderAnimationIfNecessary(mBatteryMeterView, mBatteryPercentText, prevLevel, curLevel); assertThat(mBatteryMeterView.getBatteryLevel()).isEqualTo(curLevel); assertThat(mBatteryPercentText.getText().toString()).isEqualTo("80%"); } @Test public void testOnSaveInstanceState_saveBatteryLevel() { Bundle bundle = new Bundle(); mFragment.mBatteryLevel = BATTERY_LEVEL; // mock it to stop crash in getPreferenceScreen doReturn(null).when(mFragment).getPreferenceScreen(); mFragment.onSaveInstanceState(bundle); assertThat(bundle.getInt(PowerUsageSummary.ARG_BATTERY_LEVEL)).isEqualTo(BATTERY_LEVEL); } @Test public void testOnActivityCreated_setBatteryLevel() { Bundle bundle = new Bundle(); bundle.putInt(PowerUsageSummary.ARG_BATTERY_LEVEL, BATTERY_LEVEL); mFragment.onActivityCreated(bundle); assertThat(mFragment.mBatteryLevel).isEqualTo(BATTERY_LEVEL); } @Test public void testExtractKeyFromSipper_typeAPPUidObjectNull_returnPackageNames() { mNormalBatterySipper.uidObj = null; Loading