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

Commit 2fb0482f authored by Benson Li's avatar Benson Li Committed by android-build-merger
Browse files

Merge "HFP: Send caller ID in +CLIP command (2/4)"

am: 4f7ffc56

Change-Id: I02ab2f7c5e34d674fbc688c2ef7625c7b64689df
parents 470d4fdf 4f7ffc56
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -805,7 +805,8 @@ static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index,
static jboolean phoneStateChangeNative(JNIEnv* env, jobject object,
                                       jint num_active, jint num_held,
                                       jint call_state, jstring number_str,
                                       jint type, jbyteArray address) {
                                       jint type, jstring name_str,
                                       jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
@@ -818,14 +819,16 @@ static jboolean phoneStateChangeNative(JNIEnv* env, jobject object,
    return JNI_FALSE;
  }
  const char* number = env->GetStringUTFChars(number_str, nullptr);
  const char* name = env->GetStringUTFChars(name_str, nullptr);
  bt_status_t status = sBluetoothHfpInterface->PhoneStateChange(
      num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state,
      number, (bluetooth::headset::bthf_call_addrtype_t)type,
      number, (bluetooth::headset::bthf_call_addrtype_t)type, name,
      (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed report phone state change, status: %d", status);
  }
  env->ReleaseStringUTFChars(number_str, number);
  env->ReleaseStringUTFChars(name_str, name);
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
@@ -909,7 +912,7 @@ static JNINativeMethod sMethods[] = {
    {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative},
    {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z",
     (void*)clccResponseNative},
    {"phoneStateChangeNative", "(IIILjava/lang/String;I[B)Z",
    {"phoneStateChangeNative", "(IIILjava/lang/String;ILjava/lang/String;[B)Z",
     (void*)phoneStateChangeNative},
    {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative},
    {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative},
+16 −4
Original line number Diff line number Diff line
@@ -42,13 +42,19 @@ class HeadsetCallState extends HeadsetMessageObject {
     * Phone number type
     */
    int mType;
    /**
     * Caller display name
     */
    String mName;

    HeadsetCallState(int numActive, int numHeld, int callState, String number, int type) {
    HeadsetCallState(int numActive, int numHeld, int callState, String number, int type,
            String name) {
        mNumActive = numActive;
        mNumHeld = numHeld;
        mCallState = callState;
        mNumber = number;
        mType = type;
        mName = name;
    }

    @Override
@@ -69,7 +75,13 @@ class HeadsetCallState extends HeadsetMessageObject {
        } else {
            builder.append("***");
        }
        builder.append(mNumber).append(", type=").append(mType).append("]");
        builder.append(", type=").append(mType).append(", name=");
        if (mName == null) {
            builder.append("null");
        } else {
            builder.append("***");
        }
        builder.append("]");
    }

    @Override
@@ -83,11 +95,11 @@ class HeadsetCallState extends HeadsetMessageObject {
        HeadsetCallState that = (HeadsetCallState) object;
        return mNumActive == that.mNumActive && mNumHeld == that.mNumHeld
                && mCallState == that.mCallState && Objects.equals(mNumber, that.mNumber)
                && mType == that.mType;
                && mType == that.mType && Objects.equals(mName, that.mName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mNumActive, mNumHeld, mCallState, mNumber, mType);
        return Objects.hash(mNumActive, mNumHeld, mCallState, mNumber, mType, mName);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ public class HeadsetNativeInterface {
    @VisibleForTesting
    public boolean phoneStateChange(BluetoothDevice device, HeadsetCallState callState) {
        return phoneStateChangeNative(callState.mNumActive, callState.mNumHeld,
                callState.mCallState, callState.mNumber, callState.mType,
                callState.mCallState, callState.mNumber, callState.mType, callState.mName,
                Utils.getByteAddress(device));
    }

@@ -493,7 +493,7 @@ public class HeadsetNativeInterface {
    private native boolean copsResponseNative(String operatorName, byte[] address);

    private native boolean phoneStateChangeNative(int numActive, int numHeld, int callState,
            String number, int type, byte[] address);
            String number, int type, String name, byte[] address);

    private native boolean setScoAllowedNative(boolean value);

+10 −9
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ import java.util.Objects;
 * Provides Bluetooth Headset and Handsfree profile, as a service in the Bluetooth application.
 *
 * Three modes for SCO audio:
 * Mode 1: Telecom call through {@link #phoneStateChanged(int, int, int, String, int, boolean)}
 * Mode 1: Telecom call through {@link #phoneStateChanged(int, int, int, String, int, String,
 *         boolean)}
 * Mode 2: Virtual call through {@link #startScoUsingVirtualVoiceCall()}
 * Mode 3: Voice recognition through {@link #startVoiceRecognition(BluetoothDevice)}
 *
@@ -600,12 +601,12 @@ public class HeadsetService extends ProfileService {

        @Override
        public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
                int type) {
                int type, String name) {
            HeadsetService service = getService();
            if (service == null) {
                return;
            }
            service.phoneStateChanged(numActive, numHeld, callState, number, type, false);
            service.phoneStateChanged(numActive, numHeld, callState, number, type, name, false);
        }

        @Override
@@ -1221,9 +1222,9 @@ public class HeadsetService extends ProfileService {
            }
            mVirtualCallStarted = true;
            // Send virtual phone state changed to initialize SCO
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0, true);
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0, true);
            phoneStateChanged(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, true);
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0, "", true);
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0, "", true);
            phoneStateChanged(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, "", true);
            return true;
        }
    }
@@ -1239,7 +1240,7 @@ public class HeadsetService extends ProfileService {
            }
            mVirtualCallStarted = false;
            // 2. Send virtual phone state changed to close SCO
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, true);
            phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, "", true);
        }
        return true;
    }
