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

Commit f6c9484d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Bluetooth: HID : Add support for Set Idle and Get Idle commands"

parents b9d6b7fd 2121b51c
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ namespace android {
static jmethodID method_onConnectStateChanged;
static jmethodID method_onGetProtocolMode;
static jmethodID method_onGetReport;
static jmethodID method_onGetIdleTime;
static jmethodID method_onVirtualUnplug;

static const bthh_interface_t *sBluetoothHidInterface = NULL;
@@ -96,6 +97,29 @@ static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_st
    sCallbackEnv->DeleteLocalRef(addr);
}

static void get_idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_time) {
    jbyteArray addr;

    CHECK_CALLBACK_ENV
    if (hh_status != BTHH_OK) {
        ALOGE("BTHH Status is not OK!");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }
    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr, (jint) idle_time);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}

static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status) {
    ALOGD("call to virtual_unplug_callback");
    jbyteArray addr;
@@ -135,7 +159,7 @@ static bthh_callbacks_t sBluetoothHidCallbacks = {
    connection_state_callback,
    NULL,
    get_protocol_mode_callback,
    NULL,
    get_idle_time_callback,
    NULL,
    virtual_unplug_callback
};
@@ -149,6 +173,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {

    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged", "([BI)V");
    method_onGetProtocolMode = env->GetMethodID(clazz, "onGetProtocolMode", "([BI)V");
    method_onGetIdleTime = env->GetMethodID(clazz, "onGetIdleTime", "([BI)V");
    method_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V");

/*
@@ -442,6 +467,52 @@ static jboolean sendDataNative(JNIEnv *env, jobject object, jbyteArray address,

}

static jboolean getIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address) {
    bt_status_t status;
    jbyte *addr;
    jboolean ret = JNI_TRUE;
    bthh_protocol_mode_t protocolMode;
    if (!sBluetoothHidInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        ALOGE("Bluetooth device address null");
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t *) addr)) !=
         BT_STATUS_SUCCESS) {
        ALOGE("Failed get protocol mode, status: %d", status);
        ret = JNI_FALSE;
    }
    env->ReleaseByteArrayElements(address, addr, 0);

    return ret;
}

static jboolean setIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address, jbyte idle_time) {
    bt_status_t status;
    jbyte *addr;
    jboolean ret = JNI_TRUE;
    bthh_protocol_mode_t protocolMode;
    if (!sBluetoothHidInterface) return JNI_FALSE;

    addr = env->GetByteArrayElements(address, NULL);
    if (!addr) {
        ALOGE("Bluetooth device address null");
        return JNI_FALSE;
    }

    if ( (status = sBluetoothHidInterface->set_idle_time((bt_bdaddr_t *) addr, idle_time)) !=
         BT_STATUS_SUCCESS) {
        ALOGE("Failed get protocol mode, status: %d", status);
        ret = JNI_FALSE;
    }
    env->ReleaseByteArrayElements(address, addr, 0);

    return ret;
}

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void *) classInitNative},
    {"initializeNative", "()V", (void *) initializeNative},
@@ -454,6 +525,8 @@ static JNINativeMethod sMethods[] = {
    {"getReportNative", "([BBBI)Z", (void *) getReportNative},
    {"setReportNative", "([BBLjava/lang/String;)Z", (void *) setReportNative},
    {"sendDataNative", "([BLjava/lang/String;)Z", (void *) sendDataNative},
    {"getIdleTimeNative", "([B)Z", (void *) getIdleTimeNative},
    {"setIdleTimeNative", "([BB)Z", (void *) setIdleTimeNative},
};

int register_com_android_bluetooth_hid(JNIEnv* env)
+87 −1
Original line number Diff line number Diff line
@@ -67,6 +67,9 @@ public class HidService extends ProfileService {
    private static final int MESSAGE_SET_REPORT = 10;
    private static final int MESSAGE_SEND_DATA = 11;
    private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12;
    private static final int MESSAGE_GET_IDLE_TIME = 13;
    private static final int MESSAGE_ON_GET_IDLE_TIME = 14;
    private static final int MESSAGE_SET_IDLE_TIME = 15;

    static {
        classInitNative();
@@ -268,6 +271,31 @@ public class HidService extends ProfileService {
                    broadcastVirtualUnplugStatus(device, status);
                }
                break;
                case MESSAGE_GET_IDLE_TIME:
                {
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    if(!getIdleTimeNative(Utils.getByteAddress(device)) ) {
                        Log.e(TAG, "Error: get idle time native returns false");
                    }
                }
                break;
                case MESSAGE_ON_GET_IDLE_TIME:
                {
                    BluetoothDevice device = getDevice((byte[]) msg.obj);
                    int idleTime = msg.arg1;
                    broadcastIdleTime(device, idleTime);
                }
                break;
                case MESSAGE_SET_IDLE_TIME:
                {
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    Bundle data = msg.getData();
                    byte idleTime = data.getByte(BluetoothInputDevice.EXTRA_IDLE_TIME);
                    if(!setIdleTimeNative(Utils.getByteAddress(device), idleTime)) {
                        Log.e(TAG, "Error: get idle time native returns false");
                    }
                }
                break;
            }
        }
    };
@@ -375,6 +403,18 @@ public class HidService extends ProfileService {
            if (service == null) return false;
            return service.sendData(device, report);
        }

        public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
            HidService service = getService();
            if (service == null) return false;
            return service.setIdleTime(device, idleTime);
        }

        public boolean getIdleTime(BluetoothDevice device) {
            HidService service = getService();
            if (service == null) return false;
            return service.getIdleTime(device);
        }
    };

    //APIs
@@ -538,6 +578,34 @@ public class HidService extends ProfileService {
        return true ;*/
    }

    boolean getIdleTime(BluetoothDevice device) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                       "Need BLUETOOTH_ADMIN permission");
        int state = this.getConnectionState(device);
        if (state != BluetoothInputDevice.STATE_CONNECTED) {
            return false;
        }
        Message msg = mHandler.obtainMessage(MESSAGE_GET_IDLE_TIME,device);
        mHandler.sendMessage(msg);
        return true;
    }

    boolean setIdleTime(BluetoothDevice device, byte idleTime) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                       "Need BLUETOOTH_ADMIN permission");
        int state = this.getConnectionState(device);
        if (state != BluetoothInputDevice.STATE_CONNECTED) {
            return false;
        }
        Message msg = mHandler.obtainMessage(MESSAGE_SET_IDLE_TIME);
        msg.obj = device;
        Bundle data = new Bundle();
        data.putByte(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime);
        msg.setData(data);
        mHandler.sendMessage(msg);
        return true;
    }

    private void onGetProtocolMode(byte[] address, int mode) {
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE);
        msg.obj = address;
