diff --git a/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java new file mode 100644 index 00000000000..9d373337c49 --- /dev/null +++ b/src/com/android/settings/fuelgauge/BatteryBroadcastReceiver.java @@ -0,0 +1,87 @@ +/* + * 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.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.annotation.VisibleForTesting; + +import com.android.settings.Utils; + +/** + * Use this broadcastReceiver to listen to the battery change, and it will invoke + * {@link OnBatteryChangedListener} if any of the following happens: + * + * 1. Battery level has been changed + * 2. Battery status has been changed + */ +public class BatteryBroadcastReceiver extends BroadcastReceiver { + + interface OnBatteryChangedListener { + void onBatteryChanged(); + } + + @VisibleForTesting + String mBatteryLevel; + @VisibleForTesting + String mBatteryStatus; + private OnBatteryChangedListener mBatteryListener; + private Context mContext; + + public BatteryBroadcastReceiver(Context context) { + mContext = context; + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (mBatteryListener != null && Intent.ACTION_BATTERY_CHANGED.equals(action) + && updateBatteryStatus(intent)) { + mBatteryListener.onBatteryChanged(); + } + } + + public void setBatteryChangedListener(OnBatteryChangedListener lsn) { + mBatteryListener = lsn; + } + + public void register() { + mContext.registerReceiver(this, + new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + } + + public void unRegister() { + mContext.unregisterReceiver(this); + } + + private boolean updateBatteryStatus(Intent intent) { + if (intent != null) { + String batteryLevel = Utils.getBatteryPercentage(intent); + String batteryStatus = Utils.getBatteryStatus( + mContext.getResources(), intent); + if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) { + mBatteryLevel = batteryLevel; + mBatteryStatus = batteryStatus; + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/src/com/android/settings/fuelgauge/PowerUsageBase.java b/src/com/android/settings/fuelgauge/PowerUsageBase.java index 0236a306597..1d9a2287e8d 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageBase.java +++ b/src/com/android/settings/fuelgauge/PowerUsageBase.java @@ -45,9 +45,7 @@ public abstract class PowerUsageBase extends DashboardFragment { protected BatteryStatsHelper mStatsHelper; protected UserManager mUm; - - private String mBatteryLevel; - private String mBatteryStatus; + private BatteryBroadcastReceiver mBatteryBroadcastReceiver; @Override public void onAttach(Activity activity) { @@ -61,6 +59,13 @@ public abstract class PowerUsageBase extends DashboardFragment { super.onCreate(icicle); mStatsHelper.create(icicle); setHasOptionsMenu(true); + + mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext()); + mBatteryBroadcastReceiver.setBatteryChangedListener(() -> { + if (!mHandler.hasMessages(MSG_REFRESH_STATS)) { + mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500); + } + }); } @Override @@ -73,8 +78,7 @@ public abstract class PowerUsageBase extends DashboardFragment { public void onResume() { super.onResume(); BatteryStatsHelper.dropFile(getActivity(), BatteryHistoryDetail.BATTERY_HISTORY_FILE); - updateBatteryStatus(getActivity().registerReceiver(mBatteryInfoReceiver, - new IntentFilter(Intent.ACTION_BATTERY_CHANGED))); + mBatteryBroadcastReceiver.register(); if (mHandler.hasMessages(MSG_REFRESH_STATS)) { mHandler.removeMessages(MSG_REFRESH_STATS); mStatsHelper.clearStats(); @@ -84,7 +88,7 @@ public abstract class PowerUsageBase extends DashboardFragment { @Override public void onPause() { super.onPause(); - getActivity().unregisterReceiver(mBatteryInfoReceiver); + mBatteryBroadcastReceiver.unRegister(); } @Override @@ -109,20 +113,6 @@ public abstract class PowerUsageBase extends DashboardFragment { historyPref.setStats(mStatsHelper); } - private boolean updateBatteryStatus(Intent intent) { - if (intent != null) { - String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent); - String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(), - intent); - if (!batteryLevel.equals(mBatteryLevel) || !batteryStatus.equals(mBatteryStatus)) { - mBatteryLevel = batteryLevel; - mBatteryStatus = batteryStatus; - return true; - } - } - return false; - } - static final int MSG_REFRESH_STATS = 100; private final Handler mHandler = new Handler() { @@ -137,17 +127,4 @@ public abstract class PowerUsageBase extends DashboardFragment { } }; - private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_BATTERY_CHANGED.equals(action) - && updateBatteryStatus(intent)) { - if (!mHandler.hasMessages(MSG_REFRESH_STATS)) { - mHandler.sendEmptyMessageDelayed(MSG_REFRESH_STATS, 500); - } - } - } - }; - } diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index ac041b84802..5f12d7c30ed 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -683,22 +683,28 @@ public class PowerUsageSummary extends PowerUsageBase { private static class SummaryProvider implements SummaryLoader.SummaryProvider { private final Context mContext; private final SummaryLoader mLoader; + private final BatteryBroadcastReceiver mBatteryBroadcastReceiver; private SummaryProvider(Context context, SummaryLoader loader) { mContext = context; mLoader = loader; - } - - @Override - public void setListening(boolean listening) { - if (listening) { - // TODO: Listen. + mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext); + mBatteryBroadcastReceiver.setBatteryChangedListener(() -> { BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() { @Override public void onBatteryInfoLoaded(BatteryInfo info) { mLoader.setSummary(SummaryProvider.this, info.chargeLabelString); } }); + }); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + mBatteryBroadcastReceiver.register(); + } else { + mBatteryBroadcastReceiver.unRegister(); } } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java new file mode 100644 index 00000000000..799dab99e4e --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBroadcastReceiverTest.java @@ -0,0 +1,95 @@ +/* + * 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.os.BatteryManager; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.Utils; + +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; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class BatteryBroadcastReceiverTest { + private static final String BATTERY_INIT_LEVEL = "100%"; + private static final String BATTERY_INIT_STATUS = "Not charging"; + private static final int BATTERY_INTENT_LEVEL = 80; + private static final int BATTERY_INTENT_SCALE = 100; + + @Mock + private BatteryBroadcastReceiver.OnBatteryChangedListener mBatteryListener; + private BatteryBroadcastReceiver mBatteryBroadcastReceiver; + private Context mContext; + private Intent mChargingIntent; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + + mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext); + mBatteryBroadcastReceiver.mBatteryLevel = BATTERY_INIT_LEVEL; + mBatteryBroadcastReceiver.mBatteryStatus = BATTERY_INIT_STATUS; + mBatteryBroadcastReceiver.setBatteryChangedListener(mBatteryListener); + + mChargingIntent = new Intent(Intent.ACTION_BATTERY_CHANGED); + mChargingIntent.putExtra(BatteryManager.EXTRA_LEVEL, BATTERY_INTENT_LEVEL); + mChargingIntent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_INTENT_SCALE); + mChargingIntent.putExtra(BatteryManager.EXTRA_STATUS, + BatteryManager.BATTERY_STATUS_CHARGING); + } + + @Test + public void testOnReceive_batteryDataChanged_dataUpdated() { + mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent); + + assertThat(mBatteryBroadcastReceiver.mBatteryLevel).isEqualTo( + Utils.getBatteryPercentage(mChargingIntent)); + assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo( + Utils.getBatteryStatus(mContext.getResources(), mChargingIntent)); + verify(mBatteryListener).onBatteryChanged(); + } + + @Test + public void testOnReceive_batteryDataNotChanged_listenerNotInvoked() { + final String batteryLevel = Utils.getBatteryPercentage(mChargingIntent); + final String batteryStatus = Utils.getBatteryStatus(mContext.getResources(), + mChargingIntent); + mBatteryBroadcastReceiver.mBatteryLevel = batteryLevel; + mBatteryBroadcastReceiver.mBatteryStatus = batteryStatus; + + mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent); + + assertThat(mBatteryBroadcastReceiver.mBatteryLevel).isEqualTo(batteryLevel); + assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo(batteryStatus); + verify(mBatteryListener, never()).onBatteryChanged(); + } + +}