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

Commit a2ca7f13 authored by Jack He's avatar Jack He Committed by android-build-merger
Browse files

Merge "HFP: Redesign HeadsetStateMachine"

am: 1bba5ad9

Change-Id: I81e3004f345adea5f085f06d333869211d6d7f30
parents d47a26ae 1bba5ad9
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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;
}
+3 −3
Original line number Diff line number Diff line
@@ -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";
+45 −38
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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
@@ -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) {
+23 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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);
    }

@@ -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) {
@@ -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) {
@@ -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;
    }

+1003 −1480

File changed.

Preview size limit exceeded, changes collapsed.

Loading