Loading android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java +6 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,12 @@ public final class HeadsetHalConstants { static final int CALL_STATE_WAITING = 5; static final int CALL_STATE_IDLE = 6; // Match up with bthf_hf_ind_type_t of bt_hf.h // match up with bthf_hf_ind_type_t of bt_hf.h static final int HF_INDICATOR_ENHANCED_DRIVER_SAFETY = 1; public static final int HF_INDICATOR_BATTERY_LEVEL_STATUS = 2; // match up with bthf_wbs_config_t of bt_hf.h static final int BTHF_WBS_NONE = 0; static final int BTHF_WBS_NO = 1; static final int BTHF_WBS_YES = 2; } android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +3 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ import android.util.Log; import com.android.bluetooth.Utils; /** * Defines native calls that is used by state machine/service to either send or receive * messages from the native stack. This file is registered for the native methods in corresponding * CPP file. * Defines native calls that are used by state machine/service to either send or receive * messages to/from the native stack. This file is registered for the native methods in * corresponding CPP file. */ public class HeadsetNativeInterface { private static final String TAG = "HeadsetNativeInterface"; Loading android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java +45 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Looper; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; Loading @@ -33,66 +34,74 @@ import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; // Note: // All methods in this class are not thread safe, donot call them from // multiple threads. Call them from the HeadsetPhoneStateMachine message // handler only. class HeadsetPhoneState { /** * Class that manages Telephony states * * Note: * The methods in this class are not thread safe, don't call them from * multiple threads. Call them from the HeadsetPhoneStateMachine message * handler only. */ public class HeadsetPhoneState { private static final String TAG = "HeadsetPhoneState"; private HeadsetStateMachine mStateMachine; private TelephonyManager mTelephonyManager; private final Context mContext; private final HeadsetStateMachine mStateMachine; private final TelephonyManager mTelephonyManager; private final SubscriptionManager mSubMgr; private ServiceState mServiceState; // HFP 1.6 CIND service // HFP 1.6 CIND service value private int mService = HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE; // Check this before sending out service state to the device -- if the SIM isn't fully // loaded, don't expose that the network is available. private boolean mIsSimStateLoaded = false; private boolean mIsSimStateLoaded; // Number of active (foreground) calls private int mNumActive = 0; private int mNumActive; // Current Call Setup State private int mCallState = HeadsetHalConstants.CALL_STATE_IDLE; // Number of held (background) calls private int mNumHeld = 0; private int mNumHeld; // HFP 1.6 CIND signal private int mSignal = 0; private int mSignal; // HFP 1.6 CIND roam private int mRoam = HeadsetHalConstants.SERVICE_TYPE_HOME; // HFP 1.6 CIND battchg private int mBatteryCharge = 0; private int mBatteryCharge; private int mSpeakerVolume = 0; private int mSpeakerVolume; private int mMicVolume = 0; private int mMicVolume; private boolean mListening = false; private boolean mListening; // when HFP Service Level Connection is established private boolean mSlcReady = false; private boolean mSlcReady; private Context mContext = null; private PhoneStateListener mPhoneStateListener; private PhoneStateListener mPhoneStateListener = null; private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener; private SubscriptionManager mSubMgr; private class HeadsetPhoneStateOnSubscriptionChangedListener extends OnSubscriptionsChangedListener { HeadsetPhoneStateOnSubscriptionChangedListener(Looper looper) { super(looper); } private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener = new OnSubscriptionsChangedListener() { @Override public void onSubscriptionsChanged() { listenForPhoneState(false); listenForPhoneState(true); } }; } HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) { mStateMachine = stateMachine; Loading @@ -107,15 +116,18 @@ class HeadsetPhoneState { // to invoke onSubscriptionInfoChanged and which in turns calls // loadInBackgroud. mSubMgr = SubscriptionManager.from(mContext); // Initialize subscription on the handler thread mOnSubscriptionsChangedListener = new HeadsetPhoneStateOnSubscriptionChangedListener( stateMachine.getHandler().getLooper()); mSubMgr.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); } public void cleanup() { listenForPhoneState(false); if (mOnSubscriptionsChangedListener != null) { mSubMgr.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); mTelephonyManager = null; mStateMachine = null; mOnSubscriptionsChangedListener = null; } } @Override Loading @@ -128,22 +140,17 @@ class HeadsetPhoneState { } void listenForPhoneState(boolean start) { mSlcReady = start; if (start) { startListenForPhoneState(); } else { stopListenForPhoneState(); } } private void startListenForPhoneState() { if (!mListening && mSlcReady && mTelephonyManager != null) { int subId = SubscriptionManager.getDefaultSubscriptionId(); if (SubscriptionManager.isValidSubscriptionId(subId)) { mPhoneStateListener = getPhoneStateListener(subId); if (mTelephonyManager == null) { Loading android/app/src/com/android/bluetooth/hfp/HeadsetService.java +23 −16 Original line number Diff line number Diff line Loading @@ -37,9 +37,7 @@ import java.util.ArrayList; import java.util.List; /** * Provides Bluetooth Headset and Handsfree profile, as a service in * the Bluetooth application. * @hide * Provides Bluetooth Headset and Handsfree profile, as a service in the Bluetooth application. */ public class HeadsetService extends ProfileService { private static final boolean DBG = false; Loading Loading @@ -122,8 +120,13 @@ public class HeadsetService extends ProfileService { return isAvailable() && mCreated && mStarted; } // Handle messages from native (JNI) to Java void messageFromNative(HeadsetStackEvent stackEvent) { /** * Handle messages from native (JNI) to Java. This needs to be synchronized to avoid posting * messages to state machine before start() is done * * @param stackEvent event from native stack */ synchronized void messageFromNative(HeadsetStackEvent stackEvent) { mStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, stackEvent); } Loading Loading @@ -473,10 +476,9 @@ public class HeadsetService extends ProfileService { public int getPriority(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int priority = Settings.Global.getInt(getContentResolver(), return Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothHeadsetPriorityKey(device.getAddress()), BluetoothProfile.PRIORITY_UNDEFINED); return priority; } boolean startVoiceRecognition(BluetoothDevice device) { Loading Loading @@ -507,16 +509,16 @@ public class HeadsetService extends ProfileService { boolean isAudioOn() { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mStateMachine.isAudioOn(); return mStateMachine.getAudioState() != BluetoothHeadset.STATE_AUDIO_DISCONNECTED; } boolean isAudioConnected(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mStateMachine.isAudioConnected(device); return mStateMachine.getAudioState() == BluetoothHeadset.STATE_AUDIO_CONNECTED; } int getAudioState(BluetoothDevice device) { return mStateMachine.getAudioState(device); return mStateMachine.getAudioState(); } public void setAudioRouteAllowed(boolean allowed) { Loading @@ -535,25 +537,30 @@ public class HeadsetService extends ProfileService { boolean connectAudio() { // TODO(BT) BLUETOOTH or BLUETOOTH_ADMIN permission enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!mStateMachine.isConnected()) { if (mStateMachine.getConnectionState(mStateMachine.getCurrentDevice()) != BluetoothProfile.STATE_CONNECTED) { Log.w(TAG, "connectAudio: profile not connected"); return false; } if (mStateMachine.isAudioOn()) { Log.w(TAG, "connectAudio: audio is already ON"); if (isAudioOn()) { Log.w(TAG, "connectAudio: audio is not idle, current state " + mStateMachine.getAudioState()); return false; } mStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO); mStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mStateMachine.getCurrentDevice()); return true; } boolean disconnectAudio() { // TODO(BT) BLUETOOTH or BLUETOOTH_ADMIN permission enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!mStateMachine.isAudioOn()) { if (mStateMachine.getAudioState() != BluetoothHeadset.STATE_AUDIO_CONNECTED) { Log.w(TAG, "disconnectAudio, audio is not connected"); return false; } mStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO); mStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mStateMachine.getCurrentDevice()); return true; } Loading android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +1003 −1480 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java +6 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,12 @@ public final class HeadsetHalConstants { static final int CALL_STATE_WAITING = 5; static final int CALL_STATE_IDLE = 6; // Match up with bthf_hf_ind_type_t of bt_hf.h // match up with bthf_hf_ind_type_t of bt_hf.h static final int HF_INDICATOR_ENHANCED_DRIVER_SAFETY = 1; public static final int HF_INDICATOR_BATTERY_LEVEL_STATUS = 2; // match up with bthf_wbs_config_t of bt_hf.h static final int BTHF_WBS_NONE = 0; static final int BTHF_WBS_NO = 1; static final int BTHF_WBS_YES = 2; }
android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +3 −3 Original line number Diff line number Diff line Loading @@ -24,9 +24,9 @@ import android.util.Log; import com.android.bluetooth.Utils; /** * Defines native calls that is used by state machine/service to either send or receive * messages from the native stack. This file is registered for the native methods in corresponding * CPP file. * Defines native calls that are used by state machine/service to either send or receive * messages to/from the native stack. This file is registered for the native methods in * corresponding CPP file. */ public class HeadsetNativeInterface { private static final String TAG = "HeadsetNativeInterface"; Loading
android/app/src/com/android/bluetooth/hfp/HeadsetPhoneState.java +45 −38 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Looper; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; Loading @@ -33,66 +34,74 @@ import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; // Note: // All methods in this class are not thread safe, donot call them from // multiple threads. Call them from the HeadsetPhoneStateMachine message // handler only. class HeadsetPhoneState { /** * Class that manages Telephony states * * Note: * The methods in this class are not thread safe, don't call them from * multiple threads. Call them from the HeadsetPhoneStateMachine message * handler only. */ public class HeadsetPhoneState { private static final String TAG = "HeadsetPhoneState"; private HeadsetStateMachine mStateMachine; private TelephonyManager mTelephonyManager; private final Context mContext; private final HeadsetStateMachine mStateMachine; private final TelephonyManager mTelephonyManager; private final SubscriptionManager mSubMgr; private ServiceState mServiceState; // HFP 1.6 CIND service // HFP 1.6 CIND service value private int mService = HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE; // Check this before sending out service state to the device -- if the SIM isn't fully // loaded, don't expose that the network is available. private boolean mIsSimStateLoaded = false; private boolean mIsSimStateLoaded; // Number of active (foreground) calls private int mNumActive = 0; private int mNumActive; // Current Call Setup State private int mCallState = HeadsetHalConstants.CALL_STATE_IDLE; // Number of held (background) calls private int mNumHeld = 0; private int mNumHeld; // HFP 1.6 CIND signal private int mSignal = 0; private int mSignal; // HFP 1.6 CIND roam private int mRoam = HeadsetHalConstants.SERVICE_TYPE_HOME; // HFP 1.6 CIND battchg private int mBatteryCharge = 0; private int mBatteryCharge; private int mSpeakerVolume = 0; private int mSpeakerVolume; private int mMicVolume = 0; private int mMicVolume; private boolean mListening = false; private boolean mListening; // when HFP Service Level Connection is established private boolean mSlcReady = false; private boolean mSlcReady; private Context mContext = null; private PhoneStateListener mPhoneStateListener; private PhoneStateListener mPhoneStateListener = null; private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener; private SubscriptionManager mSubMgr; private class HeadsetPhoneStateOnSubscriptionChangedListener extends OnSubscriptionsChangedListener { HeadsetPhoneStateOnSubscriptionChangedListener(Looper looper) { super(looper); } private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener = new OnSubscriptionsChangedListener() { @Override public void onSubscriptionsChanged() { listenForPhoneState(false); listenForPhoneState(true); } }; } HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) { mStateMachine = stateMachine; Loading @@ -107,15 +116,18 @@ class HeadsetPhoneState { // to invoke onSubscriptionInfoChanged and which in turns calls // loadInBackgroud. mSubMgr = SubscriptionManager.from(mContext); // Initialize subscription on the handler thread mOnSubscriptionsChangedListener = new HeadsetPhoneStateOnSubscriptionChangedListener( stateMachine.getHandler().getLooper()); mSubMgr.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); } public void cleanup() { listenForPhoneState(false); if (mOnSubscriptionsChangedListener != null) { mSubMgr.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); mTelephonyManager = null; mStateMachine = null; mOnSubscriptionsChangedListener = null; } } @Override Loading @@ -128,22 +140,17 @@ class HeadsetPhoneState { } void listenForPhoneState(boolean start) { mSlcReady = start; if (start) { startListenForPhoneState(); } else { stopListenForPhoneState(); } } private void startListenForPhoneState() { if (!mListening && mSlcReady && mTelephonyManager != null) { int subId = SubscriptionManager.getDefaultSubscriptionId(); if (SubscriptionManager.isValidSubscriptionId(subId)) { mPhoneStateListener = getPhoneStateListener(subId); if (mTelephonyManager == null) { Loading
android/app/src/com/android/bluetooth/hfp/HeadsetService.java +23 −16 Original line number Diff line number Diff line Loading @@ -37,9 +37,7 @@ import java.util.ArrayList; import java.util.List; /** * Provides Bluetooth Headset and Handsfree profile, as a service in * the Bluetooth application. * @hide * Provides Bluetooth Headset and Handsfree profile, as a service in the Bluetooth application. */ public class HeadsetService extends ProfileService { private static final boolean DBG = false; Loading Loading @@ -122,8 +120,13 @@ public class HeadsetService extends ProfileService { return isAvailable() && mCreated && mStarted; } // Handle messages from native (JNI) to Java void messageFromNative(HeadsetStackEvent stackEvent) { /** * Handle messages from native (JNI) to Java. This needs to be synchronized to avoid posting * messages to state machine before start() is done * * @param stackEvent event from native stack */ synchronized void messageFromNative(HeadsetStackEvent stackEvent) { mStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, stackEvent); } Loading Loading @@ -473,10 +476,9 @@ public class HeadsetService extends ProfileService { public int getPriority(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); int priority = Settings.Global.getInt(getContentResolver(), return Settings.Global.getInt(getContentResolver(), Settings.Global.getBluetoothHeadsetPriorityKey(device.getAddress()), BluetoothProfile.PRIORITY_UNDEFINED); return priority; } boolean startVoiceRecognition(BluetoothDevice device) { Loading Loading @@ -507,16 +509,16 @@ public class HeadsetService extends ProfileService { boolean isAudioOn() { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mStateMachine.isAudioOn(); return mStateMachine.getAudioState() != BluetoothHeadset.STATE_AUDIO_DISCONNECTED; } boolean isAudioConnected(BluetoothDevice device) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); return mStateMachine.isAudioConnected(device); return mStateMachine.getAudioState() == BluetoothHeadset.STATE_AUDIO_CONNECTED; } int getAudioState(BluetoothDevice device) { return mStateMachine.getAudioState(device); return mStateMachine.getAudioState(); } public void setAudioRouteAllowed(boolean allowed) { Loading @@ -535,25 +537,30 @@ public class HeadsetService extends ProfileService { boolean connectAudio() { // TODO(BT) BLUETOOTH or BLUETOOTH_ADMIN permission enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!mStateMachine.isConnected()) { if (mStateMachine.getConnectionState(mStateMachine.getCurrentDevice()) != BluetoothProfile.STATE_CONNECTED) { Log.w(TAG, "connectAudio: profile not connected"); return false; } if (mStateMachine.isAudioOn()) { Log.w(TAG, "connectAudio: audio is already ON"); if (isAudioOn()) { Log.w(TAG, "connectAudio: audio is not idle, current state " + mStateMachine.getAudioState()); return false; } mStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO); mStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mStateMachine.getCurrentDevice()); return true; } boolean disconnectAudio() { // TODO(BT) BLUETOOTH or BLUETOOTH_ADMIN permission enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!mStateMachine.isAudioOn()) { if (mStateMachine.getAudioState() != BluetoothHeadset.STATE_AUDIO_CONNECTED) { Log.w(TAG, "disconnectAudio, audio is not connected"); return false; } mStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO); mStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mStateMachine.getCurrentDevice()); return true; } Loading
android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +1003 −1480 File changed.Preview size limit exceeded, changes collapsed. Show changes