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

Commit 304f3a74 authored by Jason Monk's avatar Jason Monk Committed by android-build-merger
Browse files

Merge "Fix sysui depending on slow bt calls" into oc-dev

am: 02d5b79c

Change-Id: If250b772445628e26fd73d0c81f31ea89e74f7fa
parents 6d1b84bc 02d5b79c
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -183,12 +183,6 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {

        @Override
        public void onBluetoothDevicesChanged() {
            mUiHandler.post(new Runnable() {
                @Override
                public void run() {
                    mDetailAdapter.updateItems();
                }
            });
            refreshState();
            if (isShowingDetail()) {
                mDetailAdapter.updateItems();
@@ -202,6 +196,9 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
    }

    protected class BluetoothDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
        // We probably won't ever have space in the UI for more than 20 devices, so don't
        // get info for them.
        private static final int MAX_DEVICES = 20;
        private QSDetailItems mItems;

        @Override
@@ -264,13 +261,14 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
            final Collection<CachedBluetoothDevice> devices = mController.getDevices();
            if (devices != null) {
                int connectedDevices = 0;
                int count = 0;
                for (CachedBluetoothDevice device : devices) {
                    if (device.getBondState() == BluetoothDevice.BOND_NONE) continue;
                    if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
                    final Item item = new Item();
                    item.icon = R.drawable.ic_qs_bluetooth_on;
                    item.line1 = device.getName();
                    item.tag = device;
                    int state = device.getMaxConnectionState();
                    int state = mController.getMaxConnectionState(device);
                    if (state == BluetoothProfile.STATE_CONNECTED) {
                        item.icon = R.drawable.ic_qs_bluetooth_connected;
                        item.line2 = mContext.getString(R.string.quick_settings_connected);
@@ -284,6 +282,9 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
                    } else {
                        items.add(item);
                    }
                    if (++count == MAX_DEVICES) {
                        break;
                    }
                }
            }
            mItems.setItems(items.toArray(new Item[items.size()]));
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ public interface BluetoothController extends CallbackController<Callback>, Dumpa
    void disconnect(CachedBluetoothDevice device);
    boolean canConfigBluetooth();

    int getMaxConnectionState(CachedBluetoothDevice device);
    int getBondState(CachedBluetoothDevice device);

    public interface Callback {
        void onBluetoothStateChange(boolean enabled);
        void onBluetoothDevicesChanged();
+59 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.policy;

import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
@@ -33,8 +35,10 @@ import com.android.systemui.Dependency;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.WeakHashMap;

public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
        CachedBluetoothDevice.Callback {
@@ -44,18 +48,22 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
    private final LocalBluetoothManager mLocalBluetoothManager;
    private final UserManager mUserManager;
    private final int mCurrentUser;
    private final WeakHashMap<CachedBluetoothDevice, ActuallyCachedState> mCachedState =
            new WeakHashMap<>();
    private final Handler mBgHandler;

    private boolean mEnabled;
    private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
    private CachedBluetoothDevice mLastDevice;

    private final H mHandler = new H();
    private final H mHandler = new H(Looper.getMainLooper());
    private int mState;

    public BluetoothControllerImpl(Context context, Looper bgLooper) {
        mLocalBluetoothManager = Dependency.get(LocalBluetoothManager.class);
        mBgHandler = new Handler(bgLooper);
        if (mLocalBluetoothManager != null) {
            mLocalBluetoothManager.getEventManager().setReceiverHandler(new Handler(bgLooper));
            mLocalBluetoothManager.getEventManager().setReceiverHandler(mBgHandler);
            mLocalBluetoothManager.getEventManager().registerCallback(this);
            onBluetoothStateChanged(
                    mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState());
@@ -105,6 +113,16 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
        return device.getName() + " " + device.getBondState() + " " + device.isConnected();
    }

    @Override
    public int getBondState(CachedBluetoothDevice device) {
        return getCachedState(device).mBondState;
    }

    @Override
    public int getMaxConnectionState(CachedBluetoothDevice device) {
        return getCachedState(device).mMaxConnectionState;
    }

    @Override
    public void addCallback(Callback cb) {
        mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget();
@@ -225,12 +243,14 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa

    @Override
    public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
        mCachedState.remove(cachedDevice);
        updateConnected();
        mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
    }

    @Override
    public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
        mCachedState.remove(cachedDevice);
        updateConnected();
        mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
    }
@@ -243,11 +263,44 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa

    @Override
    public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
        mCachedState.remove(cachedDevice);
        mLastDevice = cachedDevice;
        updateConnected();
        mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
    }

    private ActuallyCachedState getCachedState(CachedBluetoothDevice device) {
        ActuallyCachedState state = mCachedState.get(device);
        if (state == null) {
            state = new ActuallyCachedState(device, mHandler);
            mBgHandler.post(state);
            mCachedState.put(device, state);
            return state;
        }
        return state;
    }

    private static class ActuallyCachedState implements Runnable {

        private final WeakReference<CachedBluetoothDevice> mDevice;
        private final Handler mUiHandler;
        private int mBondState = BluetoothDevice.BOND_NONE;
        private int mMaxConnectionState = BluetoothProfile.STATE_DISCONNECTED;

        private ActuallyCachedState(CachedBluetoothDevice device, Handler uiHandler) {
            mDevice = new WeakReference<>(device);
            mUiHandler = uiHandler;
        }

        @Override
        public void run() {
            mBondState = mDevice.get().getBondState();
            mMaxConnectionState = mDevice.get().getMaxConnectionState();
            mUiHandler.removeMessages(H.MSG_PAIRED_DEVICES_CHANGED);
            mUiHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
        }
    }

    private final class H extends Handler {
        private final ArrayList<BluetoothController.Callback> mCallbacks = new ArrayList<>();

@@ -256,6 +309,10 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
        private static final int MSG_ADD_CALLBACK = 3;
        private static final int MSG_REMOVE_CALLBACK = 4;

        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
+57 −0
Original line number Diff line number Diff line
@@ -14,16 +14,21 @@

package com.android.systemui.statusbar.policy;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.os.Looper;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.Log;

import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -80,4 +85,56 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
                BluetoothAdapter.STATE_DISCONNECTED);
        assertTrue(mBluetoothControllerImpl.isBluetoothConnected());
    }

    @Test
    public void testDefaultConnectionState() {
        CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
        assertEquals(BluetoothDevice.BOND_NONE, mBluetoothControllerImpl.getBondState(device));
        assertEquals(BluetoothProfile.STATE_DISCONNECTED,
                mBluetoothControllerImpl.getMaxConnectionState(device));
    }

    @Test
    public void testAsyncBondState() throws Exception {
        CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
        when(device.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
        BluetoothController.Callback callback = mock(BluetoothController.Callback.class);
        mBluetoothControllerImpl.addCallback(callback);

        // Grab the main looper, we'll need it later.
        TestableLooper mainLooper = new TestableLooper(Looper.getMainLooper());

        // Trigger the state getting.
        assertEquals(BluetoothDevice.BOND_NONE, mBluetoothControllerImpl.getBondState(device));

        mTestableLooper.processMessages(1);
        mainLooper.processAllMessages();

        assertEquals(BluetoothDevice.BOND_BONDED, mBluetoothControllerImpl.getBondState(device));
        verify(callback).onBluetoothDevicesChanged();
        mainLooper.destroy();
    }

    @Test
    public void testAsyncConnectionState() throws Exception {
        CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
        when(device.getMaxConnectionState()).thenReturn(BluetoothProfile.STATE_CONNECTED);
        BluetoothController.Callback callback = mock(BluetoothController.Callback.class);
        mBluetoothControllerImpl.addCallback(callback);

        // Grab the main looper, we'll need it later.
        TestableLooper mainLooper = new TestableLooper(Looper.getMainLooper());

        // Trigger the state getting.
        assertEquals(BluetoothProfile.STATE_DISCONNECTED,
                mBluetoothControllerImpl.getMaxConnectionState(device));

        mTestableLooper.processMessages(1);
        mainLooper.processAllMessages();

        assertEquals(BluetoothProfile.STATE_CONNECTED,
                mBluetoothControllerImpl.getMaxConnectionState(device));
        verify(callback).onBluetoothDevicesChanged();
        mainLooper.destroy();
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -83,4 +83,14 @@ public class FakeBluetoothController extends BaseLeakChecker<Callback> implement
    public boolean canConfigBluetooth() {
        return false;
    }

    @Override
    public int getMaxConnectionState(CachedBluetoothDevice device) {
        return 0;
    }

    @Override
    public int getBondState(CachedBluetoothDevice device) {
        return 0;
    }
}