Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d47a5e10 authored by Yein Jo's avatar Yein Jo
Browse files

Fix double ripple when the device is docked.

Test: Manual test, WiredChargingRippleControllerTest, BatteryControllerTest
Bug: b/229418062
Change-Id: I26c4eb98cbe621d2c273670ebc4cb19e4ff003f4
parent 0d61ab9e
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ class WiredChargingRippleController @Inject constructor(
    private val systemClock: SystemClock,
    private val uiEventLogger: UiEventLogger
) {
    private var pluggedIn: Boolean? = null
    private var pluggedIn: Boolean = false
    private val rippleEnabled: Boolean = featureFlags.isEnabled(Flags.CHARGING_RIPPLE) &&
            !SystemProperties.getBoolean("persist.debug.suppress-charging-ripple", false)
    private var normalizedPortPosX: Float = context.resources.getFloat(
@@ -99,15 +99,17 @@ class WiredChargingRippleController @Inject constructor(
                nowPluggedIn: Boolean,
                charging: Boolean
            ) {
                // Suppresses the ripple when the state change comes from wireless charging.
                if (batteryController.isPluggedInWireless) {
                // Suppresses the ripple when the state change comes from wireless charging or
                // its dock.
                if (batteryController.isPluggedInWireless ||
                        batteryController.isChargingSourceDock) {
                    return
                }
                val wasPluggedIn = pluggedIn
                pluggedIn = nowPluggedIn
                if ((wasPluggedIn == null || !wasPluggedIn) && nowPluggedIn) {

                if (!pluggedIn && nowPluggedIn) {
                    startRippleWithDebounce()
                }
                pluggedIn = nowPluggedIn
            }
        }
        batteryController.addCallback(batteryStateChangeCallback)
+11 −0
Original line number Diff line number Diff line
@@ -118,6 +118,17 @@ public interface BatteryController extends DemoMode, Dumpable,
        return false;
    }

    /**
     * Returns {@code true} if the charging source is
     * {@link android.os.BatteryManager#BATTERY_PLUGGED_DOCK}.
     *
     * <P>Note that charging from dock is not considered as wireless charging. In other words,
     * {@link BatteryController#isWirelessCharging()} and this are mutually exclusive.
     */
    default boolean isChargingSourceDock() {
        return false;
    }

    /**
     * A listener that will be notified whenever a change in battery level or power save mode has
     * occurred.
+9 −6
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC

    protected int mLevel;
    protected boolean mPluggedIn;
    private boolean mPluggedInWireless;
    private int mPluggedChargingSource;
    protected boolean mCharging;
    private boolean mStateUnknown = false;
    private boolean mCharged;
@@ -195,10 +195,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
            mLevel = (int)(100f
                    * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
                    / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
            mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
            mPluggedInWireless = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)
                    == BatteryManager.BATTERY_PLUGGED_WIRELESS;

            mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
            mPluggedIn = mPluggedChargingSource != 0;
            final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
                    BatteryManager.BATTERY_STATUS_UNKNOWN);
            mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
@@ -284,7 +282,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC

    @Override
    public boolean isPluggedInWireless() {
        return mPluggedInWireless;
        return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_WIRELESS;
    }

    @Override
@@ -441,4 +439,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
        registerReceiver();
        updatePowerSave();
    }

    @Override
    public boolean isChargingSourceDock() {
        return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_DOCK;
    }
}
+21 −3
Original line number Diff line number Diff line
@@ -74,9 +74,9 @@ class WiredChargingRippleControllerTest : SysuiTestCase() {

        // Verify ripple added to window manager.
        captor.value.onBatteryLevelChanged(
                0 /* unusedBatteryLevel */,
                true /* plugged in */,
                false /* charging */)
                /* unusedBatteryLevel= */ 0,
                /* plugged in= */ true,
                /* charging= */ false)
        val attachListenerCaptor =
                ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
        verify(rippleView).addOnAttachStateChangeListener(attachListenerCaptor.capture())
@@ -144,4 +144,22 @@ class WiredChargingRippleControllerTest : SysuiTestCase() {
        // Verify that ripple is triggered.
        verify(rippleView).addOnAttachStateChangeListener(ArgumentMatchers.any())
    }

    @Test
    fun testRipple_whenDocked_doesNotPlayRipple() {
        `when`(batteryController.isChargingSourceDock).thenReturn(true)
        val captor = ArgumentCaptor
                .forClass(BatteryController.BatteryStateChangeCallback::class.java)
        verify(batteryController).addCallback(captor.capture())

        captor.value.onBatteryLevelChanged(
                /* unusedBatteryLevel= */ 0,
                /* plugged in= */ true,
                /* charging= */ false)

        val attachListenerCaptor =
                ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
        verify(rippleView, never()).addOnAttachStateChangeListener(attachListenerCaptor.capture())
        verify(windowManager, never()).addView(eq(rippleView), any<WindowManager.LayoutParams>())
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Intent;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerSaveState;
@@ -196,4 +197,26 @@ public class BatteryControllerTest extends SysuiTestCase {
        TestableLooper.get(this).processAllMessages();
        // Should not throw an exception
    }

    @Test
    public void batteryStateChanged_withChargingSourceDock_isChargingSourceDockTrue() {
        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING);
        intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_DOCK);

        mBatteryController.onReceive(getContext(), intent);

        Assert.assertTrue(mBatteryController.isChargingSourceDock());
    }

    @Test
    public void batteryStateChanged_withChargingSourceNotDock_isChargingSourceDockFalse() {
        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_DISCHARGING);
        intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_WIRELESS);

        mBatteryController.onReceive(getContext(), intent);

        Assert.assertFalse(mBatteryController.isChargingSourceDock());
    }
}