@@ -1452,7 +1453,7 @@ public class HeadsetService extends ProfileService {
    }

    private void phoneStateChanged(int numActive, int numHeld, int callState, String number,
            int type, boolean isVirtualCall) {
            int type, String name, boolean isVirtualCall) {
        enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "Need MODIFY_PHONE_STATE permission");
        synchronized (mStateMachines) {
            // Should stop all other audio mode in this case
@@ -1498,7 +1499,7 @@ public class HeadsetService extends ProfileService {
        });
        doForEachConnectedStateMachine(
                stateMachine -> stateMachine.sendMessage(HeadsetStateMachine.CALL_STATE_CHANGED,
                        new HeadsetCallState(numActive, numHeld, callState, number, type)));
                        new HeadsetCallState(numActive, numHeld, callState, number, type, name)));
        mStateMachinesThread.getThreadHandler().post(() -> {
            if (callState == HeadsetHalConstants.CALL_STATE_IDLE
                    && mSystemInterface.isCallIdle() && !isAudioOn()) {
+37 −10
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ public class HeadsetServiceAndStateMachineTest {
    private static final int MAX_HEADSET_CONNECTIONS = 5;
    private static final ParcelUuid[] FAKE_HEADSET_UUID = {BluetoothUuid.Handsfree};
    private static final String TEST_PHONE_NUMBER = "1234567890";
    private static final String TEST_CALLER_ID = "Test Name";

    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

@@ -473,12 +474,12 @@ public class HeadsetServiceAndStateMachineTest {
        verifyVirtualCallStartSequenceInvocations(connectedDevices);
        // Virtual call should be preempted by telecom call
        mHeadsetServiceBinder.phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_INCOMING,
                TEST_PHONE_NUMBER, 128);
                TEST_PHONE_NUMBER, 128, "");
        Assert.assertFalse(mHeadsetService.isVirtualCallStarted());
        verifyVirtualCallStopSequenceInvocations(connectedDevices);
        verifyCallStateToNativeInvocation(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_INCOMING,
                        TEST_PHONE_NUMBER, 128), connectedDevices);
                        TEST_PHONE_NUMBER, 128, ""), connectedDevices);
    }

    /**
@@ -575,19 +576,19 @@ public class HeadsetServiceAndStateMachineTest {
                IntentMatchers.hasData(dialOutUri)), Intents.times(1));
        // Verify that phone state update confirms the dial out event
        mHeadsetServiceBinder.phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_DIALING,
                TEST_PHONE_NUMBER, 128);
                TEST_PHONE_NUMBER, 128, "");
        HeadsetCallState dialingCallState =
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING,
                        TEST_PHONE_NUMBER, 128);
                        TEST_PHONE_NUMBER, 128, "");
        verifyCallStateToNativeInvocation(dialingCallState, connectedDevices);
        verify(mNativeInterface).atResponseCode(dialingOutDevice,
                HeadsetHalConstants.AT_RESPONSE_OK, 0);
        // Verify that IDLE phone state clears the dialing out flag
        mHeadsetServiceBinder.phoneStateChanged(1, 0, HeadsetHalConstants.CALL_STATE_IDLE,
                TEST_PHONE_NUMBER, 128);
                TEST_PHONE_NUMBER, 128, "");
        HeadsetCallState activeCallState =
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING,
                        TEST_PHONE_NUMBER, 128);
                        TEST_PHONE_NUMBER, 128, "");
        verifyCallStateToNativeInvocation(activeCallState, connectedDevices);
        Assert.assertFalse(mHeadsetService.hasDeviceInitiatedDialingOut());
    }
@@ -1072,6 +1073,32 @@ public class HeadsetServiceAndStateMachineTest {
        verifyNoMoreInteractions(mNativeInterface);
    }

    /**
     * Test to verify the call state and caller information are correctly delivered
     * {@link BluetoothHeadset#phoneStateChanged(int, int, int, String, int, String, boolean)}
     */
    @Test
    public void testPhoneStateChangedWithIncomingCallState() throws RemoteException {
        // Connect HF
        for (int i = 0; i < MAX_HEADSET_CONNECTIONS; ++i) {
            BluetoothDevice device = TestUtils.getTestDevice(mAdapter, i);
            connectTestDevice(device);
            Assert.assertThat(mHeadsetServiceBinder.getConnectedDevices(),
                    Matchers.containsInAnyOrder(mBondedDevices.toArray()));
            Assert.assertThat(mHeadsetServiceBinder.getDevicesMatchingConnectionStates(
                    new int[]{BluetoothProfile.STATE_CONNECTED}),
                    Matchers.containsInAnyOrder(mBondedDevices.toArray()));
        }
        List<BluetoothDevice> connectedDevices = mHeadsetServiceBinder.getConnectedDevices();
        Assert.assertThat(connectedDevices, Matchers.containsInAnyOrder(mBondedDevices.toArray()));
        // Incoming call update by telecom
        mHeadsetServiceBinder.phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_INCOMING,
                TEST_PHONE_NUMBER, 128, TEST_CALLER_ID);
        HeadsetCallState incomingCallState = new HeadsetCallState(0, 0,
                HeadsetHalConstants.CALL_STATE_INCOMING, TEST_PHONE_NUMBER, 128, TEST_CALLER_ID);
        verifyCallStateToNativeInvocation(incomingCallState, connectedDevices);
    }

    private void startVoiceRecognitionFromHf(BluetoothDevice device) {
        // Start voice recognition
        HeadsetStackEvent startVrEvent =
@@ -1178,19 +1205,19 @@ public class HeadsetServiceAndStateMachineTest {
    private void verifyVirtualCallStartSequenceInvocations(List<BluetoothDevice> connectedDevices) {
        // Do not verify HeadsetPhoneState changes as it is verified in HeadsetServiceTest
        verifyCallStateToNativeInvocation(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0),
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0, ""),
                connectedDevices);
        verifyCallStateToNativeInvocation(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0),
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0, ""),
                connectedDevices);
        verifyCallStateToNativeInvocation(
                new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0),
                new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, ""),
                connectedDevices);
    }

    private void verifyVirtualCallStopSequenceInvocations(List<BluetoothDevice> connectedDevices) {
        verifyCallStateToNativeInvocation(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0),
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, ""),
                connectedDevices);
    }

Loading