Loading src/com/android/bluetooth/hfp/HeadsetService.java +23 −11 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.content.IntentFilter; import android.media.AudioManager; import android.media.AudioManager; import android.net.Uri; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManager; import android.os.Handler; import android.os.HandlerThread; import android.os.HandlerThread; import android.os.Looper; import android.os.Looper; import android.os.ParcelUuid; import android.os.ParcelUuid; Loading Loading @@ -95,6 +96,7 @@ public class HeadsetService extends ProfileService { private BluetoothDevice mActiveDevice; private BluetoothDevice mActiveDevice; private AdapterService mAdapterService; private AdapterService mAdapterService; private HandlerThread mStateMachinesThread; private HandlerThread mStateMachinesThread; private Handler mStateMachinesThreadHandler; // This is also used as a lock for shared data in HeadsetService // This is also used as a lock for shared data in HeadsetService private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>(); private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>(); private HeadsetNativeInterface mNativeInterface; private HeadsetNativeInterface mNativeInterface; Loading Loading @@ -192,11 +194,12 @@ public class HeadsetService extends ProfileService { mVoiceRecognitionStarted = false; mVoiceRecognitionStarted = false; mVirtualCallStarted = false; mVirtualCallStarted = false; if (mDialingOutTimeoutEvent != null) { if (mDialingOutTimeoutEvent != null) { mStateMachinesThread.getThreadHandler().removeCallbacks(mDialingOutTimeoutEvent); getStateMachinesThreadHandler() .removeCallbacks(mDialingOutTimeoutEvent); mDialingOutTimeoutEvent = null; mDialingOutTimeoutEvent = null; } } if (mVoiceRecognitionTimeoutEvent != null) { if (mVoiceRecognitionTimeoutEvent != null) { mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { Loading @@ -216,6 +219,7 @@ public class HeadsetService extends ProfileService { // Step 2: Stop handler thread // Step 2: Stop handler thread mStateMachinesThread.quitSafely(); mStateMachinesThread.quitSafely(); mStateMachinesThread = null; mStateMachinesThread = null; mStateMachinesThreadHandler = null; // Step 1: Clear // Step 1: Clear synchronized (mStateMachines) { synchronized (mStateMachines) { mAdapterService = null; mAdapterService = null; Loading Loading @@ -868,8 +872,7 @@ public class HeadsetService extends ProfileService { + ", fall back to requesting device"); + ", fall back to requesting device"); device = mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice; device = mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice; } } mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler().removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().release(); mSystemInterface.getVoiceRecognitionWakeLock().release(); Loading Loading @@ -1336,7 +1339,7 @@ public class HeadsetService extends ProfileService { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); startActivity(intent); mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(fromDevice); mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(fromDevice); mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); .postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); return true; return true; } } Loading Loading @@ -1426,8 +1429,9 @@ public class HeadsetService extends ProfileService { return false; return false; } } mVoiceRecognitionTimeoutEvent = new VoiceRecognitionTimeoutEvent(fromDevice); mVoiceRecognitionTimeoutEvent = new VoiceRecognitionTimeoutEvent(fromDevice); mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .postDelayed(mVoiceRecognitionTimeoutEvent, sStartVrTimeoutMs); .postDelayed(mVoiceRecognitionTimeoutEvent, sStartVrTimeoutMs); if (!mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (!mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().acquire(sStartVrTimeoutMs); mSystemInterface.getVoiceRecognitionWakeLock().acquire(sStartVrTimeoutMs); } } Loading @@ -1452,8 +1456,9 @@ public class HeadsetService extends ProfileService { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().release(); mSystemInterface.getVoiceRecognitionWakeLock().release(); } } mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; } } if (mVoiceRecognitionStarted) { if (mVoiceRecognitionStarted) { Loading Loading @@ -1489,7 +1494,7 @@ public class HeadsetService extends ProfileService { if (mDialingOutTimeoutEvent != null) { if (mDialingOutTimeoutEvent != null) { // Send result to state machine when dialing starts // Send result to state machine when dialing starts if (callState == HeadsetHalConstants.CALL_STATE_DIALING) { if (callState == HeadsetHalConstants.CALL_STATE_DIALING) { mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mDialingOutTimeoutEvent); .removeCallbacks(mDialingOutTimeoutEvent); doForStateMachine(mDialingOutTimeoutEvent.mDialingOutDevice, doForStateMachine(mDialingOutTimeoutEvent.mDialingOutDevice, stateMachine -> stateMachine.sendMessage( stateMachine -> stateMachine.sendMessage( Loading @@ -1498,14 +1503,14 @@ public class HeadsetService extends ProfileService { } else if (callState == HeadsetHalConstants.CALL_STATE_ACTIVE } else if (callState == HeadsetHalConstants.CALL_STATE_ACTIVE || callState == HeadsetHalConstants.CALL_STATE_IDLE) { || callState == HeadsetHalConstants.CALL_STATE_IDLE) { // Clear the timeout event when the call is connected or disconnected // Clear the timeout event when the call is connected or disconnected if (!mStateMachinesThread.getThreadHandler() if (!getStateMachinesThreadHandler() .hasCallbacks(mDialingOutTimeoutEvent)) { .hasCallbacks(mDialingOutTimeoutEvent)) { mDialingOutTimeoutEvent = null; mDialingOutTimeoutEvent = null; } } } } } } } } mStateMachinesThread.getThreadHandler().post(() -> { getStateMachinesThreadHandler().post(() -> { boolean isCallIdleBefore = mSystemInterface.isCallIdle(); boolean isCallIdleBefore = mSystemInterface.isCallIdle(); mSystemInterface.getHeadsetPhoneState().setNumActiveCall(numActive); mSystemInterface.getHeadsetPhoneState().setNumActiveCall(numActive); mSystemInterface.getHeadsetPhoneState().setNumHeldCall(numHeld); mSystemInterface.getHeadsetPhoneState().setNumHeldCall(numHeld); Loading @@ -1519,7 +1524,7 @@ public class HeadsetService extends ProfileService { doForEachConnectedStateMachine( doForEachConnectedStateMachine( stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED, stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED, new HeadsetCallState(numActive, numHeld, callState, number, type, name))); new HeadsetCallState(numActive, numHeld, callState, number, type, name))); mStateMachinesThread.getThreadHandler().post(() -> { getStateMachinesThreadHandler().post(() -> { if (callState == HeadsetHalConstants.CALL_STATE_IDLE if (callState == HeadsetHalConstants.CALL_STATE_IDLE && mSystemInterface.isCallIdle() && !isAudioOn()) { && mSystemInterface.isCallIdle() && !isAudioOn()) { // Resume A2DP when call ended and SCO is not connected // Resume A2DP when call ended and SCO is not connected Loading Loading @@ -1832,4 +1837,11 @@ public class HeadsetService extends ProfileService { Log.d(TAG, message); Log.d(TAG, message); } } } } private Handler getStateMachinesThreadHandler() { if (mStateMachinesThreadHandler == null) { mStateMachinesThreadHandler = new Handler(mStateMachinesThread.getLooper()); } return mStateMachinesThreadHandler; } } } Loading
src/com/android/bluetooth/hfp/HeadsetService.java +23 −11 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.content.IntentFilter; import android.media.AudioManager; import android.media.AudioManager; import android.net.Uri; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManager; import android.os.Handler; import android.os.HandlerThread; import android.os.HandlerThread; import android.os.Looper; import android.os.Looper; import android.os.ParcelUuid; import android.os.ParcelUuid; Loading Loading @@ -95,6 +96,7 @@ public class HeadsetService extends ProfileService { private BluetoothDevice mActiveDevice; private BluetoothDevice mActiveDevice; private AdapterService mAdapterService; private AdapterService mAdapterService; private HandlerThread mStateMachinesThread; private HandlerThread mStateMachinesThread; private Handler mStateMachinesThreadHandler; // This is also used as a lock for shared data in HeadsetService // This is also used as a lock for shared data in HeadsetService private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>(); private final HashMap<BluetoothDevice, HeadsetStateMachine> mStateMachines = new HashMap<>(); private HeadsetNativeInterface mNativeInterface; private HeadsetNativeInterface mNativeInterface; Loading Loading @@ -192,11 +194,12 @@ public class HeadsetService extends ProfileService { mVoiceRecognitionStarted = false; mVoiceRecognitionStarted = false; mVirtualCallStarted = false; mVirtualCallStarted = false; if (mDialingOutTimeoutEvent != null) { if (mDialingOutTimeoutEvent != null) { mStateMachinesThread.getThreadHandler().removeCallbacks(mDialingOutTimeoutEvent); getStateMachinesThreadHandler() .removeCallbacks(mDialingOutTimeoutEvent); mDialingOutTimeoutEvent = null; mDialingOutTimeoutEvent = null; } } if (mVoiceRecognitionTimeoutEvent != null) { if (mVoiceRecognitionTimeoutEvent != null) { mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { Loading @@ -216,6 +219,7 @@ public class HeadsetService extends ProfileService { // Step 2: Stop handler thread // Step 2: Stop handler thread mStateMachinesThread.quitSafely(); mStateMachinesThread.quitSafely(); mStateMachinesThread = null; mStateMachinesThread = null; mStateMachinesThreadHandler = null; // Step 1: Clear // Step 1: Clear synchronized (mStateMachines) { synchronized (mStateMachines) { mAdapterService = null; mAdapterService = null; Loading Loading @@ -868,8 +872,7 @@ public class HeadsetService extends ProfileService { + ", fall back to requesting device"); + ", fall back to requesting device"); device = mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice; device = mVoiceRecognitionTimeoutEvent.mVoiceRecognitionDevice; } } mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler().removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().release(); mSystemInterface.getVoiceRecognitionWakeLock().release(); Loading Loading @@ -1336,7 +1339,7 @@ public class HeadsetService extends ProfileService { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); startActivity(intent); mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(fromDevice); mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(fromDevice); mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); .postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); return true; return true; } } Loading Loading @@ -1426,8 +1429,9 @@ public class HeadsetService extends ProfileService { return false; return false; } } mVoiceRecognitionTimeoutEvent = new VoiceRecognitionTimeoutEvent(fromDevice); mVoiceRecognitionTimeoutEvent = new VoiceRecognitionTimeoutEvent(fromDevice); mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .postDelayed(mVoiceRecognitionTimeoutEvent, sStartVrTimeoutMs); .postDelayed(mVoiceRecognitionTimeoutEvent, sStartVrTimeoutMs); if (!mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (!mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().acquire(sStartVrTimeoutMs); mSystemInterface.getVoiceRecognitionWakeLock().acquire(sStartVrTimeoutMs); } } Loading @@ -1452,8 +1456,9 @@ public class HeadsetService extends ProfileService { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { if (mSystemInterface.getVoiceRecognitionWakeLock().isHeld()) { mSystemInterface.getVoiceRecognitionWakeLock().release(); mSystemInterface.getVoiceRecognitionWakeLock().release(); } } mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mVoiceRecognitionTimeoutEvent); .removeCallbacks(mVoiceRecognitionTimeoutEvent); mVoiceRecognitionTimeoutEvent = null; mVoiceRecognitionTimeoutEvent = null; } } if (mVoiceRecognitionStarted) { if (mVoiceRecognitionStarted) { Loading Loading @@ -1489,7 +1494,7 @@ public class HeadsetService extends ProfileService { if (mDialingOutTimeoutEvent != null) { if (mDialingOutTimeoutEvent != null) { // Send result to state machine when dialing starts // Send result to state machine when dialing starts if (callState == HeadsetHalConstants.CALL_STATE_DIALING) { if (callState == HeadsetHalConstants.CALL_STATE_DIALING) { mStateMachinesThread.getThreadHandler() getStateMachinesThreadHandler() .removeCallbacks(mDialingOutTimeoutEvent); .removeCallbacks(mDialingOutTimeoutEvent); doForStateMachine(mDialingOutTimeoutEvent.mDialingOutDevice, doForStateMachine(mDialingOutTimeoutEvent.mDialingOutDevice, stateMachine -> stateMachine.sendMessage( stateMachine -> stateMachine.sendMessage( Loading @@ -1498,14 +1503,14 @@ public class HeadsetService extends ProfileService { } else if (callState == HeadsetHalConstants.CALL_STATE_ACTIVE } else if (callState == HeadsetHalConstants.CALL_STATE_ACTIVE || callState == HeadsetHalConstants.CALL_STATE_IDLE) { || callState == HeadsetHalConstants.CALL_STATE_IDLE) { // Clear the timeout event when the call is connected or disconnected // Clear the timeout event when the call is connected or disconnected if (!mStateMachinesThread.getThreadHandler() if (!getStateMachinesThreadHandler() .hasCallbacks(mDialingOutTimeoutEvent)) { .hasCallbacks(mDialingOutTimeoutEvent)) { mDialingOutTimeoutEvent = null; mDialingOutTimeoutEvent = null; } } } } } } } } mStateMachinesThread.getThreadHandler().post(() -> { getStateMachinesThreadHandler().post(() -> { boolean isCallIdleBefore = mSystemInterface.isCallIdle(); boolean isCallIdleBefore = mSystemInterface.isCallIdle(); mSystemInterface.getHeadsetPhoneState().setNumActiveCall(numActive); mSystemInterface.getHeadsetPhoneState().setNumActiveCall(numActive); mSystemInterface.getHeadsetPhoneState().setNumHeldCall(numHeld); mSystemInterface.getHeadsetPhoneState().setNumHeldCall(numHeld); Loading @@ -1519,7 +1524,7 @@ public class HeadsetService extends ProfileService { doForEachConnectedStateMachine( doForEachConnectedStateMachine( stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED, stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED, new HeadsetCallState(numActive, numHeld, callState, number, type, name))); new HeadsetCallState(numActive, numHeld, callState, number, type, name))); mStateMachinesThread.getThreadHandler().post(() -> { getStateMachinesThreadHandler().post(() -> { if (callState == HeadsetHalConstants.CALL_STATE_IDLE if (callState == HeadsetHalConstants.CALL_STATE_IDLE && mSystemInterface.isCallIdle() && !isAudioOn()) { && mSystemInterface.isCallIdle() && !isAudioOn()) { // Resume A2DP when call ended and SCO is not connected // Resume A2DP when call ended and SCO is not connected Loading Loading @@ -1832,4 +1837,11 @@ public class HeadsetService extends ProfileService { Log.d(TAG, message); Log.d(TAG, message); } } } } private Handler getStateMachinesThreadHandler() { if (mStateMachinesThreadHandler == null) { mStateMachinesThreadHandler = new Handler(mStateMachinesThread.getLooper()); } return mStateMachinesThreadHandler; } } }