Loading packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +29 −27 Original line number Diff line number Diff line Loading @@ -41,24 +41,22 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import com.android.settingslib.graph.ThemedBatteryDrawable; import com.android.systemui.Dependency; import com.android.systemui.DualToneHandler; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.text.NumberFormat; public class BatteryMeterView extends LinearLayout implements BatteryStateChangeCallback, DarkReceiver { public class BatteryMeterView extends LinearLayout implements DarkReceiver { @Retention(SOURCE) @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF, MODE_ESTIMATE}) Loading @@ -72,7 +70,6 @@ public class BatteryMeterView extends LinearLayout implements private final ImageView mBatteryIconView; private TextView mBatteryPercentView; private BatteryController mBatteryController; private final @StyleRes int mPercentageStyleId; private int mTextColor; private int mLevel; Loading @@ -90,6 +87,8 @@ public class BatteryMeterView extends LinearLayout implements private int mNonAdaptedForegroundColor; private int mNonAdaptedBackgroundColor; private BatteryEstimateFetcher mBatteryEstimateFetcher; public BatteryMeterView(Context context, AttributeSet attrs) { this(context, attrs, 0); } Loading Loading @@ -178,22 +177,7 @@ public class BatteryMeterView extends LinearLayout implements return false; } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); mBatteryController = Dependency.get(BatteryController.class); mBatteryController.addCallback(this); updateShowPercent(); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); mBatteryController.removeCallback(this); } @Override public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { void onBatteryLevelChanged(int level, boolean pluggedIn) { mDrawable.setCharging(pluggedIn); mDrawable.setBatteryLevel(level); mCharging = pluggedIn; Loading @@ -201,8 +185,7 @@ public class BatteryMeterView extends LinearLayout implements updatePercentText(); } @Override public void onPowerSaveChanged(boolean isPowerSave) { void onPowerSaveChanged(boolean isPowerSave) { mDrawable.setPowerSaveEnabled(isPowerSave); } Loading @@ -222,19 +205,28 @@ public class BatteryMeterView extends LinearLayout implements updateShowPercent(); } /** * Sets the fetcher that should be used to get the estimated time remaining for the user's * battery. */ void setBatteryEstimateFetcher(BatteryEstimateFetcher fetcher) { mBatteryEstimateFetcher = fetcher; } void updatePercentText() { if (mBatteryStateUnknown) { setContentDescription(getContext().getString(R.string.accessibility_battery_unknown)); return; } if (mBatteryController == null) { if (mBatteryEstimateFetcher == null) { return; } if (mBatteryPercentView != null) { if (mShowPercentMode == MODE_ESTIMATE && !mCharging) { mBatteryController.getEstimatedTimeRemainingString((String estimate) -> { mBatteryEstimateFetcher.fetchBatteryTimeRemainingEstimate( (String estimate) -> { if (mBatteryPercentView == null) { return; } Loading Loading @@ -310,8 +302,7 @@ public class BatteryMeterView extends LinearLayout implements return mUnknownStateDrawable; } @Override public void onBatteryUnknownStateChanged(boolean isUnknown) { void onBatteryUnknownStateChanged(boolean isUnknown) { if (mBatteryStateUnknown == isUnknown) { return; } Loading Loading @@ -390,5 +381,16 @@ public class BatteryMeterView extends LinearLayout implements pw.println(" mLevel: " + mLevel); pw.println(" mMode: " + mShowPercentMode); } @VisibleForTesting CharSequence getBatteryPercentViewText() { return mBatteryPercentView.getText(); } /** An interface that will fetch the estimated time remaining for the user's battery. */ public interface BatteryEstimateFetcher { void fetchBatteryTimeRemainingEstimate( BatteryController.EstimateFetchCompletion completion); } } packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java +30 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.ViewController; Loading @@ -42,6 +43,7 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> private final ConfigurationController mConfigurationController; private final TunerService mTunerService; private final ContentResolver mContentResolver; private final BatteryController mBatteryController; private final String mSlotBattery; private final SettingObserver mSettingObserver; Loading @@ -66,6 +68,24 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> } }; private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback = new BatteryController.BatteryStateChangeCallback() { @Override public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { mView.onBatteryLevelChanged(level, pluggedIn); } @Override public void onPowerSaveChanged(boolean isPowerSave) { mView.onPowerSaveChanged(isPowerSave); } @Override public void onBatteryUnknownStateChanged(boolean isUnknown) { mView.onBatteryUnknownStateChanged(isUnknown); } }; // Some places may need to show the battery conditionally, and not obey the tuner private boolean mIgnoreTunerUpdates; private boolean mIsSubscribedForTunerUpdates; Loading @@ -77,11 +97,15 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> TunerService tunerService, BroadcastDispatcher broadcastDispatcher, @Main Handler mainHandler, ContentResolver contentResolver) { ContentResolver contentResolver, BatteryController batteryController) { super(view); mConfigurationController = configurationController; mTunerService = tunerService; mContentResolver = contentResolver; mBatteryController = batteryController; mView.setBatteryEstimateFetcher(mBatteryController::getEstimatedTimeRemainingString); mSlotBattery = getResources().getString(com.android.internal.R.string.status_bar_battery); mSettingObserver = new SettingObserver(mainHandler); Loading @@ -99,16 +123,21 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> protected void onViewAttached() { mConfigurationController.addCallback(mConfigurationListener); subscribeForTunerUpdates(); mBatteryController.addCallback(mBatteryStateChangeCallback); registerShowBatteryPercentObserver(ActivityManager.getCurrentUser()); registerGlobalBatteryUpdateObserver(); mCurrentUserTracker.startTracking(); mView.updateShowPercent(); } @Override protected void onViewDetached() { mConfigurationController.removeCallback(mConfigurationListener); unsubscribeFromTunerUpdates(); mBatteryController.removeCallback(mBatteryStateChangeCallback); mCurrentUserTracker.stopTracking(); mContentResolver.unregisterContentObserver(mSettingObserver); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +2 −1 Original line number Diff line number Diff line Loading @@ -1143,7 +1143,8 @@ public class StatusBar extends SystemUI implements mTunerService, mBroadcastDispatcher, mMainHandler, mContext.getContentResolver() mContext.getContentResolver(), mBatteryController ); mBatteryMeterViewController.init(); Loading packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java +7 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; Loading @@ -58,6 +59,8 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { private Handler mHandler; @Mock private ContentResolver mContentResolver; @Mock private BatteryController mBatteryController; private BatteryMeterViewController mController; Loading @@ -74,7 +77,8 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { mTunerService, mBroadcastDispatcher, mHandler, mContentResolver mContentResolver, mBatteryController ); } Loading @@ -92,6 +96,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { anyBoolean(), any() ); verify(mBatteryController).addCallback(any()); } @Test Loading @@ -104,6 +109,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { verify(mConfigurationController).removeCallback(any()); verify(mTunerService).removeTunable(any()); verify(mContentResolver).unregisterContentObserver(any()); verify(mBatteryController).removeCallback(any()); } @Test Loading packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.systemui.battery import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.battery.BatteryMeterView.BatteryEstimateFetcher import com.android.systemui.statusbar.policy.BatteryController.EstimateFetchCompletion import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) @RunWithLooper class BatteryMeterViewTest : SysuiTestCase() { private lateinit var mBatteryMeterView: BatteryMeterView @Before fun setUp() { MockitoAnnotations.initMocks(this) mBatteryMeterView = BatteryMeterView(mContext, null) } @Test fun updatePercentText_estimateModeAndNotCharging_estimateFetched() { mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) mBatteryMeterView.setBatteryEstimateFetcher(Fetcher()) mBatteryMeterView.updatePercentText() assertThat(mBatteryMeterView.batteryPercentViewText).isEqualTo(ESTIMATE) } @Test fun updatePercentText_noBatteryEstimateFetcher_noCrash() { mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) mBatteryMeterView.updatePercentText() // No assert needed } private class Fetcher : BatteryEstimateFetcher { override fun fetchBatteryTimeRemainingEstimate( completion: EstimateFetchCompletion) { completion.onBatteryRemainingEstimateRetrieved(ESTIMATE) } } private companion object { const val ESTIMATE = "2 hours 2 minutes" } } No newline at end of file Loading
packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +29 −27 Original line number Diff line number Diff line Loading @@ -41,24 +41,22 @@ import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import com.android.settingslib.graph.ThemedBatteryDrawable; import com.android.systemui.Dependency; import com.android.systemui.DualToneHandler; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.text.NumberFormat; public class BatteryMeterView extends LinearLayout implements BatteryStateChangeCallback, DarkReceiver { public class BatteryMeterView extends LinearLayout implements DarkReceiver { @Retention(SOURCE) @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF, MODE_ESTIMATE}) Loading @@ -72,7 +70,6 @@ public class BatteryMeterView extends LinearLayout implements private final ImageView mBatteryIconView; private TextView mBatteryPercentView; private BatteryController mBatteryController; private final @StyleRes int mPercentageStyleId; private int mTextColor; private int mLevel; Loading @@ -90,6 +87,8 @@ public class BatteryMeterView extends LinearLayout implements private int mNonAdaptedForegroundColor; private int mNonAdaptedBackgroundColor; private BatteryEstimateFetcher mBatteryEstimateFetcher; public BatteryMeterView(Context context, AttributeSet attrs) { this(context, attrs, 0); } Loading Loading @@ -178,22 +177,7 @@ public class BatteryMeterView extends LinearLayout implements return false; } @Override public void onAttachedToWindow() { super.onAttachedToWindow(); mBatteryController = Dependency.get(BatteryController.class); mBatteryController.addCallback(this); updateShowPercent(); } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); mBatteryController.removeCallback(this); } @Override public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { void onBatteryLevelChanged(int level, boolean pluggedIn) { mDrawable.setCharging(pluggedIn); mDrawable.setBatteryLevel(level); mCharging = pluggedIn; Loading @@ -201,8 +185,7 @@ public class BatteryMeterView extends LinearLayout implements updatePercentText(); } @Override public void onPowerSaveChanged(boolean isPowerSave) { void onPowerSaveChanged(boolean isPowerSave) { mDrawable.setPowerSaveEnabled(isPowerSave); } Loading @@ -222,19 +205,28 @@ public class BatteryMeterView extends LinearLayout implements updateShowPercent(); } /** * Sets the fetcher that should be used to get the estimated time remaining for the user's * battery. */ void setBatteryEstimateFetcher(BatteryEstimateFetcher fetcher) { mBatteryEstimateFetcher = fetcher; } void updatePercentText() { if (mBatteryStateUnknown) { setContentDescription(getContext().getString(R.string.accessibility_battery_unknown)); return; } if (mBatteryController == null) { if (mBatteryEstimateFetcher == null) { return; } if (mBatteryPercentView != null) { if (mShowPercentMode == MODE_ESTIMATE && !mCharging) { mBatteryController.getEstimatedTimeRemainingString((String estimate) -> { mBatteryEstimateFetcher.fetchBatteryTimeRemainingEstimate( (String estimate) -> { if (mBatteryPercentView == null) { return; } Loading Loading @@ -310,8 +302,7 @@ public class BatteryMeterView extends LinearLayout implements return mUnknownStateDrawable; } @Override public void onBatteryUnknownStateChanged(boolean isUnknown) { void onBatteryUnknownStateChanged(boolean isUnknown) { if (mBatteryStateUnknown == isUnknown) { return; } Loading Loading @@ -390,5 +381,16 @@ public class BatteryMeterView extends LinearLayout implements pw.println(" mLevel: " + mLevel); pw.println(" mMode: " + mShowPercentMode); } @VisibleForTesting CharSequence getBatteryPercentViewText() { return mBatteryPercentView.getText(); } /** An interface that will fetch the estimated time remaining for the user's battery. */ public interface BatteryEstimateFetcher { void fetchBatteryTimeRemainingEstimate( BatteryController.EstimateFetchCompletion completion); } }
packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java +30 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.ViewController; Loading @@ -42,6 +43,7 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> private final ConfigurationController mConfigurationController; private final TunerService mTunerService; private final ContentResolver mContentResolver; private final BatteryController mBatteryController; private final String mSlotBattery; private final SettingObserver mSettingObserver; Loading @@ -66,6 +68,24 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> } }; private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback = new BatteryController.BatteryStateChangeCallback() { @Override public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { mView.onBatteryLevelChanged(level, pluggedIn); } @Override public void onPowerSaveChanged(boolean isPowerSave) { mView.onPowerSaveChanged(isPowerSave); } @Override public void onBatteryUnknownStateChanged(boolean isUnknown) { mView.onBatteryUnknownStateChanged(isUnknown); } }; // Some places may need to show the battery conditionally, and not obey the tuner private boolean mIgnoreTunerUpdates; private boolean mIsSubscribedForTunerUpdates; Loading @@ -77,11 +97,15 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> TunerService tunerService, BroadcastDispatcher broadcastDispatcher, @Main Handler mainHandler, ContentResolver contentResolver) { ContentResolver contentResolver, BatteryController batteryController) { super(view); mConfigurationController = configurationController; mTunerService = tunerService; mContentResolver = contentResolver; mBatteryController = batteryController; mView.setBatteryEstimateFetcher(mBatteryController::getEstimatedTimeRemainingString); mSlotBattery = getResources().getString(com.android.internal.R.string.status_bar_battery); mSettingObserver = new SettingObserver(mainHandler); Loading @@ -99,16 +123,21 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView> protected void onViewAttached() { mConfigurationController.addCallback(mConfigurationListener); subscribeForTunerUpdates(); mBatteryController.addCallback(mBatteryStateChangeCallback); registerShowBatteryPercentObserver(ActivityManager.getCurrentUser()); registerGlobalBatteryUpdateObserver(); mCurrentUserTracker.startTracking(); mView.updateShowPercent(); } @Override protected void onViewDetached() { mConfigurationController.removeCallback(mConfigurationListener); unsubscribeFromTunerUpdates(); mBatteryController.removeCallback(mBatteryStateChangeCallback); mCurrentUserTracker.stopTracking(); mContentResolver.unregisterContentObserver(mSettingObserver); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +2 −1 Original line number Diff line number Diff line Loading @@ -1143,7 +1143,8 @@ public class StatusBar extends SystemUI implements mTunerService, mBroadcastDispatcher, mMainHandler, mContext.getContentResolver() mContext.getContentResolver(), mBatteryController ); mBatteryMeterViewController.init(); Loading
packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java +7 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tuner.TunerService; Loading @@ -58,6 +59,8 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { private Handler mHandler; @Mock private ContentResolver mContentResolver; @Mock private BatteryController mBatteryController; private BatteryMeterViewController mController; Loading @@ -74,7 +77,8 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { mTunerService, mBroadcastDispatcher, mHandler, mContentResolver mContentResolver, mBatteryController ); } Loading @@ -92,6 +96,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { anyBoolean(), any() ); verify(mBatteryController).addCallback(any()); } @Test Loading @@ -104,6 +109,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase { verify(mConfigurationController).removeCallback(any()); verify(mTunerService).removeTunable(any()); verify(mContentResolver).unregisterContentObserver(any()); verify(mBatteryController).removeCallback(any()); } @Test Loading
packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.systemui.battery import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.battery.BatteryMeterView.BatteryEstimateFetcher import com.android.systemui.statusbar.policy.BatteryController.EstimateFetchCompletion import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) @RunWithLooper class BatteryMeterViewTest : SysuiTestCase() { private lateinit var mBatteryMeterView: BatteryMeterView @Before fun setUp() { MockitoAnnotations.initMocks(this) mBatteryMeterView = BatteryMeterView(mContext, null) } @Test fun updatePercentText_estimateModeAndNotCharging_estimateFetched() { mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) mBatteryMeterView.setBatteryEstimateFetcher(Fetcher()) mBatteryMeterView.updatePercentText() assertThat(mBatteryMeterView.batteryPercentViewText).isEqualTo(ESTIMATE) } @Test fun updatePercentText_noBatteryEstimateFetcher_noCrash() { mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) mBatteryMeterView.updatePercentText() // No assert needed } private class Fetcher : BatteryEstimateFetcher { override fun fetchBatteryTimeRemainingEstimate( completion: EstimateFetchCompletion) { completion.onBatteryRemainingEstimateRetrieved(ESTIMATE) } } private companion object { const val ESTIMATE = "2 hours 2 minutes" } } No newline at end of file