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

Commit 05a519be authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Reset the battery level when disconnected

Reset the battery level when the battery service
is transition from CONNECTED to DISCONNECTED.
It will prevent resetting the battery level set by HFP.

Bug: 283374283
Test: atest BluetoothInstrumentationTests
Change-Id: I3930b217468a113ce28289f6d226bb8597fa2a19
parent 3e0aebc3
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.bluetooth.bas;

import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
import static android.bluetooth.BluetoothDevice.PHY_LE_1M_MASK;
import static android.bluetooth.BluetoothDevice.PHY_LE_2M_MASK;
import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
@@ -238,6 +239,27 @@ public class BatteryStateMachine extends StateMachine {
        return mBluetoothGatt != null;
    }

    @VisibleForTesting
    void updateBatteryLevel(byte[] value) {
        if (value.length == 0) {
            return;
        }
        int batteryLevel = value[0] & 0xFF;

        BatteryService service = mServiceRef.get();
        if (service != null) {
            service.handleBatteryChanged(mDevice, batteryLevel);
        }
    }

    @VisibleForTesting
    void resetBatteryLevel() {
        BatteryService service = mServiceRef.get();
        if (service != null) {
            service.handleBatteryChanged(mDevice, BATTERY_LEVEL_UNKNOWN);
        }
    }

    @Override
    protected void log(String msg) {
        if (DBG) {
@@ -481,6 +503,8 @@ public class BatteryStateMachine extends StateMachine {
        public void exit() {
            log(TAG, "Exit (" + mDevice + "): "
                    + messageWhatToString(getCurrentMessage().what));
            // Reset the battery level only after connected
            resetBatteryLevel();
            mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
        }

@@ -596,18 +620,5 @@ public class BatteryStateMachine extends StateMachine {
                Log.w(TAG, "Failed to write descriptor " + descriptor.getUuid());
            }
        }

        @VisibleForTesting
        void updateBatteryLevel(byte[] value) {
            if (value.length <= 0) {
                return;
            }
            int batteryLevel = value[0] & 0xFF;

            BatteryService service = mServiceRef.get();
            if (service != null) {
                service.handleBatteryChanged(mDevice, batteryLevel);
            }
        }
    }
}
+6 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

package com.android.bluetooth.btservice;

import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
import static android.bluetooth.BluetoothDevice.TRANSPORT_AUTO;
import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -7001,8 +7002,12 @@ public class AdapterService extends Service {
     * Sets the battery level of the remote device
     */
    public void setBatteryLevel(BluetoothDevice device, int batteryLevel) {
        if (batteryLevel == BATTERY_LEVEL_UNKNOWN) {
            mRemoteDevices.resetBatteryLevel(device);
        } else {
            mRemoteDevices.updateBatteryLevel(device, batteryLevel);
        }
    }

    public boolean interopMatchAddr(InteropFeature feature, String address) {
        return interopMatchAddrNative(feature.name(), address);
+1 −0
Original line number Diff line number Diff line
@@ -1147,6 +1147,7 @@ final class RemoteDevices {
                }
                resetBatteryLevel(device);
            }

            if (mAdapterService.isAllProfilesUnknown(device)) {
                DeviceProperties deviceProp = getDeviceProperties(device);
                if (deviceProp != null) {
+44 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.bluetooth.bas;

import static android.bluetooth.BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;

import static com.google.common.truth.Truth.assertThat;
@@ -55,7 +56,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@@ -308,9 +308,7 @@ public class BatteryStateMachineTest {
        allowConnection(true);
        allowConnectGatt(true);

        // To create a callback
        mBatteryStateMachine.connectGatt();
        mBatteryStateMachine.mGattCallback.updateBatteryLevel(new byte[]{(byte)0x30});
        mBatteryStateMachine.updateBatteryLevel(new byte[] {(byte) 0x30});

        verify(mBatteryService, timeout(TIMEOUT_MS))
                .handleBatteryChanged(any(BluetoothDevice.class), eq(0x30));
@@ -321,10 +319,8 @@ public class BatteryStateMachineTest {
        allowConnection(true);
        allowConnectGatt(true);

        // To create a callback
        mBatteryStateMachine.connectGatt();
        try {
            mBatteryStateMachine.mGattCallback.updateBatteryLevel(new byte[0]);
            mBatteryStateMachine.updateBatteryLevel(new byte[0]);
        } catch (Exception ex) {
            fail();
        }
@@ -333,6 +329,47 @@ public class BatteryStateMachineTest {
                .handleBatteryChanged(any(BluetoothDevice.class), anyInt());
    }

    @Test
    public void testDisconnetResetBatteryLevel() {
        allowConnection(true);
        allowConnectGatt(true);

        // Inject an event for when incoming connection is requested
        mBatteryStateMachine.sendMessage(BatteryStateMachine.CONNECT);

        verify(mBatteryService, timeout(TIMEOUT_MS))
                .handleConnectionStateChanged(
                        any(BatteryStateMachine.class),
                        eq(BluetoothProfile.STATE_DISCONNECTED),
                        eq(BluetoothProfile.STATE_CONNECTING));

        Assert.assertThat(
                mBatteryStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(BatteryStateMachine.Connecting.class));

        mBatteryStateMachine.notifyConnectionStateChanged(
                GATT_SUCCESS, BluetoothProfile.STATE_CONNECTED);

        verify(mBatteryService, timeout(TIMEOUT_MS))
                .handleConnectionStateChanged(
                        any(BatteryStateMachine.class),
                        eq(BluetoothProfile.STATE_CONNECTING),
                        eq(BluetoothProfile.STATE_CONNECTED));

        Assert.assertThat(
                mBatteryStateMachine.getCurrentState(),
                IsInstanceOf.instanceOf(BatteryStateMachine.Connected.class));
        // update the battery level
        mBatteryStateMachine.updateBatteryLevel(new byte[] {(byte) 0x30});
        verify(mBatteryService, timeout(TIMEOUT_MS))
                .handleBatteryChanged(any(BluetoothDevice.class), eq(0x30));

        // Disconnect should reset the battery level
        mBatteryStateMachine.sendMessage(BatteryStateMachine.DISCONNECT);
        verify(mBatteryService, timeout(TIMEOUT_MS))
                .handleBatteryChanged(any(BluetoothDevice.class), eq(BATTERY_LEVEL_UNKNOWN));
    }

    private void reconnect() {
        // Inject an event for when incoming connection is requested
        mBatteryStateMachine.sendMessage(BatteryStateMachine.CONNECT);