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

Commit d199295e authored by Manu Viswanadhan's avatar Manu Viswanadhan Committed by Myles Watson
Browse files

Settings: Fix leak of BroadcastReceiver intents

Use Case: Repeated BT ON/OFF

Failure: Broadcast receiver leak is observed with ON/OFF stress
test which leads to broadcast receiver delays.

Steps:
BT ON/OFF.

Root Cause: During every ON/OFF there are broadcast receiver leaks
caused by repeated registering of profile intent receivers.

Fix: Separate broadcast receiver created for profile intents, such
that broadcast receiver for adapter state intents is always
active. Unregister and re-register the profile receiver when BT
is turned OFF.

Test: BT ON/OFF

Bug: 35415158

Change-Id: Id1db747c61bb2dd33515ac45cdc2059844d3e4f5
parent 3851f132
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -107,14 +107,16 @@ public class BluetoothEventManager {
        addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());

        mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
        mContext.registerReceiver(mProfileBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
    }

    void registerProfileIntentReceiver() {
        mContext.registerReceiver(mBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
        mContext.registerReceiver(mProfileBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler);
    }

    public void setReceiverHandler(android.os.Handler handler) {
        mContext.unregisterReceiver(mBroadcastReceiver);
        mContext.unregisterReceiver(mProfileBroadcastReceiver);
        mReceiverHandler = handler;
        mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
        registerProfileIntentReceiver();
@@ -148,11 +150,31 @@ public class BluetoothEventManager {
        }
    };

    private final BroadcastReceiver mProfileBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            Handler handler = mHandlerMap.get(action);
            if (handler != null) {
                handler.onReceive(context, intent, device);
            }
        }
    };

    private class AdapterStateChangedHandler implements Handler {
        public void onReceive(Context context, Intent intent,
                BluetoothDevice device) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                    BluetoothAdapter.ERROR);
            // Reregister Profile Broadcast Receiver as part of TURN OFF
            if (state == BluetoothAdapter.STATE_OFF)
            {
                context.unregisterReceiver(mProfileBroadcastReceiver);
                registerProfileIntentReceiver();
            }
            // update local profiles and get paired devices
            mLocalAdapter.setBluetoothStateInt(state);
            // send callback to update UI and possibly start scanning