@@ -552,6 +620,13 @@ public class HidService extends ProfileService {
        mHandler.sendMessage(msg);
    }

    private void onGetIdleTime(byte[] address, int idleTime) {
        Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_IDLE_TIME);
        msg.obj = address;
        msg.arg1 = idleTime;
        mHandler.sendMessage(msg);
    }

    private void onConnectStateChanged(byte[] address, int state) {
        Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED);
        msg.obj = address;
@@ -601,6 +676,15 @@ public class HidService extends ProfileService {
        sendBroadcast(intent, BLUETOOTH_PERM);
    }

    private void broadcastIdleTime(BluetoothDevice device, int idleTime) {
        Intent intent = new Intent(BluetoothInputDevice.ACTION_IDLE_TIME_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothInputDevice.EXTRA_IDLE_TIME, idleTime);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        sendBroadcast(intent, BLUETOOTH_PERM);
        if (DBG) log("Idle time (" + device + "): " + idleTime);
    }

    private boolean okToConnect(BluetoothDevice device) {
        AdapterService adapterService = AdapterService.getAdapterService();
        //check if it is inbound connection in Quiet mode, priority and Bond status
@@ -647,4 +731,6 @@ public class HidService extends ProfileService {
    private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize);
    private native boolean setReportNative(byte[] btAddress, byte reportType, String report);
    private native boolean sendDataNative(byte[] btAddress, String report);
    private native boolean setIdleTimeNative(byte[] btAddress, byte idleTime);
    private native boolean getIdleTimeNative(byte[] btAddress);
}