diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java new file mode 100644 index 00000000000..04e2c7a2c12 --- /dev/null +++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java @@ -0,0 +1,91 @@ +/* + * 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.fuelgauge; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.PreferenceScreen; +import android.widget.TextView; + +import com.android.settings.R; +import com.android.settings.applications.LayoutPreference; +import com.android.settings.core.PreferenceController; +import com.android.settingslib.BatteryInfo; +import com.android.settingslib.Utils; + +/** + * Controller that update the battery header view + */ +public class BatteryHeaderPreferenceController extends PreferenceController { + @VisibleForTesting + static final String KEY_BATTERY_HEADER = "battery_header"; + @VisibleForTesting + BatteryMeterView mBatteryMeterView; + @VisibleForTesting + TextView mTimeText; + @VisibleForTesting + TextView mSummary; + + private LayoutPreference mBatteryLayoutPref; + + public BatteryHeaderPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + + mBatteryLayoutPref = (LayoutPreference) screen.findPreference(KEY_BATTERY_HEADER); + mBatteryMeterView = (BatteryMeterView) mBatteryLayoutPref + .findViewById(R.id.battery_header_icon); + mTimeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent); + mSummary = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1); + + Intent batteryBroadcast = mContext.registerReceiver(null, + new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + final int batteryLevel = Utils.getBatteryLevel(batteryBroadcast); + + mBatteryMeterView.setBatteryLevel(batteryLevel); + mTimeText.setText(Utils.formatPercentage(batteryLevel)); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY_BATTERY_HEADER; + } + + public void updateHeaderPreference(BatteryInfo info) { + mTimeText.setText(Utils.formatPercentage(info.batteryLevel)); + if (info.remainingLabel == null) { + mSummary.setText(info.statusLabel); + } else { + mSummary.setText(info.remainingLabel); + } + + mBatteryMeterView.setBatteryLevel(info.batteryLevel); + mBatteryMeterView.setCharging(!info.discharging); + } +} diff --git a/src/com/android/settings/fuelgauge/BatteryMeterView.java b/src/com/android/settings/fuelgauge/BatteryMeterView.java index c450b900cb2..93d8cd8d0e3 100644 --- a/src/com/android/settings/fuelgauge/BatteryMeterView.java +++ b/src/com/android/settings/fuelgauge/BatteryMeterView.java @@ -72,6 +72,10 @@ public class BatteryMeterView extends ImageView { } } + public int getBatteryLevel() { + return mDrawable.getBatteryLevel(); + } + public void setCharging(boolean charging) { mDrawable.setCharging(charging); } diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index b3d07b8abac..6357fe3b703 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -115,6 +115,7 @@ public class PowerUsageSummary extends PowerUsageBase { @VisibleForTesting BatteryUtils mBatteryUtils; + private BatteryHeaderPreferenceController mBatteryHeaderPreferenceController; private LayoutPreference mBatteryLayoutPref; private PreferenceGroup mAppListGroup; private int mStatsType = BatteryStats.STATS_SINCE_CHARGED; @@ -141,11 +142,6 @@ public class PowerUsageSummary extends PowerUsageBase { return MetricsEvent.FUELGAUGE_POWER_USAGE_SUMMARY; } - @Override - public void onResume() { - super.onResume(); - } - @Override public void onPause() { BatteryEntry.stopRequestQueue(); @@ -189,6 +185,8 @@ public class PowerUsageSummary extends PowerUsageBase { @Override protected List getPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); + mBatteryHeaderPreferenceController = new BatteryHeaderPreferenceController(context); + controllers.add(mBatteryHeaderPreferenceController); controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS)); controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT)); controllers.add(new BatterySaverController(context, getLifecycle())); @@ -416,7 +414,7 @@ public class PowerUsageSummary extends PowerUsageBase { new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast, mStatsHelper.getStats(), elapsedRealtimeUs, false); - updateHeaderPreference(batteryInfo); + mBatteryHeaderPreferenceController.updateHeaderPreference(batteryInfo); final TypedValue value = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.colorControlNormal, value, true); @@ -559,27 +557,6 @@ public class PowerUsageSummary extends PowerUsageBase { mStatsType /* STATS_SINCE_CHARGED */) / 1000; } - @VisibleForTesting - void updateHeaderPreference(BatteryInfo info) { - final Context context = getContext(); - if (context == null) { - return; - } - final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref - .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); - } - @VisibleForTesting double calculatePercentage(double powerUsage, double dischargeAmount) { final double totalPower = mStatsHelper.getTotalPower(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java new file mode 100644 index 00000000000..04bb2cf3be4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java @@ -0,0 +1,141 @@ +/* + * 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.fuelgauge; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.content.Intent; +import android.os.BatteryManager; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.widget.TextView; + +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.applications.LayoutPreference; +import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor; +import com.android.settingslib.BatteryInfo; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, + sdk = TestConfig.SDK_VERSION, + shadows = { + SettingsShadowResources.class, + SettingsShadowResources.SettingsShadowTheme.class, + ShadowDynamicIndexableContentMonitor.class + }) +public class BatteryHeaderPreferenceControllerTest { + private static final int BATTERY_LEVEL = 60; + private static final String TIME_LEFT = "2h30min"; + private static final String BATTERY_STATUS = "Charging"; + + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private BatteryInfo mBatteryInfo; + private BatteryHeaderPreferenceController mController; + private Context mContext; + private BatteryMeterView mBatteryMeterView; + private TextView mTimeText; + private TextView mSummary; + private LayoutPreference mBatteryLayoutPref; + private Intent mBatteryIntent; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + mBatteryMeterView = new BatteryMeterView(mContext); + mTimeText = new TextView(mContext); + mSummary = new TextView(mContext); + + mBatteryIntent = new Intent(); + mBatteryIntent.putExtra(BatteryManager.EXTRA_LEVEL, BATTERY_LEVEL); + mBatteryIntent.putExtra(BatteryManager.EXTRA_SCALE, 100); + doReturn(mBatteryIntent).when(mContext).registerReceiver(any(), any()); + + mBatteryLayoutPref = new LayoutPreference(mContext, R.layout.battery_header); + doReturn(mBatteryLayoutPref).when(mPreferenceScreen).findPreference( + BatteryHeaderPreferenceController.KEY_BATTERY_HEADER); + + mBatteryInfo.batteryLevel = BATTERY_LEVEL; + + mController = new BatteryHeaderPreferenceController(mContext); + mController.mBatteryMeterView = mBatteryMeterView; + mController.mTimeText = mTimeText; + mController.mSummary = mSummary; + } + + @Test + public void testDisplayPreference_displayBatteryLevel() { + mController.displayPreference(mPreferenceScreen); + + assertThat(((BatteryMeterView) mBatteryLayoutPref.findViewById( + R.id.battery_header_icon)).getBatteryLevel()).isEqualTo(BATTERY_LEVEL); + assertThat(((TextView) mBatteryLayoutPref.findViewById( + R.id.battery_percent)).getText()).isEqualTo("60%"); + } + + @Test + public void testUpdatePreference_hasRemainingTime_showRemainingLabel() { + mBatteryInfo.remainingLabel = TIME_LEFT; + + mController.updateHeaderPreference(mBatteryInfo); + + assertThat(mSummary.getText()).isEqualTo(mBatteryInfo.remainingLabel); + } + + @Test + public void testUpdatePreference_updateBatteryInfo() { + mBatteryInfo.remainingLabel = TIME_LEFT; + mBatteryInfo.batteryLevel = BATTERY_LEVEL; + mBatteryInfo.discharging = true; + + mController.updateHeaderPreference(mBatteryInfo); + + assertThat(mBatteryMeterView.mDrawable.getBatteryLevel()).isEqualTo(BATTERY_LEVEL); + assertThat(mBatteryMeterView.mDrawable.getCharging()).isEqualTo(false); + } + + @Test + public void testUpdatePreference_noRemainingTime_showStatusLabel() { + mBatteryInfo.remainingLabel = null; + mBatteryInfo.statusLabel = BATTERY_STATUS; + + mController.updateHeaderPreference(mBatteryInfo); + + assertThat(mSummary.getText()).isEqualTo(BATTERY_STATUS); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java index 615424c32c6..ea6c7e67b01 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java @@ -88,12 +88,9 @@ import static org.mockito.Mockito.when; }) public class PowerUsageSummaryTest { private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"}; - private static final String TIME_LEFT = "2h30min"; private static final String STUB_STRING = "stub_string"; - private static final int BATTERY_LEVEL = 55; private static final int UID = 123; private static final int POWER_MAH = 100; - private static final long REMAINING_TIME_US = 100000; private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000; private static final long TIME_SINCE_LAST_FULL_CHARGE_US = TIME_SINCE_LAST_FULL_CHARGE_MS * 1000; @@ -132,8 +129,6 @@ public class PowerUsageSummaryTest { private TextView mBatteryPercentText; @Mock private TextView mSummary1; - @Mock - private BatteryInfo mBatteryInfo; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private BatteryStatsHelper mBatteryHelper; @Mock @@ -206,8 +201,6 @@ public class PowerUsageSummaryTest { mFragment.mScreenUsagePref = mScreenUsagePref; mFragment.mLastFullChargePref = mLastFullChargePref; mFragment.mBatteryUtils = spy(new BatteryUtils(mRealContext)); - - mBatteryInfo.batteryLevel = BATTERY_LEVEL; } @Test @@ -327,45 +320,6 @@ public class PowerUsageSummaryTest { assertThat(mPreference.getSummary().toString()).isEqualTo(expectedSummary); } - @Test - public void testUpdatePreference_hasRemainingTime_showRemainingLabel() { - mBatteryInfo.remainingLabel = TIME_LEFT; - - mFragment.updateHeaderPreference(mBatteryInfo); - - verify(mSummary1).setText(mBatteryInfo.remainingLabel); - } - - @Test - public void testUpdatePreference_updateBatteryInfo() { - mBatteryInfo.remainingLabel = TIME_LEFT; - mBatteryInfo.batteryLevel = BATTERY_LEVEL; - mBatteryInfo.discharging = true; - - mFragment.updateHeaderPreference(mBatteryInfo); - - assertThat(mBatteryMeterView.mDrawable.getBatteryLevel()).isEqualTo(BATTERY_LEVEL); - assertThat(mBatteryMeterView.mDrawable.getCharging()).isEqualTo(false); - } - - @Test - public void testUpdatePreference_noRemainingTime_showStatusLabel() { - mBatteryInfo.remainingLabel = null; - - mFragment.updateHeaderPreference(mBatteryInfo); - - verify(mSummary1).setText(mBatteryInfo.statusLabel); - } - - @Test - public void testUpdateHeaderPreference_asyncUpdate_shouldNotCrash() { - when(mFragment.getContext()).thenReturn(null); - mBatteryInfo.remainingTimeUs = REMAINING_TIME_US; - - //Should not crash - mFragment.updateHeaderPreference(mBatteryInfo); - } - private void testToggleAllApps(final boolean isShowApps) { mFragment.mShowAllApps = isShowApps;