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

Commit 40c727d0 authored by Hansong Zhang's avatar Hansong Zhang Committed by android-build-merger
Browse files

Merge changes from topics "hearing-aid-white-list", "hearing-aid" into pi-dev

am: 79a5f4d1

Change-Id: Ie3671401583fff7528eff61796320140c136d69c
parents 0e30e333 79a5f4d1
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -194,6 +194,40 @@ static jboolean disconnectHearingAidNative(JNIEnv* env, jobject object,
  return JNI_TRUE;
}

static jboolean addToWhiteListNative(JNIEnv* env, jobject object,
                                     jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sHearingAidInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = (RawAddress*)addr;
  sHearingAidInterface->AddToWhiteList(*tmpraw);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static jboolean removeFromWhiteListNative(JNIEnv* env, jobject object,
                                          jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sHearingAidInterface) return JNI_FALSE;

  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  RawAddress* tmpraw = (RawAddress*)addr;
  sHearingAidInterface->RemoveFromWhiteList(*tmpraw);
  env->ReleaseByteArrayElements(address, addr, 0);
  return JNI_TRUE;
}

static void setVolumeNative(JNIEnv* env, jclass clazz, jint volume) {
  if (!sHearingAidInterface) {
    LOG(ERROR) << __func__
@@ -209,6 +243,8 @@ static JNINativeMethod sMethods[] = {
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"connectHearingAidNative", "([B)Z", (void*)connectHearingAidNative},
    {"disconnectHearingAidNative", "([B)Z", (void*)disconnectHearingAidNative},
    {"addToWhiteListNative", "([B)Z", (void*)addToWhiteListNative},
    {"removeFromWhiteListNative", "([B)Z", (void*)removeFromWhiteListNative},
    {"setVolumeNative", "(I)V", (void*)setVolumeNative},
};

+24 −0
Original line number Diff line number Diff line
@@ -104,6 +104,28 @@ public class HearingAidNativeInterface {
        return disconnectHearingAidNative(getByteAddress(device));
    }

    /**
     * Add a hearing aid device to white list.
     *
     * @param device the remote device
     * @return true on success, otherwise false.
     */
    @VisibleForTesting (otherwise = VisibleForTesting.PACKAGE_PRIVATE)
    public boolean addToWhiteList(BluetoothDevice device) {
        return addToWhiteListNative(getByteAddress(device));
    }

    /**
     * Remove a hearing aid device from white list.
     *
     * @param device the remote device
     * @return true on success, otherwise false.
     */
    @VisibleForTesting (otherwise = VisibleForTesting.PACKAGE_PRIVATE)
    public boolean removeFromWhiteList(BluetoothDevice device) {
        return removeFromWhiteListNative(getByteAddress(device));
    }

    /**
     * Sets the HearingAid volume
     * @param volume
@@ -168,5 +190,7 @@ public class HearingAidNativeInterface {
    private native void cleanupNative();
    private native boolean connectHearingAidNative(byte[] address);
    private native boolean disconnectHearingAidNative(byte[] address);
    private native boolean addToWhiteListNative(byte[] address);
    private native boolean removeFromWhiteListNative(byte[] address);
    private native void setVolumeNative(int volume);
}
+22 −13
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@ public class HearingAidService extends ProfileService {
    // Upper limit of all HearingAid devices: Bonded or Connected
    private static final int MAX_HEARING_AID_STATE_MACHINES = 10;
    private static HearingAidService sHearingAidService;
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    static int sConnectTimeoutForEachSideMs = 8000;
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    static int sCheckWhitelistTimeoutMs = 16000;

    private AdapterService mAdapterService;
    private HandlerThread mStateMachinesThread;
@@ -243,14 +247,6 @@ public class HearingAidService extends ProfileService {
            }
        }

        synchronized (mStateMachines) {
            HearingAidStateMachine smConnect = getOrCreateStateMachine(device);
            if (smConnect == null) {
                Log.e(TAG, "Cannot connect to " + device + " : no state machine");
            }
            smConnect.sendMessage(HearingAidStateMachine.CONNECT);
        }

        for (BluetoothDevice storedDevice : mDeviceHiSyncIdMap.keySet()) {
            if (device.equals(storedDevice)) {
                continue;
@@ -263,14 +259,27 @@ public class HearingAidService extends ProfileService {
                        Log.e(TAG, "Ignored connect request for " + device + " : no state machine");
                        continue;
                    }
                    sm.sendMessage(HearingAidStateMachine.CONNECT);
                    sm.sendMessage(HearingAidStateMachine.CONNECT,
                            sConnectTimeoutForEachSideMs);
                    sm.sendMessageDelayed(HearingAidStateMachine.CHECK_WHITELIST_CONNECTION,
                            sCheckWhitelistTimeoutMs);
                }
                if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID
                        && !device.equals(storedDevice)) {
                break;
            }
        }

        synchronized (mStateMachines) {
            HearingAidStateMachine smConnect = getOrCreateStateMachine(device);
            if (smConnect == null) {
                Log.e(TAG, "Cannot connect to " + device + " : no state machine");
            } else {
                smConnect.sendMessage(HearingAidStateMachine.CONNECT,
                        sConnectTimeoutForEachSideMs * 2);
                smConnect.sendMessageDelayed(HearingAidStateMachine.CHECK_WHITELIST_CONNECTION,
                        sCheckWhitelistTimeoutMs);
            }
        }

        return true;
    }

+21 −12
Original line number Diff line number Diff line
@@ -69,13 +69,15 @@ final class HearingAidStateMachine extends StateMachine {

    static final int CONNECT = 1;
    static final int DISCONNECT = 2;
    static final int CHECK_WHITELIST_CONNECTION = 3;
    @VisibleForTesting
    static final int STACK_EVENT = 101;
    private static final int CONNECT_TIMEOUT = 201;

    // NOTE: the value is not "final" - it is modified in the unit tests
    @VisibleForTesting
    static int sConnectTimeoutMs = 30000;        // 30s
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    static int sConnectTimeoutMs = 16000;
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    static int sDisconnectTimeoutMs = 16000;

    private Disconnected mDisconnected;
    private Connecting mConnecting;
@@ -172,6 +174,12 @@ final class HearingAidStateMachine extends StateMachine {
                case DISCONNECT:
                    Log.w(TAG, "Disconnected: DISCONNECT ignored: " + mDevice);
                    break;
                case CHECK_WHITELIST_CONNECTION:
                    if (mService.getConnectedDevices().isEmpty()) {
                        log("No device connected, remove this device from white list");
                        mNativeInterface.removeFromWhiteList(mDevice);
                    }
                    break;
                case STACK_EVENT:
                    HearingAidStackEvent event = (HearingAidStackEvent) message.obj;
                    if (DBG) {
@@ -238,7 +246,9 @@ final class HearingAidStateMachine extends StateMachine {
        public void enter() {
            Log.i(TAG, "Enter Connecting(" + mDevice + "): "
                    + messageWhatToString(getCurrentMessage().what));
            sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
            int timeout = getCurrentMessage().arg1 != 0
                    ? getCurrentMessage().arg1 : sConnectTimeoutMs;
            sendMessageDelayed(CONNECT_TIMEOUT, timeout);
            mConnectionState = BluetoothProfile.STATE_CONNECTING;
            broadcastConnectionState(mConnectionState, mLastConnectionState);
        }
@@ -261,14 +271,13 @@ final class HearingAidStateMachine extends StateMachine {
                    deferMessage(message);
                    break;
                case CONNECT_TIMEOUT:
                    Log.w(TAG, "Connecting connection timeout: " + mDevice);
                    Log.w(TAG, "Connecting connection timeout: " + mDevice + ". Try whitelist");
                    mNativeInterface.disconnectHearingAid(mDevice);
                    HearingAidStackEvent disconnectEvent =
                            new HearingAidStackEvent(
                                    HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
                    disconnectEvent.device = mDevice;
                    disconnectEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_DISCONNECTED;
                    sendMessage(STACK_EVENT, disconnectEvent);
                    mNativeInterface.addToWhiteList(mDevice);
                    transitionTo(mDisconnected);
                    break;
                case CHECK_WHITELIST_CONNECTION:
                    deferMessage(message);
                    break;
                case DISCONNECT:
                    log("Connecting: connection canceled to " + mDevice);
@@ -325,7 +334,7 @@ final class HearingAidStateMachine extends StateMachine {
        public void enter() {
            Log.i(TAG, "Enter Disconnecting(" + mDevice + "): "
                    + messageWhatToString(getCurrentMessage().what));
            sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
            sendMessageDelayed(CONNECT_TIMEOUT, sDisconnectTimeoutMs);
            mConnectionState = BluetoothProfile.STATE_DISCONNECTING;
            broadcastConnectionState(mConnectionState, mLastConnectionState);
        }
+4 −1
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ public class HearingAidServiceTest {
                .getBondState(any(BluetoothDevice.class));
        doReturn(new ParcelUuid[]{BluetoothUuid.HearingAid}).when(mAdapterService)
                .getRemoteUuids(any(BluetoothDevice.class));
        HearingAidService.sConnectTimeoutForEachSideMs = 1000;
        HearingAidService.sCheckWhitelistTimeoutMs = 2000;
    }

    @After
@@ -343,7 +345,8 @@ public class HearingAidServiceTest {
                mService.getConnectionState(mLeftDevice));

        // Verify the connection state broadcast, and that we are in Disconnected state
        verifyConnectionStateIntent(HearingAidStateMachine.sConnectTimeoutMs * 2, mLeftDevice,
        verifyConnectionStateIntent(HearingAidService.sConnectTimeoutForEachSideMs * 3,
                mLeftDevice,
                BluetoothProfile.STATE_DISCONNECTED,
                BluetoothProfile.STATE_CONNECTING);
        Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
Loading