Merge "Update battery icon for incompatible charging" into udc-qpr-dev
This commit is contained in:
@@ -178,6 +178,11 @@ class AccessorizedBatteryDrawable(
|
||||
mainBatteryDrawable.charging = charging
|
||||
}
|
||||
|
||||
/** Returns whether the battery is currently charging. */
|
||||
fun getCharging(): Boolean {
|
||||
return mainBatteryDrawable.charging
|
||||
}
|
||||
|
||||
/** Sets the current level (out of 100) of the battery. */
|
||||
fun setBatteryLevel(level: Int) {
|
||||
mainBatteryDrawable.setBatteryLevel(level)
|
||||
|
||||
@@ -77,8 +77,9 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
private int mShowPercentMode = MODE_DEFAULT;
|
||||
private boolean mShowPercentAvailable;
|
||||
private String mEstimateText = null;
|
||||
private boolean mCharging;
|
||||
private boolean mPluggedIn;
|
||||
private boolean mIsBatteryDefender;
|
||||
private boolean mIsIncompatibleCharging;
|
||||
private boolean mDisplayShieldEnabled;
|
||||
// Error state where we know nothing about the current battery state
|
||||
private boolean mBatteryStateUnknown;
|
||||
@@ -202,10 +203,10 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
* @param pluggedIn whether the device is plugged in or not
|
||||
*/
|
||||
public void onBatteryLevelChanged(@IntRange(from = 0, to = 100) int level, boolean pluggedIn) {
|
||||
mDrawable.setCharging(pluggedIn);
|
||||
mDrawable.setBatteryLevel(level);
|
||||
mCharging = pluggedIn;
|
||||
mPluggedIn = pluggedIn;
|
||||
mLevel = level;
|
||||
mDrawable.setCharging(isCharging());
|
||||
mDrawable.setBatteryLevel(level);
|
||||
updatePercentText();
|
||||
}
|
||||
|
||||
@@ -224,6 +225,15 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
void onIsIncompatibleChargingChanged(boolean isIncompatibleCharging) {
|
||||
boolean valueChanged = mIsIncompatibleCharging != isIncompatibleCharging;
|
||||
mIsIncompatibleCharging = isIncompatibleCharging;
|
||||
if (valueChanged) {
|
||||
mDrawable.setCharging(isCharging());
|
||||
updateContentDescription();
|
||||
}
|
||||
}
|
||||
|
||||
private TextView loadPercentView() {
|
||||
return (TextView) LayoutInflater.from(getContext())
|
||||
.inflate(R.layout.battery_percentage_view, null);
|
||||
@@ -263,7 +273,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
}
|
||||
|
||||
if (mBatteryPercentView != null) {
|
||||
if (mShowPercentMode == MODE_ESTIMATE && !mCharging) {
|
||||
if (mShowPercentMode == MODE_ESTIMATE && !isCharging()) {
|
||||
mBatteryEstimateFetcher.fetchBatteryTimeRemainingEstimate(
|
||||
(String estimate) -> {
|
||||
if (mBatteryPercentView == null) {
|
||||
@@ -316,7 +326,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
} else if (mIsBatteryDefender) {
|
||||
contentDescription =
|
||||
context.getString(R.string.accessibility_battery_level_charging_paused, mLevel);
|
||||
} else if (mCharging) {
|
||||
} else if (isCharging()) {
|
||||
contentDescription =
|
||||
context.getString(R.string.accessibility_battery_level_charging, mLevel);
|
||||
} else {
|
||||
@@ -462,16 +472,24 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCharging() {
|
||||
return mPluggedIn && !mIsIncompatibleCharging;
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw, String[] args) {
|
||||
String powerSave = mDrawable == null ? null : mDrawable.getPowerSaveEnabled() + "";
|
||||
String displayShield = mDrawable == null ? null : mDrawable.getDisplayShield() + "";
|
||||
String charging = mDrawable == null ? null : mDrawable.getCharging() + "";
|
||||
CharSequence percent = mBatteryPercentView == null ? null : mBatteryPercentView.getText();
|
||||
pw.println(" BatteryMeterView:");
|
||||
pw.println(" mDrawable.getPowerSave: " + powerSave);
|
||||
pw.println(" mDrawable.getDisplayShield: " + displayShield);
|
||||
pw.println(" mDrawable.getCharging: " + charging);
|
||||
pw.println(" mBatteryPercentView.getText(): " + percent);
|
||||
pw.println(" mTextColor: #" + Integer.toHexString(mTextColor));
|
||||
pw.println(" mBatteryStateUnknown: " + mBatteryStateUnknown);
|
||||
pw.println(" mIsIncompatibleCharging: " + mIsIncompatibleCharging);
|
||||
pw.println(" mPluggedIn: " + mPluggedIn);
|
||||
pw.println(" mLevel: " + mLevel);
|
||||
pw.println(" mMode: " + mShowPercentMode);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
import com.android.systemui.statusbar.phone.StatusBarLocation;
|
||||
@@ -50,6 +52,7 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView>
|
||||
private final TunerService mTunerService;
|
||||
private final Handler mMainHandler;
|
||||
private final ContentResolver mContentResolver;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final BatteryController mBatteryController;
|
||||
|
||||
private final String mSlotBattery;
|
||||
@@ -98,6 +101,13 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView>
|
||||
mView.onIsBatteryDefenderChanged(isBatteryDefender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIsIncompatibleChargingChanged(boolean isIncompatibleCharging) {
|
||||
if (mFeatureFlags.isEnabled(Flags.INCOMPATIBLE_CHARGING_BATTERY_ICON)) {
|
||||
mView.onIsIncompatibleChargingChanged(isIncompatibleCharging);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
||||
pw.print(super.toString());
|
||||
@@ -129,6 +139,7 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView>
|
||||
TunerService tunerService,
|
||||
@Main Handler mainHandler,
|
||||
ContentResolver contentResolver,
|
||||
FeatureFlags featureFlags,
|
||||
BatteryController batteryController) {
|
||||
super(view);
|
||||
mLocation = location;
|
||||
@@ -137,6 +148,7 @@ public class BatteryMeterViewController extends ViewController<BatteryMeterView>
|
||||
mTunerService = tunerService;
|
||||
mMainHandler = mainHandler;
|
||||
mContentResolver = contentResolver;
|
||||
mFeatureFlags = featureFlags;
|
||||
mBatteryController = batteryController;
|
||||
|
||||
mView.setBatteryEstimateFetcher(mBatteryController::getEstimatedTimeRemainingString);
|
||||
|
||||
@@ -273,6 +273,7 @@ abstract class ShadeViewProviderModule {
|
||||
tunerService: TunerService,
|
||||
@Main mainHandler: Handler,
|
||||
contentResolver: ContentResolver,
|
||||
featureFlags: FeatureFlags,
|
||||
batteryController: BatteryController,
|
||||
): BatteryMeterViewController {
|
||||
return BatteryMeterViewController(
|
||||
@@ -283,6 +284,7 @@ abstract class ShadeViewProviderModule {
|
||||
tunerService,
|
||||
mainHandler,
|
||||
contentResolver,
|
||||
featureFlags,
|
||||
batteryController,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -162,6 +162,9 @@ public interface BatteryController extends DemoMode,
|
||||
default void onIsBatteryDefenderChanged(boolean isBatteryDefender) {
|
||||
}
|
||||
|
||||
default void onIsIncompatibleChargingChanged(boolean isIncompatibleCharging) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
||||
pw.println(this);
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -42,6 +43,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||
import com.android.settingslib.fuelgauge.Estimate;
|
||||
import com.android.settingslib.utils.PowerUtil;
|
||||
@@ -97,6 +99,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
private boolean mAodPowerSave;
|
||||
private boolean mWirelessCharging;
|
||||
private boolean mIsBatteryDefender = false;
|
||||
private boolean mIsIncompatibleCharging = false;
|
||||
private boolean mTestMode = false;
|
||||
@VisibleForTesting
|
||||
boolean mHasReceivedBattery = false;
|
||||
@@ -136,6 +139,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
|
||||
filter.addAction(ACTION_LEVEL_TEST);
|
||||
filter.addAction(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
|
||||
mBroadcastDispatcher.registerReceiver(this, filter);
|
||||
}
|
||||
|
||||
@@ -169,6 +173,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
ipw.print("mCharging="); ipw.println(mCharging);
|
||||
ipw.print("mCharged="); ipw.println(mCharged);
|
||||
ipw.print("mIsBatteryDefender="); ipw.println(mIsBatteryDefender);
|
||||
ipw.print("mIsIncompatibleCharging="); ipw.println(mIsIncompatibleCharging);
|
||||
ipw.print("mPowerSave="); ipw.println(mPowerSave);
|
||||
ipw.print("mStateUnknown="); ipw.println(mStateUnknown);
|
||||
ipw.println("Callbacks:------------------");
|
||||
@@ -214,6 +219,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
cb.onBatteryUnknownStateChanged(mStateUnknown);
|
||||
cb.onWirelessChargingChanged(mWirelessCharging);
|
||||
cb.onIsBatteryDefenderChanged(mIsBatteryDefender);
|
||||
cb.onIsIncompatibleChargingChanged(mIsIncompatibleCharging);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,7 +235,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
|
||||
if (mTestMode && !intent.getBooleanExtra("testmode", false)) return;
|
||||
mHasReceivedBattery = true;
|
||||
mLevel = (int)(100f
|
||||
mLevel = (int) (100f
|
||||
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
|
||||
/ intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
|
||||
mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
|
||||
@@ -262,6 +268,12 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
fireBatteryLevelChanged();
|
||||
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
|
||||
updatePowerSave();
|
||||
} else if (action.equals(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED)) {
|
||||
boolean isIncompatibleCharging = Utils.containsIncompatibleChargers(mContext, TAG);
|
||||
if (isIncompatibleCharging != mIsIncompatibleCharging) {
|
||||
mIsIncompatibleCharging = isIncompatibleCharging;
|
||||
fireIsIncompatibleChargingChanged();
|
||||
}
|
||||
} else if (action.equals(ACTION_LEVEL_TEST)) {
|
||||
mTestMode = true;
|
||||
mMainHandler.post(new Runnable() {
|
||||
@@ -270,6 +282,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
int mSavedLevel = mLevel;
|
||||
boolean mSavedPluggedIn = mPluggedIn;
|
||||
Intent mTestIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mCurrentLevel < 0) {
|
||||
@@ -333,6 +346,13 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
return mIsBatteryDefender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the charging adapter is incompatible.
|
||||
*/
|
||||
public boolean isIncompatibleCharging() {
|
||||
return mIsIncompatibleCharging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getEstimatedTimeRemainingString(EstimateFetchCompletion completion) {
|
||||
// Need to fetch or refresh the estimate, but it may involve binder calls so offload the
|
||||
@@ -453,6 +473,15 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
}
|
||||
}
|
||||
|
||||
private void fireIsIncompatibleChargingChanged() {
|
||||
synchronized (mChangeCallbacks) {
|
||||
final int n = mChangeCallbacks.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
mChangeCallbacks.get(i).onIsIncompatibleChargingChanged(mIsIncompatibleCharging);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDemoCommand(String command, Bundle args) {
|
||||
if (!mDemoModeController.isInDemoMode()) {
|
||||
@@ -464,6 +493,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
String powerSave = args.getString("powersave");
|
||||
String present = args.getString("present");
|
||||
String defender = args.getString("defender");
|
||||
String incompatible = args.getString("incompatible");
|
||||
if (level != null) {
|
||||
mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
|
||||
}
|
||||
@@ -482,6 +512,10 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
|
||||
mIsBatteryDefender = defender.equals("true");
|
||||
fireIsBatteryDefenderChanged();
|
||||
}
|
||||
if (incompatible != null) {
|
||||
mIsIncompatibleCharging = incompatible.equals("true");
|
||||
fireIsIncompatibleChargingChanged();
|
||||
}
|
||||
fireBatteryLevelChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.StatusBarLocation;
|
||||
import com.android.systemui.statusbar.policy.BatteryController;
|
||||
@@ -63,6 +64,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase {
|
||||
private ContentResolver mContentResolver;
|
||||
@Mock
|
||||
private BatteryController mBatteryController;
|
||||
private FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
|
||||
|
||||
private BatteryMeterViewController mController;
|
||||
|
||||
@@ -160,6 +162,7 @@ public class BatteryMeterViewControllerTest extends SysuiTestCase {
|
||||
mTunerService,
|
||||
mHandler,
|
||||
mContentResolver,
|
||||
mFakeFeatureFlags,
|
||||
mBatteryController
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,16 @@ class BatteryMeterViewTest : SysuiTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contentDescription_isIncompatibleCharging_notCharging() {
|
||||
mBatteryMeterView.onBatteryLevelChanged(45, true)
|
||||
mBatteryMeterView.onIsIncompatibleChargingChanged(true)
|
||||
|
||||
assertThat(mBatteryMeterView.contentDescription).isEqualTo(
|
||||
context.getString(R.string.accessibility_battery_level, 45)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changesFromEstimateToPercent_textAndContentDescriptionChanges() {
|
||||
mBatteryMeterView.onBatteryLevelChanged(15, false)
|
||||
@@ -231,14 +241,33 @@ class BatteryMeterViewTest : SysuiTestCase() {
|
||||
assertThat(drawable.displayShield).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isIncompatibleChargingChanged_true_drawableGetsChargingFalse() {
|
||||
mBatteryMeterView.onBatteryLevelChanged(45, true)
|
||||
val drawable = getBatteryDrawable()
|
||||
|
||||
mBatteryMeterView.onIsIncompatibleChargingChanged(true)
|
||||
|
||||
assertThat(drawable.getCharging()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isIncompatibleChargingChanged_false_drawableGetsChargingTrue() {
|
||||
mBatteryMeterView.onBatteryLevelChanged(45, true)
|
||||
val drawable = getBatteryDrawable()
|
||||
|
||||
mBatteryMeterView.onIsIncompatibleChargingChanged(false)
|
||||
|
||||
assertThat(drawable.getCharging()).isTrue()
|
||||
}
|
||||
|
||||
private fun getBatteryDrawable(): AccessorizedBatteryDrawable {
|
||||
return (mBatteryMeterView.getChildAt(0) as ImageView)
|
||||
.drawable as AccessorizedBatteryDrawable
|
||||
}
|
||||
|
||||
private class Fetcher : BatteryEstimateFetcher {
|
||||
override fun fetchBatteryTimeRemainingEstimate(
|
||||
completion: EstimateFetchCompletion) {
|
||||
override fun fetchBatteryTimeRemainingEstimate(completion: EstimateFetchCompletion) {
|
||||
completion.onBatteryRemainingEstimateRetrieved(ESTIMATE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.hardware.usb.UsbPortStatus;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
@@ -56,6 +59,9 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.MockitoSession;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
@@ -65,8 +71,10 @@ public class BatteryControllerTest extends SysuiTestCase {
|
||||
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock private DemoModeController mDemoModeController;
|
||||
@Mock private View mView;
|
||||
@Mock private UsbPort mUsbPort;
|
||||
@Mock private UsbManager mUsbManager;
|
||||
@Mock private UsbPortStatus mUsbPortStatus;
|
||||
private BatteryControllerImpl mBatteryController;
|
||||
|
||||
private MockitoSession mMockitoSession;
|
||||
|
||||
@Before
|
||||
@@ -255,4 +263,38 @@ public class BatteryControllerTest extends SysuiTestCase {
|
||||
|
||||
Assert.assertFalse(mBatteryController.isBatteryDefender());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void complianceChanged_complianceIncompatible_outputsTrue() {
|
||||
mContext.addMockSystemService(UsbManager.class, mUsbManager);
|
||||
setupIncompatibleCharging();
|
||||
Intent intent = new Intent(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
|
||||
|
||||
mBatteryController.onReceive(getContext(), intent);
|
||||
|
||||
Assert.assertTrue(mBatteryController.isIncompatibleCharging());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void complianceChanged_emptyComplianceWarnings_outputsFalse() {
|
||||
mContext.addMockSystemService(UsbManager.class, mUsbManager);
|
||||
setupIncompatibleCharging();
|
||||
when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[1]);
|
||||
Intent intent = new Intent(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
|
||||
|
||||
mBatteryController.onReceive(getContext(), intent);
|
||||
|
||||
Assert.assertFalse(mBatteryController.isIncompatibleCharging());
|
||||
}
|
||||
|
||||
private void setupIncompatibleCharging() {
|
||||
final List<UsbPort> usbPorts = new ArrayList<>();
|
||||
usbPorts.add(mUsbPort);
|
||||
when(mUsbManager.getPorts()).thenReturn(usbPorts);
|
||||
when(mUsbPort.getStatus()).thenReturn(mUsbPortStatus);
|
||||
when(mUsbPort.supportsComplianceWarnings()).thenReturn(true);
|
||||
when(mUsbPortStatus.isConnected()).thenReturn(true);
|
||||
when(mUsbPortStatus.getComplianceWarnings())
|
||||
.thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_OTHER});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user