From d199295ef36b28aa5893f00b12e430acaaf4aa87 Mon Sep 17 00:00:00 2001 From: Manu Viswanadhan Date: Tue, 25 Oct 2016 20:38:23 +0530 Subject: 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 --- .../bluetooth/BluetoothEventManager.java | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 80b943c31183..740ce4316fbb 100755 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -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 -- cgit v1.2.3-59-g8ed1b